diff --git a/app/scenes/CollectionDelete.tsx b/app/components/CollectionDeleteDialog.tsx similarity index 57% rename from app/scenes/CollectionDelete.tsx rename to app/components/CollectionDeleteDialog.tsx index 56d15a0cf..27a82ec63 100644 --- a/app/scenes/CollectionDelete.tsx +++ b/app/components/CollectionDeleteDialog.tsx @@ -3,12 +3,10 @@ import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import { useHistory } from "react-router-dom"; import Collection from "~/models/Collection"; -import Button from "~/components/Button"; -import Flex from "~/components/Flex"; +import ConfirmationDialog from "~/components/ConfirmationDialog"; import Text from "~/components/Text"; import useCurrentTeam from "~/hooks/useCurrentTeam"; import useStores from "~/hooks/useStores"; -import useToasts from "~/hooks/useToasts"; import { homePath } from "~/utils/routeHelpers"; type Props = { @@ -16,39 +14,29 @@ type Props = { onSubmit: () => void; }; -function CollectionDelete({ collection, onSubmit }: Props) { - const [isDeleting, setIsDeleting] = React.useState(false); +function CollectionDeleteDialog({ collection, onSubmit }: Props) { const team = useCurrentTeam(); - const { showToast } = useToasts(); const { ui } = useStores(); const history = useHistory(); const { t } = useTranslation(); - const handleSubmit = React.useCallback( - async (ev: React.SyntheticEvent) => { - ev.preventDefault(); - setIsDeleting(true); - try { - const redirect = collection.id === ui.activeCollectionId; - await collection.delete(); - onSubmit(); - if (redirect) { - history.push(homePath()); - } - } catch (err) { - showToast(err.message, { - type: "error", - }); - } finally { - setIsDeleting(false); - } - }, - [collection, history, onSubmit, showToast, ui.activeCollectionId] - ); + const handleSubmit = async () => { + const redirect = collection.id === ui.activeCollectionId; + await collection.delete(); + onSubmit(); + if (redirect) { + history.push(homePath()); + } + }; return ( - -
+ + <> ) : null} - - -
+ + ); } -export default observer(CollectionDelete); +export default observer(CollectionDeleteDialog); diff --git a/app/components/ConfirmationDialog.tsx b/app/components/ConfirmationDialog.tsx index ac5baffa1..590be3d4f 100644 --- a/app/components/ConfirmationDialog.tsx +++ b/app/components/ConfirmationDialog.tsx @@ -7,20 +7,23 @@ import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; type Props = { - onSubmit: () => void; - children: JSX.Element; + /** Callback when the dialog is submitted */ + onSubmit: () => Promise | void; + /** Text to display on the submit button */ submitText?: string; + /** Text to display while the form is saving */ savingText?: string; + /** If true, the submit button will be a dangerous red */ danger?: boolean; }; -function ConfirmationDialog({ +const ConfirmationDialog: React.FC = ({ onSubmit, children, submitText, savingText, danger, -}: Props) { +}) => { const [isSaving, setIsSaving] = React.useState(false); const { dialogs } = useStores(); const { showToast } = useToasts(); @@ -53,6 +56,6 @@ function ConfirmationDialog({ ); -} +}; export default observer(ConfirmationDialog); diff --git a/app/components/Flex.tsx b/app/components/Flex.tsx index ba3afef95..788606591 100644 --- a/app/components/Flex.tsx +++ b/app/components/Flex.tsx @@ -11,11 +11,19 @@ const Flex = styled.div<{ align?: AlignValues; justify?: JustifyValues; shrink?: boolean; + reverse?: boolean; gap?: number; }>` display: flex; flex: ${({ auto }) => (auto ? "1 1 auto" : "initial")}; - flex-direction: ${({ column }) => (column ? "column" : "row")}; + flex-direction: ${({ column, reverse }) => + reverse + ? column + ? "column-reverse" + : "row-reverse" + : column + ? "column" + : "row"}; align-items: ${({ align }) => align}; justify-content: ${({ justify }) => justify}; flex-shrink: ${({ shrink }) => (shrink ? 1 : "initial")}; diff --git a/app/components/Modal.tsx b/app/components/Modal.tsx index 0d3c814a6..59875d199 100644 --- a/app/components/Modal.tsx +++ b/app/components/Modal.tsx @@ -67,6 +67,7 @@ const Modal: React.FC = ({ = ({ {(props) => isCentered && !isMobile ? ( - ev.stopPropagation()} column> + ev.stopPropagation()} + column + reverse + > + {children}
{title && ( @@ -88,7 +94,6 @@ const Modal: React.FC = ({
- {children}
) : ( diff --git a/app/menus/CollectionMenu.tsx b/app/menus/CollectionMenu.tsx index eecd9bcc6..83521aa01 100644 --- a/app/menus/CollectionMenu.tsx +++ b/app/menus/CollectionMenu.tsx @@ -18,10 +18,10 @@ import { useMenuState, MenuButton, MenuButtonHTMLProps } from "reakit/Menu"; import { VisuallyHidden } from "reakit/VisuallyHidden"; import getDataTransferFiles from "@shared/utils/getDataTransferFiles"; import Collection from "~/models/Collection"; -import CollectionDelete from "~/scenes/CollectionDelete"; import CollectionEdit from "~/scenes/CollectionEdit"; import CollectionExport from "~/scenes/CollectionExport"; import CollectionPermissions from "~/scenes/CollectionPermissions"; +import CollectionDeleteDialog from "~/components/CollectionDeleteDialog"; import ContextMenu, { Placement } from "~/components/ContextMenu"; import OverflowMenuButton from "~/components/ContextMenu/OverflowMenuButton"; import Template from "~/components/ContextMenu/Template"; @@ -160,7 +160,7 @@ function CollectionMenu({ isCentered: true, title: t("Delete collection"), content: ( - diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index decbb0b1d..23f325ea4 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -57,6 +57,10 @@ "previously edited": "previously edited", "You": "You", "Viewers": "Viewers", + "I’m sure – Delete": "I’m sure – Delete", + "Deleting": "Deleting", + "Are you sure about that? Deleting the {{collectionName}} collection is permanent and cannot be restored, however documents within will be moved to the trash.": "Deleting the {{collectionName}} collection is permanent and cannot be restored, however documents within will be moved to the trash.", + "Also, {{collectionName}} is being used as the start view – deleting it will reset the start view to the Home page.": "Also, {{collectionName}} is being used as the start view – deleting it will reset the start view to the Home page.", "Sorry, an error occurred saving the collection": "Sorry, an error occurred saving the collection", "Add a description": "Add a description", "Collapse": "Collapse", @@ -321,10 +325,6 @@ "Get started by creating a new one!": "Get started by creating a new one!", "Create a document": "Create a document", "Manage permissions": "Manage permissions", - "Are you sure about that? Deleting the {{collectionName}} collection is permanent and cannot be restored, however documents within will be moved to the trash.": "Deleting the {{collectionName}} collection is permanent and cannot be restored, however documents within will be moved to the trash.", - "Also, {{collectionName}} is being used as the start view – deleting it will reset the start view to the Home page.": "Also, {{collectionName}} is being used as the start view – deleting it will reset the start view to the Home page.", - "Deleting": "Deleting", - "I’m sure – Delete": "I’m sure – Delete", "The collection was updated": "The collection was updated", "You can edit the name and other details at any time, however doing so often might confuse your team mates.": "You can edit the name and other details at any time, however doing so often might confuse your team mates.", "Name": "Name",