fix: many fields in an object (#10061)

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2025-02-11 17:15:30 +01:00
committed by GitHub
co-authored by Charles Bochet
parent 47f262c970
commit ed4a5b0c15
43 changed files with 22317 additions and 22057 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -488,6 +488,7 @@ export type Field = {
label: Scalars['String'];
name: Scalars['String'];
object?: Maybe<Object>;
objectMetadataId: Scalars['UUID'];
options?: Maybe<Scalars['JSON']>;
relation?: Maybe<Relation>;
relationDefinition?: Maybe<RelationDefinition>;
@@ -519,6 +520,7 @@ export type FieldFilter = {
isActive?: InputMaybe<BooleanFieldComparison>;
isCustom?: InputMaybe<BooleanFieldComparison>;
isSystem?: InputMaybe<BooleanFieldComparison>;
objectMetadataId?: InputMaybe<StringFieldComparison>;
or?: InputMaybe<Array<FieldFilter>>;
};
@@ -1569,6 +1571,23 @@ export type SignUpOutput = {
workspace: WorkspaceUrlsAndId;
};
export type StringFieldComparison = {
eq?: InputMaybe<Scalars['String']>;
gt?: InputMaybe<Scalars['String']>;
gte?: InputMaybe<Scalars['String']>;
iLike?: InputMaybe<Scalars['String']>;
in?: InputMaybe<Array<Scalars['String']>>;
is?: InputMaybe<Scalars['Boolean']>;
isNot?: InputMaybe<Scalars['Boolean']>;
like?: InputMaybe<Scalars['String']>;
lt?: InputMaybe<Scalars['String']>;
lte?: InputMaybe<Scalars['String']>;
neq?: InputMaybe<Scalars['String']>;
notILike?: InputMaybe<Scalars['String']>;
notIn?: InputMaybe<Array<Scalars['String']>>;
notLike?: InputMaybe<Scalars['String']>;
};
export enum SubscriptionInterval {
Day = 'Day',
Month = 'Month',
@@ -1690,6 +1709,7 @@ export type UpdateFieldInput = {
isUnique?: InputMaybe<Scalars['Boolean']>;
label?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;
objectMetadataId?: InputMaybe<Scalars['UUID']>;
options?: InputMaybe<Scalars['JSON']>;
settings?: InputMaybe<Scalars['JSON']>;
};
@@ -47,7 +47,8 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
taskId
type
updatedAt
@@ -65,7 +65,8 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
taskId
type
updatedAt
@@ -94,8 +95,9 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
petId
position
rocketId
surveyResultId
taskId
updatedAt
viewId
@@ -119,7 +121,8 @@ const mocks: MockedResponse[] = [
id
opportunityId
personId
rocketId
petId
surveyResultId
taskId
updatedAt
}
@@ -141,8 +144,9 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
petId
properties
rocketId
surveyResultId
taskId
updatedAt
workflowId
@@ -269,9 +269,70 @@ mutation UpdateOneFavorite(
}
}
personId
position
rocket {
pet {
__typename
age
averageCostOfKibblePerMonth {
amountMicros
currencyCode
}
bio
birthday
comments
createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt
extraData
id
interestingFacts
isGoodWithKids
location {
addressStreet1
addressStreet2
addressCity
addressState
addressCountry
addressPostcode
addressLat
addressLng
}
makesOwnerThinkOf {
firstName
lastName
}
name
pictures {
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
position
soundSwag
species
traits
updatedAt
vetEmail {
primaryEmail
additionalEmails
}
vetPhone {
primaryPhoneNumber
primaryPhoneCountryCode
primaryPhoneCallingCode
additionalPhones
}
}
petId
position
surveyResult {
__typename
averageEstimatedNumberOfAtomsInTheUniverse
comments
createdAt
createdBy {
source
@@ -282,10 +343,14 @@ mutation UpdateOneFavorite(
deletedAt
id
name
participants
percentageOfCompletion
position
score
shortNotes
updatedAt
}
rocketId
surveyResultId
task {
__typename
assigneeId
@@ -314,6 +379,8 @@ mutation UpdateOneFavorite(
icon
id
isCompact
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
kanbanFieldMetadataId
key
name
@@ -326,6 +393,12 @@ mutation UpdateOneFavorite(
workflow {
__typename
createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt
id
lastPublishedVersionId
@@ -337,6 +410,7 @@ mutation UpdateOneFavorite(
workflowId
workflowRun {
__typename
context
createdAt
createdBy {
source
@@ -564,9 +638,70 @@ export const mocks = [
}
}
personId
position
rocket {
pet {
__typename
age
averageCostOfKibblePerMonth {
amountMicros
currencyCode
}
bio
birthday
comments
createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt
extraData
id
interestingFacts
isGoodWithKids
location {
addressStreet1
addressStreet2
addressCity
addressState
addressCountry
addressPostcode
addressLat
addressLng
}
makesOwnerThinkOf {
firstName
lastName
}
name
pictures {
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
position
soundSwag
species
traits
updatedAt
vetEmail {
primaryEmail
additionalEmails
}
vetPhone {
primaryPhoneNumber
primaryPhoneCountryCode
primaryPhoneCallingCode
additionalPhones
}
}
petId
position
surveyResult {
__typename
averageEstimatedNumberOfAtomsInTheUniverse
comments
createdAt
createdBy {
source
@@ -577,10 +712,14 @@ export const mocks = [
deletedAt
id
name
participants
percentageOfCompletion
position
score
shortNotes
updatedAt
}
rocketId
surveyResultId
task {
__typename
assigneeId
@@ -609,6 +748,8 @@ export const mocks = [
icon
id
isCompact
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
kanbanFieldMetadataId
key
name
@@ -621,6 +762,12 @@ export const mocks = [
workflow {
__typename
createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt
id
lastPublishedVersionId
@@ -632,6 +779,7 @@ export const mocks = [
workflowId
workflowRun {
__typename
context
createdAt
createdBy {
source
@@ -1,11 +1,8 @@
import { gql } from '@apollo/client';
export const FIND_MANY_OBJECT_METADATA_ITEMS = gql`
query ObjectMetadataItems(
$objectFilter: ObjectFilter
$fieldFilter: FieldFilter
) {
objects(paging: { first: 1000 }, filter: $objectFilter) {
query ObjectMetadataItems {
objects(paging: { first: 1000 }) {
edges {
node {
id
@@ -50,55 +47,45 @@ export const FIND_MANY_OBJECT_METADATA_ITEMS = gql`
}
}
}
fields(paging: { first: 1000 }, filter: $fieldFilter) {
edges {
node {
fieldsList {
id
type
name
label
description
icon
isCustom
isActive
isSystem
isNullable
isUnique
createdAt
updatedAt
defaultValue
options
settings
isLabelSyncedWithName
relationDefinition {
relationId
direction
sourceObjectMetadata {
id
type
nameSingular
namePlural
}
sourceFieldMetadata {
id
name
label
description
icon
isCustom
isActive
isSystem
isNullable
isUnique
createdAt
updatedAt
defaultValue
options
settings
isLabelSyncedWithName
relationDefinition {
relationId
direction
sourceObjectMetadata {
id
nameSingular
namePlural
}
sourceFieldMetadata {
id
name
}
targetObjectMetadata {
id
nameSingular
namePlural
}
targetFieldMetadata {
id
name
}
}
}
targetObjectMetadata {
id
nameSingular
namePlural
}
targetFieldMetadata {
id
name
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
@@ -1,116 +1,6 @@
import { gql } from '@apollo/client';
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '@/object-metadata/graphql/queries';
import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result';
export const query = gql`
query ObjectMetadataItems($objectFilter: ObjectFilter, $fieldFilter: FieldFilter) {
objects(paging: {first: 1000}, filter: $objectFilter) {
edges {
node {
id
dataSourceId
nameSingular
namePlural
labelSingular
labelPlural
description
icon
isCustom
isRemote
isActive
isSystem
createdAt
updatedAt
labelIdentifierFieldMetadataId
imageIdentifierFieldMetadataId
shortcut
isLabelSyncedWithName
indexMetadatas(paging: {first: 100}) {
edges {
node {
id
createdAt
updatedAt
name
indexWhereClause
indexType
isUnique
indexFieldMetadatas(paging: {first: 100}) {
edges {
node {
id
createdAt
updatedAt
order
fieldMetadataId
}
}
}
}
}
}
fields(paging: {first: 1000}, filter: $fieldFilter) {
edges {
node {
id
type
name
label
description
icon
isCustom
isActive
isSystem
isNullable
isUnique
createdAt
updatedAt
defaultValue
options
settings
isLabelSyncedWithName
relationDefinition {
relationId
direction
sourceObjectMetadata {
id
nameSingular
namePlural
}
sourceFieldMetadata {
id
name
}
targetObjectMetadata {
id
nameSingular
namePlural
}
targetFieldMetadata {
id
name
}
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
`;
export const variables = { objectFilter: undefined, fieldFilter: undefined };
export const query = FIND_MANY_OBJECT_METADATA_ITEMS;
export const responseData = mockedStandardObjectMetadataQueryResult;
@@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems';
@@ -9,14 +9,12 @@ import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/Sn
import {
query,
responseData,
variables,
} from '../__mocks__/useFindManyObjectMetadataItems';
const mocks = [
{
request: {
query,
variables,
},
result: jest.fn(() => ({
data: {
@@ -4,8 +4,6 @@ import { useMemo } from 'react';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import {
FieldFilter,
ObjectFilter,
ObjectMetadataItemsQuery,
ObjectMetadataItemsQueryVariables,
} from '~/generated-metadata/graphql';
@@ -18,12 +16,8 @@ import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useFindManyObjectMetadataItems = ({
skip,
objectFilter,
fieldFilter,
}: {
skip?: boolean;
objectFilter?: ObjectFilter;
fieldFilter?: FieldFilter;
} = {}) => {
const apolloMetadataClient = useApolloMetadataClient();
@@ -33,10 +27,6 @@ export const useFindManyObjectMetadataItems = ({
ObjectMetadataItemsQuery,
ObjectMetadataItemsQueryVariables
>(FIND_MANY_OBJECT_METADATA_ITEMS, {
variables: {
objectFilter,
fieldFilter,
},
client: apolloMetadataClient ?? undefined,
skip: skip || !apolloMetadataClient,
onError: (error) => {
@@ -28,6 +28,8 @@ export const useRefreshObjectMetadataItems = (
});
replaceObjectMetadataItemIfDifferent(objectMetadataItems);
return objectMetadataItems;
};
const replaceObjectMetadataItemIfDifferent = useRecoilCallback(
@@ -45,6 +47,7 @@ export const useRefreshObjectMetadataItems = (
},
[],
);
return {
refreshObjectMetadataItems,
};
@@ -10,6 +10,7 @@ export type ObjectMetadataItem = Omit<
| 'dataSourceId'
| 'indexMetadatas'
| 'labelIdentifierFieldMetadataId'
| 'fieldsList'
> & {
__typename?: string;
fields: FieldMetadataItem[];
@@ -14,9 +14,11 @@ export const mapPaginatedObjectMetadataItemsToObjectMetadataItems = ({
object.node.labelIdentifierFieldMetadataId,
);
const { fieldsList, ...objectWithoutFieldsList } = object.node;
return {
...object.node,
fields: object.node.fields.edges.map((field) => field.node),
...objectWithoutFieldsList,
fields: fieldsList,
labelIdentifierFieldMetadataId,
indexMetadatas: object.node.indexMetadatas?.edges.map((index) => ({
...index.node,
@@ -66,7 +66,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId
opportunityId
personId
rocketId
petId
surveyResultId
taskId
type
updatedAt
@@ -173,8 +174,9 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId
opportunityId
personId
petId
position
rocketId
surveyResultId
taskId
updatedAt
viewId
@@ -225,7 +227,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId
opportunityId
personId
rocketId
petId
surveyResultId
updatedAt
}
}
@@ -275,7 +278,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
id
opportunityId
personId
rocketId
petId
surveyResultId
taskId
updatedAt
}
@@ -297,8 +301,9 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId
opportunityId
personId
petId
properties
rocketId
surveyResultId
taskId
updatedAt
workflowId
@@ -201,7 +201,7 @@ const mocks: MockedResponse[] = [
}
}
personId
rocket {
pet {
__typename
createdAt
createdBy {
@@ -216,7 +216,8 @@ const mocks: MockedResponse[] = [
position
updatedAt
}
rocketId
petId
surveyResultId
updatedAt
}
}
@@ -361,7 +362,7 @@ const mocks: MockedResponse[] = [
}
}
personId
rocket {
pet {
__typename
createdAt
createdBy {
@@ -376,7 +377,8 @@ const mocks: MockedResponse[] = [
position
updatedAt
}
rocketId
petId
surveyResultId
task {
__typename
assigneeId
@@ -75,7 +75,8 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
taskId
type
updatedAt
@@ -108,8 +109,9 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
petId
position
rocketId
surveyResultId
taskId
updatedAt
viewId
@@ -144,7 +146,8 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
updatedAt
}
}
@@ -243,7 +246,8 @@ const mocks: MockedResponse[] = [
id
opportunityId
personId
rocketId
petId
surveyResultId
taskId
updatedAt
}
@@ -265,8 +269,9 @@ const mocks: MockedResponse[] = [
noteId
opportunityId
personId
petId
properties
rocketId
surveyResultId
taskId
updatedAt
workflowId
@@ -74,7 +74,8 @@ const companyMocks = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
taskId
type
updatedAt
@@ -107,8 +108,9 @@ const companyMocks = [
noteId
opportunityId
personId
petId
position
rocketId
surveyResultId
taskId
updatedAt
viewId
@@ -143,7 +145,8 @@ const companyMocks = [
noteId
opportunityId
personId
rocketId
petId
surveyResultId
updatedAt
}
}
@@ -242,7 +245,8 @@ const companyMocks = [
id
opportunityId
personId
rocketId
petId
surveyResultId
taskId
updatedAt
}
@@ -264,8 +268,9 @@ const companyMocks = [
noteId
opportunityId
personId
petId
properties
rocketId
surveyResultId
taskId
updatedAt
workflowId
@@ -24,8 +24,10 @@ export const mockedFavoritesData = [
view: null,
taskId: null,
task: null,
rocketId: null,
rocket: null,
petId: null,
pet: null,
surveyResultId: null,
surveyResult: null,
personId: null,
person: null,
opportunityId: null,
@@ -55,8 +57,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[0],
taskId: null,
task: null,
rocketId: null,
rocket: null,
petId: null,
pet: null,
surveyResultId: null,
surveyResult: null,
personId: null,
person: null,
opportunityId: null,
@@ -86,8 +90,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[1],
taskId: null,
task: null,
rocketId: null,
rocket: null,
petId: null,
pet: null,
surveyResultId: null,
surveyResult: null,
personId: null,
person: null,
opportunityId: null,
@@ -117,8 +123,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[1],
taskId: null,
task: null,
rocketId: null,
rocket: null,
petId: null,
pet: null,
surveyResultId: null,
surveyResult: null,
personId: null,
person: null,
opportunityId: null,
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,6 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { objectMetadataItemSchema } from '@/object-metadata/validation-schemas/objectMetadataItemSchema';
import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result';
export const generatedMockObjectMetadataItems: ObjectMetadataItem[] =
@@ -9,9 +10,11 @@ export const generatedMockObjectMetadataItems: ObjectMetadataItem[] =
edge.node.labelIdentifierFieldMetadataId,
);
const { fieldsList, ...objectWithoutFieldsList } = edge.node;
return {
...edge.node,
fields: edge.node.fields.edges.map((edge) => edge.node),
...objectWithoutFieldsList,
fields: fieldsList,
labelIdentifierFieldMetadataId,
indexMetadatas: edge.node.indexMetadatas.edges.map((index) => ({
...index.node,