fix: many fields in an object (#10061)
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -3,9 +3,10 @@ import { JestConfigWithTsJest, pathsToModuleNameMapper } from 'ts-jest';
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const tsConfig = require('./tsconfig.spec.json');
|
||||
process.env.TZ = 'GMT';
|
||||
process.env.LC_ALL = 'en_US.UTF-8';
|
||||
const jestConfig: JestConfigWithTsJest = {
|
||||
// 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
|
||||
// Prettier v3 will should be supported in jest v30 https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.1
|
||||
prettierPath: null,
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
}
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
sourceFieldMetadata {
|
||||
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,
|
||||
|
||||
@ -9,6 +9,7 @@ import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-wo
|
||||
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_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 { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.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,
|
||||
UpgradeTo0_40CommandModule,
|
||||
UpgradeTo0_41CommandModule,
|
||||
UpgradeTo0_42CommandModule,
|
||||
FeatureFlagModule,
|
||||
],
|
||||
providers: [
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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 {}
|
||||
@ -10,4 +10,5 @@ export const settings: Settings = {
|
||||
maxFileSize: '10MB',
|
||||
},
|
||||
minLengthOfStringForDuplicateCheck: 3,
|
||||
maxVisibleViewFields: 30,
|
||||
};
|
||||
|
||||
@ -12,4 +12,5 @@ export interface Settings {
|
||||
maxFileSize: `${number}MB`;
|
||||
};
|
||||
minLengthOfStringForDuplicateCheck: number;
|
||||
maxVisibleViewFields: number;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import DataLoader from 'dataloader';
|
||||
|
||||
import {
|
||||
FieldMetadataLoaderPayload,
|
||||
RelationLoaderPayload,
|
||||
RelationMetadataLoaderPayload,
|
||||
} from 'src/engine/dataloaders/dataloader.service';
|
||||
@ -23,4 +24,9 @@ export interface IDataloaders {
|
||||
targetFieldMetadata: FieldMetadataEntity;
|
||||
}
|
||||
>;
|
||||
|
||||
fieldMetadataLoader: DataLoader<
|
||||
FieldMetadataLoaderPayload,
|
||||
FieldMetadataEntity[]
|
||||
>;
|
||||
}
|
||||
|
||||
@ -3,9 +3,11 @@ import { Injectable } from '@nestjs/common';
|
||||
import DataLoader from 'dataloader';
|
||||
|
||||
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 { 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 { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-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()
|
||||
export class DataloaderService {
|
||||
constructor(
|
||||
private readonly relationMetadataService: RelationMetadataService,
|
||||
private readonly fieldMetadataRelationService: FieldMetadataRelationService,
|
||||
private readonly fieldMetadataService: FieldMetadataService,
|
||||
) {}
|
||||
|
||||
createLoaders(): IDataloaders {
|
||||
const relationMetadataLoader = this.createRelationMetadataLoader();
|
||||
const relationLoader = this.createRelationLoader();
|
||||
const fieldMetadataLoader = this.createFieldMetadataLoader();
|
||||
|
||||
return {
|
||||
relationMetadataLoader,
|
||||
relationLoader,
|
||||
fieldMetadataLoader,
|
||||
};
|
||||
}
|
||||
|
||||
@ -92,4 +102,23 @@ export class DataloaderService {
|
||||
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;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import { DataSource, FindOneOptions, In, Repository } from 'typeorm';
|
||||
import { v4 as uuidV4, v4 } from 'uuid';
|
||||
|
||||
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 { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
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"
|
||||
WHERE "viewId" = '${view[0].id}'`,
|
||||
)) as ViewFieldWorkspaceEntity[];
|
||||
const isVisible =
|
||||
existingViewFields.length < settings.maxVisibleViewFields;
|
||||
|
||||
const createdFieldIsAlreadyInView = existingViewFields.some(
|
||||
(existingViewField) =>
|
||||
@ -882,7 +885,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
("fieldMetadataId", "position", "isVisible", "size", "viewId")
|
||||
VALUES ('${createdFieldMetadata.id}', '${
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,11 @@ import { SettingsFeatures } from 'twenty-shared';
|
||||
|
||||
import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type';
|
||||
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 { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.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 { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
import {
|
||||
@ -104,4 +106,26 @@ export class ObjectMetadataResolver {
|
||||
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 [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,8 @@ describe('attachmentsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,7 +65,8 @@ describe('attachmentsResolver (e2e)', () => {
|
||||
expect(attachments).toHaveProperty('personId');
|
||||
expect(attachments).toHaveProperty('companyId');
|
||||
expect(attachments).toHaveProperty('opportunityId');
|
||||
expect(attachments).toHaveProperty('rocketId');
|
||||
expect(attachments).toHaveProperty('petId');
|
||||
expect(attachments).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -25,7 +25,8 @@ describe('favoritesResolver (e2e)', () => {
|
||||
taskId
|
||||
noteId
|
||||
viewId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +69,8 @@ describe('favoritesResolver (e2e)', () => {
|
||||
expect(favorites).toHaveProperty('taskId');
|
||||
expect(favorites).toHaveProperty('noteId');
|
||||
expect(favorites).toHaveProperty('viewId');
|
||||
expect(favorites).toHaveProperty('rocketId');
|
||||
expect(favorites).toHaveProperty('petId');
|
||||
expect(favorites).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,7 +18,8 @@ describe('noteTargetsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,7 +55,8 @@ describe('noteTargetsResolver (e2e)', () => {
|
||||
expect(noteTargets).toHaveProperty('personId');
|
||||
expect(noteTargets).toHaveProperty('companyId');
|
||||
expect(noteTargets).toHaveProperty('opportunityId');
|
||||
expect(noteTargets).toHaveProperty('rocketId');
|
||||
expect(noteTargets).toHaveProperty('petId');
|
||||
expect(noteTargets).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,12 +2,12 @@ import request from 'supertest';
|
||||
|
||||
const client = request(`http://localhost:${APP_PORT}`);
|
||||
|
||||
describe('rocketsResolver (e2e)', () => {
|
||||
it('should find many rockets', () => {
|
||||
describe('petsResolver (e2e)', () => {
|
||||
it('should find many pets', () => {
|
||||
const queryData = {
|
||||
query: `
|
||||
query rockets {
|
||||
rockets {
|
||||
query pets {
|
||||
pets {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
@ -34,7 +34,7 @@ describe('rocketsResolver (e2e)', () => {
|
||||
expect(res.body.errors).toBeUndefined();
|
||||
})
|
||||
.expect((res) => {
|
||||
const data = res.body.data.rockets;
|
||||
const data = res.body.data.pets;
|
||||
|
||||
expect(data).toBeDefined();
|
||||
expect(Array.isArray(data.edges)).toBe(true);
|
||||
@ -42,15 +42,15 @@ describe('rocketsResolver (e2e)', () => {
|
||||
const edges = data.edges;
|
||||
|
||||
if (edges.length > 0) {
|
||||
const rockets = edges[0].node;
|
||||
const pets = edges[0].node;
|
||||
|
||||
expect(rockets).toHaveProperty('id');
|
||||
expect(rockets).toHaveProperty('name');
|
||||
expect(rockets).toHaveProperty('createdAt');
|
||||
expect(rockets).toHaveProperty('updatedAt');
|
||||
expect(rockets).toHaveProperty('deletedAt');
|
||||
expect(rockets).toHaveProperty('position');
|
||||
expect(rockets).toHaveProperty('searchVector');
|
||||
expect(pets).toHaveProperty('id');
|
||||
expect(pets).toHaveProperty('name');
|
||||
expect(pets).toHaveProperty('createdAt');
|
||||
expect(pets).toHaveProperty('updatedAt');
|
||||
expect(pets).toHaveProperty('deletedAt');
|
||||
expect(pets).toHaveProperty('position');
|
||||
expect(pets).toHaveProperty('searchVector');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -23,7 +23,8 @@ describe('searchAttachmentsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,7 +65,8 @@ describe('searchAttachmentsResolver (e2e)', () => {
|
||||
expect(searchAttachments).toHaveProperty('personId');
|
||||
expect(searchAttachments).toHaveProperty('companyId');
|
||||
expect(searchAttachments).toHaveProperty('opportunityId');
|
||||
expect(searchAttachments).toHaveProperty('rocketId');
|
||||
expect(searchAttachments).toHaveProperty('petId');
|
||||
expect(searchAttachments).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -25,7 +25,8 @@ describe('searchFavoritesResolver (e2e)', () => {
|
||||
taskId
|
||||
noteId
|
||||
viewId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +69,8 @@ describe('searchFavoritesResolver (e2e)', () => {
|
||||
expect(searchFavorites).toHaveProperty('taskId');
|
||||
expect(searchFavorites).toHaveProperty('noteId');
|
||||
expect(searchFavorites).toHaveProperty('viewId');
|
||||
expect(searchFavorites).toHaveProperty('rocketId');
|
||||
expect(searchFavorites).toHaveProperty('petId');
|
||||
expect(searchFavorites).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,7 +18,8 @@ describe('searchNoteTargetsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,7 +55,8 @@ describe('searchNoteTargetsResolver (e2e)', () => {
|
||||
expect(searchNoteTargets).toHaveProperty('personId');
|
||||
expect(searchNoteTargets).toHaveProperty('companyId');
|
||||
expect(searchNoteTargets).toHaveProperty('opportunityId');
|
||||
expect(searchNoteTargets).toHaveProperty('rocketId');
|
||||
expect(searchNoteTargets).toHaveProperty('petId');
|
||||
expect(searchNoteTargets).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,12 +2,12 @@ import request from 'supertest';
|
||||
|
||||
const client = request(`http://localhost:${APP_PORT}`);
|
||||
|
||||
describe('searchRocketsResolver (e2e)', () => {
|
||||
it('should find many searchRockets', () => {
|
||||
describe('searchPetsResolver (e2e)', () => {
|
||||
it('should find many searchPets', () => {
|
||||
const queryData = {
|
||||
query: `
|
||||
query searchRockets {
|
||||
searchRockets {
|
||||
query searchPets {
|
||||
searchPets {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
@ -34,7 +34,7 @@ describe('searchRocketsResolver (e2e)', () => {
|
||||
expect(res.body.errors).toBeUndefined();
|
||||
})
|
||||
.expect((res) => {
|
||||
const data = res.body.data.searchRockets;
|
||||
const data = res.body.data.searchPets;
|
||||
|
||||
expect(data).toBeDefined();
|
||||
expect(Array.isArray(data.edges)).toBe(true);
|
||||
@ -42,15 +42,15 @@ describe('searchRocketsResolver (e2e)', () => {
|
||||
const edges = data.edges;
|
||||
|
||||
if (edges.length > 0) {
|
||||
const searchRockets = edges[0].node;
|
||||
const searchPets = edges[0].node;
|
||||
|
||||
expect(searchRockets).toHaveProperty('id');
|
||||
expect(searchRockets).toHaveProperty('name');
|
||||
expect(searchRockets).toHaveProperty('createdAt');
|
||||
expect(searchRockets).toHaveProperty('updatedAt');
|
||||
expect(searchRockets).toHaveProperty('deletedAt');
|
||||
expect(searchRockets).toHaveProperty('position');
|
||||
expect(searchRockets).toHaveProperty('searchVector');
|
||||
expect(searchPets).toHaveProperty('id');
|
||||
expect(searchPets).toHaveProperty('name');
|
||||
expect(searchPets).toHaveProperty('createdAt');
|
||||
expect(searchPets).toHaveProperty('updatedAt');
|
||||
expect(searchPets).toHaveProperty('deletedAt');
|
||||
expect(searchPets).toHaveProperty('position');
|
||||
expect(searchPets).toHaveProperty('searchVector');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,7 +18,8 @@ describe('searchTaskTargetsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,7 +55,8 @@ describe('searchTaskTargetsResolver (e2e)', () => {
|
||||
expect(searchTaskTargets).toHaveProperty('personId');
|
||||
expect(searchTaskTargets).toHaveProperty('companyId');
|
||||
expect(searchTaskTargets).toHaveProperty('opportunityId');
|
||||
expect(searchTaskTargets).toHaveProperty('rocketId');
|
||||
expect(searchTaskTargets).toHaveProperty('petId');
|
||||
expect(searchTaskTargets).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -29,7 +29,8 @@ describe('searchTimelineActivitiesResolver (e2e)', () => {
|
||||
workflowId
|
||||
workflowVersionId
|
||||
workflowRunId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,7 +81,8 @@ describe('searchTimelineActivitiesResolver (e2e)', () => {
|
||||
expect(searchTimelineActivities).toHaveProperty('workflowId');
|
||||
expect(searchTimelineActivities).toHaveProperty('workflowVersionId');
|
||||
expect(searchTimelineActivities).toHaveProperty('workflowRunId');
|
||||
expect(searchTimelineActivities).toHaveProperty('rocketId');
|
||||
expect(searchTimelineActivities).toHaveProperty('petId');
|
||||
expect(searchTimelineActivities).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,7 +18,8 @@ describe('taskTargetsResolver (e2e)', () => {
|
||||
personId
|
||||
companyId
|
||||
opportunityId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,7 +55,8 @@ describe('taskTargetsResolver (e2e)', () => {
|
||||
expect(taskTargets).toHaveProperty('personId');
|
||||
expect(taskTargets).toHaveProperty('companyId');
|
||||
expect(taskTargets).toHaveProperty('opportunityId');
|
||||
expect(taskTargets).toHaveProperty('rocketId');
|
||||
expect(taskTargets).toHaveProperty('petId');
|
||||
expect(taskTargets).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -29,7 +29,8 @@ describe('timelineActivitiesResolver (e2e)', () => {
|
||||
workflowId
|
||||
workflowVersionId
|
||||
workflowRunId
|
||||
rocketId
|
||||
petId
|
||||
surveyResultId
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,7 +77,8 @@ describe('timelineActivitiesResolver (e2e)', () => {
|
||||
expect(timelineActivities).toHaveProperty('workflowId');
|
||||
expect(timelineActivities).toHaveProperty('workflowVersionId');
|
||||
expect(timelineActivities).toHaveProperty('workflowRunId');
|
||||
expect(timelineActivities).toHaveProperty('rocketId');
|
||||
expect(timelineActivities).toHaveProperty('petId');
|
||||
expect(timelineActivities).toHaveProperty('surveyResultId');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user