feat: status editing and deleting

This commit is contained in:
2025-08-07 15:46:11 +04:00
parent 7e2dd9763b
commit e29664ecc5
12 changed files with 616 additions and 69 deletions

View File

@ -4,14 +4,14 @@ import React, { FC, ReactNode } from "react";
import DealCard from "@/app/deals/components/DealCard/DealCard"; import DealCard from "@/app/deals/components/DealCard/DealCard";
import DealContainer from "@/app/deals/components/DealContainer/DealContainer"; import DealContainer from "@/app/deals/components/DealContainer/DealContainer";
import StatusColumnWrapper from "@/app/deals/components/StatusColumnWrapper/StatusColumnWrapper"; import StatusColumnWrapper from "@/app/deals/components/StatusColumnWrapper/StatusColumnWrapper";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { useDealsContext } from "@/app/deals/contexts/DealsContext";
import useDealsAndStatusesDnd from "@/app/deals/hooks/useDealsAndStatusesDnd"; import useDealsAndStatusesDnd from "@/app/deals/hooks/useDealsAndStatusesDnd";
import FunnelDnd from "@/components/dnd/FunnelDnd/FunnelDnd"; import FunnelDnd from "@/components/dnd/FunnelDnd/FunnelDnd";
import { DealSchema, StatusSchema } from "@/lib/client"; import { DealSchema, StatusSchema } from "@/lib/client";
import { sortByLexorank } from "@/utils/lexorank"; import { sortByLexorank } from "@/utils/lexorank";
const Funnel: FC = () => { const Funnel: FC = () => {
const { deals } = useStatusesContext(); const { deals } = useDealsContext();
const { const {
sortedStatuses, sortedStatuses,

View File

@ -1,5 +1,7 @@
import React, { ReactNode } from "react"; import React, { ReactNode, useEffect, useRef, useState } from "react";
import { Box, Text } from "@mantine/core"; import { Box, Group, Text, TextInput } from "@mantine/core";
import StatusMenu from "@/app/deals/components/StatusColumnWrapper/StatusMenu";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import { StatusSchema } from "@/lib/client"; import { StatusSchema } from "@/lib/client";
type Props = { type Props = {
@ -13,15 +15,84 @@ const StatusColumnWrapper = ({
children, children,
isDragging = false, isDragging = false,
}: Props) => { }: Props) => {
const { onUpdateStatus } = useStatusesContext();
const [isEditing, setIsEditing] = useState(false);
const [editValue, setEditValue] = useState(status.name);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (isEditing && inputRef.current) {
inputRef.current.focus();
}
}, [isEditing]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
isEditing &&
inputRef.current &&
!inputRef.current.contains(event.target as Node)
) {
handleSave();
}
};
document.addEventListener("mousedown", handleClickOutside);
return () =>
document.removeEventListener("mousedown", handleClickOutside);
}, [isEditing, editValue]);
const handleEdit = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
e.stopPropagation();
setEditValue(status.name);
setIsEditing(true);
};
const handleSave = () => {
const newValue = editValue.trim();
if (newValue && newValue !== status.name) {
onUpdateStatus(status.id, { name: newValue });
}
setIsEditing(false);
};
return ( return (
<Box <Box
p={"xs"}
style={{ style={{
borderWidth: 1, borderWidth: 1,
borderColor: "gray", borderColor: "gray",
padding: 2,
width: "15vw", width: "15vw",
minWidth: 150, minWidth: 150,
}}> }}>
<Group
wrap={"nowrap"}
justify={"space-between"}
ml={"xs"}
mb={"xs"}>
{isEditing ? (
<TextInput
ref={inputRef}
value={editValue}
onChange={e => setEditValue(e.target.value)}
onKeyDown={e => {
if (e.key === "Enter") handleSave();
if (e.key === "Escape") {
setEditValue(status.name);
setIsEditing(false);
}
}}
variant="unstyled"
styles={{
input: {
height: 25,
minHeight: 25,
},
}}
/>
) : (
<Text <Text
style={{ style={{
cursor: "grab", cursor: "grab",
@ -30,6 +101,12 @@ const StatusColumnWrapper = ({
}}> }}>
{status.name} {status.name}
</Text> </Text>
)}
<StatusMenu
status={status}
handleEdit={handleEdit}
/>
</Group>
{children} {children}
</Box> </Box>
); );

View File

@ -0,0 +1,48 @@
import React, { FC } from "react";
import { IconDotsVertical, IconEdit, IconTrash } from "@tabler/icons-react";
import { Box, Group, Menu, Text } from "@mantine/core";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import { StatusSchema } from "@/lib/client";
type Props = {
status: StatusSchema;
handleEdit: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
};
const StatusMenu: FC<Props> = ({ status, handleEdit }) => {
const { onDeleteStatus } = useStatusesContext();
return (
<Menu>
<Menu.Target>
<Box
p={5}
style={{
cursor: "pointer",
}}
onClick={e => {
e.preventDefault();
e.stopPropagation();
}}>
<IconDotsVertical size={16} />
</Box>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item onClick={handleEdit}>
<Group wrap={"nowrap"}>
<IconEdit />
<Text>Переименовать</Text>
</Group>
</Menu.Item>
<Menu.Item onClick={() => onDeleteStatus(status.id)}>
<Group wrap={"nowrap"}>
<IconTrash />
<Text>Удалить</Text>
</Group>
</Menu.Item>
</Menu.Dropdown>
</Menu>
);
};
export default StatusMenu;

View File

@ -0,0 +1,80 @@
"use client";
import React, { createContext, FC, useContext } from "react";
import { useMutation, UseMutationResult } from "@tanstack/react-query";
import { AxiosError } from "axios";
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
import useDealsList from "@/hooks/useDealsList";
import {
DealSchema,
HttpValidationError,
Options,
UpdateDealData,
UpdateDealResponse,
} from "@/lib/client";
import { updateDealMutation } from "@/lib/client/@tanstack/react-query.gen";
import { notifications } from "@/lib/notifications";
type DealsContextState = {
deals: DealSchema[];
setDeals: React.Dispatch<React.SetStateAction<DealSchema[]>>;
updateDeal: UseMutationResult<
UpdateDealResponse,
AxiosError<HttpValidationError>,
Options<UpdateDealData>
>;
refetchDeals: () => void;
};
const DealsContext = createContext<DealsContextState | undefined>(undefined);
const useDealsContextState = () => {
const { selectedBoard } = useBoardsContext();
const {
deals,
setDeals,
refetch: refetchDeals,
} = useDealsList({ boardId: selectedBoard?.id });
const updateDeal = useMutation({
...updateDealMutation(),
onError: error => {
console.error(error);
notifications.error({
message: error.response?.data?.detail as string | undefined,
});
refetchDeals();
},
});
return {
deals,
setDeals,
updateDeal,
refetchDeals,
};
};
type DealsContextProviderProps = {
children: React.ReactNode;
};
export const DealsContextProvider: FC<DealsContextProviderProps> = ({
children,
}) => {
const state = useDealsContextState();
return (
<DealsContext.Provider value={state}>{children}</DealsContext.Provider>
);
};
export const useDealsContext = () => {
const context = useContext(DealsContext);
if (!context) {
throw new Error(
"useDealsContext must be used within a DealsContextProvider"
);
}
return context;
};

View File

@ -4,22 +4,17 @@ import React, { createContext, FC, useContext, useEffect } from "react";
import { useMutation, UseMutationResult } from "@tanstack/react-query"; import { useMutation, UseMutationResult } from "@tanstack/react-query";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
import useDealsList from "@/hooks/useDealsList";
import useStatusesList from "@/hooks/useStatusesList"; import useStatusesList from "@/hooks/useStatusesList";
import { useStatusesOperations } from "@/hooks/useStatusesOperations";
import { import {
DealSchema,
HttpValidationError, HttpValidationError,
Options, Options,
StatusSchema, StatusSchema,
UpdateDealData,
UpdateDealResponse,
UpdateStatusData, UpdateStatusData,
UpdateStatusResponse, UpdateStatusResponse,
UpdateStatusSchema,
} from "@/lib/client"; } from "@/lib/client";
import { import { updateStatusMutation } from "@/lib/client/@tanstack/react-query.gen";
updateDealMutation,
updateStatusMutation,
} from "@/lib/client/@tanstack/react-query.gen";
import { notifications } from "@/lib/notifications"; import { notifications } from "@/lib/notifications";
type StatusesContextState = { type StatusesContextState = {
@ -31,14 +26,9 @@ type StatusesContextState = {
Options<UpdateStatusData> Options<UpdateStatusData>
>; >;
refetchStatuses: () => void; refetchStatuses: () => void;
deals: DealSchema[]; onCreateStatus: (name: string) => void;
setDeals: React.Dispatch<React.SetStateAction<DealSchema[]>>; onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void;
updateDeal: UseMutationResult< onDeleteStatus: (statusId: number) => void;
UpdateDealResponse,
AxiosError<HttpValidationError>,
Options<UpdateDealData>
>;
refetchDeals: () => void;
}; };
const StatusesContext = createContext<StatusesContextState | undefined>( const StatusesContext = createContext<StatusesContextState | undefined>(
@ -55,12 +45,6 @@ const useStatusesContextState = () => {
boardId: selectedBoard?.id, boardId: selectedBoard?.id,
}); });
const {
deals,
setDeals,
refetch: refetchDeals,
} = useDealsList({ boardId: selectedBoard?.id });
useEffect(() => { useEffect(() => {
refetchStatuses(); refetchStatuses();
}, [selectedBoard]); }, [selectedBoard]);
@ -76,15 +60,12 @@ const useStatusesContextState = () => {
}, },
}); });
const updateDeal = useMutation({ const { onCreateStatus, onUpdateStatus, onDeleteStatus } =
...updateDealMutation(), useStatusesOperations({
onError: error => { statuses,
console.error(error); setStatuses,
notifications.error({ refetchStatuses,
message: error.response?.data?.detail as string | undefined, boardId: selectedBoard?.id,
});
refetchDeals();
},
}); });
return { return {
@ -92,10 +73,9 @@ const useStatusesContextState = () => {
setStatuses, setStatuses,
updateStatus, updateStatus,
refetchStatuses, refetchStatuses,
deals, onCreateStatus,
setDeals, onUpdateStatus,
updateDeal, onDeleteStatus,
refetchDeals,
}; };
}; };

View File

@ -1,6 +1,7 @@
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { DragOverEvent, DragStartEvent, Over } from "@dnd-kit/core"; import { DragOverEvent, DragStartEvent, Over } from "@dnd-kit/core";
import { useDebouncedCallback } from "@mantine/hooks"; import { useDebouncedCallback } from "@mantine/hooks";
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import useGetNewRank from "@/app/deals/hooks/useGetNewRank"; import useGetNewRank from "@/app/deals/hooks/useGetNewRank";
import { getStatusId, isStatusId } from "@/app/deals/utils/statusId"; import { getStatusId, isStatusId } from "@/app/deals/utils/statusId";
@ -10,8 +11,8 @@ import { sortByLexorank } from "@/utils/lexorank";
const useDealsAndStatusesDnd = () => { const useDealsAndStatusesDnd = () => {
const [activeDeal, setActiveDeal] = useState<DealSchema | null>(null); const [activeDeal, setActiveDeal] = useState<DealSchema | null>(null);
const [activeStatus, setActiveStatus] = useState<StatusSchema | null>(null); const [activeStatus, setActiveStatus] = useState<StatusSchema | null>(null);
const { statuses, deals, setDeals, setStatuses, updateDeal, updateStatus } = const { statuses, setStatuses, updateStatus } = useStatusesContext();
useStatusesContext(); const { deals, setDeals, updateDeal } = useDealsContext();
const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]); const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]);
const { const {

View File

@ -7,6 +7,7 @@ import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext"; import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext";
import PageBlock from "@/components/layout/PageBlock/PageBlock"; import PageBlock from "@/components/layout/PageBlock/PageBlock";
import PageContainer from "@/components/layout/PageContainer/PageContainer"; import PageContainer from "@/components/layout/PageContainer/PageContainer";
import { DealsContextProvider } from "./contexts/DealsContext";
export default function DealsPage() { export default function DealsPage() {
return ( return (
@ -18,7 +19,9 @@ export default function DealsPage() {
<Boards /> <Boards />
<Divider my={"xl"} /> <Divider my={"xl"} />
<StatusesContextProvider> <StatusesContextProvider>
<DealsContextProvider>
<Funnel /> <Funnel />
</DealsContextProvider>
</StatusesContextProvider> </StatusesContextProvider>
</BoardsContextProvider> </BoardsContextProvider>
</ProjectsContextProvider> </ProjectsContextProvider>

View File

@ -0,0 +1,110 @@
import React from "react";
import { useMutation } from "@tanstack/react-query";
import { AxiosError } from "axios";
import { LexoRank } from "lexorank";
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 } from "@/utils/lexorank";
type Props = {
statuses: StatusSchema[];
setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>;
refetchStatuses: () => void;
boardId?: number;
};
export const useStatusesOperations = ({
statuses,
setStatuses,
refetchStatuses,
boardId,
}: Props) => {
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 =>
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 = (statusId: number) => {
deleteStatus.mutate({
path: { statusId },
});
setStatuses(statuses =>
statuses.filter(status => status.id !== statusId)
);
};
return {
onCreateStatus,
onUpdateStatus,
onDeleteStatus,
};
};

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, deleteBoard, updateBoard, getDeals, updateDeal, getProjects, getStatuses, updateStatus } from '../sdk.gen'; import { type Options, getBoards, createBoard, deleteBoard, updateBoard, getDeals, updateDeal, getProjects, getStatuses, createStatus, deleteStatus, 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, DeleteBoardData, DeleteBoardError, DeleteBoardResponse2, 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, CreateStatusData, CreateStatusError, CreateStatusResponse2, DeleteStatusData, DeleteStatusError, DeleteStatusResponse2, 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';
@ -205,6 +205,60 @@ export const getStatusesOptions = (options: Options<GetStatusesData>) => {
}); });
}; };
export const createStatusQueryKey = (options: Options<CreateStatusData>) => createQueryKey('createStatus', options);
/**
* Create Status
*/
export const createStatusOptions = (options: Options<CreateStatusData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await createStatus({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: createStatusQueryKey(options)
});
};
/**
* Create Status
*/
export const createStatusMutation = (options?: Partial<Options<CreateStatusData>>): UseMutationOptions<CreateStatusResponse2, AxiosError<CreateStatusError>, Options<CreateStatusData>> => {
const mutationOptions: UseMutationOptions<CreateStatusResponse2, AxiosError<CreateStatusError>, Options<CreateStatusData>> = {
mutationFn: async (localOptions) => {
const { data } = await createStatus({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
/**
* Delete Status
*/
export const deleteStatusMutation = (options?: Partial<Options<DeleteStatusData>>): UseMutationOptions<DeleteStatusResponse2, AxiosError<DeleteStatusError>, Options<DeleteStatusData>> => {
const mutationOptions: UseMutationOptions<DeleteStatusResponse2, AxiosError<DeleteStatusError>, Options<DeleteStatusData>> = {
mutationFn: async (localOptions) => {
const { data } = await deleteStatus({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
/** /**
* Update Status * Update Status
*/ */

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, DeleteBoardData, DeleteBoardResponses, DeleteBoardErrors, 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, CreateStatusData, CreateStatusResponses, CreateStatusErrors, DeleteStatusData, DeleteStatusResponses, DeleteStatusErrors, UpdateStatusData, UpdateStatusResponses, UpdateStatusErrors } from './types.gen';
import { zGetBoardsData, zGetBoardsResponse2, zCreateBoardData, zCreateBoardResponse2, zDeleteBoardData, zDeleteBoardResponse2, 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, zCreateStatusData, zCreateStatusResponse2, zDeleteStatusData, zDeleteStatusResponse2, 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> & {
@ -167,6 +167,44 @@ export const getStatuses = <ThrowOnError extends boolean = false>(options: Optio
}); });
}; };
/**
* Create Status
*/
export const createStatus = <ThrowOnError extends boolean = false>(options: Options<CreateStatusData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<CreateStatusResponses, CreateStatusErrors, ThrowOnError>({
requestValidator: async (data) => {
return await zCreateStatusData.parseAsync(data);
},
responseType: 'json',
responseValidator: async (data) => {
return await zCreateStatusResponse2.parseAsync(data);
},
url: '/status/',
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
});
};
/**
* Delete Status
*/
export const deleteStatus = <ThrowOnError extends boolean = false>(options: Options<DeleteStatusData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).delete<DeleteStatusResponses, DeleteStatusErrors, ThrowOnError>({
requestValidator: async (data) => {
return await zDeleteStatusData.parseAsync(data);
},
responseType: 'json',
responseValidator: async (data) => {
return await zDeleteStatusResponse2.parseAsync(data);
},
url: '/status/{statusId}',
...options
});
};
/** /**
* Update Status * Update Status
*/ */

View File

@ -54,6 +54,42 @@ export type CreateBoardSchema = {
lexorank: string; lexorank: string;
}; };
/**
* CreateStatusRequest
*/
export type CreateStatusRequest = {
status: CreateStatusSchema;
};
/**
* CreateStatusResponse
*/
export type CreateStatusResponse = {
/**
* Message
*/
message: string;
status: StatusSchema;
};
/**
* CreateStatusSchema
*/
export type CreateStatusSchema = {
/**
* Name
*/
name: string;
/**
* Boardid
*/
boardId: number;
/**
* Lexorank
*/
lexorank: string;
};
/** /**
* DealSchema * DealSchema
*/ */
@ -86,6 +122,16 @@ export type DeleteBoardResponse = {
message: string; message: string;
}; };
/**
* DeleteStatusResponse
*/
export type DeleteStatusResponse = {
/**
* Message
*/
message: string;
};
/** /**
* GetBoardsResponse * GetBoardsResponse
*/ */
@ -154,14 +200,14 @@ export type ProjectSchema = {
* StatusSchema * StatusSchema
*/ */
export type StatusSchema = { export type StatusSchema = {
/**
* Name
*/
name: string;
/** /**
* Id * Id
*/ */
id: number; id: number;
/**
* Name
*/
name: string;
/** /**
* Lexorank * Lexorank
*/ */
@ -504,6 +550,61 @@ export type GetStatusesResponses = {
export type GetStatusesResponse2 = GetStatusesResponses[keyof GetStatusesResponses]; export type GetStatusesResponse2 = GetStatusesResponses[keyof GetStatusesResponses];
export type CreateStatusData = {
body: CreateStatusRequest;
path?: never;
query?: never;
url: '/status/';
};
export type CreateStatusErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type CreateStatusError = CreateStatusErrors[keyof CreateStatusErrors];
export type CreateStatusResponses = {
/**
* Successful Response
*/
200: CreateStatusResponse;
};
export type CreateStatusResponse2 = CreateStatusResponses[keyof CreateStatusResponses];
export type DeleteStatusData = {
body?: never;
path: {
/**
* Statusid
*/
statusId: number;
};
query?: never;
url: '/status/{statusId}';
};
export type DeleteStatusErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type DeleteStatusError = DeleteStatusErrors[keyof DeleteStatusErrors];
export type DeleteStatusResponses = {
/**
* Successful Response
*/
200: DeleteStatusResponse;
};
export type DeleteStatusResponse2 = DeleteStatusResponses[keyof DeleteStatusResponses];
export type UpdateStatusData = { export type UpdateStatusData = {
body: UpdateStatusRequest; body: UpdateStatusRequest;
path: { path: {

View File

@ -35,6 +35,39 @@ export const zCreateBoardResponse = z.object({
board: zBoardSchema board: zBoardSchema
}); });
/**
* CreateStatusSchema
*/
export const zCreateStatusSchema = z.object({
name: z.string(),
boardId: z.int(),
lexorank: z.string()
});
/**
* CreateStatusRequest
*/
export const zCreateStatusRequest = z.object({
status: zCreateStatusSchema
});
/**
* StatusSchema
*/
export const zStatusSchema = z.object({
id: z.int(),
name: z.string(),
lexorank: z.string()
});
/**
* CreateStatusResponse
*/
export const zCreateStatusResponse = z.object({
message: z.string(),
status: zStatusSchema
});
/** /**
* DealSchema * DealSchema
*/ */
@ -52,6 +85,13 @@ export const zDeleteBoardResponse = z.object({
message: z.string() message: z.string()
}); });
/**
* DeleteStatusResponse
*/
export const zDeleteStatusResponse = z.object({
message: z.string()
});
/** /**
* GetBoardsResponse * GetBoardsResponse
*/ */
@ -81,15 +121,6 @@ export const zGetProjectsResponse = z.object({
projects: z.array(zProjectSchema) projects: z.array(zProjectSchema)
}); });
/**
* StatusSchema
*/
export const zStatusSchema = z.object({
name: z.string(),
id: z.int(),
lexorank: z.string()
});
/** /**
* GetStatusesResponse * GetStatusesResponse
*/ */
@ -304,6 +335,30 @@ export const zGetStatusesData = z.object({
*/ */
export const zGetStatusesResponse2 = zGetStatusesResponse; export const zGetStatusesResponse2 = zGetStatusesResponse;
export const zCreateStatusData = z.object({
body: zCreateStatusRequest,
path: z.optional(z.never()),
query: z.optional(z.never())
});
/**
* Successful Response
*/
export const zCreateStatusResponse2 = zCreateStatusResponse;
export const zDeleteStatusData = z.object({
body: z.optional(z.never()),
path: z.object({
statusId: z.int()
}),
query: z.optional(z.never())
});
/**
* Successful Response
*/
export const zDeleteStatusResponse2 = zDeleteStatusResponse;
export const zUpdateStatusData = z.object({ export const zUpdateStatusData = z.object({
body: zUpdateStatusRequest, body: zUpdateStatusRequest,
path: z.object({ path: z.object({