UPDATE: Deleting a sheet prompts a confirmation dialog
This commit is contained in:
141
webapp/IronCalc/src/components/SheetTabBar/SheetDeleteDialog.tsx
Normal file
141
webapp/IronCalc/src/components/SheetTabBar/SheetDeleteDialog.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import styled from "@emotion/styled";
|
||||
import { Button, Dialog } from "@mui/material";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { theme } from "../../theme";
|
||||
|
||||
interface SheetDeleteDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onDelete: () => void;
|
||||
sheetName: string;
|
||||
}
|
||||
|
||||
function SheetDeleteDialog({
|
||||
open,
|
||||
onClose,
|
||||
onDelete,
|
||||
sheetName,
|
||||
}: SheetDeleteDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose}>
|
||||
<DialogWrapper>
|
||||
<IconWrapper>
|
||||
<Trash2 />
|
||||
</IconWrapper>
|
||||
<Title>{t("sheet_delete.title")}</Title>
|
||||
<Body>
|
||||
{t("sheet_delete.message1")} <strong>'{sheetName}'</strong>{" "}
|
||||
{t("sheet_delete.message2")}
|
||||
</Body>
|
||||
<ButtonGroup>
|
||||
<DeleteButton onClick={onDelete} autoFocus>
|
||||
{t("sheet_delete.confirm")}
|
||||
</DeleteButton>
|
||||
<CancelButton onClick={onClose}>
|
||||
{t("sheet_delete.cancel")}
|
||||
</CancelButton>
|
||||
</ButtonGroup>
|
||||
</DialogWrapper>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
const DialogWrapper = styled.div`
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 1px 3px 0px ${theme.palette.common.black}1A;
|
||||
width: 280px;
|
||||
max-width: calc(100% - 40px);
|
||||
z-index: 50;
|
||||
font-family: "Inter", sans-serif;
|
||||
`;
|
||||
|
||||
const IconWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
background-color: ${theme.palette.error.main}1A;
|
||||
margin: 12px auto 8px auto;
|
||||
color: ${theme.palette.error.main};
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Title = styled.h2`
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: ${theme.palette.grey["900"]};
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const Body = styled.p`
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
color: ${theme.palette.grey["900"]};
|
||||
font-size: 12px;
|
||||
`;
|
||||
|
||||
const ButtonGroup = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledButton = styled.button`
|
||||
cursor: pointer;
|
||||
color: ${theme.palette.common.white};
|
||||
background-color: ${theme.palette.primary.main};
|
||||
padding: 0px 10px;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
text-overflow: ellipsis;
|
||||
transition: background-color 150ms;
|
||||
text-transform: none;
|
||||
&:hover {
|
||||
background-color: ${theme.palette.primary.dark};
|
||||
}
|
||||
`;
|
||||
|
||||
const DeleteButton = styled(Button)`
|
||||
background-color: ${theme.palette.error.main};
|
||||
color: ${theme.palette.common.white};
|
||||
text-transform: none;
|
||||
&:hover {
|
||||
background-color: ${theme.palette.error.dark};
|
||||
}
|
||||
`;
|
||||
|
||||
const CancelButton = styled(Button)`
|
||||
background-color: ${theme.palette.grey["200"]};
|
||||
color: ${theme.palette.grey["700"]};
|
||||
text-transform: none;
|
||||
&:hover {
|
||||
background-color: ${theme.palette.grey["300"]};
|
||||
}
|
||||
`;
|
||||
|
||||
export default SheetDeleteDialog;
|
||||
@@ -6,6 +6,7 @@ import { theme } from "../../theme";
|
||||
import ColorPicker from "../colorPicker";
|
||||
import { isInReferenceMode } from "../editor/util";
|
||||
import type { WorkbookState } from "../workbookState";
|
||||
import SheetDeleteDialog from "./SheetDeleteDialog";
|
||||
import SheetRenameDialog from "./SheetRenameDialog";
|
||||
|
||||
interface SheetTabProps {
|
||||
@@ -37,9 +38,20 @@ function SheetTab(props: SheetTabProps) {
|
||||
const handleCloseRenameDialog = () => {
|
||||
setRenameDialogOpen(false);
|
||||
};
|
||||
|
||||
const handleOpenRenameDialog = () => {
|
||||
setRenameDialogOpen(true);
|
||||
};
|
||||
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
|
||||
const handleOpenDeleteDialog = () => {
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseDeleteDialog = () => {
|
||||
setDeleteDialogOpen(false);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<TabWrapper
|
||||
@@ -97,7 +109,7 @@ function SheetTab(props: SheetTabProps) {
|
||||
<StyledMenuItem
|
||||
disabled={!props.canDelete}
|
||||
onClick={() => {
|
||||
props.onDeleted();
|
||||
handleOpenDeleteDialog();
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
@@ -134,6 +146,15 @@ function SheetTab(props: SheetTabProps) {
|
||||
anchorEl={colorButton}
|
||||
open={colorPickerOpen}
|
||||
/>
|
||||
<SheetDeleteDialog
|
||||
open={deleteDialogOpen}
|
||||
onClose={handleCloseDeleteDialog}
|
||||
onDelete={() => {
|
||||
props.onDeleted();
|
||||
handleCloseDeleteDialog();
|
||||
}}
|
||||
sheetName={name}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user