refactor: sorted hooks
This commit is contained in:
141
src/hooks/cruds/baseCrud/useCrudOperations.tsx
Normal file
141
src/hooks/cruds/baseCrud/useCrudOperations.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import React from "react";
|
||||
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
||||
import { AxiosError } from "axios";
|
||||
import { Text } from "@mantine/core";
|
||||
import { modals } from "@mantine/modals";
|
||||
import { HttpValidationError } from "@/lib/client";
|
||||
import { notifications } from "@/lib/notifications";
|
||||
import { sortByLexorank } from "@/utils/lexorank";
|
||||
import {
|
||||
BaseEntity,
|
||||
CreateMutationOptions,
|
||||
DeleteMutationOptions,
|
||||
UpdateMutationOptions,
|
||||
} from "./types";
|
||||
|
||||
type CrudOperations<TEntity, TUpdate> = {
|
||||
onCreate: (name: string) => void;
|
||||
onUpdate: (id: number, update: TUpdate) => void;
|
||||
onDelete: (entity: TEntity) => void;
|
||||
};
|
||||
|
||||
type UseEntityOperationsProps<TEntity extends BaseEntity, TUpdate, TCreate> = {
|
||||
entities: TEntity[];
|
||||
setEntities: React.Dispatch<React.SetStateAction<TEntity[]>>;
|
||||
refetch: () => void;
|
||||
mutations: {
|
||||
create: UseMutationOptions<
|
||||
any,
|
||||
AxiosError<HttpValidationError>,
|
||||
CreateMutationOptions
|
||||
>;
|
||||
update: UseMutationOptions<
|
||||
any,
|
||||
AxiosError<HttpValidationError>,
|
||||
UpdateMutationOptions
|
||||
>;
|
||||
delete: UseMutationOptions<
|
||||
any,
|
||||
AxiosError<HttpValidationError>,
|
||||
DeleteMutationOptions
|
||||
>;
|
||||
};
|
||||
getCreateEntity: (name: string) => TCreate | null;
|
||||
getUpdateEntity: (oldEntity: TEntity, update: TUpdate) => TEntity;
|
||||
getDeleteConfirmTitle: (entity: TEntity) => string;
|
||||
};
|
||||
|
||||
const useCrudOperations = <
|
||||
TEntity extends BaseEntity,
|
||||
TUpdate extends object,
|
||||
TCreate extends object,
|
||||
>({
|
||||
entities,
|
||||
setEntities,
|
||||
refetch,
|
||||
mutations,
|
||||
getCreateEntity,
|
||||
getUpdateEntity,
|
||||
getDeleteConfirmTitle,
|
||||
}: UseEntityOperationsProps<TEntity, TUpdate, TCreate>): CrudOperations<
|
||||
TEntity,
|
||||
TUpdate
|
||||
> => {
|
||||
const onError = (error: AxiosError<HttpValidationError>) => {
|
||||
console.error(error);
|
||||
notifications.error({
|
||||
message: error.response?.data?.detail as string | undefined,
|
||||
});
|
||||
refetch();
|
||||
};
|
||||
|
||||
const createMutation = useMutation({
|
||||
...mutations.create,
|
||||
onError,
|
||||
onSuccess: (res: { entity: TEntity }) => {
|
||||
setEntities([...entities, res.entity]);
|
||||
},
|
||||
});
|
||||
|
||||
const updateMutation = useMutation({
|
||||
...mutations.update,
|
||||
onError,
|
||||
});
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
...mutations.delete,
|
||||
onError,
|
||||
});
|
||||
|
||||
const onCreate = (name: string) => {
|
||||
const entity = getCreateEntity(name);
|
||||
if (!entity) return;
|
||||
createMutation.mutate({
|
||||
body: {
|
||||
entity,
|
||||
},
|
||||
path: undefined,
|
||||
query: undefined,
|
||||
});
|
||||
};
|
||||
|
||||
const onUpdate = (id: number, update: TUpdate) => {
|
||||
updateMutation.mutate({
|
||||
body: {
|
||||
entity: update,
|
||||
},
|
||||
path: { pk: id },
|
||||
query: undefined,
|
||||
});
|
||||
setEntities(prev => {
|
||||
const updated = prev.map(entity =>
|
||||
entity.id === id ? getUpdateEntity(entity, update) : entity
|
||||
);
|
||||
if ("lexorank" in update) {
|
||||
return sortByLexorank(
|
||||
updated as (TEntity & { lexorank: string })[]
|
||||
);
|
||||
}
|
||||
return updated;
|
||||
});
|
||||
};
|
||||
|
||||
const onDelete = (entity: TEntity) => {
|
||||
modals.openConfirmModal({
|
||||
title: getDeleteConfirmTitle(entity),
|
||||
children: (
|
||||
<Text>Вы уверены, что хотите удалить "{entity.name}"?</Text>
|
||||
),
|
||||
labels: { confirm: "Да", cancel: "Нет" },
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: () => {
|
||||
deleteMutation.mutate({ path: { pk: entity.id } } as any);
|
||||
setEntities(prev => prev.filter(e => e.id !== entity.id));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return { onCreate, onUpdate, onDelete };
|
||||
};
|
||||
|
||||
export default useCrudOperations;
|
||||
Reference in New Issue
Block a user