fix: Focus submit button by default in confirmation dialogs
fix: Move collection delete to use confirmation dialog closes #3446
This commit is contained in:
@@ -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 (
|
||||
<Flex column>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<ConfirmationDialog
|
||||
onSubmit={handleSubmit}
|
||||
submitText={t("I’m sure – Delete")}
|
||||
savingText={`${t("Deleting")}…`}
|
||||
danger
|
||||
>
|
||||
<>
|
||||
<Text type="secondary">
|
||||
<Trans
|
||||
defaults="Are you sure about that? Deleting the <em>{{collectionName}}</em> collection is permanent and cannot be restored, however documents within will be moved to the trash."
|
||||
@@ -73,12 +61,9 @@ function CollectionDelete({ collection, onSubmit }: Props) {
|
||||
/>
|
||||
</Text>
|
||||
) : null}
|
||||
<Button type="submit" disabled={isDeleting} autoFocus danger>
|
||||
{isDeleting ? `${t("Deleting")}…` : t("I’m sure – Delete")}
|
||||
</Button>
|
||||
</form>
|
||||
</Flex>
|
||||
</>
|
||||
</ConfirmationDialog>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(CollectionDelete);
|
||||
export default observer(CollectionDeleteDialog);
|
||||
@@ -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> | 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<Props> = ({
|
||||
onSubmit,
|
||||
children,
|
||||
submitText,
|
||||
savingText,
|
||||
danger,
|
||||
}: Props) {
|
||||
}) => {
|
||||
const [isSaving, setIsSaving] = React.useState(false);
|
||||
const { dialogs } = useStores();
|
||||
const { showToast } = useToasts();
|
||||
@@ -53,6 +56,6 @@ function ConfirmationDialog({
|
||||
</form>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default observer(ConfirmationDialog);
|
||||
|
||||
@@ -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")};
|
||||
|
||||
@@ -67,6 +67,7 @@ const Modal: React.FC<Props> = ({
|
||||
<Backdrop $isCentered={isCentered} {...props}>
|
||||
<Dialog
|
||||
{...dialog}
|
||||
aria-label={typeof title === "string" ? title : undefined}
|
||||
preventBodyScroll
|
||||
hideOnEsc
|
||||
hideOnClickOutside={!!isCentered}
|
||||
@@ -75,7 +76,12 @@ const Modal: React.FC<Props> = ({
|
||||
{(props) =>
|
||||
isCentered && !isMobile ? (
|
||||
<Small {...props}>
|
||||
<Centered onClick={(ev) => ev.stopPropagation()} column>
|
||||
<Centered
|
||||
onClick={(ev) => ev.stopPropagation()}
|
||||
column
|
||||
reverse
|
||||
>
|
||||
<SmallContent shadow>{children}</SmallContent>
|
||||
<Header>
|
||||
{title && (
|
||||
<Text as="span" size="large">
|
||||
@@ -88,7 +94,6 @@ const Modal: React.FC<Props> = ({
|
||||
</NudeButton>
|
||||
</Text>
|
||||
</Header>
|
||||
<SmallContent shadow>{children}</SmallContent>
|
||||
</Centered>
|
||||
</Small>
|
||||
) : (
|
||||
|
||||
@@ -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: (
|
||||
<CollectionDelete
|
||||
<CollectionDeleteDialog
|
||||
collection={collection}
|
||||
onSubmit={dialogs.closeAllModals}
|
||||
/>
|
||||
|
||||
@@ -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 <em>{{collectionName}}</em> collection is permanent and cannot be restored, however documents within will be moved to the trash.": "Deleting the <em>{{collectionName}}</em> collection is permanent and cannot be restored, however documents within will be moved to the trash.",
|
||||
"Also, <em>{{collectionName}}</em> is being used as the start view – deleting it will reset the start view to the Home page.": "Also, <em>{{collectionName}}</em> 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 <em>{{collectionName}}</em> collection is permanent and cannot be restored, however documents within will be moved to the trash.": "Deleting the <em>{{collectionName}}</em> collection is permanent and cannot be restored, however documents within will be moved to the trash.",
|
||||
"Also, <em>{{collectionName}}</em> is being used as the start view – deleting it will reset the start view to the Home page.": "Also, <em>{{collectionName}}</em> 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",
|
||||
|
||||
Reference in New Issue
Block a user