137 lines
3.8 KiB
TypeScript
137 lines
3.8 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 {
|
||
HttpValidationError,
|
||
StatusSchema,
|
||
UpdateStatusSchema,
|
||
} from "@/lib/client";
|
||
import {
|
||
createStatusMutation,
|
||
deleteStatusMutation,
|
||
updateStatusMutation,
|
||
} from "@/lib/client/@tanstack/react-query.gen";
|
||
import { notifications } from "@/lib/notifications";
|
||
import {
|
||
getMaxByLexorank,
|
||
getNewLexorank,
|
||
sortByLexorank,
|
||
} from "@/utils/lexorank";
|
||
|
||
type Props = {
|
||
statuses: StatusSchema[];
|
||
setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>;
|
||
refetchStatuses: () => void;
|
||
boardId?: number;
|
||
};
|
||
|
||
type StatusesOperations = {
|
||
onCreateStatus: (name: string) => void;
|
||
onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void;
|
||
onDeleteStatus: (status: StatusSchema) => void;
|
||
};
|
||
|
||
export const useStatusesOperations = ({
|
||
statuses,
|
||
setStatuses,
|
||
refetchStatuses,
|
||
boardId,
|
||
}: Props): StatusesOperations => {
|
||
const onError = (error: AxiosError<HttpValidationError>) => {
|
||
console.error(error);
|
||
notifications.error({
|
||
message: error.response?.data?.detail as string | undefined,
|
||
});
|
||
refetchStatuses();
|
||
};
|
||
|
||
const createStatus = useMutation({
|
||
...createStatusMutation(),
|
||
onError,
|
||
onSuccess: res => {
|
||
setStatuses([...statuses, res.status]);
|
||
},
|
||
});
|
||
|
||
const updateStatus = useMutation({
|
||
...updateStatusMutation(),
|
||
onError,
|
||
});
|
||
|
||
const deleteStatus = useMutation({
|
||
...deleteStatusMutation(),
|
||
onError,
|
||
});
|
||
|
||
const onCreateStatus = (name: string) => {
|
||
if (!boardId) return;
|
||
const lastStatus = getMaxByLexorank(statuses);
|
||
const newLexorank = getNewLexorank(
|
||
lastStatus ? LexoRank.parse(lastStatus.lexorank) : null
|
||
);
|
||
|
||
createStatus.mutate({
|
||
body: {
|
||
status: {
|
||
name,
|
||
boardId,
|
||
lexorank: newLexorank.toString(),
|
||
},
|
||
},
|
||
});
|
||
};
|
||
|
||
const onUpdateStatus = (statusId: number, status: UpdateStatusSchema) => {
|
||
updateStatus.mutate({
|
||
path: { statusId },
|
||
body: { status },
|
||
});
|
||
|
||
setStatuses(statuses =>
|
||
sortByLexorank(
|
||
statuses.map(oldStatus =>
|
||
oldStatus.id !== statusId
|
||
? oldStatus
|
||
: {
|
||
id: oldStatus.id,
|
||
name: status.name ? status.name : oldStatus.name,
|
||
lexorank: status.lexorank
|
||
? status.lexorank
|
||
: oldStatus.lexorank,
|
||
}
|
||
)
|
||
)
|
||
);
|
||
};
|
||
|
||
const onDeleteStatus = (status: StatusSchema) => {
|
||
modals.openConfirmModal({
|
||
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)
|
||
);
|
||
},
|
||
});
|
||
};
|
||
|
||
return {
|
||
onCreateStatus,
|
||
onUpdateStatus,
|
||
onDeleteStatus,
|
||
};
|
||
};
|