Micro interaction for manage tab (#139)

This commit is contained in:
darth-coder00 2021-08-13 14:56:12 +05:30 committed by GitHub
parent ddb1bc3f94
commit d9392c8ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 42 deletions

View File

@ -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);

View File

@ -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 <div className="loader" />;
type Props = {
size?: 'default' | 'small';
type?: 'default' | 'success' | 'error' | 'white';
};
const Loader: FunctionComponent<Props> = ({
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 <div className={classes} />;
};
export default Loader;

View File

@ -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<void>;
};
const ManageTab: FunctionComponent<Props> = ({
@ -37,6 +41,10 @@ const ManageTab: FunctionComponent<Props> = ({
onSave,
}: Props) => {
const { data } = cardData;
const [loading, setLoading] = useState<boolean>(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<Props> = ({
};
const handleSave = () => {
setLoading(true);
setStatus('waiting');
// Save API call goes here...
const newOwner: TableDetail['owner'] =
owner !== currentUser
@ -90,7 +100,10 @@ const ManageTab: FunctionComponent<Props> = ({
}
: 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<Props> = ({
setOwner(currentUser);
}, [currentUser]);
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 1000);
if (status === 'waiting') {
setStatus('success');
setTimeout(() => {
setStatus('initial');
}, 3000);
}
}, [currentTier, currentUser]);
return (
<div className="tw-max-w-3xl tw-mx-auto">
<div className="tw-mt-2 tw-mb-4 tw-pb-4 tw-border-b tw-border-separator">
@ -154,13 +179,34 @@ const ManageTab: FunctionComponent<Props> = ({
onClick={handleCancel}>
Discard
</Button>
<Button
size="regular"
theme="primary"
variant="contained"
onClick={handleSave}>
Save
</Button>
{loading ? (
<Button
disabled
className="tw-w-16 tw-h-10 disabled:tw-opacity-100"
size="regular"
theme="primary"
variant="contained">
<Loader size="small" type="white" />
</Button>
) : status === 'success' ? (
<Button
disabled
className="tw-w-16 tw-h-10 disabled:tw-opacity-100"
size="regular"
theme="primary"
variant="contained">
<i aria-hidden="true" className="fa fa-check" />
</Button>
) : (
<Button
className="tw-w-16 tw-h-10"
size="regular"
theme="primary"
variant="contained"
onClick={handleSave}>
Save
</Button>
)}
</div>
</div>
);

View File

@ -223,31 +223,38 @@ const MyDataDetailsPage = () => {
const onSettingsUpdate = (
newOwner?: TableDetail['owner'],
newTier?: TableDetail['tier']
) => {
if (newOwner || newTier) {
const tierTag: TableDetail['tags'] = newTier
? [
...getTagsWithoutTier(tableDetails.tags),
{ tagFQN: newTier, labelType: 'Manual', state: 'Confirmed' },
]
: tableDetails.tags;
const updatedTableDetails = {
...tableDetails,
owner: newOwner
? {
...tableDetails.owner,
...newOwner,
}
: tableDetails.owner,
// tier: newTier || tableDetails.tier,
tags: tierTag,
};
saveUpdatedTableData(updatedTableDetails).then((res) => {
setTableDetails(res.data);
setOwner(res.data.owner);
setTier(getTierFromTableTags(res.data.tags));
});
}
): Promise<void> => {
return new Promise<void>((resolve, reject) => {
if (newOwner || newTier) {
const tierTag: TableDetail['tags'] = newTier
? [
...getTagsWithoutTier(tableDetails.tags),
{ tagFQN: newTier, labelType: 'Manual', state: 'Confirmed' },
]
: tableDetails.tags;
const updatedTableDetails = {
...tableDetails,
owner: newOwner
? {
...tableDetails.owner,
...newOwner,
}
: tableDetails.owner,
// tier: newTier || tableDetails.tier,
tags: tierTag,
};
saveUpdatedTableData(updatedTableDetails)
.then((res) => {
setTableDetails(res.data);
setOwner(res.data.owner);
setTier(getTierFromTableTags(res.data.tags));
resolve();
})
.catch(() => reject());
} else {
reject();
}
});
};
const onSuggest = (updatedHTML: string) => {

View File

@ -67,10 +67,6 @@ module.exports = {
search: '#D5D6D9',
},
colors: {
success: success,
error: error,
warning: warning,
info: info,
'grey-body': textBody,
'grey-muted': textMuted,
'grey-muted-lite': textMutedLite,
@ -83,6 +79,10 @@ module.exports = {
'body-main': bodyBG,
'body-hover': bodyHoverBG,
tag: tagBG,
success: success,
error: error,
warning: warning,
info: info,
},
fontFamily: {
sans: ['Inter', ...defaultTheme.fontFamily.sans],
@ -117,6 +117,7 @@ module.exports = {
borderStyle: ['hover'],
borderWidth: ['hover'],
display: ['group-hover'],
opacity: ['disabled'],
},
},
plugins: [require('@tailwindcss/custom-forms')],