feat: board deletion

This commit is contained in:
2025-08-07 10:13:08 +04:00
parent 335fbfe81c
commit 41f8d19d49
6 changed files with 126 additions and 7 deletions

View File

@ -10,7 +10,7 @@ type Props = {
const Board: FC<Props> = ({ board }) => { const Board: FC<Props> = ({ board }) => {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const { selectedBoard } = useBoardsContext(); const { selectedBoard, onDeleteBoardClick } = useBoardsContext();
return ( return (
<Group <Group
@ -47,7 +47,7 @@ const Board: FC<Props> = ({ board }) => {
<Text>Переименовать</Text> <Text>Переименовать</Text>
</Group> </Group>
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item onClick={() => onDeleteBoardClick(board.id)}>
<Group wrap={"nowrap"}> <Group wrap={"nowrap"}>
<IconTrash /> <IconTrash />
<Text>Удалить</Text> <Text>Удалить</Text>

View File

@ -12,7 +12,10 @@ import { LexoRank } from "lexorank";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import useBoardsList from "@/hooks/useBoardsList"; import useBoardsList from "@/hooks/useBoardsList";
import { BoardSchema } from "@/lib/client"; import { BoardSchema } from "@/lib/client";
import { createBoardMutation } from "@/lib/client/@tanstack/react-query.gen"; import {
createBoardMutation,
deleteBoardMutation,
} from "@/lib/client/@tanstack/react-query.gen";
import { notifications } from "@/lib/notifications"; import { notifications } from "@/lib/notifications";
import { getMaxByLexorank, getNewLexorank } from "@/utils/lexorank"; import { getMaxByLexorank, getNewLexorank } from "@/utils/lexorank";
@ -23,6 +26,7 @@ type BoardsContextState = {
setSelectedBoard: React.Dispatch<React.SetStateAction<BoardSchema | null>>; setSelectedBoard: React.Dispatch<React.SetStateAction<BoardSchema | null>>;
refetchBoards: () => void; refetchBoards: () => void;
onCreateBoardClick: (name: string) => void; onCreateBoardClick: (name: string) => void;
onDeleteBoardClick: (boardId: number) => void;
}; };
const BoardsContext = createContext<BoardsContextState | undefined>(undefined); const BoardsContext = createContext<BoardsContextState | undefined>(undefined);
@ -86,6 +90,26 @@ const useBoardsContextState = () => {
}); });
}; };
const deleteBoard = useMutation({
...deleteBoardMutation(),
onError: error => {
console.error(error);
notifications.error({
message: error.response?.data?.detail as string | undefined,
});
refetchBoards();
},
});
const onDeleteBoardClick = (boardId: number) => {
deleteBoard.mutate({
path: {
boardId,
},
});
setBoards(boards => boards.filter(board => board.id !== boardId));
};
return { return {
boards, boards,
setBoards, setBoards,
@ -93,6 +117,7 @@ const useBoardsContextState = () => {
setSelectedBoard, setSelectedBoard,
refetchBoards, refetchBoards,
onCreateBoardClick, onCreateBoardClick,
onDeleteBoardClick,
}; };
}; };

View File

@ -1,8 +1,8 @@
// This file is auto-generated by @hey-api/openapi-ts // This file is auto-generated by @hey-api/openapi-ts
import { type Options, getBoards, createBoard, updateBoard, getDeals, updateDeal, getProjects, getStatuses, updateStatus } from '../sdk.gen'; import { type Options, getBoards, createBoard, deleteBoard, updateBoard, getDeals, updateDeal, getProjects, getStatuses, updateStatus } from '../sdk.gen';
import { queryOptions, type UseMutationOptions } from '@tanstack/react-query'; import { queryOptions, type UseMutationOptions } from '@tanstack/react-query';
import type { GetBoardsData, CreateBoardData, CreateBoardError, CreateBoardResponse2, UpdateBoardData, UpdateBoardError, UpdateBoardResponse2, GetDealsData, UpdateDealData, UpdateDealError, UpdateDealResponse2, GetProjectsData, GetStatusesData, UpdateStatusData, UpdateStatusError, UpdateStatusResponse2 } from '../types.gen'; import type { GetBoardsData, CreateBoardData, CreateBoardError, CreateBoardResponse2, DeleteBoardData, DeleteBoardError, DeleteBoardResponse2, UpdateBoardData, UpdateBoardError, UpdateBoardResponse2, GetDealsData, UpdateDealData, UpdateDealError, UpdateDealResponse2, GetProjectsData, GetStatusesData, UpdateStatusData, UpdateStatusError, UpdateStatusResponse2 } from '../types.gen';
import type { AxiosError } from 'axios'; import type { AxiosError } from 'axios';
import { client as _heyApiClient } from '../client.gen'; import { client as _heyApiClient } from '../client.gen';
@ -94,6 +94,23 @@ export const createBoardMutation = (options?: Partial<Options<CreateBoardData>>)
return mutationOptions; return mutationOptions;
}; };
/**
* Delete Board
*/
export const deleteBoardMutation = (options?: Partial<Options<DeleteBoardData>>): UseMutationOptions<DeleteBoardResponse2, AxiosError<DeleteBoardError>, Options<DeleteBoardData>> => {
const mutationOptions: UseMutationOptions<DeleteBoardResponse2, AxiosError<DeleteBoardError>, Options<DeleteBoardData>> = {
mutationFn: async (localOptions) => {
const { data } = await deleteBoard({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
/** /**
* Update Board * Update Board
*/ */

View File

@ -1,8 +1,8 @@
// This file is auto-generated by @hey-api/openapi-ts // This file is auto-generated by @hey-api/openapi-ts
import type { Options as ClientOptions, TDataShape, Client } from './client'; import type { Options as ClientOptions, TDataShape, Client } from './client';
import type { GetBoardsData, GetBoardsResponses, GetBoardsErrors, CreateBoardData, CreateBoardResponses, CreateBoardErrors, UpdateBoardData, UpdateBoardResponses, UpdateBoardErrors, GetDealsData, GetDealsResponses, GetDealsErrors, UpdateDealData, UpdateDealResponses, UpdateDealErrors, GetProjectsData, GetProjectsResponses, GetStatusesData, GetStatusesResponses, GetStatusesErrors, UpdateStatusData, UpdateStatusResponses, UpdateStatusErrors } from './types.gen'; import type { GetBoardsData, GetBoardsResponses, GetBoardsErrors, CreateBoardData, CreateBoardResponses, CreateBoardErrors, DeleteBoardData, DeleteBoardResponses, DeleteBoardErrors, UpdateBoardData, UpdateBoardResponses, UpdateBoardErrors, GetDealsData, GetDealsResponses, GetDealsErrors, UpdateDealData, UpdateDealResponses, UpdateDealErrors, GetProjectsData, GetProjectsResponses, GetStatusesData, GetStatusesResponses, GetStatusesErrors, UpdateStatusData, UpdateStatusResponses, UpdateStatusErrors } from './types.gen';
import { zGetBoardsData, zGetBoardsResponse2, zCreateBoardData, zCreateBoardResponse2, zUpdateBoardData, zUpdateBoardResponse2, zGetDealsData, zGetDealsResponse2, zUpdateDealData, zUpdateDealResponse2, zGetProjectsData, zGetProjectsResponse2, zGetStatusesData, zGetStatusesResponse2, zUpdateStatusData, zUpdateStatusResponse2 } from './zod.gen'; import { zGetBoardsData, zGetBoardsResponse2, zCreateBoardData, zCreateBoardResponse2, zDeleteBoardData, zDeleteBoardResponse2, zUpdateBoardData, zUpdateBoardResponse2, zGetDealsData, zGetDealsResponse2, zUpdateDealData, zUpdateDealResponse2, zGetProjectsData, zGetProjectsResponse2, zGetStatusesData, zGetStatusesResponse2, zUpdateStatusData, zUpdateStatusResponse2 } from './zod.gen';
import { client as _heyApiClient } from './client.gen'; import { client as _heyApiClient } from './client.gen';
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & { export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
@ -57,6 +57,23 @@ export const createBoard = <ThrowOnError extends boolean = false>(options: Optio
}); });
}; };
/**
* Delete Board
*/
export const deleteBoard = <ThrowOnError extends boolean = false>(options: Options<DeleteBoardData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).delete<DeleteBoardResponses, DeleteBoardErrors, ThrowOnError>({
requestValidator: async (data) => {
return await zDeleteBoardData.parseAsync(data);
},
responseType: 'json',
responseValidator: async (data) => {
return await zDeleteBoardResponse2.parseAsync(data);
},
url: '/board/{boardId}',
...options
});
};
/** /**
* Update Board * Update Board
*/ */

View File

@ -76,6 +76,16 @@ export type DealSchema = {
statusId: number; statusId: number;
}; };
/**
* DeleteBoardResponse
*/
export type DeleteBoardResponse = {
/**
* Message
*/
message: string;
};
/** /**
* GetBoardsResponse * GetBoardsResponse
*/ */
@ -328,6 +338,36 @@ export type CreateBoardResponses = {
export type CreateBoardResponse2 = CreateBoardResponses[keyof CreateBoardResponses]; export type CreateBoardResponse2 = CreateBoardResponses[keyof CreateBoardResponses];
export type DeleteBoardData = {
body?: never;
path: {
/**
* Boardid
*/
boardId: number;
};
query?: never;
url: '/board/{boardId}';
};
export type DeleteBoardErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type DeleteBoardError = DeleteBoardErrors[keyof DeleteBoardErrors];
export type DeleteBoardResponses = {
/**
* Successful Response
*/
200: DeleteBoardResponse;
};
export type DeleteBoardResponse2 = DeleteBoardResponses[keyof DeleteBoardResponses];
export type UpdateBoardData = { export type UpdateBoardData = {
body: UpdateBoardRequest; body: UpdateBoardRequest;
path: { path: {

View File

@ -45,6 +45,13 @@ export const zDealSchema = z.object({
statusId: z.int() statusId: z.int()
}); });
/**
* DeleteBoardResponse
*/
export const zDeleteBoardResponse = z.object({
message: z.string()
});
/** /**
* GetBoardsResponse * GetBoardsResponse
*/ */
@ -221,6 +228,19 @@ export const zCreateBoardData = z.object({
*/ */
export const zCreateBoardResponse2 = zCreateBoardResponse; export const zCreateBoardResponse2 = zCreateBoardResponse;
export const zDeleteBoardData = z.object({
body: z.optional(z.never()),
path: z.object({
boardId: z.int()
}),
query: z.optional(z.never())
});
/**
* Successful Response
*/
export const zDeleteBoardResponse2 = zDeleteBoardResponse;
export const zUpdateBoardData = z.object({ export const zUpdateBoardData = z.object({
body: zUpdateBoardRequest, body: zUpdateBoardRequest,
path: z.object({ path: z.object({