Feat/metadata datatable types (#2175)

* Handled new url v2 type

* Fixed refetch queries

* wip

* Ok delete but views bug

* Fix lint

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2023-10-21 14:07:18 +02:00
committed by GitHub
parent 598fda8f45
commit f1670f0cf4
50 changed files with 1125 additions and 350 deletions

View File

@ -0,0 +1,160 @@
import { getOperationName } from '@apollo/client/utilities';
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
import { FieldType } from '@/ui/data/field/types/FieldType';
import { IconBrandLinkedin } from '@/ui/display/icon';
import { GET_VIEW_FIELDS } from '@/views/graphql/queries/getViewFields';
import { GET_VIEWS } from '@/views/graphql/queries/getViews';
import { toViewFieldInput } from '@/views/hooks/useTableViewFields';
import {
useCreateViewFieldsMutation,
useCreateViewMutation,
ViewType,
} from '~/generated/graphql';
import { useCreateOneMetadataField } from './useCreateOneMetadataField';
import { useCreateOneMetadataObject } from './useCreateOneMetadataObject';
import { useUpdateOneMetadataField } from './useUpdateOneMetadataField';
import { useUpdateOneMetadataObject } from './useUpdateOneMetadataObject';
export const useCreateNewTempsCustomObject = () => {
const { createOneMetadataObject } = useCreateOneMetadataObject();
const { createOneMetadataField } = useCreateOneMetadataField();
const { updateOneMetadataObject } = useUpdateOneMetadataObject();
const { updateOneMetadataField } = useUpdateOneMetadataField();
const [createViewMutation] = useCreateViewMutation();
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
return async () => {
const date = new Date().toISOString().replace(/[\/:\.\-\_]/g, '');
const { data: createdMetadataObject } = await createOneMetadataObject({
labelPlural: 'Suppliers' + date,
labelSingular: 'Supplier' + date,
nameSingular: 'supplier' + date,
namePlural: 'suppliers' + date,
description: 'Suppliers' + date,
icon: 'IconBuilding',
});
const supplierObjectId = createdMetadataObject?.createOneObject?.id ?? '';
if (!createdMetadataObject) {
throw new Error('Could not create metadata object');
}
await updateOneMetadataObject({
idToUpdate: supplierObjectId,
updatePayload: {
isActive: true,
},
});
const { data: nameFieldData } = await createOneMetadataField({
objectId: supplierObjectId,
name: 'name',
type: 'text',
description: 'Name',
label: 'Name',
icon: 'IconBuilding',
});
if (!nameFieldData || !nameFieldData.createOneField.name) {
throw new Error('Could not create metadata field');
}
await updateOneMetadataField({
fieldIdToUpdate: nameFieldData?.createOneField?.id ?? '',
updatePayload: {
isActive: true,
},
});
const { data: cityFieldData } = await createOneMetadataField({
objectId: supplierObjectId,
label: 'City',
name: 'city',
type: 'text',
description: 'City',
icon: 'IconMap',
});
if (!cityFieldData || !cityFieldData.createOneField.name) {
throw new Error('Could not create metadata field');
}
await updateOneMetadataField({
fieldIdToUpdate: cityFieldData?.createOneField?.id ?? '',
updatePayload: {
isActive: true,
},
});
const { data: emailFieldData } = await createOneMetadataField({
objectId: supplierObjectId,
label: 'Email',
name: 'email',
type: 'url',
description: 'Email',
icon: 'IconMap',
});
if (!emailFieldData || !emailFieldData.createOneField.name) {
throw new Error('Could not create metadata field');
}
await updateOneMetadataField({
fieldIdToUpdate: emailFieldData?.createOneField?.id ?? '',
updatePayload: {
isActive: true,
},
});
const objectId = 'suppliers' + date;
const { data: newView } = await createViewMutation({
variables: {
data: {
name: 'Default',
objectId: objectId,
type: ViewType.Table,
},
},
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
});
const createdFields = [
emailFieldData.createOneField,
nameFieldData.createOneField,
cityFieldData.createOneField,
];
const tempColumnDefinitions: ColumnDefinition<FieldMetadata>[] =
createdFields.map((field, index) => ({
index,
key: field.name,
name: field.label,
size: 100,
type: field.type as FieldType,
metadata: {
fieldName: field.name,
placeHolder: field.label,
},
Icon: IconBrandLinkedin,
isVisible: true,
})) ?? [];
await createViewFieldsMutation({
variables: {
data: tempColumnDefinitions.map((column) => ({
...toViewFieldInput(objectId, column),
viewId: newView?.view.id ?? '',
})),
},
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
});
};
};

View File

@ -1,6 +1,7 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { FieldType } from '@/ui/data/field/types/FieldType';
import {
CreateOneMetadataFieldMutation,
CreateOneMetadataFieldMutationVariables,
@ -11,6 +12,11 @@ import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
import { useApolloMetadataClient } from './useApolloMetadataClient';
type CreateOneMetadataFieldArgs =
CreateOneMetadataFieldMutationVariables['input']['field'] & {
type: FieldType;
};
export const useCreateOneMetadataField = () => {
const apolloMetadataClient = useApolloMetadataClient();
@ -21,10 +27,8 @@ export const useCreateOneMetadataField = () => {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});
const createOneMetadataField = (
input: CreateOneMetadataFieldMutationVariables['input']['field'],
) =>
mutate({
const createOneMetadataField = async (input: CreateOneMetadataFieldArgs) => {
return await mutate({
variables: {
input: {
field: {
@ -32,8 +36,10 @@ export const useCreateOneMetadataField = () => {
},
},
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};
return {
createOneMetadataField,

View File

@ -21,10 +21,10 @@ export const useCreateOneMetadataObject = () => {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});
const createOneMetadataObject = (
const createOneMetadataObject = async (
input: CreateOneMetadataObjectMutationVariables['input']['object'],
) =>
mutate({
) => {
return await mutate({
variables: {
input: {
object: {
@ -32,8 +32,10 @@ export const useCreateOneMetadataObject = () => {
},
},
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};
return {
createOneMetadataObject,

View File

@ -1,30 +1,24 @@
import { gql, useMutation } from '@apollo/client';
import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { generateCreateOneObjectMutation } from '../utils/generateCreateOneObjectMutation';
import { useFindOneMetadataObject } from './useFindOneMetadataObject';
export const useCreateOneObject = ({
objectNamePlural,
}: MetadataObjectIdentifier) => {
const { foundMetadataObject, objectNotFoundInMetadata } =
useFindOneMetadataObject({
objectNamePlural,
});
const generatedMutation = foundMetadataObject
? generateCreateOneObjectMutation({
metadataObject: foundMetadataObject,
})
: gql`
mutation EmptyMutation {
empty
}
`;
const {
foundMetadataObject,
objectNotFoundInMetadata,
findManyQuery,
createOneMutation,
} = useFindOneMetadataObject({
objectNamePlural,
});
// TODO: type this with a minimal type at least with Record<string, any>
const [mutate] = useMutation(generatedMutation);
const [mutate] = useMutation(createOneMutation);
const createOneObject = foundMetadataObject
? (input: Record<string, any>) => {
@ -34,6 +28,7 @@ export const useCreateOneObject = ({
...input,
},
},
refetchQueries: [getOperationName(findManyQuery) ?? ''],
});
}
: undefined;

View File

@ -0,0 +1,39 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import {
DeleteOneMetadataFieldMutation,
DeleteOneMetadataFieldMutationVariables,
} from '~/generated-metadata/graphql';
import { DELETE_ONE_METADATA_FIELD } from '../graphql/mutations';
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useDeleteOneMetadataField = () => {
const apolloMetadataClient = useApolloMetadataClient();
const [mutate] = useMutation<
DeleteOneMetadataFieldMutation,
DeleteOneMetadataFieldMutationVariables
>(DELETE_ONE_METADATA_FIELD, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});
const deleteOneMetadataField = async (
idToDelete: DeleteOneMetadataFieldMutationVariables['idToDelete'],
) => {
return await mutate({
variables: {
idToDelete,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};
return {
deleteOneMetadataField,
};
};

View File

@ -0,0 +1,39 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import {
DeleteOneMetadataObjectMutation,
DeleteOneMetadataObjectMutationVariables,
} from '~/generated-metadata/graphql';
import { DELETE_ONE_METADATA_OBJECT } from '../graphql/mutations';
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useDeleteOneMetadataObject = () => {
const apolloMetadataClient = useApolloMetadataClient();
const [mutate] = useMutation<
DeleteOneMetadataObjectMutation,
DeleteOneMetadataObjectMutationVariables
>(DELETE_ONE_METADATA_OBJECT, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});
const deleteOneMetadataObject = async (
idToDelete: DeleteOneMetadataObjectMutationVariables['idToDelete'],
) => {
return await mutate({
variables: {
idToDelete,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};
return {
deleteOneMetadataObject,
};
};

View File

@ -0,0 +1,40 @@
import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { useFindOneMetadataObject } from './useFindOneMetadataObject';
export const useDeleteOneObject = ({
objectNamePlural,
}: MetadataObjectIdentifier) => {
const {
foundMetadataObject,
objectNotFoundInMetadata,
findManyQuery,
deleteOneMutation,
} = useFindOneMetadataObject({
objectNamePlural,
});
// TODO: type this with a minimal type at least with Record<string, any>
const [mutate] = useMutation(deleteOneMutation);
const deleteOneObject = foundMetadataObject
? (input: Record<string, any>) => {
return mutate({
variables: {
input: {
...input,
},
},
refetchQueries: [getOperationName(findManyQuery) ?? ''],
});
}
: undefined;
return {
deleteOneObject,
objectNotFoundInMetadata,
};
};

View File

@ -15,13 +15,17 @@ import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useFindManyMetadataObjects = () => {
const apolloMetadataClient = useApolloMetadataClient();
const { data, fetchMore: fetchMoreInternal } = useQuery<
MetadataObjectsQuery,
MetadataObjectsQueryVariables
>(FIND_MANY_METADATA_OBJECTS, {
client: apolloMetadataClient ?? undefined,
skip: !apolloMetadataClient,
});
const {
data,
fetchMore: fetchMoreInternal,
loading,
} = useQuery<MetadataObjectsQuery, MetadataObjectsQueryVariables>(
FIND_MANY_METADATA_OBJECTS,
{
client: apolloMetadataClient ?? undefined,
skip: !apolloMetadataClient,
},
);
const hasMore = data?.objects?.pageInfo?.hasNextPage;
@ -38,23 +42,10 @@ export const useFindManyMetadataObjects = () => {
});
}, [data]);
const getMetadataObjectsFromCache = () => {
const queryResult = apolloMetadataClient?.readQuery<
MetadataObjectsQuery,
MetadataObjectsQueryVariables
>({
query: FIND_MANY_METADATA_OBJECTS,
});
return formatPagedMetadataObjectsToMetadataObjects({
pagedMetadataObjects: queryResult ?? undefined,
});
};
return {
metadataObjects,
hasMore,
fetchMore,
getMetadataObjectsFromCache,
loading,
};
};

View File

@ -1,10 +1,9 @@
import { useMemo } from 'react';
import { gql, useQuery } from '@apollo/client';
import { useQuery } from '@apollo/client';
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { PaginatedObjectType } from '../types/PaginatedObjectType';
import { formatPagedObjectsToObjects } from '../utils/formatPagedObjectsToObjects';
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
import { useFindOneMetadataObject } from './useFindOneMetadataObject';
@ -15,23 +14,13 @@ export const useFindManyObjects = <
>({
objectNamePlural,
}: MetadataObjectIdentifier) => {
const { foundMetadataObject, objectNotFoundInMetadata } =
const { foundMetadataObject, objectNotFoundInMetadata, findManyQuery } =
useFindOneMetadataObject({
objectNamePlural,
});
const generatedQuery = foundMetadataObject
? generateFindManyCustomObjectsQuery({
metadataObject: foundMetadataObject,
})
: gql`
query EmptyQuery {
empty
}
`;
const { data, loading, error } = useQuery<PaginatedObjectType<ObjectType>>(
generatedQuery,
findManyQuery,
{
skip: !foundMetadataObject,
},

View File

@ -1,21 +1,80 @@
import { gql } from '@apollo/client';
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { formatMetadataFieldAsColumnDefinition } from '../utils/formatMetadataFieldAsColumnDefinition';
import { generateCreateOneObjectMutation } from '../utils/generateCreateOneObjectMutation';
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
export const useFindOneMetadataObject = ({
objectNamePlural,
}: MetadataObjectIdentifier) => {
const { metadataObjects } = useFindManyMetadataObjects();
const { metadataObjects, loading } = useFindManyMetadataObjects();
const foundMetadataObject = metadataObjects.find(
(object) => object.namePlural === objectNamePlural,
);
const objectNotFoundInMetadata =
metadataObjects.length > 0 && !foundMetadataObject;
metadataObjects.length === 0 ||
(metadataObjects.length > 0 && !foundMetadataObject);
const columnDefinitions: ColumnDefinition<FieldMetadata>[] =
foundMetadataObject?.fields.map((field, index) =>
formatMetadataFieldAsColumnDefinition({
index,
field,
}),
) ?? [];
// eslint-disable-next-line no-console
console.log({
foundMetadataObject,
columnDefinitions,
});
const findManyQuery = foundMetadataObject
? generateFindManyCustomObjectsQuery({
metadataObject: foundMetadataObject,
})
: gql`
query EmptyQuery {
empty
}
`;
const createOneMutation = foundMetadataObject
? generateCreateOneObjectMutation({
metadataObject: foundMetadataObject,
})
: gql`
mutation EmptyMutation {
empty
}
`;
// TODO: implement backend delete
const deleteOneMutation = foundMetadataObject
? generateCreateOneObjectMutation({
metadataObject: foundMetadataObject,
})
: gql`
mutation EmptyMutation {
empty
}
`;
return {
foundMetadataObject,
objectNotFoundInMetadata,
columnDefinitions,
findManyQuery,
createOneMutation,
deleteOneMutation,
loading,
};
};

View File

@ -0,0 +1,18 @@
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { MetadataObjectScopeInternalContext } from '../scopes/scope-internal-context/MetadataObjectScopeInternalContext';
type UseMetadataObjectProps = {
metadataObjectNamePlural?: string;
};
export const useMetadataObject = (props?: UseMetadataObjectProps) => {
const scopeId = useAvailableScopeIdOrThrow(
MetadataObjectScopeInternalContext,
props?.metadataObjectNamePlural,
);
return {
scopeId,
};
};

View File

@ -0,0 +1,27 @@
import { useContext } from 'react';
import { MetadataObjectScopeInternalContext } from '../scopes/scope-internal-context/MetadataObjectScopeInternalContext';
import { useFindOneMetadataObject } from './useFindOneMetadataObject';
export const useMetadataObjectInContext = () => {
const context = useContext(MetadataObjectScopeInternalContext);
if (!context) {
throw new Error(
'Could not find MetadataObjectScopeInternalContext while in useMetadataObjectInContext',
);
}
const { foundMetadataObject, loading, columnDefinitions } =
useFindOneMetadataObject({
objectNamePlural: context.objectNamePlural,
});
return {
...context,
foundMetadataObject,
loading,
columnDefinitions,
};
};

View File

@ -0,0 +1,81 @@
import { useSearchParams } from 'react-router-dom';
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
import { filtersScopedState } from '@/ui/data/view-bar/states/filtersScopedState';
import { sortsScopedState } from '@/ui/data/view-bar/states/sortsScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useTableViewFields } from '@/views/hooks/useTableViewFields';
import { useViewFilters } from '@/views/hooks/useViewFilters';
import { useViews } from '@/views/hooks/useViews';
import { useViewSorts } from '@/views/hooks/useViewSorts';
import { ViewType } from '~/generated/graphql';
import { useMetadataObjectInContext } from './useMetadataObjectInContext';
export const useMetadataTableViews = () => {
const { objectNamePlural, columnDefinitions } = useMetadataObjectInContext();
const tableColumns = useRecoilScopedValue(
tableColumnsScopedState,
TableRecoilScopeContext,
);
const filters = useRecoilScopedValue(
filtersScopedState,
TableRecoilScopeContext,
);
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
const [_, setSearchParams] = useSearchParams();
const handleViewCreate = async (viewId: string) => {
await createViewFields(tableColumns, viewId);
await createViewFilters(filters, viewId);
await createViewSorts(sorts, viewId);
setSearchParams({ view: viewId });
};
const objectId = objectNamePlural;
const { createView, deleteView, isFetchingViews, updateView } = useViews({
objectId,
onViewCreate: handleViewCreate,
type: ViewType.Table,
RecoilScopeContext: TableRecoilScopeContext,
});
const { createViewFields, persistColumns } = useTableViewFields({
objectId,
columnDefinitions,
skipFetch: isFetchingViews,
});
const createDefaultViewFields = async () => {
await createViewFields(tableColumns);
};
const { createViewFilters, persistFilters } = useViewFilters({
RecoilScopeContext: TableRecoilScopeContext,
skipFetch: isFetchingViews,
});
const { createViewSorts, persistSorts } = useViewSorts({
RecoilScopeContext: TableRecoilScopeContext,
skipFetch: isFetchingViews,
});
const submitCurrentView = async () => {
await persistFilters();
await persistSorts();
};
return {
createView,
deleteView,
persistColumns,
submitCurrentView,
updateView,
createDefaultViewFields,
isFetchingViews,
};
};

View File

@ -2,16 +2,11 @@ import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
import { useCreateOneMetadataField } from './useCreateOneMetadataField';
import { useCreateOneMetadataObject } from './useCreateOneMetadataObject';
import { useUpdateOneMetadataField } from './useUpdateOneMetadataField';
import { useUpdateOneMetadataObject } from './useUpdateOneMetadataObject';
export const useSeedCustomObjectsTemp = () => {
const { createOneMetadataObject } = useCreateOneMetadataObject();
const { createOneMetadataField } = useCreateOneMetadataField();
const { updateOneMetadataObject } = useUpdateOneMetadataObject();
const { updateOneMetadataField } = useUpdateOneMetadataField();
return async () => {
const { data: createdMetadataObject, errors } =
await createOneMetadataObject({
@ -26,7 +21,7 @@ export const useSeedCustomObjectsTemp = () => {
if (!isNonEmptyArray(errors)) {
const supplierObjectId = createdMetadataObject?.createOneObject?.id ?? '';
const { data: createNameFieldData } = await createOneMetadataField({
await createOneMetadataField({
objectId: supplierObjectId,
name: 'name',
type: 'text',
@ -35,9 +30,7 @@ export const useSeedCustomObjectsTemp = () => {
icon: 'IconBuilding',
});
const nameFieldId = createNameFieldData?.createOneField.id ?? '';
const { data: createCityFieldData } = await createOneMetadataField({
await createOneMetadataField({
objectId: supplierObjectId,
label: 'City',
name: 'city',
@ -45,31 +38,6 @@ export const useSeedCustomObjectsTemp = () => {
description: 'City',
icon: 'IconMap',
});
const cityFieldId = createCityFieldData?.createOneField.id ?? '';
await updateOneMetadataObject({
idToUpdate: supplierObjectId,
updatePayload: {
labelPlural: 'Suppliers 2',
},
});
await updateOneMetadataField({
objectIdToUpdate: supplierObjectId,
fieldIdToUpdate: cityFieldId,
updatePayload: {
label: 'City 2',
},
});
await updateOneMetadataField({
objectIdToUpdate: supplierObjectId,
fieldIdToUpdate: nameFieldId,
updatePayload: {
label: 'Name 2',
},
});
}
};
};

View File

@ -10,13 +10,10 @@ import { UPDATE_ONE_METADATA_FIELD } from '../graphql/mutations';
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
import { useApolloMetadataClient } from './useApolloMetadataClient';
import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
export const useUpdateOneMetadataField = () => {
const apolloMetadataClient = useApolloMetadataClient();
const { getMetadataObjectsFromCache } = useFindManyMetadataObjects();
const [mutate] = useMutation<
UpdateOneMetadataFieldMutation,
UpdateOneMetadataFieldMutationVariables
@ -24,48 +21,24 @@ export const useUpdateOneMetadataField = () => {
client: apolloMetadataClient ?? undefined,
});
const updateOneMetadataField = ({
objectIdToUpdate,
const updateOneMetadataField = async ({
fieldIdToUpdate,
updatePayload,
}: {
objectIdToUpdate: string;
fieldIdToUpdate: UpdateOneMetadataFieldMutationVariables['idToUpdate'];
updatePayload: Partial<
Pick<
UpdateOneMetadataFieldMutationVariables['updatePayload'],
'description' | 'icon' | 'isActive' | 'label'
>
updatePayload: Pick<
UpdateOneMetadataFieldMutationVariables['updatePayload'],
'description' | 'icon' | 'isActive' | 'label'
>;
}) => {
const metadataObjects = getMetadataObjectsFromCache();
const foundMetadataObject = metadataObjects.find(
(metadataObject) => metadataObject.id === objectIdToUpdate,
);
if (!foundMetadataObject)
throw new Error(`Metadata object with id ${objectIdToUpdate} not found`);
const foundMetadataField = foundMetadataObject.fields.find(
(metadataField) => metadataField.id === fieldIdToUpdate,
);
if (!foundMetadataField)
throw new Error(`Metadata field with id ${fieldIdToUpdate} not found`);
return mutate({
return await mutate({
variables: {
idToUpdate: fieldIdToUpdate,
updatePayload: {
name: foundMetadataField.name,
description: foundMetadataField.description,
icon: foundMetadataField.icon,
isActive: foundMetadataField.isActive,
label: foundMetadataField.label,
...updatePayload,
label: updatePayload.label ?? undefined,
},
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};

View File

@ -10,14 +10,11 @@ import { UPDATE_ONE_METADATA_OBJECT } from '../graphql/mutations';
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
import { useApolloMetadataClient } from './useApolloMetadataClient';
import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
// 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 useUpdateOneMetadataObject = () => {
const apolloClientMetadata = useApolloMetadataClient();
const { getMetadataObjectsFromCache } = useFindManyMetadataObjects();
const [mutate] = useMutation<
UpdateOneMetadataObjectMutation,
UpdateOneMetadataObjectMutationVariables
@ -25,41 +22,22 @@ export const useUpdateOneMetadataObject = () => {
client: apolloClientMetadata ?? undefined,
});
const updateOneMetadataObject = ({
const updateOneMetadataObject = async ({
idToUpdate,
updatePayload,
}: {
idToUpdate: UpdateOneMetadataObjectMutationVariables['idToUpdate'];
updatePayload: Partial<
Pick<
UpdateOneMetadataObjectMutationVariables['updatePayload'],
'description' | 'icon' | 'isActive' | 'labelPlural' | 'labelSingular'
>
updatePayload: Pick<
UpdateOneMetadataObjectMutationVariables['updatePayload'],
'description' | 'icon' | 'isActive' | 'labelPlural' | 'labelSingular'
>;
}) => {
const metadataObjects = getMetadataObjectsFromCache();
const foundMetadataObject = metadataObjects.find(
(metadataObject) => metadataObject.id === idToUpdate,
);
if (!foundMetadataObject)
throw new Error(`Metadata object with id ${idToUpdate} not found`);
return mutate({
return await mutate({
variables: {
idToUpdate,
updatePayload: {
namePlural: foundMetadataObject.namePlural,
nameSingular: foundMetadataObject.nameSingular,
description: foundMetadataObject.description,
icon: foundMetadataObject.icon,
isActive: foundMetadataObject.isActive,
labelPlural: foundMetadataObject.labelPlural,
labelSingular: foundMetadataObject.labelSingular,
...updatePayload,
},
updatePayload,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_METADATA_OBJECTS) ?? ''],
});
};