diff --git a/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.css b/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.css index 906f8e71f20..e578acdcf22 100644 --- a/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.css +++ b/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.css @@ -20,12 +20,32 @@ height: 50px; border-radius: 50%; border: 5px solid rgba(0, 0, 0, 0.1); - border-left-color: rgba(37, 99, 235, 1); + border-left-color: #7147e8; background: transparent; animation: rotate 1s linear infinite; margin: 6rem auto; } +.loader.loader-sm { + width: 20px; + height: 20px; + border-width: 2px; + margin: auto; +} + +.loader.loader-success { + border-left-color: #51c41a; +} + +.loader.loader-error { + border-left-color: #ff4c3b; +} + +.loader.loader-white { + border-color: #ffffff; + border-right-color: transparent; +} + @keyframes rotate { from { transform: rotate(0); diff --git a/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.tsx b/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.tsx index 274b56f04f5..bf44b4c1e4c 100644 --- a/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/components/Loader/Loader.tsx @@ -15,10 +15,46 @@ * limitations under the License. */ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import './Loader.css'; -const Loader: Function = (): JSX.Element => { - return
; + +type Props = { + size?: 'default' | 'small'; + type?: 'default' | 'success' | 'error' | 'white'; +}; + +const Loader: FunctionComponent = ({ + size = 'default', + type = 'default', +}: Props): JSX.Element => { + let classes = 'loader'; + switch (size) { + case 'small': + classes += ' loader-sm'; + + break; + default: + break; + } + + switch (type) { + case 'success': + classes += ' loader-success'; + + break; + case 'error': + classes += ' loader-error'; + + break; + case 'white': + classes += ' loader-white'; + + break; + default: + break; + } + + return
; }; export default Loader; diff --git a/catalog-rest-service/src/main/resources/ui/src/components/my-data-details/ManageTab.tsx b/catalog-rest-service/src/main/resources/ui/src/components/my-data-details/ManageTab.tsx index b98f32b6ef9..963dd7df8f6 100644 --- a/catalog-rest-service/src/main/resources/ui/src/components/my-data-details/ManageTab.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/components/my-data-details/ManageTab.tsx @@ -24,11 +24,15 @@ import SVGIcons from '../../utils/SvgUtils'; import { Button } from '../buttons/Button/Button'; import CardListItem from '../card-list/CardListItem/CardWithListItems'; import DropDownList from '../dropdown/DropDownList'; +import Loader from '../Loader/Loader'; type Props = { currentTier?: string; currentUser?: string; - onSave: (owner: TableDetail['owner'], tier: TableDetail['tier']) => void; + onSave: ( + owner: TableDetail['owner'], + tier: TableDetail['tier'] + ) => Promise; }; const ManageTab: FunctionComponent = ({ @@ -37,6 +41,10 @@ const ManageTab: FunctionComponent = ({ onSave, }: Props) => { const { data } = cardData; + const [loading, setLoading] = useState(false); + const [status, setStatus] = useState<'initial' | 'waiting' | 'success'>( + 'initial' + ); const [activeTier, setActiveTier] = useState(currentTier); const [listVisible, setListVisible] = useState(false); const [listOwners] = useState(() => { @@ -81,6 +89,8 @@ const ManageTab: FunctionComponent = ({ }; const handleSave = () => { + setLoading(true); + setStatus('waiting'); // Save API call goes here... const newOwner: TableDetail['owner'] = owner !== currentUser @@ -90,7 +100,10 @@ const ManageTab: FunctionComponent = ({ } : undefined; const newTier = activeTier !== currentTier ? activeTier : undefined; - onSave(newOwner, newTier); + onSave(newOwner, newTier).catch(() => { + setStatus('initial'); + setLoading(false); + }); }; const handleCancel = () => { @@ -106,6 +119,18 @@ const ManageTab: FunctionComponent = ({ setOwner(currentUser); }, [currentUser]); + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 1000); + if (status === 'waiting') { + setStatus('success'); + setTimeout(() => { + setStatus('initial'); + }, 3000); + } + }, [currentTier, currentUser]); + return (
@@ -154,13 +179,34 @@ const ManageTab: FunctionComponent = ({ onClick={handleCancel}> Discard - + {loading ? ( + + ) : status === 'success' ? ( +