diff --git a/src/app/deals/components/Boards/Boards.tsx b/src/app/deals/components/Boards/Boards.tsx index 5730073..ced04d4 100644 --- a/src/app/deals/components/Boards/Boards.tsx +++ b/src/app/deals/components/Boards/Boards.tsx @@ -1,21 +1,46 @@ "use client"; import React from "react"; +import { useMutation } from "@tanstack/react-query"; +import { AxiosError } from "axios"; import { ScrollArea } from "@mantine/core"; import Board from "@/app/deals/components/Board/Board"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { BoardSchema } from "@/client"; +import { updateBoardMutation } from "@/client/@tanstack/react-query.gen"; import SortableDnd from "@/components/SortableDnd"; +import { notifications } from "@/lib/notifications"; +import { ErrorBody } from "@/types/ErrorBody"; const Boards = () => { - const { boards, setSelectedBoard } = useBoardsContext(); + const { boards, setSelectedBoard, refetchBoards } = useBoardsContext(); + + const updateBoard = useMutation({ + ...updateBoardMutation(), + onError: (error: AxiosError) => { + console.error(error); + notifications.error({ + message: error.response?.data?.detail, + }); + refetchBoards(); + }, + }); const renderBoard = (board: BoardSchema) => { return ; }; const onDragEnd = (itemId: number, newLexorank: string) => { - console.log("onDragEnd:", itemId, newLexorank); + updateBoard.mutate({ + path: { + boardId: itemId, + }, + body: { + board: { + lexorank: newLexorank, + }, + }, + }); }; const selectBoard = (board: BoardSchema) => { diff --git a/src/app/deals/contexts/BoardsContext.tsx b/src/app/deals/contexts/BoardsContext.tsx index d913e61..88732d8 100644 --- a/src/app/deals/contexts/BoardsContext.tsx +++ b/src/app/deals/contexts/BoardsContext.tsx @@ -16,13 +16,14 @@ type BoardsContextState = { setBoards: React.Dispatch>; selectedBoard: BoardSchema | null; setSelectedBoard: React.Dispatch>; + refetchBoards: () => void; }; const BoardsContext = createContext(undefined); const useBoardsContextState = () => { const { selectedProject: project } = useProjectsContext(); - const { boards, setBoards } = useBoardsList({ projectId: project?.id }); + const { boards, setBoards, refetch: refetchBoards } = useBoardsList({ projectId: project?.id }); const [selectedBoard, setSelectedBoard] = useState( null ); @@ -48,6 +49,7 @@ const useBoardsContextState = () => { setBoards, selectedBoard, setSelectedBoard, + refetchBoards, }; }; diff --git a/src/client/@tanstack/react-query.gen.ts b/src/client/@tanstack/react-query.gen.ts index 00facee..08ff511 100644 --- a/src/client/@tanstack/react-query.gen.ts +++ b/src/client/@tanstack/react-query.gen.ts @@ -1,12 +1,22 @@ // This file is auto-generated by @hey-api/openapi-ts -import { queryOptions } from "@tanstack/react-query"; +import { queryOptions, type UseMutationOptions } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; import { client as _heyApiClient } from "../client.gen"; -import { getBoards, getDeals, getProjects, type Options } from "../sdk.gen"; +import { + getBoards, + getDeals, + getProjects, + updateBoard, + type Options, +} from "../sdk.gen"; import type { GetBoardsData, GetDealsData, GetProjectsData, + UpdateBoardData, + UpdateBoardError, + UpdateBoardResponse2, } from "../types.gen"; export type QueryKey = [ @@ -87,6 +97,33 @@ export const getBoardsOptions = (options: Options) => { }); }; +/** + * Update Board + */ +export const updateBoardMutation = ( + options?: Partial> +): UseMutationOptions< + UpdateBoardResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + UpdateBoardResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { + const { data } = await updateBoard({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + export const getDealsQueryKey = (options: Options) => createQueryKey("getDeals", options); diff --git a/src/client/sdk.gen.ts b/src/client/sdk.gen.ts index 4f400a0..9be8e4e 100644 --- a/src/client/sdk.gen.ts +++ b/src/client/sdk.gen.ts @@ -11,6 +11,9 @@ import type { GetDealsResponses, GetProjectsData, GetProjectsResponses, + UpdateBoardData, + UpdateBoardErrors, + UpdateBoardResponses, } from "./types.gen"; export type Options< @@ -59,11 +62,32 @@ export const getBoards = ( ThrowOnError >({ responseType: "json", - url: "/board/{project_id}", + url: "/board/{projectId}", ...options, }); }; +/** + * Update Board + */ +export const updateBoard = ( + options: Options +) => { + return (options.client ?? _heyApiClient).patch< + UpdateBoardResponses, + UpdateBoardErrors, + ThrowOnError + >({ + responseType: "json", + url: "/board/{boardId}", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, + }); +}; + /** * Get Deals */ @@ -76,7 +100,7 @@ export const getDeals = ( ThrowOnError >({ responseType: "json", - url: "/deal/{board_id}", + url: "/deal/{boardId}", ...options, }); }; diff --git a/src/client/types.gen.ts b/src/client/types.gen.ts index b7c27e1..7ac4861 100644 --- a/src/client/types.gen.ts +++ b/src/client/types.gen.ts @@ -116,6 +116,37 @@ export type StatusSchema = { lexorank: string; }; +/** + * UpdateBoardRequest + */ +export type UpdateBoardRequest = { + board: UpdateBoardSchema; +}; + +/** + * UpdateBoardResponse + */ +export type UpdateBoardResponse = { + /** + * Message + */ + message: string; +}; + +/** + * UpdateBoardSchema + */ +export type UpdateBoardSchema = { + /** + * Name + */ + name?: string | null; + /** + * Lexorank + */ + lexorank?: string | null; +}; + /** * ValidationError */ @@ -155,12 +186,12 @@ export type GetBoardsData = { body?: never; path: { /** - * Project Id + * Projectid */ - project_id: number; + projectId: number; }; query?: never; - url: "/board/{project_id}"; + url: "/board/{projectId}"; }; export type GetBoardsErrors = { @@ -181,16 +212,51 @@ export type GetBoardsResponses = { export type GetBoardsResponse2 = GetBoardsResponses[keyof GetBoardsResponses]; +export type UpdateBoardData = { + body: UpdateBoardRequest; + path: { + /** + * Boardid + */ + boardId: number; + }; + query?: never; + url: "/board/{boardId}"; +}; + +export type UpdateBoardErrors = { + /** + * Item not found + */ + 404: unknown; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type UpdateBoardError = UpdateBoardErrors[keyof UpdateBoardErrors]; + +export type UpdateBoardResponses = { + /** + * Successful Response + */ + 200: UpdateBoardResponse; +}; + +export type UpdateBoardResponse2 = + UpdateBoardResponses[keyof UpdateBoardResponses]; + export type GetDealsData = { body?: never; path: { /** - * Board Id + * Boardid */ - board_id: number; + boardId: number; }; query?: never; - url: "/deal/{board_id}"; + url: "/deal/{boardId}"; }; export type GetDealsErrors = { diff --git a/src/hooks/useBoardsList.ts b/src/hooks/useBoardsList.ts index 6b4cb00..456424f 100644 --- a/src/hooks/useBoardsList.ts +++ b/src/hooks/useBoardsList.ts @@ -11,7 +11,7 @@ const useBoardsList = ({ projectId }: Props) => { const [boards, setBoards] = useState([]); const { data, refetch, isLoading } = useQuery({ - ...getBoardsOptions({ path: { project_id: projectId! } }), + ...getBoardsOptions({ path: { projectId: projectId! } }), enabled: projectId !== undefined, }); diff --git a/src/hooks/useDealsList.ts b/src/hooks/useDealsList.ts index 968adab..53eb2cd 100644 --- a/src/hooks/useDealsList.ts +++ b/src/hooks/useDealsList.ts @@ -11,7 +11,7 @@ const useDealsList = ({ boardId }: Props) => { const [deals, setDeals] = useState([]); const { data, refetch, isLoading } = useQuery({ - ...getDealsOptions({ path: { board_id: boardId! } }), + ...getDealsOptions({ path: { boardId: boardId! } }), enabled: boardId !== undefined, }); diff --git a/src/types/ErrorBody.ts b/src/types/ErrorBody.ts new file mode 100644 index 0000000..dfc1c40 --- /dev/null +++ b/src/types/ErrorBody.ts @@ -0,0 +1,3 @@ +export type ErrorBody = { + detail?: string; +};