Files
twenty/front/src/modules/views/hooks/useTableViews.ts
2023-08-16 14:27:03 -07:00

136 lines
3.4 KiB
TypeScript

import { useCallback } from 'react';
import { getOperationName } from '@apollo/client/utilities';
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import {
type TableView,
tableViewsByIdState,
tableViewsState,
} from '@/ui/table/states/tableViewsState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import {
useCreateViewsMutation,
useDeleteViewsMutation,
useGetViewsQuery,
useUpdateViewMutation,
ViewType,
} from '~/generated/graphql';
import { GET_VIEWS } from '../graphql/queries/getViews';
export const useTableViews = ({
objectId,
}: {
objectId: 'company' | 'person';
}) => {
const [, setViews] = useRecoilScopedState(
tableViewsState,
TableRecoilScopeContext,
);
const viewsById = useRecoilScopedValue(
tableViewsByIdState,
TableRecoilScopeContext,
);
const [createViewsMutation] = useCreateViewsMutation();
const [updateViewMutation] = useUpdateViewMutation();
const [deleteViewsMutation] = useDeleteViewsMutation();
const createViews = useCallback(
(views: TableView[]) => {
if (!views.length) return;
return createViewsMutation({
variables: {
data: views.map((view) => ({
...view,
objectId,
type: ViewType.Table,
})),
},
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
});
},
[createViewsMutation, objectId],
);
const updateViewFields = useCallback(
(views: TableView[]) => {
if (!views.length) return;
return Promise.all(
views.map((view) =>
updateViewMutation({
variables: {
data: { name: view.name },
where: { id: view.id },
},
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
}),
),
);
},
[updateViewMutation],
);
const deleteViews = useCallback(
(viewIds: string[]) => {
if (!viewIds.length) return;
return deleteViewsMutation({
variables: {
where: {
id: { in: viewIds },
},
},
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
});
},
[deleteViewsMutation],
);
useGetViewsQuery({
variables: {
where: {
objectId: { equals: objectId },
},
},
onCompleted: (data) => {
setViews(
data.views.map((view) => ({
id: view.id,
name: view.name,
})),
);
},
});
const handleViewsChange = useCallback(
async (nextViews: TableView[]) => {
setViews(nextViews);
const viewsToCreate = nextViews.filter(
(nextView) => !viewsById[nextView.id],
);
await createViews(viewsToCreate);
const viewsToUpdate = nextViews.filter(
(nextView) =>
viewsById[nextView.id] &&
viewsById[nextView.id].name !== nextView.name,
);
await updateViewFields(viewsToUpdate);
const nextViewIds = nextViews.map((nextView) => nextView.id);
const viewIdsToDelete = Object.keys(viewsById).filter(
(previousViewId) => !nextViewIds.includes(previousViewId),
);
return deleteViews(viewIdsToDelete);
},
[createViews, deleteViews, setViews, updateViewFields, viewsById],
);
return { handleViewsChange };
};