fix: when field metadata SELECT type is edited update view groups (#8344)

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2024-11-06 11:41:44 +01:00
committed by GitHub
parent e36363fe15
commit ac7d740135
11 changed files with 304 additions and 28 deletions

View File

@ -21,6 +21,7 @@ const baseFields = `
settings
`;
export const queries = {
deleteMetadataField: gql`
mutation DeleteOneFieldMetadataItem($idToDelete: UUID!) {
@ -29,6 +30,37 @@ export const queries = {
}
}
`,
findManyViewsQuery: gql`
query FindManyViews($filter: ViewFilterInput, $orderBy: [ViewOrderByInput], $lastCursor: String, $limit: Int) {
views(filter: $filter, orderBy: $orderBy, first: $limit, after: $lastCursor) {
edges {
node {
__typename
id
viewGroups {
edges {
node {
__typename
fieldMetadataId
fieldValue
id
isVisible
position
}
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}`,
deleteMetadataFieldRelation: gql`
mutation DeleteOneRelationMetadataItem($idToDelete: UUID!) {
deleteOneRelation(input: { id: $idToDelete }) {

View File

@ -1,12 +1,11 @@
import { MockedProvider } from '@apollo/client/testing';
import { renderHook } from '@testing-library/react';
import { act, ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
import { act } from 'react';
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { FieldMetadataType, RelationDefinitionType } from '~/generated/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import {
FIELD_METADATA_ID,
FIELD_RELATION_METADATA_ID,
@ -58,6 +57,31 @@ const fieldRelationMetadataItem: FieldMetadataItem = {
};
const mocks = [
{
request: {
query: queries.findManyViewsQuery,
variables: {
filter: {
objectMetadataId: { eq: '25611fce-6637-4089-b0ca-91afeec95784' },
},
},
},
result: jest.fn(() => ({
data: {
views: {
__typename: 'ViewConnection',
totalCount: 0,
pageInfo: {
__typename: 'PageInfo',
hasNextPage: false,
startCursor: '',
endCursor: '',
},
edges: [],
},
},
})),
},
{
request: {
query: queries.deleteMetadataField,
@ -115,13 +139,9 @@ const mocks = [
},
];
const Wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>
<MockedProvider mocks={mocks} addTypename={false}>
{children}
</MockedProvider>
</RecoilRoot>
);
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: mocks,
});
describe('useFieldMetadataItem', () => {
it('should activateMetadataField', async () => {
@ -130,7 +150,10 @@ describe('useFieldMetadataItem', () => {
});
await act(async () => {
const res = await result.current.activateMetadataField(fieldMetadataItem);
const res = await result.current.activateMetadataField(
fieldMetadataItem.id,
objectMetadataId,
);
expect(res.data).toEqual({
updateOneField: responseData.default,
@ -162,8 +185,10 @@ describe('useFieldMetadataItem', () => {
});
await act(async () => {
const res =
await result.current.deactivateMetadataField(fieldMetadataItem);
const res = await result.current.deactivateMetadataField(
fieldMetadataItem.id,
objectMetadataId,
);
expect(res.data).toEqual({
updateOneField: responseData.default,

View File

@ -40,15 +40,23 @@ export const useFieldMetadataItem = () => {
});
};
const activateMetadataField = (metadataField: FieldMetadataItem) =>
const activateMetadataField = (
fieldMetadataId: string,
objectMetadataId: string,
) =>
updateOneFieldMetadataItem({
fieldMetadataIdToUpdate: metadataField.id,
objectMetadataId: objectMetadataId,
fieldMetadataIdToUpdate: fieldMetadataId,
updatePayload: { isActive: true },
});
const deactivateMetadataField = (metadataField: FieldMetadataItem) =>
const deactivateMetadataField = (
fieldMetadataId: string,
objectMetadataId: string,
) =>
updateOneFieldMetadataItem({
fieldMetadataIdToUpdate: metadataField.id,
objectMetadataId: objectMetadataId,
fieldMetadataIdToUpdate: fieldMetadataId,
updatePayload: { isActive: false },
});

View File

@ -1,4 +1,4 @@
import { useMutation } from '@apollo/client';
import { useApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import {
@ -9,10 +9,27 @@ import {
import { UPDATE_ONE_FIELD_METADATA_ITEM } from '../graphql/mutations';
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useUpdateOneFieldMetadataItem = () => {
const apolloMetadataClient = useApolloMetadataClient();
const apolloClient = useApolloClient();
const { findManyRecordsQuery } = useFindManyRecordsQuery({
objectNameSingular: CoreObjectNameSingular.View,
recordGqlFields: {
id: true,
viewGroups: {
id: true,
fieldMetadataId: true,
isVisible: true,
fieldValue: true,
position: true,
},
},
});
const [mutate] = useMutation<
UpdateOneFieldMetadataItemMutation,
@ -22,9 +39,11 @@ export const useUpdateOneFieldMetadataItem = () => {
});
const updateOneFieldMetadataItem = async ({
objectMetadataId,
fieldMetadataIdToUpdate,
updatePayload,
}: {
objectMetadataId: string;
fieldMetadataIdToUpdate: UpdateOneFieldMetadataItemMutationVariables['idToUpdate'];
updatePayload: Pick<
UpdateOneFieldMetadataItemMutationVariables['updatePayload'],
@ -37,7 +56,7 @@ export const useUpdateOneFieldMetadataItem = () => {
| 'options'
>;
}) => {
return await mutate({
const result = await mutate({
variables: {
idToUpdate: fieldMetadataIdToUpdate,
updatePayload: {
@ -48,6 +67,20 @@ export const useUpdateOneFieldMetadataItem = () => {
awaitRefetchQueries: true,
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
});
await apolloClient.query({
query: findManyRecordsQuery,
variables: {
filter: {
objectMetadataId: {
eq: objectMetadataId,
},
},
},
fetchPolicy: 'network-only',
});
return result;
};
return {

View File

@ -1,8 +1,8 @@
import { useRecoilCallback } from 'recoil';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useSetRecordBoardColumns = (recordBoardId?: string) => {
const { scopeId, columnIdsState, columnsFamilySelector } =
@ -19,12 +19,10 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => {
.filter(({ isVisible }) => isVisible)
.map(({ id }) => id);
if (isDeeplyEqual(currentColumnsIds, columnIds)) {
return;
if (!isDeeplyEqual(currentColumnsIds, columnIds)) {
set(columnIdsState, columnIds);
}
set(columnIdsState, columnIds);
columns.forEach((column) => {
const currentColumn = snapshot
.getLoadable(columnsFamilySelector(column.id))

View File

@ -127,7 +127,10 @@ export const SettingsObjectFieldItemTableRow = ({
const handleDisableField = async (
activeFieldMetadatItem: FieldMetadataItem,
) => {
await deactivateMetadataField(activeFieldMetadatItem);
await deactivateMetadataField(
activeFieldMetadatItem.id,
objectMetadataItem.id,
);
const deletedViewIds = allViews
.map((view) => {
@ -272,7 +275,9 @@ export const SettingsObjectFieldItemTableRow = ({
isCustomField={fieldMetadataItem.isCustom === true}
scopeKey={fieldMetadataItem.id}
onEdit={() => navigate(linkToNavigate)}
onActivate={() => activateMetadataField(fieldMetadataItem)}
onActivate={() =>
activateMetadataField(fieldMetadataItem.id, objectMetadataItem.id)
}
onDelete={() => deleteMetadataField(fieldMetadataItem)}
/>
) : (