Files
twenty/packages/twenty-front/src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
T
Raphaël Bosi 9080180156 [COMMAND MENU ITEMS] Sync object metadata with navigation command menu items (#19456)
When an object is created or enabled we create a navigation command menu
item to that object. And when the object is disabled or deleted, we
remove this command menu item.
2026-04-09 08:18:49 +00:00

97 lines
3.0 KiB
TypeScript

import { useApolloClient, useMutation } from '@apollo/client/react';
import {
type UpdateOneObjectInput,
FindManyCommandMenuItemsDocument,
UpdateOneObjectMetadataItemDocument,
} from '~/generated-metadata/graphql';
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMetadataItem';
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { CombinedGraphQLErrors } from '@apollo/client/errors';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { CrudOperationType } from 'twenty-shared/types';
// TODO: Slice the Apollo store synchronously in the update function instead of subscribing, so we can use update after read in the same function call
export const useUpdateOneObjectMetadataItem = () => {
const [updateOneObjectMetadataItemMutation, { loading }] = useMutation(
UpdateOneObjectMetadataItemDocument,
);
const client = useApolloClient();
const { handleMetadataError } = useMetadataErrorHandler();
const { enqueueErrorSnackBar } = useSnackBar();
const { updateInDraft, replaceDraft, applyChanges } =
useUpdateMetadataStoreDraft();
const updateOneObjectMetadataItem = async ({
idToUpdate,
updatePayload,
}: {
idToUpdate: UpdateOneObjectInput['id'];
updatePayload: UpdateOneObjectInput['update'];
}): Promise<
MetadataRequestResult<
Awaited<ReturnType<typeof updateOneObjectMetadataItemMutation>>
>
> => {
try {
const response = await updateOneObjectMetadataItemMutation({
variables: {
idToUpdate,
updatePayload,
},
});
const updatedObject = response.data?.updateOneObject;
if (isDefined(updatedObject)) {
const { __typename, ...objectData } = updatedObject;
updateInDraft('objectMetadataItems', [
objectData as FlatObjectMetadataItem,
]);
applyChanges();
const commandMenuItemsResult = await client.query({
query: FindManyCommandMenuItemsDocument,
fetchPolicy: 'network-only',
});
replaceDraft(
'commandMenuItems',
commandMenuItemsResult.data?.commandMenuItems ?? [],
);
applyChanges();
}
return {
status: 'successful',
response,
};
} catch (error) {
if (CombinedGraphQLErrors.is(error)) {
handleMetadataError(error, {
primaryMetadataName: 'objectMetadata',
operationType: CrudOperationType.UPDATE,
});
} else {
enqueueErrorSnackBar({ message: t`An error occurred.` });
}
return {
status: 'failed',
error,
};
}
};
return {
updateOneObjectMetadataItem,
loading,
};
};