From 56e6b5211a68ba6b9858d371e95f538d93e3bb9a Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Tue, 19 Dec 2023 11:21:30 -0500 Subject: [PATCH] fix: Confirmation dialog call to action should be on the right --- app/actions/definitions/documents.tsx | 2 +- app/components/ConfirmationDialog.tsx | 15 ++- app/components/UserDialogs.tsx | 24 +--- app/scenes/DocumentDelete.tsx | 106 +++++++++--------- app/scenes/DocumentPermanentDelete.tsx | 64 +++++------ app/scenes/GroupDelete.tsx | 57 ++++------ app/scenes/Settings/Security.tsx | 1 - .../components/FileOperationListItem.tsx | 1 - app/scenes/TeamDelete.tsx | 65 +++++------ app/scenes/UserDelete.tsx | 66 +++++------ shared/i18n/locales/en_US/translation.json | 3 +- 11 files changed, 180 insertions(+), 224 deletions(-) diff --git a/app/actions/definitions/documents.tsx b/app/actions/definitions/documents.tsx index 6e659f0c0..3fd5ef511 100644 --- a/app/actions/definitions/documents.tsx +++ b/app/actions/definitions/documents.tsx @@ -784,7 +784,7 @@ export const archiveDocument = createAction({ }); export const deleteDocument = createAction({ - name: ({ t }) => t("Delete"), + name: ({ t }) => `${t("Delete")}…`, analyticsName: "Delete document", section: DocumentSection, icon: , diff --git a/app/components/ConfirmationDialog.tsx b/app/components/ConfirmationDialog.tsx index 70282781c..074664fb4 100644 --- a/app/components/ConfirmationDialog.tsx +++ b/app/components/ConfirmationDialog.tsx @@ -1,5 +1,6 @@ import { observer } from "mobx-react"; import * as React from "react"; +import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import Button from "~/components/Button"; import Flex from "~/components/Flex"; @@ -29,6 +30,7 @@ const ConfirmationDialog: React.FC = ({ disabled = false, }: Props) => { const [isSaving, setIsSaving] = React.useState(false); + const { t } = useTranslation(); const { dialogs } = useStores(); const handleSubmit = React.useCallback( @@ -48,19 +50,20 @@ const ConfirmationDialog: React.FC = ({ ); return ( - -
- {children} + + {children} + + - -
+
+ ); }; diff --git a/app/components/UserDialogs.tsx b/app/components/UserDialogs.tsx index 7aeb3c1e5..e7d6fff2f 100644 --- a/app/components/UserDialogs.tsx +++ b/app/components/UserDialogs.tsx @@ -21,11 +21,7 @@ export function UserChangeToViewerDialog({ user, onSubmit }: Props) { }; return ( - + {t( "Are you sure you want to make {{ userName }} a read-only viewer? They will not be able to edit any content", { @@ -47,11 +43,7 @@ export function UserChangeToMemberDialog({ user, onSubmit }: Props) { }; return ( - + {t("Are you sure you want to make {{ userName }} a member?", { userName: user.name, })} @@ -94,11 +86,7 @@ export function UserChangeToAdminDialog({ user, onSubmit }: Props) { }; return ( - + {t( "Are you sure you want to make {{ userName }} an admin? Admins can modify team and billing information.", { @@ -119,11 +107,7 @@ export function UserSuspendDialog({ user, onSubmit }: Props) { }; return ( - + {t( "Are you sure you want to suspend {{ userName }}? Suspended users will be prevented from logging in.", { diff --git a/app/scenes/DocumentDelete.tsx b/app/scenes/DocumentDelete.tsx index 28d74fbf6..81818b96e 100644 --- a/app/scenes/DocumentDelete.tsx +++ b/app/scenes/DocumentDelete.tsx @@ -82,65 +82,65 @@ function DocumentDelete({ document, onSubmit }: Props) { ); return ( - -
- - {document.isTemplate ? ( - , - }} - /> - ) : nestedDocumentsCount < 1 ? ( - , - }} - /> - ) : ( - , - }} - /> - )} - - {canArchive && ( - - - If you’d like the option of referencing or restoring the{" "} - {{ - noun: document.noun, - }}{" "} - in the future, consider archiving it instead. - - + + + {document.isTemplate ? ( + , + }} + /> + ) : nestedDocumentsCount < 1 ? ( + , + }} + /> + ) : ( + , + }} + /> )} - -    + + {canArchive && ( + + + If you’d like the option of referencing or restoring the{" "} + {{ + noun: document.noun, + }}{" "} + in the future, consider archiving it instead. + + + )} + + {canArchive && ( )} - -
+ +
+ ); } diff --git a/app/scenes/DocumentPermanentDelete.tsx b/app/scenes/DocumentPermanentDelete.tsx index 81cefa058..6ae4ed20d 100644 --- a/app/scenes/DocumentPermanentDelete.tsx +++ b/app/scenes/DocumentPermanentDelete.tsx @@ -4,9 +4,8 @@ import { useTranslation, Trans } from "react-i18next"; import { useHistory } from "react-router-dom"; import { toast } from "sonner"; import Document from "~/models/Document"; -import Button from "~/components/Button"; +import ConfirmationDialog from "~/components/ConfirmationDialog"; import Flex from "~/components/Flex"; -import Text from "~/components/Text"; import useStores from "~/hooks/useStores"; type Props = { @@ -15,50 +14,37 @@ type Props = { }; function DocumentPermanentDelete({ document, onSubmit }: Props) { - const [isDeleting, setIsDeleting] = React.useState(false); const { t } = useTranslation(); const { documents } = useStores(); const history = useHistory(); - const handleSubmit = React.useCallback( - async (ev: React.SyntheticEvent) => { - ev.preventDefault(); - - try { - setIsDeleting(true); - await documents.delete(document, { - permanent: true, - }); - toast.success(t("Document permanently deleted")); - onSubmit(); - history.push("/trash"); - } catch (err) { - toast.error(err.message); - } finally { - setIsDeleting(false); - } - }, - [document, onSubmit, t, history, documents] - ); + const handleSubmit = async () => { + await documents.delete(document, { + permanent: true, + }); + toast.success(t("Document permanently deleted")); + onSubmit(); + history.push("/trash"); + }; return ( -
- - , - }} - /> - - -
+ + , + }} + /> +
); } diff --git a/app/scenes/GroupDelete.tsx b/app/scenes/GroupDelete.tsx index a3f464bc6..2051d97f3 100644 --- a/app/scenes/GroupDelete.tsx +++ b/app/scenes/GroupDelete.tsx @@ -2,11 +2,8 @@ import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import { useHistory } from "react-router-dom"; -import { toast } from "sonner"; import Group from "~/models/Group"; -import Button from "~/components/Button"; -import Flex from "~/components/Flex"; -import Text from "~/components/Text"; +import ConfirmationDialog from "~/components/ConfirmationDialog"; import { settingsPath } from "~/utils/routeHelpers"; type Props = { @@ -17,42 +14,30 @@ type Props = { function GroupDelete({ group, onSubmit }: Props) { const { t } = useTranslation(); const history = useHistory(); - const [isDeleting, setIsDeleting] = React.useState(false); - const handleSubmit = async (ev: React.SyntheticEvent) => { - ev.preventDefault(); - setIsDeleting(true); - - try { - await group.delete(); - history.push(settingsPath("groups")); - onSubmit(); - } catch (err) { - toast.error(err.message); - } finally { - setIsDeleting(false); - } + const handleSubmit = async () => { + await group.delete(); + history.push(settingsPath("groups")); + onSubmit(); }; return ( - -
- - , - }} - /> - - -
-
+ + , + }} + /> + ); } diff --git a/app/scenes/Settings/Security.tsx b/app/scenes/Settings/Security.tsx index 7f2a2824d..8bc811002 100644 --- a/app/scenes/Settings/Security.tsx +++ b/app/scenes/Settings/Security.tsx @@ -109,7 +109,6 @@ function Security() { onSubmit={async () => { await saveData(newData); }} - submitText={t("I’m sure")} savingText={`${t("Saving")}…`} danger > diff --git a/app/scenes/Settings/components/FileOperationListItem.tsx b/app/scenes/Settings/components/FileOperationListItem.tsx index d5ee548a5..13b33e609 100644 --- a/app/scenes/Settings/components/FileOperationListItem.tsx +++ b/app/scenes/Settings/components/FileOperationListItem.tsx @@ -81,7 +81,6 @@ const FileOperationListItem = ({ fileOperation }: Props) => { content: ( diff --git a/app/scenes/TeamDelete.tsx b/app/scenes/TeamDelete.tsx index 152528c1b..68c73156e 100644 --- a/app/scenes/TeamDelete.tsx +++ b/app/scenes/TeamDelete.tsx @@ -64,36 +64,37 @@ function TeamDelete({ onSubmit }: Props) { const workspaceName = team.name; return ( - -
- {isWaitingCode ? ( - <> - - - A confirmation code has been sent to your email address, please - enter the code below to permanently destroy this workspace. - - - - - ) : ( - <> - - - Deleting the {{ workspaceName }} workspace will - destroy all collections, documents, users, and associated data. - You will be immediately logged out of {{ appName }}. - - - - )} + + {isWaitingCode ? ( + <> + + + A confirmation code has been sent to your email address, please + enter the code below to permanently destroy this workspace. + + + + + ) : ( + <> + + + Deleting the {{ workspaceName }} workspace will + destroy all collections, documents, users, and associated data. + You will be immediately logged out of {{ appName }}. + + + + )} + + {env.EMAIL_ENABLED && !isWaitingCode ? ( )} - -
+
+ ); } diff --git a/app/scenes/UserDelete.tsx b/app/scenes/UserDelete.tsx index 34e40ce91..234448e42 100644 --- a/app/scenes/UserDelete.tsx +++ b/app/scenes/UserDelete.tsx @@ -56,37 +56,37 @@ function UserDelete() { const appName = env.APP_NAME; return ( - -
- {isWaitingCode ? ( - <> - - - A confirmation code has been sent to your email address, please - enter the code below to permanently destroy your account. - - - - - ) : ( - <> - - - Are you sure? Deleting your account will destroy identifying - data associated with your user and cannot be undone. You will be - immediately logged out of {{ appName }} and all your API tokens - will be revoked. - - - - )} + + {isWaitingCode ? ( + <> + + + A confirmation code has been sent to your email address, please + enter the code below to permanently destroy your account. + + + + + ) : ( + <> + + + Are you sure? Deleting your account will destroy identifying data + associated with your user and cannot be undone. You will be + immediately logged out of {{ appName }} and all your API tokens + will be revoked. + + + + )} + {env.EMAIL_ENABLED && !isWaitingCode ? ( )} - -
+
+ ); } diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index 6ddaee755..960caa9c8 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -126,6 +126,7 @@ "Type a command or search": "Type a command or search", "Are you sure you want to permanently delete this entire comment thread?": "Are you sure you want to permanently delete this entire comment thread?", "Are you sure you want to permanently delete this comment?": "Are you sure you want to permanently delete this comment?", + "Confirm": "Confirm", "Document is too large": "Document is too large", "This document has reached the maximum size and can no longer be edited": "This document has reached the maximum size and can no longer be edited", "Authentication failed": "Authentication failed", @@ -262,7 +263,6 @@ "No results": "No results", "Previous page": "Previous page", "Next page": "Next page", - "Confirm": "Confirm", "Saving": "Saving", "Are you sure you want to make {{ userName }} a read-only viewer? They will not be able to edit any content": "Are you sure you want to make {{ userName }} a read-only viewer? They will not be able to edit any content", "Are you sure you want to make {{ userName }} a member?": "Are you sure you want to make {{ userName }} a member?", @@ -753,7 +753,6 @@ "Import deleted": "Import deleted", "Export deleted": "Export deleted", "Are you sure you want to delete this import?": "Are you sure you want to delete this import?", - "I’m sure": "I’m sure", "Deleting this import will also delete all collections and documents that were created from it. This cannot be undone.": "Deleting this import will also delete all collections and documents that were created from it. This cannot be undone.", "Check server logs for more details.": "Check server logs for more details.", "{{userName}} requested": "{{userName}} requested",