[WEB-570] chore: toast refactor (#3836)
* new toast setup * chore: new toast implementation. * chore: move toast component to ui package. * chore: replace `setToast` with `setPromiseToast` in required places for better UX. * chore: code cleanup. * chore: update theme. * fix: theme switching issue. * chore: remove toast from issue update operations. * chore: add promise toast for add/ remove issue to cycle/ module and remove local spinners. --------- Co-authored-by: rahulramesha <rahulramesham@gmail.com>
This commit is contained in:
parent
c06ef4d1d7
commit
53367a6bc4
167 changed files with 1827 additions and 1896 deletions
|
|
@ -4,9 +4,8 @@ import { Dialog, Transition } from "@headlessui/react";
|
|||
import { observer } from "mobx-react-lite";
|
||||
// hooks
|
||||
import { useEventTracker, useModule } from "hooks/store";
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "@plane/ui";
|
||||
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
|
||||
// icons
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
// types
|
||||
|
|
@ -30,8 +29,6 @@ export const DeleteModuleModal: React.FC<Props> = observer((props) => {
|
|||
// store hooks
|
||||
const { captureModuleEvent } = useEventTracker();
|
||||
const { deleteModule } = useModule();
|
||||
// toast alert
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
|
|
@ -47,8 +44,8 @@ export const DeleteModuleModal: React.FC<Props> = observer((props) => {
|
|||
.then(() => {
|
||||
if (moduleId || peekModule) router.push(`/${workspaceSlug}/projects/${data.project_id}/modules`);
|
||||
handleClose();
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Module deleted successfully.",
|
||||
});
|
||||
|
|
@ -58,8 +55,8 @@ export const DeleteModuleModal: React.FC<Props> = observer((props) => {
|
|||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Module could not be deleted. Please try again.",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import { useForm } from "react-hook-form";
|
|||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// hooks
|
||||
import { useEventTracker, useModule, useProject } from "hooks/store";
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { TOAST_TYPE, setToast } from "@plane/ui";
|
||||
// components
|
||||
import { ModuleForm } from "components/modules";
|
||||
// types
|
||||
|
|
@ -36,8 +37,6 @@ export const CreateUpdateModuleModal: React.FC<Props> = observer((props) => {
|
|||
const { captureModuleEvent } = useEventTracker();
|
||||
const { workspaceProjectIds } = useProject();
|
||||
const { createModule, updateModuleDetails } = useModule();
|
||||
// toast alert
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const handleClose = () => {
|
||||
reset(defaultValues);
|
||||
|
|
@ -55,8 +54,8 @@ export const CreateUpdateModuleModal: React.FC<Props> = observer((props) => {
|
|||
await createModule(workspaceSlug.toString(), selectedProjectId, payload)
|
||||
.then((res) => {
|
||||
handleClose();
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Module created successfully.",
|
||||
});
|
||||
|
|
@ -66,8 +65,8 @@ export const CreateUpdateModuleModal: React.FC<Props> = observer((props) => {
|
|||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: err.detail ?? "Module could not be created. Please try again.",
|
||||
});
|
||||
|
|
@ -86,8 +85,8 @@ export const CreateUpdateModuleModal: React.FC<Props> = observer((props) => {
|
|||
.then((res) => {
|
||||
handleClose();
|
||||
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Module updated successfully.",
|
||||
});
|
||||
|
|
@ -97,8 +96,8 @@ export const CreateUpdateModuleModal: React.FC<Props> = observer((props) => {
|
|||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: err.detail ?? "Module could not be updated. Please try again.",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@ import { observer } from "mobx-react-lite";
|
|||
import { Info, LinkIcon, Pencil, Star, Trash2 } from "lucide-react";
|
||||
// hooks
|
||||
import { useEventTracker, useMember, useModule, useUser } from "hooks/store";
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { CreateUpdateModuleModal, DeleteModuleModal } from "components/modules";
|
||||
// ui
|
||||
import { Avatar, AvatarGroup, CustomMenu, LayersIcon, Tooltip } from "@plane/ui";
|
||||
import { Avatar, AvatarGroup, CustomMenu, LayersIcon, Tooltip, TOAST_TYPE, setToast, setPromiseToast } from "@plane/ui";
|
||||
// helpers
|
||||
import { copyUrlToClipboard } from "helpers/string.helper";
|
||||
import { renderFormattedDate } from "helpers/date-time.helper";
|
||||
|
|
@ -30,8 +29,6 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
// toast alert
|
||||
const { setToastAlert } = useToast();
|
||||
// store hooks
|
||||
const {
|
||||
membership: { currentProjectRole },
|
||||
|
|
@ -48,21 +45,27 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
e.preventDefault();
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
addModuleToFavorites(workspaceSlug.toString(), projectId.toString(), moduleId)
|
||||
.then(() => {
|
||||
const addToFavoritePromise = addModuleToFavorites(workspaceSlug.toString(), projectId.toString(), moduleId).then(
|
||||
() => {
|
||||
captureEvent(MODULE_FAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't add the module to favorites. Please try again.",
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
setPromiseToast(addToFavoritePromise, {
|
||||
loading: "Adding module to favorites...",
|
||||
success: {
|
||||
title: "Success!",
|
||||
message: () => "Module added to favorites.",
|
||||
},
|
||||
error: {
|
||||
title: "Error!",
|
||||
message: () => "Couldn't add the module to favorites. Please try again.",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleRemoveFromFavorites = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
|
|
@ -70,29 +73,37 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
e.preventDefault();
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
removeModuleFromFavorites(workspaceSlug.toString(), projectId.toString(), moduleId)
|
||||
.then(() => {
|
||||
captureEvent(MODULE_UNFAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't remove the module from favorites. Please try again.",
|
||||
});
|
||||
const removeFromFavoritePromise = removeModuleFromFavorites(
|
||||
workspaceSlug.toString(),
|
||||
projectId.toString(),
|
||||
moduleId
|
||||
).then(() => {
|
||||
captureEvent(MODULE_UNFAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
});
|
||||
|
||||
setPromiseToast(removeFromFavoritePromise, {
|
||||
loading: "Removing module from favorites...",
|
||||
success: {
|
||||
title: "Success!",
|
||||
message: () => "Module removed from favorites.",
|
||||
},
|
||||
error: {
|
||||
title: "Error!",
|
||||
message: () => "Couldn't remove the module from favorites. Please try again.",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleCopyText = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/modules/${moduleId}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Link Copied!",
|
||||
message: "Module link copied to clipboard.",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,11 +5,19 @@ import { observer } from "mobx-react-lite";
|
|||
import { Check, Info, LinkIcon, Pencil, Star, Trash2, User2 } from "lucide-react";
|
||||
// hooks
|
||||
import { useModule, useUser, useEventTracker, useMember } from "hooks/store";
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { CreateUpdateModuleModal, DeleteModuleModal } from "components/modules";
|
||||
// ui
|
||||
import { Avatar, AvatarGroup, CircularProgressIndicator, CustomMenu, Tooltip } from "@plane/ui";
|
||||
import {
|
||||
Avatar,
|
||||
AvatarGroup,
|
||||
CircularProgressIndicator,
|
||||
CustomMenu,
|
||||
Tooltip,
|
||||
TOAST_TYPE,
|
||||
setToast,
|
||||
setPromiseToast,
|
||||
} from "@plane/ui";
|
||||
// helpers
|
||||
import { copyUrlToClipboard } from "helpers/string.helper";
|
||||
import { renderFormattedDate } from "helpers/date-time.helper";
|
||||
|
|
@ -30,8 +38,6 @@ export const ModuleListItem: React.FC<Props> = observer((props) => {
|
|||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
// toast alert
|
||||
const { setToastAlert } = useToast();
|
||||
// store hooks
|
||||
const {
|
||||
membership: { currentProjectRole },
|
||||
|
|
@ -48,21 +54,27 @@ export const ModuleListItem: React.FC<Props> = observer((props) => {
|
|||
e.preventDefault();
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
addModuleToFavorites(workspaceSlug.toString(), projectId.toString(), moduleId)
|
||||
.then(() => {
|
||||
const addToFavoritePromise = addModuleToFavorites(workspaceSlug.toString(), projectId.toString(), moduleId).then(
|
||||
() => {
|
||||
captureEvent(MODULE_FAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't add the module to favorites. Please try again.",
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
setPromiseToast(addToFavoritePromise, {
|
||||
loading: "Adding module to favorites...",
|
||||
success: {
|
||||
title: "Success!",
|
||||
message: () => "Module added to favorites.",
|
||||
},
|
||||
error: {
|
||||
title: "Error!",
|
||||
message: () => "Couldn't add the module to favorites. Please try again.",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleRemoveFromFavorites = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
|
|
@ -70,29 +82,37 @@ export const ModuleListItem: React.FC<Props> = observer((props) => {
|
|||
e.preventDefault();
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
removeModuleFromFavorites(workspaceSlug.toString(), projectId.toString(), moduleId)
|
||||
.then(() => {
|
||||
captureEvent(MODULE_UNFAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't remove the module from favorites. Please try again.",
|
||||
});
|
||||
const removeFromFavoritePromise = removeModuleFromFavorites(
|
||||
workspaceSlug.toString(),
|
||||
projectId.toString(),
|
||||
moduleId
|
||||
).then(() => {
|
||||
captureEvent(MODULE_UNFAVORITED, {
|
||||
module_id: moduleId,
|
||||
element: "Grid layout",
|
||||
state: "SUCCESS",
|
||||
});
|
||||
});
|
||||
|
||||
setPromiseToast(removeFromFavoritePromise, {
|
||||
loading: "Removing module from favorites...",
|
||||
success: {
|
||||
title: "Success!",
|
||||
message: () => "Module removed from favorites.",
|
||||
},
|
||||
error: {
|
||||
title: "Error!",
|
||||
message: () => "Couldn't remove the module from favorites. Please try again.",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleCopyText = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/modules/${moduleId}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Link Copied!",
|
||||
message: "Module link copied to clipboard.",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,14 +16,22 @@ import {
|
|||
} from "lucide-react";
|
||||
// hooks
|
||||
import { useModule, useUser, useEventTracker } from "hooks/store";
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { LinkModal, LinksList, SidebarProgressStats } from "components/core";
|
||||
import { DeleteModuleModal } from "components/modules";
|
||||
import ProgressChart from "components/core/sidebar/progress-chart";
|
||||
import { DateRangeDropdown, MemberDropdown } from "components/dropdowns";
|
||||
// ui
|
||||
import { CustomMenu, Loader, LayersIcon, CustomSelect, ModuleStatusIcon, UserGroupIcon } from "@plane/ui";
|
||||
import {
|
||||
CustomMenu,
|
||||
Loader,
|
||||
LayersIcon,
|
||||
CustomSelect,
|
||||
ModuleStatusIcon,
|
||||
UserGroupIcon,
|
||||
TOAST_TYPE,
|
||||
setToast,
|
||||
} from "@plane/ui";
|
||||
// helpers
|
||||
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
|
||||
import { copyUrlToClipboard } from "helpers/string.helper";
|
||||
|
|
@ -65,8 +73,6 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
const { setTrackElement, captureModuleEvent, captureEvent } = useEventTracker();
|
||||
const moduleDetails = getModuleById(moduleId);
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const { reset, control } = useForm({
|
||||
defaultValues,
|
||||
});
|
||||
|
|
@ -99,15 +105,15 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
module_id: moduleId,
|
||||
state: "SUCCESS",
|
||||
});
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Module link created",
|
||||
message: "Module link created successfully.",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Some error occurred",
|
||||
});
|
||||
|
|
@ -125,15 +131,15 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
module_id: moduleId,
|
||||
state: "SUCCESS",
|
||||
});
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Module link updated",
|
||||
message: "Module link updated successfully.",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Some error occurred",
|
||||
});
|
||||
|
|
@ -149,15 +155,15 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
module_id: moduleId,
|
||||
state: "SUCCESS",
|
||||
});
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Module link deleted",
|
||||
message: "Module link deleted successfully.",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Some error occurred",
|
||||
});
|
||||
|
|
@ -167,15 +173,15 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
const handleCopyText = () => {
|
||||
copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/modules/${moduleId}`)
|
||||
.then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Link copied",
|
||||
message: "Module link copied to clipboard",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Some error occurred",
|
||||
});
|
||||
|
|
@ -187,8 +193,8 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
start_date: startDate ? renderFormattedPayloadDate(startDate) : null,
|
||||
target_date: targetDate ? renderFormattedPayloadDate(targetDate) : null,
|
||||
});
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Module updated successfully.",
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue