feat: confirm modals on deleting

This commit is contained in:
2025-08-08 15:32:56 +04:00
parent afad1b4605
commit d3febcdfb0
6 changed files with 52 additions and 24 deletions

View File

@ -27,17 +27,13 @@ const BoardMenu: FC<Props> = ({ isHovered, board, startEditing }) => {
: 0, : 0,
cursor: "pointer", cursor: "pointer",
}} }}
onClick={e => { onClick={e => e.stopPropagation()}>
e.preventDefault();
e.stopPropagation();
}}>
<IconDotsVertical size={16} /> <IconDotsVertical size={16} />
</Box> </Box>
</Menu.Target> </Menu.Target>
<Menu.Dropdown> <Menu.Dropdown>
<Menu.Item <Menu.Item
onClick={e => { onClick={e => {
e.preventDefault();
e.stopPropagation(); e.stopPropagation();
startEditing(); startEditing();
}}> }}>
@ -46,7 +42,11 @@ const BoardMenu: FC<Props> = ({ isHovered, board, startEditing }) => {
<Text>Переименовать</Text> <Text>Переименовать</Text>
</Group> </Group>
</Menu.Item> </Menu.Item>
<Menu.Item onClick={() => onDeleteBoard(board.id)}> <Menu.Item
onClick={e => {
e.stopPropagation();
onDeleteBoard(board);
}}>
<Group wrap={"nowrap"}> <Group wrap={"nowrap"}>
<IconTrash /> <IconTrash />
<Text>Удалить</Text> <Text>Удалить</Text>

View File

@ -20,17 +20,13 @@ const StatusMenu: FC<Props> = ({ status, handleEdit }) => {
style={{ style={{
cursor: "pointer", cursor: "pointer",
}} }}
onClick={e => { onClick={e => e.stopPropagation()}>
e.preventDefault();
e.stopPropagation();
}}>
<IconDotsVertical size={16} /> <IconDotsVertical size={16} />
</Box> </Box>
</Menu.Target> </Menu.Target>
<Menu.Dropdown> <Menu.Dropdown>
<Menu.Item <Menu.Item
onClick={e => { onClick={e => {
e.preventDefault();
e.stopPropagation(); e.stopPropagation();
handleEdit(); handleEdit();
}}> }}>
@ -39,7 +35,11 @@ const StatusMenu: FC<Props> = ({ status, handleEdit }) => {
<Text>Переименовать</Text> <Text>Переименовать</Text>
</Group> </Group>
</Menu.Item> </Menu.Item>
<Menu.Item onClick={() => onDeleteStatus(status.id)}> <Menu.Item
onClick={e => {
e.stopPropagation();
onDeleteStatus(status);
}}>
<Group wrap={"nowrap"}> <Group wrap={"nowrap"}>
<IconTrash /> <IconTrash />
<Text>Удалить</Text> <Text>Удалить</Text>

View File

@ -20,7 +20,7 @@ type BoardsContextState = {
refetchBoards: () => void; refetchBoards: () => void;
onCreateBoard: (name: string) => void; onCreateBoard: (name: string) => void;
onUpdateBoard: (boardId: number, board: UpdateBoardSchema) => void; onUpdateBoard: (boardId: number, board: UpdateBoardSchema) => void;
onDeleteBoard: (boardId: number) => void; onDeleteBoard: (board: BoardSchema) => void;
}; };
const BoardsContext = createContext<BoardsContextState | undefined>(undefined); const BoardsContext = createContext<BoardsContextState | undefined>(undefined);

View File

@ -28,7 +28,7 @@ type StatusesContextState = {
refetchStatuses: () => void; refetchStatuses: () => void;
onCreateStatus: (name: string) => void; onCreateStatus: (name: string) => void;
onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void; onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void;
onDeleteStatus: (statusId: number) => void; onDeleteStatus: (status: StatusSchema) => void;
}; };
const StatusesContext = createContext<StatusesContextState | undefined>( const StatusesContext = createContext<StatusesContextState | undefined>(

View File

@ -2,6 +2,8 @@ import React from "react";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { LexoRank } from "lexorank"; import { LexoRank } from "lexorank";
import { Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import { import {
BoardSchema, BoardSchema,
HttpValidationError, HttpValidationError,
@ -93,11 +95,23 @@ export const useBoardsOperations = ({
); );
}; };
const onDeleteBoard = (boardId: number) => { const onDeleteBoard = (board: BoardSchema) => {
deleteBoard.mutate({ modals.openConfirmModal({
path: { boardId }, title: "Удаление доски",
children: (
<Text>
Вы уверены, что хотите удалить доску "{board.name}"?
</Text>
),
labels: { confirm: "Да", cancel: "Нет" },
confirmProps: { color: "red" },
onConfirm: () => {
deleteBoard.mutate({
path: { boardId: board.id },
});
setBoards(boards => boards.filter(b => b.id !== board.id));
},
}); });
setBoards(boards => boards.filter(board => board.id !== boardId));
}; };
return { return {

View File

@ -2,6 +2,8 @@ import React from "react";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { LexoRank } from "lexorank"; import { LexoRank } from "lexorank";
import { Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import { import {
HttpValidationError, HttpValidationError,
StatusSchema, StatusSchema,
@ -93,13 +95,25 @@ export const useStatusesOperations = ({
); );
}; };
const onDeleteStatus = (statusId: number) => { const onDeleteStatus = (status: StatusSchema) => {
deleteStatus.mutate({ modals.openConfirmModal({
path: { statusId }, title: "Удаление колонки",
children: (
<Text>
Вы уверены, что хотите удалить колонку "{status.name}"?
</Text>
),
labels: { confirm: "Да", cancel: "Нет" },
confirmProps: { color: "red" },
onConfirm: () => {
deleteStatus.mutate({
path: { statusId: status.id },
});
setStatuses(statuses =>
statuses.filter(s => s.id !== status.id)
);
},
}); });
setStatuses(statuses =>
statuses.filter(status => status.id !== statusId)
);
}; };
return { return {