refactor: crud objects in contexts

This commit is contained in:
2025-08-23 11:20:32 +04:00
parent f2084ae3d4
commit 6ad813ea1d
25 changed files with 120 additions and 128 deletions

View File

@ -13,7 +13,7 @@ type Props = {
}; };
const Board: FC<Props> = ({ board }) => { const Board: FC<Props> = ({ board }) => {
const { selectedBoard, onUpdateBoard, onDeleteBoard } = useBoardsContext(); const { selectedBoard, boardsCrud } = useBoardsContext();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
@ -30,7 +30,9 @@ const Board: FC<Props> = ({ board }) => {
onMouseLeave={() => setIsHovered(false)}> onMouseLeave={() => setIsHovered(false)}>
<InPlaceInput <InPlaceInput
defaultValue={board.name} defaultValue={board.name}
onComplete={value => onUpdateBoard(board.id, { name: value })} onComplete={value =>
boardsCrud.onUpdate(board.id, { name: value })
}
inputStyles={{ inputStyles={{
input: { input: {
height: 24, height: 24,
@ -49,7 +51,7 @@ const Board: FC<Props> = ({ board }) => {
isHovered={ isHovered={
selectedBoard?.id === board.id || isHovered selectedBoard?.id === board.id || isHovered
} }
onDeleteBoard={onDeleteBoard} onDeleteBoard={boardsCrud.onDelete}
board={board} board={board}
startEditing={startEditing} startEditing={startEditing}
/> />

View File

@ -11,13 +11,13 @@ import { BoardSchema } from "@/lib/client";
import styles from "./Boards.module.css"; import styles from "./Boards.module.css";
const Boards = () => { const Boards = () => {
const { boards, setSelectedBoardId, onUpdateBoard } = useBoardsContext(); const { boards, setSelectedBoardId, boardsCrud } = useBoardsContext();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const renderBoard = (board: BoardSchema) => <Board board={board} />; const renderBoard = (board: BoardSchema) => <Board board={board} />;
const onDragEnd = (itemId: number, newLexorank: string) => { const onDragEnd = (itemId: number, newLexorank: string) => {
onUpdateBoard(itemId, { lexorank: newLexorank }); boardsCrud.onUpdate(itemId, { lexorank: newLexorank });
}; };
const selectBoard = (board: BoardSchema) => { const selectBoard = (board: BoardSchema) => {

View File

@ -5,13 +5,13 @@ import InPlaceInput from "@/components/ui/InPlaceInput/InPlaceInput";
import styles from "./CreateBoardButton.module.css"; import styles from "./CreateBoardButton.module.css";
const CreateBoardButton = () => { const CreateBoardButton = () => {
const { onCreateBoard } = useBoardsContext(); const { boardsCrud } = useBoardsContext();
return ( return (
<Flex style={{ borderBottom: "2px solid gray" }}> <Flex style={{ borderBottom: "2px solid gray" }}>
<InPlaceInput <InPlaceInput
placeholder={"Название доски"} placeholder={"Название доски"}
onComplete={onCreateBoard} onComplete={boardsCrud.onCreate}
getChildren={startEditing => ( getChildren={startEditing => (
<Box <Box
onClick={startEditing} onClick={startEditing}

View File

@ -7,7 +7,7 @@ import useIsMobile from "@/hooks/useIsMobile";
import styles from "./CreateStatusButton.module.css"; import styles from "./CreateStatusButton.module.css";
const CreateStatusButton = () => { const CreateStatusButton = () => {
const { onCreateStatus } = useStatusesContext(); const { statusesCrud } = useStatusesContext();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return ( return (
@ -15,7 +15,7 @@ const CreateStatusButton = () => {
<Box className={styles["inner-container"]}> <Box className={styles["inner-container"]}>
<InPlaceInput <InPlaceInput
placeholder={"Название колонки"} placeholder={"Название колонки"}
onComplete={onCreateStatus} onComplete={statusesCrud.onCreate}
getChildren={startEditing => ( getChildren={startEditing => (
<Center <Center
p={"sm"} p={"sm"}

View File

@ -13,14 +13,13 @@ type Props = {
}; };
const StatusColumnHeader: FC<Props> = ({ status, isDragging }) => { const StatusColumnHeader: FC<Props> = ({ status, isDragging }) => {
const { onUpdateStatus, onDeleteStatus, refetchStatuses } = const { statusesCrud, refetchStatuses } = useStatusesContext();
useStatusesContext();
const { selectedBoard } = useBoardsContext(); const { selectedBoard } = useBoardsContext();
const handleSave = (value: string) => { const handleSave = (value: string) => {
const newValue = value.trim(); const newValue = value.trim();
if (newValue && newValue !== status.name) { if (newValue && newValue !== status.name) {
onUpdateStatus(status.id, { name: newValue }); statusesCrud.onUpdate(status.id, { name: newValue });
} }
}; };
@ -55,7 +54,7 @@ const StatusColumnHeader: FC<Props> = ({ status, isDragging }) => {
status={status} status={status}
handleEdit={startEditing} handleEdit={startEditing}
refetchStatuses={refetchStatuses} refetchStatuses={refetchStatuses}
onDeleteStatus={onDeleteStatus} onDeleteStatus={statusesCrud.onDelete}
/> />
</> </>
)} )}

View File

@ -2,9 +2,9 @@
import React, { createContext, FC, useContext, useState } from "react"; import React, { createContext, FC, useContext, useState } from "react";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import { BoardsCrud, useBoardsCrud } from "@/hooks/useBoardsCrud";
import useBoardsList from "@/hooks/useBoardsList"; import useBoardsList from "@/hooks/useBoardsList";
import { useBoardsOperations } from "@/hooks/useBoardsOperations"; import { BoardSchema } from "@/lib/client";
import { BoardSchema, UpdateBoardSchema } from "@/lib/client";
type BoardsContextState = { type BoardsContextState = {
boards: BoardSchema[]; boards: BoardSchema[];
@ -12,9 +12,7 @@ type BoardsContextState = {
selectedBoard: BoardSchema | null; selectedBoard: BoardSchema | null;
setSelectedBoardId: React.Dispatch<React.SetStateAction<number | null>>; setSelectedBoardId: React.Dispatch<React.SetStateAction<number | null>>;
refetchBoards: () => void; refetchBoards: () => void;
onCreateBoard: (name: string) => void; boardsCrud: BoardsCrud;
onUpdateBoard: (boardId: number, board: UpdateBoardSchema) => void;
onDeleteBoard: (board: BoardSchema) => void;
isEditorDrawerOpened: boolean; isEditorDrawerOpened: boolean;
setIsEditorDrawerOpened: React.Dispatch<React.SetStateAction<boolean>>; setIsEditorDrawerOpened: React.Dispatch<React.SetStateAction<boolean>>;
}; };
@ -39,7 +37,7 @@ const useBoardsContextState = () => {
setSelectedBoardId(boards[0].id); setSelectedBoardId(boards[0].id);
} }
const { onCreate, onUpdate, onDelete } = useBoardsOperations({ const boardsCrud = useBoardsCrud({
boards, boards,
setBoards, setBoards,
refetchBoards, refetchBoards,
@ -52,9 +50,7 @@ const useBoardsContextState = () => {
selectedBoard, selectedBoard,
setSelectedBoardId, setSelectedBoardId,
refetchBoards, refetchBoards,
onCreateBoard: onCreate, boardsCrud,
onUpdateBoard: onUpdate,
onDeleteBoard: onDelete,
isEditorDrawerOpened, isEditorDrawerOpened,
setIsEditorDrawerOpened, setIsEditorDrawerOpened,
}; };

View File

@ -1,18 +1,16 @@
"use client"; "use client";
import React, { createContext, FC, useContext, useState } from "react"; import React, { createContext, FC, useContext, useState } from "react";
import { ProjectsCrud, useProjectsCrud } from "@/hooks/useProjectsCrud";
import useProjectsList from "@/hooks/useProjectsList"; import useProjectsList from "@/hooks/useProjectsList";
import { useProjectsOperations } from "@/hooks/useProjectsOperations"; import { ProjectSchema } from "@/lib/client";
import { ProjectSchema, UpdateProjectSchema } from "@/lib/client";
type ProjectsContextState = { type ProjectsContextState = {
selectedProject: ProjectSchema | null; selectedProject: ProjectSchema | null;
setSelectedProjectId: React.Dispatch<React.SetStateAction<number | null>>; setSelectedProjectId: React.Dispatch<React.SetStateAction<number | null>>;
refetchProjects: () => Promise<void>; refetchProjects: () => Promise<void>;
projects: ProjectSchema[]; projects: ProjectSchema[];
onCreateProject: (name: string) => void; projectsCrud: ProjectsCrud;
onUpdateProject: (projectId: number, project: UpdateProjectSchema) => void;
onDeleteProject: (project: ProjectSchema) => void;
}; };
const ProjectsContext = createContext<ProjectsContextState | undefined>( const ProjectsContext = createContext<ProjectsContextState | undefined>(
@ -36,7 +34,7 @@ const useProjectsContextState = () => {
setSelectedProjectId(projects[0].id); setSelectedProjectId(projects[0].id);
} }
const { onCreate, onUpdate, onDelete } = useProjectsOperations({ const projectsCrud = useProjectsCrud({
projects, projects,
setProjects, setProjects,
refetchProjects, refetchProjects,
@ -47,9 +45,7 @@ const useProjectsContextState = () => {
selectedProject, selectedProject,
refetchProjects, refetchProjects,
setSelectedProjectId, setSelectedProjectId,
onCreateProject: onCreate, projectsCrud,
onUpdateProject: onUpdate,
onDeleteProject: onDelete,
}; };
}; };

View File

@ -2,17 +2,15 @@
import React, { createContext, FC, useContext } from "react"; import React, { createContext, FC, useContext } from "react";
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
import { StatusesCrud, useStatusesCrud } from "@/hooks/useStatusesCrud";
import useStatusesList from "@/hooks/useStatusesList"; import useStatusesList from "@/hooks/useStatusesList";
import { useStatusesOperations } from "@/hooks/useStatusesOperations"; import { StatusSchema } from "@/lib/client";
import { StatusSchema, UpdateStatusSchema } from "@/lib/client";
type StatusesContextState = { type StatusesContextState = {
statuses: StatusSchema[]; statuses: StatusSchema[];
setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>; setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>;
refetchStatuses: () => void; refetchStatuses: () => void;
onCreateStatus: (name: string) => void; statusesCrud: StatusesCrud;
onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void;
onDeleteStatus: (status: StatusSchema) => void;
}; };
const StatusesContext = createContext<StatusesContextState | undefined>( const StatusesContext = createContext<StatusesContextState | undefined>(
@ -29,7 +27,7 @@ const useStatusesContextState = () => {
boardId: selectedBoard?.id, boardId: selectedBoard?.id,
}); });
const { onCreate, onUpdate, onDelete } = useStatusesOperations({ const statusesCrud = useStatusesCrud({
statuses, statuses,
setStatuses, setStatuses,
refetchStatuses, refetchStatuses,
@ -40,9 +38,7 @@ const useStatusesContextState = () => {
statuses, statuses,
setStatuses, setStatuses,
refetchStatuses, refetchStatuses,
onCreateStatus: onCreate, statusesCrud,
onUpdateStatus: onUpdate,
onDeleteStatus: onDelete,
}; };
}; };

View File

@ -5,7 +5,7 @@ import { modals } from "@mantine/modals";
import { useBoardStatusesContext } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext"; import { useBoardStatusesContext } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext";
const CreateStatusButton: FC = () => { const CreateStatusButton: FC = () => {
const { onCreateStatus } = useBoardStatusesContext(); const { statusesCrud } = useBoardStatusesContext();
const onStartCreating = () => { const onStartCreating = () => {
modals.openContextModal({ modals.openContextModal({
@ -13,7 +13,7 @@ const CreateStatusButton: FC = () => {
title: "Создание колонки", title: "Создание колонки",
withCloseButton: true, withCloseButton: true,
innerProps: { innerProps: {
onComplete: onCreateStatus, onComplete: statusesCrud.onCreate,
}, },
}); });
}; };

View File

@ -11,7 +11,7 @@ type Props = {
}; };
const StatusMobile: FC<Props> = ({ status, board }) => { const StatusMobile: FC<Props> = ({ status, board }) => {
const { onUpdateStatus, onDeleteStatus } = useBoardStatusesContext(); const { statusesCrud } = useBoardStatusesContext();
const startEditing = () => { const startEditing = () => {
modals.openContextModal({ modals.openContextModal({
@ -19,7 +19,7 @@ const StatusMobile: FC<Props> = ({ status, board }) => {
title: "Редактирование статуса", title: "Редактирование статуса",
withCloseButton: true, withCloseButton: true,
innerProps: { innerProps: {
onComplete: name => onUpdateStatus(status.id, { name }), onComplete: name => statusesCrud.onUpdate(status.id, { name }),
defaultValue: status.name, defaultValue: status.name,
}, },
}); });
@ -38,7 +38,7 @@ const StatusMobile: FC<Props> = ({ status, board }) => {
<StatusMenu <StatusMenu
status={status} status={status}
board={board} board={board}
onDeleteStatus={onDeleteStatus} onDeleteStatus={statusesCrud.onDelete}
handleEdit={startEditing} handleEdit={startEditing}
withChangeOrderButton={false} withChangeOrderButton={false}
/> />

View File

@ -12,7 +12,7 @@ type Props = {
}; };
const StatusesDrawerBody: FC<Props> = ({ onClose }) => { const StatusesDrawerBody: FC<Props> = ({ onClose }) => {
const { onUpdateStatus, board, statuses } = useBoardStatusesContext(); const { statusesCrud, board, statuses } = useBoardStatusesContext();
const renderDraggable = () => ( const renderDraggable = () => (
<Box p={"xs"}> <Box p={"xs"}>
@ -36,7 +36,7 @@ const StatusesDrawerBody: FC<Props> = ({ onClose }) => {
}; };
const onDragEnd = (itemId: number, newLexorank: string) => const onDragEnd = (itemId: number, newLexorank: string) =>
onUpdateStatus(itemId, { lexorank: newLexorank }); statusesCrud.onUpdate(itemId, { lexorank: newLexorank });
return ( return (
<> <>

View File

@ -1,18 +1,16 @@
"use client"; "use client";
import React, { createContext, FC, useContext } from "react"; import React, { createContext, FC, useContext } from "react";
import { StatusesCrud, useStatusesCrud } from "@/hooks/useStatusesCrud";
import useStatusesList from "@/hooks/useStatusesList"; import useStatusesList from "@/hooks/useStatusesList";
import { useStatusesOperations } from "@/hooks/useStatusesOperations"; import { BoardSchema, StatusSchema } from "@/lib/client";
import { BoardSchema, StatusSchema, UpdateStatusSchema } from "@/lib/client";
type BoardStatusesContextState = { type BoardStatusesContextState = {
board: BoardSchema; board: BoardSchema;
statuses: StatusSchema[]; statuses: StatusSchema[];
setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>; setStatuses: React.Dispatch<React.SetStateAction<StatusSchema[]>>;
refetchStatuses: () => void; refetchStatuses: () => void;
onCreateStatus: (name: string) => void; statusesCrud: StatusesCrud;
onUpdateStatus: (statusId: number, status: UpdateStatusSchema) => void;
onDeleteStatus: (status: StatusSchema) => void;
}; };
const BoardStatusesContext = createContext< const BoardStatusesContext = createContext<
@ -32,7 +30,7 @@ const useBoardStatusesContextState = ({ board }: Props) => {
boardId: board.id, boardId: board.id,
}); });
const { onCreate, onUpdate, onDelete } = useStatusesOperations({ const statusesCrud = useStatusesCrud({
statuses, statuses,
setStatuses, setStatuses,
refetchStatuses, refetchStatuses,
@ -44,9 +42,7 @@ const useBoardStatusesContextState = ({ board }: Props) => {
statuses, statuses,
setStatuses, setStatuses,
refetchStatuses, refetchStatuses,
onCreateStatus: onCreate, statusesCrud,
onUpdateStatus: onUpdate,
onDeleteStatus: onDelete,
}; };
}; };

View File

@ -10,7 +10,7 @@ type Props = {
}; };
const BoardMobile: FC<Props> = ({ board }) => { const BoardMobile: FC<Props> = ({ board }) => {
const { onUpdateBoard, onDeleteBoard } = useProjectBoardsContext(); const { boardsCrud } = useProjectBoardsContext();
const startEditing = () => { const startEditing = () => {
modals.openContextModal({ modals.openContextModal({
@ -18,7 +18,7 @@ const BoardMobile: FC<Props> = ({ board }) => {
title: "Редактирование доски", title: "Редактирование доски",
withCloseButton: true, withCloseButton: true,
innerProps: { innerProps: {
onComplete: name => onUpdateBoard(board.id, { name }), onComplete: name => boardsCrud.onUpdate(board.id, { name }),
defaultValue: board.name, defaultValue: board.name,
}, },
}); });
@ -37,7 +37,7 @@ const BoardMobile: FC<Props> = ({ board }) => {
<BoardMenu <BoardMenu
board={board} board={board}
startEditing={startEditing} startEditing={startEditing}
onDeleteBoard={onDeleteBoard} onDeleteBoard={boardsCrud.onDelete}
/> />
</Group> </Group>
); );

View File

@ -12,8 +12,7 @@ type Props = {
}; };
const BoardsDrawerBody: FC<Props> = ({ onClose }) => { const BoardsDrawerBody: FC<Props> = ({ onClose }) => {
const { boards, onUpdateBoard, project, onCreateBoard } = const { boards, boardsCrud, project } = useProjectBoardsContext();
useProjectBoardsContext();
const renderDraggable = () => ( const renderDraggable = () => (
<Box p={"xs"}> <Box p={"xs"}>
@ -34,7 +33,7 @@ const BoardsDrawerBody: FC<Props> = ({ onClose }) => {
}; };
const onDragEnd = (itemId: number, newLexorank: string) => { const onDragEnd = (itemId: number, newLexorank: string) => {
onUpdateBoard(itemId, { lexorank: newLexorank }); boardsCrud.onUpdate(itemId, { lexorank: newLexorank });
}; };
return ( return (
@ -59,7 +58,7 @@ const BoardsDrawerBody: FC<Props> = ({ onClose }) => {
dragHandleStyle={{ width: "auto" }} dragHandleStyle={{ width: "auto" }}
vertical vertical
/> />
<CreateBoardButton onCreateBoard={onCreateBoard} /> <CreateBoardButton onCreateBoard={boardsCrud.onCreate} />
</> </>
); );
}; };

View File

@ -1,18 +1,16 @@
"use client"; "use client";
import React, { createContext, FC, useContext } from "react"; import React, { createContext, FC, useContext } from "react";
import { BoardsCrud, useBoardsCrud } from "@/hooks/useBoardsCrud";
import useBoardsList from "@/hooks/useBoardsList"; import useBoardsList from "@/hooks/useBoardsList";
import { useBoardsOperations } from "@/hooks/useBoardsOperations"; import { BoardSchema, ProjectSchema } from "@/lib/client";
import { BoardSchema, ProjectSchema, UpdateBoardSchema } from "@/lib/client";
type ProjectBoardsContextState = { type ProjectBoardsContextState = {
boards: BoardSchema[]; boards: BoardSchema[];
setBoards: React.Dispatch<React.SetStateAction<BoardSchema[]>>; setBoards: React.Dispatch<React.SetStateAction<BoardSchema[]>>;
project: ProjectSchema; project: ProjectSchema;
refetchBoards: () => void; refetchBoards: () => void;
onCreateBoard: (name: string) => void; boardsCrud: BoardsCrud;
onUpdateBoard: (boardId: number, board: UpdateBoardSchema) => void;
onDeleteBoard: (board: BoardSchema) => void;
}; };
const ProjectBoardsContext = createContext< const ProjectBoardsContext = createContext<
@ -30,7 +28,7 @@ const useProjectBoardsContextState = ({ project }: Props) => {
refetch: refetchBoards, refetch: refetchBoards,
} = useBoardsList({ projectId: project?.id }); } = useBoardsList({ projectId: project?.id });
const { onCreate, onUpdate, onDelete } = useBoardsOperations({ const boardsCrud = useBoardsCrud({
boards, boards,
setBoards, setBoards,
refetchBoards, refetchBoards,
@ -42,9 +40,7 @@ const useProjectBoardsContextState = ({ project }: Props) => {
setBoards, setBoards,
project, project,
refetchBoards, refetchBoards,
onCreateBoard: onCreate, boardsCrud,
onUpdateBoard: onUpdate,
onDeleteBoard: onDelete,
}; };
}; };

View File

@ -5,7 +5,7 @@ import { modals } from "@mantine/modals";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
const CreateProjectButton: FC = () => { const CreateProjectButton: FC = () => {
const { onCreateProject } = useProjectsContext(); const { projectsCrud } = useProjectsContext();
const onStartCreating = () => { const onStartCreating = () => {
modals.openContextModal({ modals.openContextModal({
@ -13,7 +13,7 @@ const CreateProjectButton: FC = () => {
title: "Создание проекта", title: "Создание проекта",
withCloseButton: true, withCloseButton: true,
innerProps: { innerProps: {
onComplete: onCreateProject, onComplete: projectsCrud.onCreate,
}, },
}); });
}; };

View File

@ -11,7 +11,7 @@ type Props = {
}; };
const ProjectMenu: FC<Props> = ({ project, startEditing }) => { const ProjectMenu: FC<Props> = ({ project, startEditing }) => {
const { onDeleteProject } = useProjectsContext(); const { projectsCrud } = useProjectsContext();
return ( return (
<Menu> <Menu>
@ -36,7 +36,7 @@ const ProjectMenu: FC<Props> = ({ project, startEditing }) => {
<Menu.Item <Menu.Item
onClick={e => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
onDeleteProject(project); projectsCrud.onDelete(project);
}}> }}>
<Group wrap={"nowrap"}> <Group wrap={"nowrap"}>
<IconTrash /> <IconTrash />

View File

@ -17,7 +17,7 @@ const ProjectMobile: FC<Props> = ({
setSelectedProjectId, setSelectedProjectId,
closeDrawer, closeDrawer,
}) => { }) => {
const { onUpdateProject } = useProjectsContext(); const { projectsCrud } = useProjectsContext();
const startEditing = () => { const startEditing = () => {
modals.openContextModal({ modals.openContextModal({
@ -25,7 +25,7 @@ const ProjectMobile: FC<Props> = ({
title: "Редактирование проекта", title: "Редактирование проекта",
withCloseButton: true, withCloseButton: true,
innerProps: { innerProps: {
onComplete: name => onUpdateProject(project.id, { name }), onComplete: name => projectsCrud.onUpdate(project.id, { name }),
defaultValue: project.name, defaultValue: project.name,
}, },
}); });

View File

@ -24,7 +24,7 @@ const useDealsAndStatusesDnd = (): ReturnType => {
const swiperRef = useRef<SwiperRef>(null); const swiperRef = useRef<SwiperRef>(null);
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, setStatuses, onUpdateStatus } = useStatusesContext(); const { statuses, setStatuses, statusesCrud } = useStatusesContext();
const { deals, setDeals, updateDeal } = useDealsContext(); const { deals, setDeals, updateDeal } = useDealsContext();
const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]); const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -229,7 +229,7 @@ const useDealsAndStatusesDnd = (): ReturnType => {
}; };
const onStatusDragEnd = (statusId: number, lexorank: string) => { const onStatusDragEnd = (statusId: number, lexorank: string) => {
onUpdateStatus(statusId, { lexorank }); statusesCrud.onUpdate(statusId, { lexorank });
}; };
const handleDealDragEnd = (activeId: number | string, over: Over) => { const handleDealDragEnd = (activeId: number | string, over: Over) => {

View File

@ -0,0 +1,32 @@
import { Options } from "@/lib/client";
export type BaseEntity = {
id: number;
name: string;
lexorank?: string;
};
export type CreateMutationOptions = Options<{
body: any;
query: undefined;
path: undefined;
url: string;
}>;
export type UpdateMutationOptions = Options<{
body: any;
query: undefined;
path: {
pk: number;
};
url: string;
}>;
export type DeleteMutationOptions = Options<{
body: undefined;
query: undefined;
path: {
pk: number;
};
url: string;
}>;

View File

@ -3,46 +3,23 @@ import { useMutation, UseMutationOptions } from "@tanstack/react-query";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { Text } from "@mantine/core"; import { Text } from "@mantine/core";
import { modals } from "@mantine/modals"; import { modals } from "@mantine/modals";
import { HttpValidationError, Options } from "@/lib/client"; import {
BaseEntity,
CreateMutationOptions,
DeleteMutationOptions,
UpdateMutationOptions,
} from "@/hooks/baseCrud/types";
import { HttpValidationError } from "@/lib/client";
import { notifications } from "@/lib/notifications"; import { notifications } from "@/lib/notifications";
import { sortByLexorank } from "@/utils/lexorank"; import { sortByLexorank } from "@/utils/lexorank";
type BaseEntity = { type CrudOperations<TEntity, TUpdate> = {
id: number; onCreate: (name: string) => void;
name: string; onUpdate: (id: number, update: TUpdate) => void;
lexorank?: string; onDelete: (entity: TEntity) => void;
}; };
type CreateMutationOptions = Options<{ type UseEntityOperationsProps<TEntity extends BaseEntity, TUpdate, TCreate> = {
body: any;
query: undefined;
path: undefined;
url: string;
}>;
type UpdateMutationOptions = Options<{
body: any;
query: undefined;
path: {
pk: number;
};
url: string;
}>;
type DeleteMutationOptions = Options<{
body: undefined;
query: undefined;
path: {
pk: number;
};
url: string;
}>;
type UseEntityOperationsProps<
TEntity extends BaseEntity,
TUpdate,
TCreate,
> = {
entities: TEntity[]; entities: TEntity[];
setEntities: React.Dispatch<React.SetStateAction<TEntity[]>>; setEntities: React.Dispatch<React.SetStateAction<TEntity[]>>;
refetch: () => void; refetch: () => void;
@ -80,7 +57,10 @@ const useCrudOperations = <
getCreateEntity, getCreateEntity,
getUpdateEntity, getUpdateEntity,
getDeleteConfirmTitle, getDeleteConfirmTitle,
}: UseEntityOperationsProps<TEntity, TUpdate, TCreate>) => { }: UseEntityOperationsProps<TEntity, TUpdate, TCreate>): CrudOperations<
TEntity,
TUpdate
> => {
const onError = (error: AxiosError<HttpValidationError>) => { const onError = (error: AxiosError<HttpValidationError>) => {
console.error(error); console.error(error);
notifications.error({ notifications.error({

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { LexoRank } from "lexorank"; import { LexoRank } from "lexorank";
import { useCrudOperations } from "@/hooks/base"; import { useCrudOperations } from "@/hooks/baseCrud";
import { import {
BoardSchema, BoardSchema,
CreateBoardSchema, CreateBoardSchema,
@ -20,18 +20,18 @@ type UseBoardsOperationsProps = {
projectId?: number; projectId?: number;
}; };
type BoardsOperations = { export type BoardsCrud = {
onCreate: (name: string) => void; onCreate: (name: string) => void;
onUpdate: (boardId: number, board: UpdateBoardSchema) => void; onUpdate: (boardId: number, board: UpdateBoardSchema) => void;
onDelete: (board: BoardSchema) => void; onDelete: (board: BoardSchema) => void;
}; };
export const useBoardsOperations = ({ export const useBoardsCrud = ({
boards, boards,
setBoards, setBoards,
refetchBoards, refetchBoards,
projectId, projectId,
}: UseBoardsOperationsProps): BoardsOperations => { }: UseBoardsOperationsProps): BoardsCrud => {
return useCrudOperations<BoardSchema, UpdateBoardSchema, CreateBoardSchema>( return useCrudOperations<BoardSchema, UpdateBoardSchema, CreateBoardSchema>(
{ {
entities: boards, entities: boards,

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { useCrudOperations } from "@/hooks/base"; import { useCrudOperations } from "@/hooks/baseCrud";
import { import {
CreateProjectSchema, CreateProjectSchema,
ProjectSchema, ProjectSchema,
@ -17,17 +17,17 @@ type Props = {
refetchProjects: () => void; refetchProjects: () => void;
}; };
type ProjectsOperations = { export type ProjectsCrud = {
onCreate: (name: string) => void; onCreate: (name: string) => void;
onUpdate: (projectId: number, project: UpdateProjectSchema) => void; onUpdate: (projectId: number, project: UpdateProjectSchema) => void;
onDelete: (project: ProjectSchema) => void; onDelete: (project: ProjectSchema) => void;
}; };
export const useProjectsOperations = ({ export const useProjectsCrud = ({
projects, projects,
setProjects, setProjects,
refetchProjects, refetchProjects,
}: Props): ProjectsOperations => { }: Props): ProjectsCrud => {
return useCrudOperations< return useCrudOperations<
ProjectSchema, ProjectSchema,
UpdateProjectSchema, UpdateProjectSchema,

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { LexoRank } from "lexorank"; import { LexoRank } from "lexorank";
import { useCrudOperations } from "@/hooks/base"; import { useCrudOperations } from "@/hooks/baseCrud";
import { import {
CreateStatusSchema, CreateStatusSchema,
StatusSchema, StatusSchema,
@ -20,18 +20,18 @@ type Props = {
boardId?: number; boardId?: number;
}; };
type StatusesOperations = { export type StatusesCrud = {
onCreate: (name: string) => void; onCreate: (name: string) => void;
onUpdate: (statusId: number, status: UpdateStatusSchema) => void; onUpdate: (statusId: number, status: UpdateStatusSchema) => void;
onDelete: (status: StatusSchema) => void; onDelete: (status: StatusSchema) => void;
}; };
export const useStatusesOperations = ({ export const useStatusesCrud = ({
statuses, statuses,
setStatuses, setStatuses,
refetchStatuses, refetchStatuses,
boardId, boardId,
}: Props): StatusesOperations => { }: Props): StatusesCrud => {
return useCrudOperations< return useCrudOperations<
StatusSchema, StatusSchema,
UpdateStatusSchema, UpdateStatusSchema,