mirror of
				https://github.com/usememos/memos.git
				synced 2025-06-05 22:09:59 +02:00 
			
		
		
		
	chore: update confirm dialog
This commit is contained in:
		| @@ -1,91 +0,0 @@ | ||||
| import { Button, IconButton } from "@mui/joy"; | ||||
| import { DefaultColorPalette } from "@mui/joy/styles/types"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import Icon from "../Icon"; | ||||
| import { generateDialog } from "./BaseDialog"; | ||||
| import "@/less/common-dialog.less"; | ||||
|  | ||||
| interface Props extends DialogProps { | ||||
|   title: string; | ||||
|   content: string; | ||||
|   style?: DefaultColorPalette; | ||||
|   closeBtnText?: string; | ||||
|   confirmBtnText?: string; | ||||
|   onClose?: () => void; | ||||
|   onConfirm?: () => void; | ||||
| } | ||||
|  | ||||
| const defaultProps = { | ||||
|   title: "", | ||||
|   content: "", | ||||
|   style: "neutral", | ||||
|   closeBtnText: "common.close", | ||||
|   confirmBtnText: "common.confirm", | ||||
|   onClose: () => null, | ||||
|   onConfirm: () => null, | ||||
| } as const; | ||||
|  | ||||
| const CommonDialog: React.FC<Props> = (props: Props) => { | ||||
|   const t = useTranslate(); | ||||
|   const { title, content, destroy, closeBtnText, confirmBtnText, onClose, onConfirm, style } = { | ||||
|     ...defaultProps, | ||||
|     closeBtnText: t(defaultProps.closeBtnText), | ||||
|     confirmBtnText: t(defaultProps.confirmBtnText), | ||||
|     ...props, | ||||
|   }; | ||||
|  | ||||
|   const handleCloseBtnClick = () => { | ||||
|     onClose(); | ||||
|     destroy(); | ||||
|   }; | ||||
|  | ||||
|   const handleConfirmBtnClick = async () => { | ||||
|     onConfirm(); | ||||
|     destroy(); | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <div className="dialog-header-container"> | ||||
|         <p className="title-text">{title}</p> | ||||
|         <IconButton size="sm" onClick={handleCloseBtnClick}> | ||||
|           <Icon.X className="w-5 h-auto" /> | ||||
|         </IconButton> | ||||
|       </div> | ||||
|       <div className="dialog-content-container"> | ||||
|         <p className="content-text">{content}</p> | ||||
|         <div className="mt-4 w-full flex flex-row justify-end items-center gap-2"> | ||||
|           <Button color="neutral" variant="plain" onClick={handleCloseBtnClick}> | ||||
|             {closeBtnText} | ||||
|           </Button> | ||||
|           <Button color={style} onClick={handleConfirmBtnClick}> | ||||
|             {confirmBtnText} | ||||
|           </Button> | ||||
|         </div> | ||||
|       </div> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| interface CommonDialogProps { | ||||
|   title: string; | ||||
|   content: string; | ||||
|   className?: string; | ||||
|   style?: DefaultColorPalette; | ||||
|   dialogName: string; | ||||
|   closeBtnText?: string; | ||||
|   confirmBtnText?: string; | ||||
|   onClose?: () => void; | ||||
|   onConfirm?: () => void; | ||||
| } | ||||
|  | ||||
| export const showCommonDialog = (props: CommonDialogProps) => { | ||||
|   generateDialog( | ||||
|     { | ||||
|       className: `common-dialog ${props?.className ?? ""}`, | ||||
|       dialogName: `common-dialog ${props?.className ?? ""}`, | ||||
|     }, | ||||
|     CommonDialog, | ||||
|     props, | ||||
|   ); | ||||
| }; | ||||
| @@ -8,7 +8,6 @@ import useCurrentUser from "@/hooks/useCurrentUser"; | ||||
| import { useFilterStore } from "@/store/module"; | ||||
| import { useMemoList, useTagStore } from "@/store/v1"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import { showCommonDialog } from "../Dialog/CommonDialog"; | ||||
| import Icon from "../Icon"; | ||||
| import showRenameTagDialog from "../RenameTagDialog"; | ||||
|  | ||||
| @@ -42,20 +41,15 @@ const TagsSection = (props: Props) => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteTag = async (tag: string) => { | ||||
|     showCommonDialog({ | ||||
|       title: t("tag.delete-tag"), | ||||
|       content: t("tag.delete-confirm"), | ||||
|       style: "danger", | ||||
|       dialogName: "delete-tag-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm(t("tag.delete-confirm")); | ||||
|     if (confirmed) { | ||||
|       await memoServiceClient.deleteMemoTag({ | ||||
|         parent: "memos/-", | ||||
|         tag: tag, | ||||
|       }); | ||||
|       await tagStore.fetchTags({ location, user }, { skipCache: true }); | ||||
|       toast.success(t("message.deleted-successfully")); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import { useMemoStore } from "@/store/v1"; | ||||
| import { RowStatus } from "@/types/proto/api/v1/common"; | ||||
| import { Memo } from "@/types/proto/api/v1/memo_service"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import { showCommonDialog } from "./Dialog/CommonDialog"; | ||||
| import showMemoEditorDialog from "./MemoEditor/MemoEditorDialog"; | ||||
|  | ||||
| interface Props { | ||||
| @@ -95,19 +94,14 @@ const MemoActionMenu = (props: Props) => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteMemoClick = async () => { | ||||
|     showCommonDialog({ | ||||
|       title: t("memo.delete-memo"), | ||||
|       content: t("memo.delete-confirm"), | ||||
|       style: "danger", | ||||
|       dialogName: "delete-memo-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm(t("memo.delete-confirm")); | ||||
|     if (confirmed) { | ||||
|       await memoStore.deleteMemo(memo.name); | ||||
|       toast.success(t("message.deleted-successfully")); | ||||
|       if (isInMemoDetailPage) { | ||||
|         navigateTo("/"); | ||||
|       } | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -7,7 +7,6 @@ import useCurrentUser from "@/hooks/useCurrentUser"; | ||||
| import { UserAccessToken } from "@/types/proto/api/v1/user_service"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import showCreateAccessTokenDialog from "../CreateAccessTokenDialog"; | ||||
| import { showCommonDialog } from "../Dialog/CommonDialog"; | ||||
| import Icon from "../Icon"; | ||||
| import LearnMore from "../LearnMore"; | ||||
|  | ||||
| @@ -38,16 +37,13 @@ const AccessTokenSection = () => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteAccessToken = async (accessToken: string) => { | ||||
|     showCommonDialog({ | ||||
|       title: "Delete Access Token", | ||||
|       content: `Are you sure to delete access token \`${getFormatedAccessToken(accessToken)}\`? You cannot undo this action.`, | ||||
|       style: "danger", | ||||
|       dialogName: "delete-access-token-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm( | ||||
|       `Are you sure to delete access token \`${getFormatedAccessToken(accessToken)}\`? You cannot undo this action.`, | ||||
|     ); | ||||
|     if (confirmed) { | ||||
|       await userServiceClient.deleteUserAccessToken({ name: currentUser.name, accessToken: accessToken }); | ||||
|       setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== accessToken)); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const getFormatedAccessToken = (accessToken: string) => { | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import { RowStatus } from "@/types/proto/api/v1/common"; | ||||
| import { User, User_Role } from "@/types/proto/api/v1/user_service"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import showChangeMemberPasswordDialog from "../ChangeMemberPasswordDialog"; | ||||
| import { showCommonDialog } from "../Dialog/CommonDialog"; | ||||
| import Icon from "../Icon"; | ||||
|  | ||||
| interface State { | ||||
| @@ -101,13 +100,9 @@ const MemberSection = () => { | ||||
|     showChangeMemberPasswordDialog(user); | ||||
|   }; | ||||
|  | ||||
|   const handleArchiveUserClick = (user: User) => { | ||||
|     showCommonDialog({ | ||||
|       title: t("setting.member-section.archive-member"), | ||||
|       content: t("setting.member-section.archive-warning", { username: user.nickname }), | ||||
|       style: "danger", | ||||
|       dialogName: "archive-user-dialog", | ||||
|       onConfirm: async () => { | ||||
|   const handleArchiveUserClick = async (user: User) => { | ||||
|     const confirmed = window.confirm(t("setting.member-section.archive-warning", { username: user.nickname })); | ||||
|     if (confirmed) { | ||||
|       await userServiceClient.updateUser({ | ||||
|         user: { | ||||
|           name: user.name, | ||||
| @@ -116,8 +111,7 @@ const MemberSection = () => { | ||||
|         updateMask: ["row_status"], | ||||
|       }); | ||||
|       fetchUsers(); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const handleRestoreUserClick = async (user: User) => { | ||||
| @@ -131,17 +125,12 @@ const MemberSection = () => { | ||||
|     fetchUsers(); | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteUserClick = (user: User) => { | ||||
|     showCommonDialog({ | ||||
|       title: t("setting.member-section.delete-member"), | ||||
|       content: t("setting.member-section.delete-warning", { username: user.nickname }), | ||||
|       style: "danger", | ||||
|       dialogName: "delete-user-dialog", | ||||
|       onConfirm: async () => { | ||||
|   const handleDeleteUserClick = async (user: User) => { | ||||
|     const confirmed = window.confirm(t("setting.member-section.delete-warning", { username: user.nickname })); | ||||
|     if (confirmed) { | ||||
|       await userStore.deleteUser(user.name); | ||||
|       fetchUsers(); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -6,7 +6,6 @@ import { identityProviderServiceClient } from "@/grpcweb"; | ||||
| import { IdentityProvider } from "@/types/proto/api/v1/idp_service"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import showCreateIdentityProviderDialog from "../CreateIdentityProviderDialog"; | ||||
| import { showCommonDialog } from "../Dialog/CommonDialog"; | ||||
| import Icon from "../Icon"; | ||||
| import LearnMore from "../LearnMore"; | ||||
|  | ||||
| @@ -24,14 +23,8 @@ const SSOSection = () => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteIdentityProvider = async (identityProvider: IdentityProvider) => { | ||||
|     const content = t("setting.sso-section.confirm-delete", { name: identityProvider.title }); | ||||
|  | ||||
|     showCommonDialog({ | ||||
|       title: t("setting.sso-section.delete-sso"), | ||||
|       content: content, | ||||
|       style: "danger", | ||||
|       dialogName: "delete-identity-provider-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm(t("setting.sso-section.confirm-delete", { name: identityProvider.title })); | ||||
|     if (confirmed) { | ||||
|       try { | ||||
|         await identityProviderServiceClient.deleteIdentityProvider({ name: identityProvider.name }); | ||||
|       } catch (error: any) { | ||||
| @@ -39,8 +32,7 @@ const SSOSection = () => { | ||||
|         toast.error(error.details); | ||||
|       } | ||||
|       await fetchIdentityProviderList(); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -6,7 +6,6 @@ import useCurrentUser from "@/hooks/useCurrentUser"; | ||||
| import { Webhook } from "@/types/proto/api/v1/webhook_service"; | ||||
| import { useTranslate } from "@/utils/i18n"; | ||||
| import showCreateWebhookDialog from "../CreateWebhookDialog"; | ||||
| import { showCommonDialog } from "../Dialog/CommonDialog"; | ||||
| import Icon from "../Icon"; | ||||
|  | ||||
| const listWebhooks = async (userId: number) => { | ||||
| @@ -33,16 +32,11 @@ const WebhookSection = () => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteWebhook = async (webhook: Webhook) => { | ||||
|     showCommonDialog({ | ||||
|       title: "Delete Webhook", | ||||
|       content: `Are you sure to delete webhook \`${webhook.name}\`? You cannot undo this action.`, | ||||
|       style: "danger", | ||||
|       dialogName: "delete-webhook-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm(`Are you sure to delete webhook \`${webhook.name}\`? You cannot undo this action.`); | ||||
|     if (confirmed) { | ||||
|       await webhookServiceClient.deleteWebhook({ id: webhook.id }); | ||||
|       setWebhooks(webhooks.filter((item) => item.id !== webhook.id)); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import { Button, Tooltip } from "@mui/joy"; | ||||
| import { ClientError } from "nice-grpc-web"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import toast from "react-hot-toast"; | ||||
| import { showCommonDialog } from "@/components/Dialog/CommonDialog"; | ||||
| import Empty from "@/components/Empty"; | ||||
| import Icon from "@/components/Icon"; | ||||
| import MemoContent from "@/components/MemoContent"; | ||||
| @@ -57,15 +56,10 @@ const Archived = () => { | ||||
|   }; | ||||
|  | ||||
|   const handleDeleteMemoClick = async (memo: Memo) => { | ||||
|     showCommonDialog({ | ||||
|       title: t("memo.delete-memo"), | ||||
|       content: t("memo.delete-confirm"), | ||||
|       style: "danger", | ||||
|       dialogName: "delete-memo-dialog", | ||||
|       onConfirm: async () => { | ||||
|     const confirmed = window.confirm(t("memo.delete-confirm")); | ||||
|     if (confirmed) { | ||||
|       await memoStore.deleteMemo(memo.name); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const handleRestoreMemoClick = async (memo: Memo) => { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| import { Divider, IconButton, Input, Tooltip } from "@mui/joy"; | ||||
| import { includes } from "lodash-es"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import { showCommonDialog } from "@/components/Dialog/CommonDialog"; | ||||
| import Empty from "@/components/Empty"; | ||||
| import Icon from "@/components/Icon"; | ||||
| import MobileHeader from "@/components/MobileHeader"; | ||||
| @@ -58,19 +57,14 @@ const Resources = () => { | ||||
|     }); | ||||
|   }, []); | ||||
|  | ||||
|   const handleDeleteUnusedResources = () => { | ||||
|     showCommonDialog({ | ||||
|       title: "Delete all unused resources", | ||||
|       content: "Are you sure to delete all unused resources? This action cannot be undone.", | ||||
|       style: "warning", | ||||
|       dialogName: "delete-unused-resources-dialog", | ||||
|       onConfirm: async () => { | ||||
|   const handleDeleteUnusedResources = async () => { | ||||
|     const confirmed = window.confirm("Are you sure to delete all unused resources? This action cannot be undone."); | ||||
|     if (confirmed) { | ||||
|       for (const resource of unusedResources) { | ||||
|         await resourceServiceClient.deleteResource({ name: resource.name }); | ||||
|       } | ||||
|       setResources(resources.filter((resource) => resource.memo)); | ||||
|       }, | ||||
|     }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user