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
parent 47f262c970
commit ed4a5b0c15
43 changed files with 22318 additions and 22058 deletions

View File

@ -3,9 +3,10 @@ import { JestConfigWithTsJest, pathsToModuleNameMapper } from 'ts-jest';
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const tsConfig = require('./tsconfig.spec.json'); const tsConfig = require('./tsconfig.spec.json');
process.env.TZ = 'GMT'; process.env.TZ = 'GMT';
process.env.LC_ALL = 'en_US.UTF-8';
const jestConfig: JestConfigWithTsJest = { const jestConfig: JestConfigWithTsJest = {
// to enable logs, comment out the following line // to enable logs, comment out the following line
silent: true, silent: false,
// For more information please have a look to official docs https://jestjs.io/docs/configuration/#prettierpath-string // For more information please have a look to official docs https://jestjs.io/docs/configuration/#prettierpath-string
// Prettier v3 will should be supported in jest v30 https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.1 // Prettier v3 will should be supported in jest v30 https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.1
prettierPath: null, prettierPath: null,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -488,6 +488,7 @@ export type Field = {
label: Scalars['String']; label: Scalars['String'];
name: Scalars['String']; name: Scalars['String'];
object?: Maybe<Object>; object?: Maybe<Object>;
objectMetadataId: Scalars['UUID'];
options?: Maybe<Scalars['JSON']>; options?: Maybe<Scalars['JSON']>;
relation?: Maybe<Relation>; relation?: Maybe<Relation>;
relationDefinition?: Maybe<RelationDefinition>; relationDefinition?: Maybe<RelationDefinition>;
@ -519,6 +520,7 @@ export type FieldFilter = {
isActive?: InputMaybe<BooleanFieldComparison>; isActive?: InputMaybe<BooleanFieldComparison>;
isCustom?: InputMaybe<BooleanFieldComparison>; isCustom?: InputMaybe<BooleanFieldComparison>;
isSystem?: InputMaybe<BooleanFieldComparison>; isSystem?: InputMaybe<BooleanFieldComparison>;
objectMetadataId?: InputMaybe<StringFieldComparison>;
or?: InputMaybe<Array<FieldFilter>>; or?: InputMaybe<Array<FieldFilter>>;
}; };
@ -1569,6 +1571,23 @@ export type SignUpOutput = {
workspace: WorkspaceUrlsAndId; 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 { export enum SubscriptionInterval {
Day = 'Day', Day = 'Day',
Month = 'Month', Month = 'Month',
@ -1690,6 +1709,7 @@ export type UpdateFieldInput = {
isUnique?: InputMaybe<Scalars['Boolean']>; isUnique?: InputMaybe<Scalars['Boolean']>;
label?: InputMaybe<Scalars['String']>; label?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>; name?: InputMaybe<Scalars['String']>;
objectMetadataId?: InputMaybe<Scalars['UUID']>;
options?: InputMaybe<Scalars['JSON']>; options?: InputMaybe<Scalars['JSON']>;
settings?: InputMaybe<Scalars['JSON']>; settings?: InputMaybe<Scalars['JSON']>;
}; };

View File

@ -47,7 +47,8 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
type type
updatedAt updatedAt

View File

@ -65,7 +65,8 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
type type
updatedAt updatedAt
@ -94,8 +95,9 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
petId
position position
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
viewId viewId
@ -119,7 +121,8 @@ const mocks: MockedResponse[] = [
id id
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
updatedAt updatedAt
} }
@ -141,8 +144,9 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
petId
properties properties
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
workflowId workflowId

View File

@ -269,9 +269,70 @@ mutation UpdateOneFavorite(
} }
} }
personId personId
position pet {
rocket {
__typename __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 createdAt
createdBy { createdBy {
source source
@ -282,10 +343,14 @@ mutation UpdateOneFavorite(
deletedAt deletedAt
id id
name name
participants
percentageOfCompletion
position position
score
shortNotes
updatedAt updatedAt
} }
rocketId surveyResultId
task { task {
__typename __typename
assigneeId assigneeId
@ -314,6 +379,8 @@ mutation UpdateOneFavorite(
icon icon
id id
isCompact isCompact
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
kanbanFieldMetadataId kanbanFieldMetadataId
key key
name name
@ -326,6 +393,12 @@ mutation UpdateOneFavorite(
workflow { workflow {
__typename __typename
createdAt createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt deletedAt
id id
lastPublishedVersionId lastPublishedVersionId
@ -337,6 +410,7 @@ mutation UpdateOneFavorite(
workflowId workflowId
workflowRun { workflowRun {
__typename __typename
context
createdAt createdAt
createdBy { createdBy {
source source
@ -564,9 +638,70 @@ export const mocks = [
} }
} }
personId personId
position pet {
rocket {
__typename __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 createdAt
createdBy { createdBy {
source source
@ -577,10 +712,14 @@ export const mocks = [
deletedAt deletedAt
id id
name name
participants
percentageOfCompletion
position position
score
shortNotes
updatedAt updatedAt
} }
rocketId surveyResultId
task { task {
__typename __typename
assigneeId assigneeId
@ -609,6 +748,8 @@ export const mocks = [
icon icon
id id
isCompact isCompact
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
kanbanFieldMetadataId kanbanFieldMetadataId
key key
name name
@ -621,6 +762,12 @@ export const mocks = [
workflow { workflow {
__typename __typename
createdAt createdAt
createdBy {
source
workspaceMemberId
name
context
}
deletedAt deletedAt
id id
lastPublishedVersionId lastPublishedVersionId
@ -632,6 +779,7 @@ export const mocks = [
workflowId workflowId
workflowRun { workflowRun {
__typename __typename
context
createdAt createdAt
createdBy { createdBy {
source source

View File

@ -1,11 +1,8 @@
import { gql } from '@apollo/client'; import { gql } from '@apollo/client';
export const FIND_MANY_OBJECT_METADATA_ITEMS = gql` export const FIND_MANY_OBJECT_METADATA_ITEMS = gql`
query ObjectMetadataItems( query ObjectMetadataItems {
$objectFilter: ObjectFilter objects(paging: { first: 1000 }) {
$fieldFilter: FieldFilter
) {
objects(paging: { first: 1000 }, filter: $objectFilter) {
edges { edges {
node { node {
id id
@ -50,55 +47,45 @@ export const FIND_MANY_OBJECT_METADATA_ITEMS = gql`
} }
} }
} }
fields(paging: { first: 1000 }, filter: $fieldFilter) { fieldsList {
edges { id
node { type
name
label
description
icon
isCustom
isActive
isSystem
isNullable
isUnique
createdAt
updatedAt
defaultValue
options
settings
isLabelSyncedWithName
relationDefinition {
relationId
direction
sourceObjectMetadata {
id id
type nameSingular
name namePlural
label }
description sourceFieldMetadata {
icon id
isCustom name
isActive }
isSystem targetObjectMetadata {
isNullable id
isUnique nameSingular
createdAt namePlural
updatedAt }
defaultValue targetFieldMetadata {
options id
settings name
isLabelSyncedWithName
relationDefinition {
relationId
direction
sourceObjectMetadata {
id
nameSingular
namePlural
}
sourceFieldMetadata {
id
name
}
targetObjectMetadata {
id
nameSingular
namePlural
}
targetFieldMetadata {
id
name
}
}
} }
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
} }
} }
} }

View File

@ -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'; import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result';
export const query = gql` export const query = FIND_MANY_OBJECT_METADATA_ITEMS;
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 responseData = mockedStandardObjectMetadataQueryResult; export const responseData = mockedStandardObjectMetadataQueryResult;

View File

@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil'; import { RecoilRoot } from 'recoil';
import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems'; import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems';
@ -9,14 +9,12 @@ import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/Sn
import { import {
query, query,
responseData, responseData,
variables,
} from '../__mocks__/useFindManyObjectMetadataItems'; } from '../__mocks__/useFindManyObjectMetadataItems';
const mocks = [ const mocks = [
{ {
request: { request: {
query, query,
variables,
}, },
result: jest.fn(() => ({ result: jest.fn(() => ({
data: { data: {

View File

@ -4,8 +4,6 @@ import { useMemo } from 'react';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { import {
FieldFilter,
ObjectFilter,
ObjectMetadataItemsQuery, ObjectMetadataItemsQuery,
ObjectMetadataItemsQueryVariables, ObjectMetadataItemsQueryVariables,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
@ -18,12 +16,8 @@ import { useApolloMetadataClient } from './useApolloMetadataClient';
export const useFindManyObjectMetadataItems = ({ export const useFindManyObjectMetadataItems = ({
skip, skip,
objectFilter,
fieldFilter,
}: { }: {
skip?: boolean; skip?: boolean;
objectFilter?: ObjectFilter;
fieldFilter?: FieldFilter;
} = {}) => { } = {}) => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -33,10 +27,6 @@ export const useFindManyObjectMetadataItems = ({
ObjectMetadataItemsQuery, ObjectMetadataItemsQuery,
ObjectMetadataItemsQueryVariables ObjectMetadataItemsQueryVariables
>(FIND_MANY_OBJECT_METADATA_ITEMS, { >(FIND_MANY_OBJECT_METADATA_ITEMS, {
variables: {
objectFilter,
fieldFilter,
},
client: apolloMetadataClient ?? undefined, client: apolloMetadataClient ?? undefined,
skip: skip || !apolloMetadataClient, skip: skip || !apolloMetadataClient,
onError: (error) => { onError: (error) => {

View File

@ -28,6 +28,8 @@ export const useRefreshObjectMetadataItems = (
}); });
replaceObjectMetadataItemIfDifferent(objectMetadataItems); replaceObjectMetadataItemIfDifferent(objectMetadataItems);
return objectMetadataItems;
}; };
const replaceObjectMetadataItemIfDifferent = useRecoilCallback( const replaceObjectMetadataItemIfDifferent = useRecoilCallback(
@ -45,6 +47,7 @@ export const useRefreshObjectMetadataItems = (
}, },
[], [],
); );
return { return {
refreshObjectMetadataItems, refreshObjectMetadataItems,
}; };

View File

@ -10,6 +10,7 @@ export type ObjectMetadataItem = Omit<
| 'dataSourceId' | 'dataSourceId'
| 'indexMetadatas' | 'indexMetadatas'
| 'labelIdentifierFieldMetadataId' | 'labelIdentifierFieldMetadataId'
| 'fieldsList'
> & { > & {
__typename?: string; __typename?: string;
fields: FieldMetadataItem[]; fields: FieldMetadataItem[];

View File

@ -14,9 +14,11 @@ export const mapPaginatedObjectMetadataItemsToObjectMetadataItems = ({
object.node.labelIdentifierFieldMetadataId, object.node.labelIdentifierFieldMetadataId,
); );
const { fieldsList, ...objectWithoutFieldsList } = object.node;
return { return {
...object.node, ...objectWithoutFieldsList,
fields: object.node.fields.edges.map((field) => field.node), fields: fieldsList,
labelIdentifierFieldMetadataId, labelIdentifierFieldMetadataId,
indexMetadatas: object.node.indexMetadatas?.edges.map((index) => ({ indexMetadatas: object.node.indexMetadatas?.edges.map((index) => ({
...index.node, ...index.node,

View File

@ -66,7 +66,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
type type
updatedAt updatedAt
@ -173,8 +174,9 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId noteId
opportunityId opportunityId
personId personId
petId
position position
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
viewId viewId
@ -225,7 +227,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
updatedAt updatedAt
} }
} }
@ -275,7 +278,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
id id
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
updatedAt updatedAt
} }
@ -297,8 +301,9 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
noteId noteId
opportunityId opportunityId
personId personId
petId
properties properties
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
workflowId workflowId

View File

@ -201,7 +201,7 @@ const mocks: MockedResponse[] = [
} }
} }
personId personId
rocket { pet {
__typename __typename
createdAt createdAt
createdBy { createdBy {
@ -216,7 +216,8 @@ const mocks: MockedResponse[] = [
position position
updatedAt updatedAt
} }
rocketId petId
surveyResultId
updatedAt updatedAt
} }
} }
@ -361,7 +362,7 @@ const mocks: MockedResponse[] = [
} }
} }
personId personId
rocket { pet {
__typename __typename
createdAt createdAt
createdBy { createdBy {
@ -376,7 +377,8 @@ const mocks: MockedResponse[] = [
position position
updatedAt updatedAt
} }
rocketId petId
surveyResultId
task { task {
__typename __typename
assigneeId assigneeId

View File

@ -75,7 +75,8 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
type type
updatedAt updatedAt
@ -108,8 +109,9 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
petId
position position
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
viewId viewId
@ -144,7 +146,8 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
updatedAt updatedAt
} }
} }
@ -243,7 +246,8 @@ const mocks: MockedResponse[] = [
id id
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
updatedAt updatedAt
} }
@ -265,8 +269,9 @@ const mocks: MockedResponse[] = [
noteId noteId
opportunityId opportunityId
personId personId
petId
properties properties
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
workflowId workflowId

View File

@ -74,7 +74,8 @@ const companyMocks = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
type type
updatedAt updatedAt
@ -107,8 +108,9 @@ const companyMocks = [
noteId noteId
opportunityId opportunityId
personId personId
petId
position position
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
viewId viewId
@ -143,7 +145,8 @@ const companyMocks = [
noteId noteId
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
updatedAt updatedAt
} }
} }
@ -242,7 +245,8 @@ const companyMocks = [
id id
opportunityId opportunityId
personId personId
rocketId petId
surveyResultId
taskId taskId
updatedAt updatedAt
} }
@ -264,8 +268,9 @@ const companyMocks = [
noteId noteId
opportunityId opportunityId
personId personId
petId
properties properties
rocketId surveyResultId
taskId taskId
updatedAt updatedAt
workflowId workflowId

View File

@ -24,8 +24,10 @@ export const mockedFavoritesData = [
view: null, view: null,
taskId: null, taskId: null,
task: null, task: null,
rocketId: null, petId: null,
rocket: null, pet: null,
surveyResultId: null,
surveyResult: null,
personId: null, personId: null,
person: null, person: null,
opportunityId: null, opportunityId: null,
@ -55,8 +57,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[0], view: mockedViewsData[0],
taskId: null, taskId: null,
task: null, task: null,
rocketId: null, petId: null,
rocket: null, pet: null,
surveyResultId: null,
surveyResult: null,
personId: null, personId: null,
person: null, person: null,
opportunityId: null, opportunityId: null,
@ -86,8 +90,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[1], view: mockedViewsData[1],
taskId: null, taskId: null,
task: null, task: null,
rocketId: null, petId: null,
rocket: null, pet: null,
surveyResultId: null,
surveyResult: null,
personId: null, personId: null,
person: null, person: null,
opportunityId: null, opportunityId: null,
@ -117,8 +123,10 @@ export const mockedFavoritesData = [
view: mockedViewsData[1], view: mockedViewsData[1],
taskId: null, taskId: null,
task: null, task: null,
rocketId: null, petId: null,
rocket: null, pet: null,
surveyResultId: null,
surveyResult: null,
personId: null, personId: null,
person: null, person: null,
opportunityId: null, opportunityId: null,

View File

@ -1,5 +1,6 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { objectMetadataItemSchema } from '@/object-metadata/validation-schemas/objectMetadataItemSchema'; import { objectMetadataItemSchema } from '@/object-metadata/validation-schemas/objectMetadataItemSchema';
import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result'; import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result';
export const generatedMockObjectMetadataItems: ObjectMetadataItem[] = export const generatedMockObjectMetadataItems: ObjectMetadataItem[] =
@ -9,9 +10,11 @@ export const generatedMockObjectMetadataItems: ObjectMetadataItem[] =
edge.node.labelIdentifierFieldMetadataId, edge.node.labelIdentifierFieldMetadataId,
); );
const { fieldsList, ...objectWithoutFieldsList } = edge.node;
return { return {
...edge.node, ...objectWithoutFieldsList,
fields: edge.node.fields.edges.map((edge) => edge.node), fields: fieldsList,
labelIdentifierFieldMetadataId, labelIdentifierFieldMetadataId,
indexMetadatas: edge.node.indexMetadatas.edges.map((index) => ({ indexMetadatas: edge.node.indexMetadatas.edges.map((index) => ({
...index.node, ...index.node,

View File

@ -9,6 +9,7 @@ import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-wo
import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question';
import { UpgradeTo0_40CommandModule } from 'src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module'; import { UpgradeTo0_40CommandModule } from 'src/database/commands/upgrade-version/0-40/0-40-upgrade-version.module';
import { UpgradeTo0_41CommandModule } from 'src/database/commands/upgrade-version/0-41/0-41-upgrade-version.module'; import { UpgradeTo0_41CommandModule } from 'src/database/commands/upgrade-version/0-41/0-41-upgrade-version.module';
import { UpgradeTo0_42CommandModule } from 'src/database/commands/upgrade-version/0-42/0-42-upgrade-version.module';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
@ -51,6 +52,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp
WorkspaceMetadataVersionModule, WorkspaceMetadataVersionModule,
UpgradeTo0_40CommandModule, UpgradeTo0_40CommandModule,
UpgradeTo0_41CommandModule, UpgradeTo0_41CommandModule,
UpgradeTo0_42CommandModule,
FeatureFlagModule, FeatureFlagModule,
], ],
providers: [ providers: [

View File

@ -0,0 +1,117 @@
import { InjectRepository } from '@nestjs/typeorm';
import chalk from 'chalk';
import { Command } from 'nest-commander';
import { Repository } from 'typeorm';
import {
ActiveWorkspacesCommandOptions,
ActiveWorkspacesCommandRunner,
} from 'src/database/commands/active-workspaces.command';
import { CommandLogger } from 'src/database/commands/logger';
import { settings } from 'src/engine/constants/settings';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
@Command({
name: 'upgrade-0.42:limit-amount-of-view-field',
description: 'Limit amount of view field.',
})
export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesCommandRunner {
protected readonly logger: CommandLogger;
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {
super(workspaceRepository);
this.logger = new CommandLogger({
constructorName: this.constructor.name,
verbose: false,
});
this.logger.setVerbose(false);
}
async execute(workspaceId: string, dryRun?: boolean): Promise<void> {
this.logger.log(
`Processing workspace ${workspaceId} for view field limitation`,
);
try {
const viewRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
ViewWorkspaceEntity,
);
const views = await viewRepository.find({});
for (const view of views) {
const viewFieldRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
ViewFieldWorkspaceEntity,
);
const viewFields = await viewFieldRepository.find({
where: {
viewId: view.id,
isVisible: true,
},
order: {
position: 'ASC',
},
});
if (viewFields.length > settings.maxVisibleViewFields) {
const extraFields = viewFields.slice(settings.maxVisibleViewFields);
for (const field of extraFields) {
this.logger.log(
`Workspace ${workspaceId} - Hiding field ${field.id} in view ${view.id} (position ${field.position})`,
);
if (!dryRun) {
await viewFieldRepository.update(
{ id: field.id },
{ isVisible: false },
);
}
}
}
}
} catch (error) {
this.logger.error(
`Error limiting view fields in workspace ${workspaceId}`,
error,
);
throw error;
}
}
async executeActiveWorkspacesCommand(
_passedParam: string[],
options: ActiveWorkspacesCommandOptions,
workspaceIds: string[],
): Promise<void> {
this.logger.log(`Running limit-amount-of-view-field command`);
if (options?.dryRun) {
this.logger.log(chalk.yellow('Dry run mode: No changes will be applied'));
}
for (const [index, workspaceId] of workspaceIds.entries()) {
try {
await this.execute(workspaceId, options?.dryRun);
this.logger.verbose(
`Processed workspace: ${workspaceId} (${index + 1}/${
workspaceIds.length
})`,
);
} catch (error) {
this.logger.error(`Error for workspace: ${workspaceId}`, error);
}
}
}
}

View File

@ -0,0 +1,37 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Command } from 'nest-commander';
import { Repository } from 'typeorm';
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
import { BaseCommandOptions } from 'src/database/commands/base.command';
import { LimitAmountOfViewFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-limit-amount-of-view-field';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Command({
name: 'upgrade-0.42',
description: 'Upgrade to 0.42',
})
export class UpgradeTo0_42Command extends ActiveWorkspacesCommandRunner {
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly limitAmountOfViewFieldCommand: LimitAmountOfViewFieldCommand,
) {
super(workspaceRepository);
}
async executeActiveWorkspacesCommand(
passedParam: string[],
options: BaseCommandOptions,
workspaceIds: string[],
): Promise<void> {
this.logger.log('Running command to upgrade to 0.42');
await this.limitAmountOfViewFieldCommand.executeActiveWorkspacesCommand(
passedParam,
options,
workspaceIds,
);
}
}

View File

@ -0,0 +1,37 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { LimitAmountOfViewFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-limit-amount-of-view-field';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module';
import { SyncWorkspaceLoggerService } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service';
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module';
import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module';
@Module({
imports: [
TypeOrmModule.forFeature([Workspace], 'core'),
TypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'),
TypeORMModule,
DataSourceModule,
ObjectMetadataModule,
WorkspaceSyncMetadataCommandsModule,
WorkspaceSyncMetadataModule,
WorkspaceHealthModule,
WorkspaceDataSourceModule,
WorkspaceMetadataVersionModule,
],
providers: [
SyncWorkspaceLoggerService,
SyncWorkspaceMetadataCommand,
LimitAmountOfViewFieldCommand,
],
})
export class UpgradeTo0_42CommandModule {}

View File

@ -10,4 +10,5 @@ export const settings: Settings = {
maxFileSize: '10MB', maxFileSize: '10MB',
}, },
minLengthOfStringForDuplicateCheck: 3, minLengthOfStringForDuplicateCheck: 3,
maxVisibleViewFields: 30,
}; };

View File

@ -12,4 +12,5 @@ export interface Settings {
maxFileSize: `${number}MB`; maxFileSize: `${number}MB`;
}; };
minLengthOfStringForDuplicateCheck: number; minLengthOfStringForDuplicateCheck: number;
maxVisibleViewFields: number;
} }

View File

@ -1,6 +1,7 @@
import DataLoader from 'dataloader'; import DataLoader from 'dataloader';
import { import {
FieldMetadataLoaderPayload,
RelationLoaderPayload, RelationLoaderPayload,
RelationMetadataLoaderPayload, RelationMetadataLoaderPayload,
} from 'src/engine/dataloaders/dataloader.service'; } from 'src/engine/dataloaders/dataloader.service';
@ -23,4 +24,9 @@ export interface IDataloaders {
targetFieldMetadata: FieldMetadataEntity; targetFieldMetadata: FieldMetadataEntity;
} }
>; >;
fieldMetadataLoader: DataLoader<
FieldMetadataLoaderPayload,
FieldMetadataEntity[]
>;
} }

View File

@ -3,9 +3,11 @@ import { Injectable } from '@nestjs/common';
import DataLoader from 'dataloader'; import DataLoader from 'dataloader';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface'; import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
import { FieldMetadataRelationService } from 'src/engine/metadata-modules/field-metadata/relation/field-metadata-relation.service'; import { FieldMetadataRelationService } from 'src/engine/metadata-modules/field-metadata/relation/field-metadata-relation.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@ -31,20 +33,28 @@ export type RelationLoaderPayload = {
>; >;
}; };
export type FieldMetadataLoaderPayload = {
workspaceId: string;
objectMetadata: Pick<ObjectMetadataInterface, 'id'>;
};
@Injectable() @Injectable()
export class DataloaderService { export class DataloaderService {
constructor( constructor(
private readonly relationMetadataService: RelationMetadataService, private readonly relationMetadataService: RelationMetadataService,
private readonly fieldMetadataRelationService: FieldMetadataRelationService, private readonly fieldMetadataRelationService: FieldMetadataRelationService,
private readonly fieldMetadataService: FieldMetadataService,
) {} ) {}
createLoaders(): IDataloaders { createLoaders(): IDataloaders {
const relationMetadataLoader = this.createRelationMetadataLoader(); const relationMetadataLoader = this.createRelationMetadataLoader();
const relationLoader = this.createRelationLoader(); const relationLoader = this.createRelationLoader();
const fieldMetadataLoader = this.createFieldMetadataLoader();
return { return {
relationMetadataLoader, relationMetadataLoader,
relationLoader, relationLoader,
fieldMetadataLoader,
}; };
} }
@ -92,4 +102,23 @@ export class DataloaderService {
return fieldMetadataRelationCollection; return fieldMetadataRelationCollection;
}); });
} }
private createFieldMetadataLoader() {
return new DataLoader<FieldMetadataLoaderPayload, FieldMetadataEntity[]>(
async (dataLoaderParams: FieldMetadataLoaderPayload[]) => {
const workspaceId = dataLoaderParams[0].workspaceId;
const objectMetadataItems = dataLoaderParams.map(
(dataLoaderParam) => dataLoaderParam.objectMetadata,
);
const fieldMetadataCollection =
await this.fieldMetadataService.getFieldMetadataItemsByBatch(
objectMetadataItems.map((item) => item.id),
workspaceId,
);
return fieldMetadataCollection;
},
);
}
} }

View File

@ -9,6 +9,7 @@ import { DataSource, FindOneOptions, In, Repository } from 'typeorm';
import { v4 as uuidV4, v4 } from 'uuid'; import { v4 as uuidV4, v4 } from 'uuid';
import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { settings } from 'src/engine/constants/settings';
import { generateMessageId } from 'src/engine/core-modules/i18n/utils/generateMessageId'; import { generateMessageId } from 'src/engine/core-modules/i18n/utils/generateMessageId';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
@ -860,6 +861,8 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
`SELECT * FROM ${dataSourceMetadata.schema}."viewField" `SELECT * FROM ${dataSourceMetadata.schema}."viewField"
WHERE "viewId" = '${view[0].id}'`, WHERE "viewId" = '${view[0].id}'`,
)) as ViewFieldWorkspaceEntity[]; )) as ViewFieldWorkspaceEntity[];
const isVisible =
existingViewFields.length < settings.maxVisibleViewFields;
const createdFieldIsAlreadyInView = existingViewFields.some( const createdFieldIsAlreadyInView = existingViewFields.some(
(existingViewField) => (existingViewField) =>
@ -882,7 +885,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
("fieldMetadataId", "position", "isVisible", "size", "viewId") ("fieldMetadataId", "position", "isVisible", "size", "viewId")
VALUES ('${createdFieldMetadata.id}', '${ VALUES ('${createdFieldMetadata.id}', '${
lastPosition + 1 lastPosition + 1
}', true, 180, '${view[0].id}')`, }', ${isVisible}, 180, '${view[0].id}')`,
); );
} }
} }
@ -895,4 +898,20 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
await workspaceQueryRunner.release(); await workspaceQueryRunner.release();
} }
} }
async getFieldMetadataItemsByBatch(
objectMetadataIds: string[],
workspaceId: string,
) {
const fieldMetadataItems = await this.fieldMetadataRepository.find({
where: { objectMetadataId: In(objectMetadataIds), workspaceId },
});
return objectMetadataIds.map((objectMetadataId) =>
fieldMetadataItems.filter(
(fieldMetadataItem) =>
fieldMetadataItem.objectMetadataId === objectMetadataId,
),
);
}
} }

View File

@ -12,9 +12,11 @@ import { SettingsFeatures } from 'twenty-shared';
import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type'; import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input'; import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input';
import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
import { import {
@ -104,4 +106,26 @@ export class ObjectMetadataResolver {
objectMetadataGraphqlApiExceptionHandler(error); objectMetadataGraphqlApiExceptionHandler(error);
} }
} }
@ResolveField(() => [FieldMetadataDTO], { nullable: false })
async fieldsList(
@AuthWorkspace() workspace: Workspace,
@Parent() objectMetadata: ObjectMetadataDTO,
@Context() context: { loaders: IDataloaders },
): Promise<FieldMetadataDTO[]> {
try {
const fieldMetadataItems = await context.loaders.fieldMetadataLoader.load(
{
objectMetadata,
workspaceId: workspace.id,
},
);
return fieldMetadataItems;
} catch (error) {
objectMetadataGraphqlApiExceptionHandler(error);
return [];
}
}
} }

View File

@ -23,7 +23,8 @@ describe('attachmentsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -64,7 +65,8 @@ describe('attachmentsResolver (e2e)', () => {
expect(attachments).toHaveProperty('personId'); expect(attachments).toHaveProperty('personId');
expect(attachments).toHaveProperty('companyId'); expect(attachments).toHaveProperty('companyId');
expect(attachments).toHaveProperty('opportunityId'); expect(attachments).toHaveProperty('opportunityId');
expect(attachments).toHaveProperty('rocketId'); expect(attachments).toHaveProperty('petId');
expect(attachments).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -25,7 +25,8 @@ describe('favoritesResolver (e2e)', () => {
taskId taskId
noteId noteId
viewId viewId
rocketId petId
surveyResultId
} }
} }
} }
@ -68,7 +69,8 @@ describe('favoritesResolver (e2e)', () => {
expect(favorites).toHaveProperty('taskId'); expect(favorites).toHaveProperty('taskId');
expect(favorites).toHaveProperty('noteId'); expect(favorites).toHaveProperty('noteId');
expect(favorites).toHaveProperty('viewId'); expect(favorites).toHaveProperty('viewId');
expect(favorites).toHaveProperty('rocketId'); expect(favorites).toHaveProperty('petId');
expect(favorites).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -18,7 +18,8 @@ describe('noteTargetsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -54,7 +55,8 @@ describe('noteTargetsResolver (e2e)', () => {
expect(noteTargets).toHaveProperty('personId'); expect(noteTargets).toHaveProperty('personId');
expect(noteTargets).toHaveProperty('companyId'); expect(noteTargets).toHaveProperty('companyId');
expect(noteTargets).toHaveProperty('opportunityId'); expect(noteTargets).toHaveProperty('opportunityId');
expect(noteTargets).toHaveProperty('rocketId'); expect(noteTargets).toHaveProperty('petId');
expect(noteTargets).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -2,12 +2,12 @@ import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`); const client = request(`http://localhost:${APP_PORT}`);
describe('rocketsResolver (e2e)', () => { describe('petsResolver (e2e)', () => {
it('should find many rockets', () => { it('should find many pets', () => {
const queryData = { const queryData = {
query: ` query: `
query rockets { query pets {
rockets { pets {
edges { edges {
node { node {
id id
@ -34,7 +34,7 @@ describe('rocketsResolver (e2e)', () => {
expect(res.body.errors).toBeUndefined(); expect(res.body.errors).toBeUndefined();
}) })
.expect((res) => { .expect((res) => {
const data = res.body.data.rockets; const data = res.body.data.pets;
expect(data).toBeDefined(); expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true); expect(Array.isArray(data.edges)).toBe(true);
@ -42,15 +42,15 @@ describe('rocketsResolver (e2e)', () => {
const edges = data.edges; const edges = data.edges;
if (edges.length > 0) { if (edges.length > 0) {
const rockets = edges[0].node; const pets = edges[0].node;
expect(rockets).toHaveProperty('id'); expect(pets).toHaveProperty('id');
expect(rockets).toHaveProperty('name'); expect(pets).toHaveProperty('name');
expect(rockets).toHaveProperty('createdAt'); expect(pets).toHaveProperty('createdAt');
expect(rockets).toHaveProperty('updatedAt'); expect(pets).toHaveProperty('updatedAt');
expect(rockets).toHaveProperty('deletedAt'); expect(pets).toHaveProperty('deletedAt');
expect(rockets).toHaveProperty('position'); expect(pets).toHaveProperty('position');
expect(rockets).toHaveProperty('searchVector'); expect(pets).toHaveProperty('searchVector');
} }
}); });
}); });

View File

@ -23,7 +23,8 @@ describe('searchAttachmentsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -64,7 +65,8 @@ describe('searchAttachmentsResolver (e2e)', () => {
expect(searchAttachments).toHaveProperty('personId'); expect(searchAttachments).toHaveProperty('personId');
expect(searchAttachments).toHaveProperty('companyId'); expect(searchAttachments).toHaveProperty('companyId');
expect(searchAttachments).toHaveProperty('opportunityId'); expect(searchAttachments).toHaveProperty('opportunityId');
expect(searchAttachments).toHaveProperty('rocketId'); expect(searchAttachments).toHaveProperty('petId');
expect(searchAttachments).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -25,7 +25,8 @@ describe('searchFavoritesResolver (e2e)', () => {
taskId taskId
noteId noteId
viewId viewId
rocketId petId
surveyResultId
} }
} }
} }
@ -68,7 +69,8 @@ describe('searchFavoritesResolver (e2e)', () => {
expect(searchFavorites).toHaveProperty('taskId'); expect(searchFavorites).toHaveProperty('taskId');
expect(searchFavorites).toHaveProperty('noteId'); expect(searchFavorites).toHaveProperty('noteId');
expect(searchFavorites).toHaveProperty('viewId'); expect(searchFavorites).toHaveProperty('viewId');
expect(searchFavorites).toHaveProperty('rocketId'); expect(searchFavorites).toHaveProperty('petId');
expect(searchFavorites).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -18,7 +18,8 @@ describe('searchNoteTargetsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -54,7 +55,8 @@ describe('searchNoteTargetsResolver (e2e)', () => {
expect(searchNoteTargets).toHaveProperty('personId'); expect(searchNoteTargets).toHaveProperty('personId');
expect(searchNoteTargets).toHaveProperty('companyId'); expect(searchNoteTargets).toHaveProperty('companyId');
expect(searchNoteTargets).toHaveProperty('opportunityId'); expect(searchNoteTargets).toHaveProperty('opportunityId');
expect(searchNoteTargets).toHaveProperty('rocketId'); expect(searchNoteTargets).toHaveProperty('petId');
expect(searchNoteTargets).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -2,12 +2,12 @@ import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`); const client = request(`http://localhost:${APP_PORT}`);
describe('searchRocketsResolver (e2e)', () => { describe('searchPetsResolver (e2e)', () => {
it('should find many searchRockets', () => { it('should find many searchPets', () => {
const queryData = { const queryData = {
query: ` query: `
query searchRockets { query searchPets {
searchRockets { searchPets {
edges { edges {
node { node {
id id
@ -34,7 +34,7 @@ describe('searchRocketsResolver (e2e)', () => {
expect(res.body.errors).toBeUndefined(); expect(res.body.errors).toBeUndefined();
}) })
.expect((res) => { .expect((res) => {
const data = res.body.data.searchRockets; const data = res.body.data.searchPets;
expect(data).toBeDefined(); expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true); expect(Array.isArray(data.edges)).toBe(true);
@ -42,15 +42,15 @@ describe('searchRocketsResolver (e2e)', () => {
const edges = data.edges; const edges = data.edges;
if (edges.length > 0) { if (edges.length > 0) {
const searchRockets = edges[0].node; const searchPets = edges[0].node;
expect(searchRockets).toHaveProperty('id'); expect(searchPets).toHaveProperty('id');
expect(searchRockets).toHaveProperty('name'); expect(searchPets).toHaveProperty('name');
expect(searchRockets).toHaveProperty('createdAt'); expect(searchPets).toHaveProperty('createdAt');
expect(searchRockets).toHaveProperty('updatedAt'); expect(searchPets).toHaveProperty('updatedAt');
expect(searchRockets).toHaveProperty('deletedAt'); expect(searchPets).toHaveProperty('deletedAt');
expect(searchRockets).toHaveProperty('position'); expect(searchPets).toHaveProperty('position');
expect(searchRockets).toHaveProperty('searchVector'); expect(searchPets).toHaveProperty('searchVector');
} }
}); });
}); });

View File

@ -18,7 +18,8 @@ describe('searchTaskTargetsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -54,7 +55,8 @@ describe('searchTaskTargetsResolver (e2e)', () => {
expect(searchTaskTargets).toHaveProperty('personId'); expect(searchTaskTargets).toHaveProperty('personId');
expect(searchTaskTargets).toHaveProperty('companyId'); expect(searchTaskTargets).toHaveProperty('companyId');
expect(searchTaskTargets).toHaveProperty('opportunityId'); expect(searchTaskTargets).toHaveProperty('opportunityId');
expect(searchTaskTargets).toHaveProperty('rocketId'); expect(searchTaskTargets).toHaveProperty('petId');
expect(searchTaskTargets).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -29,7 +29,8 @@ describe('searchTimelineActivitiesResolver (e2e)', () => {
workflowId workflowId
workflowVersionId workflowVersionId
workflowRunId workflowRunId
rocketId petId
surveyResultId
} }
} }
} }
@ -80,7 +81,8 @@ describe('searchTimelineActivitiesResolver (e2e)', () => {
expect(searchTimelineActivities).toHaveProperty('workflowId'); expect(searchTimelineActivities).toHaveProperty('workflowId');
expect(searchTimelineActivities).toHaveProperty('workflowVersionId'); expect(searchTimelineActivities).toHaveProperty('workflowVersionId');
expect(searchTimelineActivities).toHaveProperty('workflowRunId'); expect(searchTimelineActivities).toHaveProperty('workflowRunId');
expect(searchTimelineActivities).toHaveProperty('rocketId'); expect(searchTimelineActivities).toHaveProperty('petId');
expect(searchTimelineActivities).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -18,7 +18,8 @@ describe('taskTargetsResolver (e2e)', () => {
personId personId
companyId companyId
opportunityId opportunityId
rocketId petId
surveyResultId
} }
} }
} }
@ -54,7 +55,8 @@ describe('taskTargetsResolver (e2e)', () => {
expect(taskTargets).toHaveProperty('personId'); expect(taskTargets).toHaveProperty('personId');
expect(taskTargets).toHaveProperty('companyId'); expect(taskTargets).toHaveProperty('companyId');
expect(taskTargets).toHaveProperty('opportunityId'); expect(taskTargets).toHaveProperty('opportunityId');
expect(taskTargets).toHaveProperty('rocketId'); expect(taskTargets).toHaveProperty('petId');
expect(taskTargets).toHaveProperty('surveyResultId');
} }
}); });
}); });

View File

@ -29,7 +29,8 @@ describe('timelineActivitiesResolver (e2e)', () => {
workflowId workflowId
workflowVersionId workflowVersionId
workflowRunId workflowRunId
rocketId petId
surveyResultId
} }
} }
} }
@ -76,7 +77,8 @@ describe('timelineActivitiesResolver (e2e)', () => {
expect(timelineActivities).toHaveProperty('workflowId'); expect(timelineActivities).toHaveProperty('workflowId');
expect(timelineActivities).toHaveProperty('workflowVersionId'); expect(timelineActivities).toHaveProperty('workflowVersionId');
expect(timelineActivities).toHaveProperty('workflowRunId'); expect(timelineActivities).toHaveProperty('workflowRunId');
expect(timelineActivities).toHaveProperty('rocketId'); expect(timelineActivities).toHaveProperty('petId');
expect(timelineActivities).toHaveProperty('surveyResultId');
} }
}); });
}); });