135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import React from "react";
|
||
import { useMutation } from "@tanstack/react-query";
|
||
import { AxiosError } from "axios";
|
||
import { LexoRank } from "lexorank";
|
||
import { Text } from "@mantine/core";
|
||
import { modals } from "@mantine/modals";
|
||
import {
|
||
BoardSchema,
|
||
HttpValidationError,
|
||
UpdateBoardSchema,
|
||
} from "@/lib/client";
|
||
import {
|
||
createBoardMutation,
|
||
deleteBoardMutation,
|
||
updateBoardMutation,
|
||
} from "@/lib/client/@tanstack/react-query.gen";
|
||
import { notifications } from "@/lib/notifications";
|
||
import {
|
||
getMaxByLexorank,
|
||
getNewLexorank,
|
||
sortByLexorank,
|
||
} from "@/utils/lexorank";
|
||
|
||
type UseBoardsOperationsProps = {
|
||
boards: BoardSchema[];
|
||
setBoards: React.Dispatch<React.SetStateAction<BoardSchema[]>>;
|
||
refetchBoards: () => void;
|
||
projectId?: number;
|
||
};
|
||
|
||
type BoardsOperations = {
|
||
onCreateBoard: (name: string) => void;
|
||
onUpdateBoard: (boardId: number, board: UpdateBoardSchema) => void;
|
||
onDeleteBoard: (board: BoardSchema) => void;
|
||
};
|
||
|
||
export const useBoardsOperations = ({
|
||
boards,
|
||
setBoards,
|
||
refetchBoards,
|
||
projectId,
|
||
}: UseBoardsOperationsProps): BoardsOperations => {
|
||
const onError = (error: AxiosError<HttpValidationError>) => {
|
||
console.error(error);
|
||
notifications.error({
|
||
message: error.response?.data?.detail as string | undefined,
|
||
});
|
||
refetchBoards();
|
||
};
|
||
|
||
const createBoard = useMutation({
|
||
...createBoardMutation(),
|
||
onError,
|
||
onSuccess: res => {
|
||
setBoards([...boards, res.board]);
|
||
},
|
||
});
|
||
|
||
const updateBoard = useMutation({
|
||
...updateBoardMutation(),
|
||
onError,
|
||
});
|
||
|
||
const deleteBoard = useMutation({
|
||
...deleteBoardMutation(),
|
||
onError,
|
||
});
|
||
|
||
const onCreateBoard = (name: string) => {
|
||
if (!projectId) return;
|
||
const lastBoard = getMaxByLexorank(boards);
|
||
const newLexorank = getNewLexorank(
|
||
lastBoard ? LexoRank.parse(lastBoard.lexorank) : null
|
||
);
|
||
|
||
createBoard.mutate({
|
||
body: {
|
||
board: {
|
||
name,
|
||
projectId,
|
||
lexorank: newLexorank.toString(),
|
||
},
|
||
},
|
||
});
|
||
};
|
||
|
||
const onUpdateBoard = (boardId: number, board: UpdateBoardSchema) => {
|
||
updateBoard.mutate({
|
||
path: { boardId },
|
||
body: { board },
|
||
});
|
||
|
||
setBoards(boards =>
|
||
sortByLexorank(
|
||
boards.map(oldBoard =>
|
||
oldBoard.id !== boardId
|
||
? oldBoard
|
||
: {
|
||
id: oldBoard.id,
|
||
name: board.name ? board.name : oldBoard.name,
|
||
lexorank: board.lexorank
|
||
? board.lexorank
|
||
: oldBoard.lexorank,
|
||
}
|
||
)
|
||
)
|
||
);
|
||
};
|
||
|
||
const onDeleteBoard = (board: BoardSchema) => {
|
||
modals.openConfirmModal({
|
||
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));
|
||
},
|
||
});
|
||
};
|
||
|
||
return {
|
||
onCreateBoard,
|
||
onUpdateBoard,
|
||
onDeleteBoard,
|
||
};
|
||
};
|