Remove relations for remotes (#5455)
For remotes, we will only create the foreign key, without the relation metadata. Expected behavior will be: - possible to create an activity. But the remote object will not be displayed in the relations of the activity - the remote objects should not be available in the search for relations Also switched the number settings to an enum, since we now have to handle `BigInt` case. --------- Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
@ -95,6 +95,7 @@
|
|||||||
"graphql-fields": "^2.0.3",
|
"graphql-fields": "^2.0.3",
|
||||||
"graphql-middleware": "^6.1.35",
|
"graphql-middleware": "^6.1.35",
|
||||||
"graphql-rate-limit": "^3.3.0",
|
"graphql-rate-limit": "^3.3.0",
|
||||||
|
"graphql-scalars": "^1.23.0",
|
||||||
"graphql-subscriptions": "2.0.0",
|
"graphql-subscriptions": "2.0.0",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"graphql-type-json": "^0.3.2",
|
"graphql-type-json": "^0.3.2",
|
||||||
|
|||||||
@ -29,19 +29,19 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||||
|
|
||||||
const nonSystemObjectMetadataItems = objectMetadataItems.filter(
|
const selectableObjectMetadataItems = objectMetadataItems.filter(
|
||||||
({ isSystem }) => !isSystem,
|
({ isSystem, isRemote }) => !isSystem && !isRemote,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { searchFilterPerMetadataItemNameSingular } =
|
const { searchFilterPerMetadataItemNameSingular } =
|
||||||
useSearchFilterPerMetadataItem({
|
useSearchFilterPerMetadataItem({
|
||||||
objectMetadataItems: nonSystemObjectMetadataItems,
|
objectMetadataItems: selectableObjectMetadataItems,
|
||||||
searchFilterValue,
|
searchFilterValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
const objectRecordsToSelectAndMatchesSearchFilterTextFilterPerMetadataItem =
|
const objectRecordsToSelectAndMatchesSearchFilterTextFilterPerMetadataItem =
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
nonSystemObjectMetadataItems
|
selectableObjectMetadataItems
|
||||||
.map(({ nameSingular }) => {
|
.map(({ nameSingular }) => {
|
||||||
const selectedIds = selectedObjectRecordIds
|
const selectedIds = selectedObjectRecordIds
|
||||||
.filter(
|
.filter(
|
||||||
@ -74,16 +74,16 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { orderByFieldPerMetadataItem } = useOrderByFieldPerMetadataItem({
|
const { orderByFieldPerMetadataItem } = useOrderByFieldPerMetadataItem({
|
||||||
objectMetadataItems: nonSystemObjectMetadataItems,
|
objectMetadataItems: selectableObjectMetadataItems,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { limitPerMetadataItem } = useLimitPerMetadataItem({
|
const { limitPerMetadataItem } = useLimitPerMetadataItem({
|
||||||
objectMetadataItems: nonSystemObjectMetadataItems,
|
objectMetadataItems: selectableObjectMetadataItems,
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
|
|
||||||
const multiSelectQuery = useGenerateCombinedFindManyRecordsQuery({
|
const multiSelectQuery = useGenerateCombinedFindManyRecordsQuery({
|
||||||
operationSignatures: nonSystemObjectMetadataItems.map(
|
operationSignatures: selectableObjectMetadataItems.map(
|
||||||
(objectMetadataItem) => ({
|
(objectMetadataItem) => ({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
variables: {},
|
variables: {},
|
||||||
|
|||||||
@ -1,22 +1,18 @@
|
|||||||
import {
|
import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql';
|
||||||
GraphQLInputObjectType,
|
import { GraphQLBigInt } from 'graphql-scalars';
|
||||||
GraphQLList,
|
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLInt,
|
|
||||||
} from 'graphql';
|
|
||||||
|
|
||||||
import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type';
|
import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type';
|
||||||
|
|
||||||
export const BigIntFilterType = new GraphQLInputObjectType({
|
export const BigIntFilterType = new GraphQLInputObjectType({
|
||||||
name: 'BigIntFilter',
|
name: 'BigIntFilter',
|
||||||
fields: {
|
fields: {
|
||||||
eq: { type: GraphQLInt },
|
eq: { type: GraphQLBigInt },
|
||||||
gt: { type: GraphQLInt },
|
gt: { type: GraphQLBigInt },
|
||||||
gte: { type: GraphQLInt },
|
gte: { type: GraphQLBigInt },
|
||||||
in: { type: new GraphQLList(new GraphQLNonNull(GraphQLInt)) },
|
in: { type: new GraphQLList(new GraphQLNonNull(GraphQLBigInt)) },
|
||||||
lt: { type: GraphQLInt },
|
lt: { type: GraphQLBigInt },
|
||||||
lte: { type: GraphQLInt },
|
lte: { type: GraphQLBigInt },
|
||||||
neq: { type: GraphQLInt },
|
neq: { type: GraphQLBigInt },
|
||||||
is: { type: FilterIs },
|
is: { type: FilterIs },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import {
|
|||||||
GraphQLID,
|
GraphQLID,
|
||||||
GraphQLInputObjectType,
|
GraphQLInputObjectType,
|
||||||
GraphQLInputType,
|
GraphQLInputType,
|
||||||
GraphQLInt,
|
|
||||||
GraphQLList,
|
GraphQLList,
|
||||||
GraphQLNonNull,
|
GraphQLNonNull,
|
||||||
GraphQLScalarType,
|
GraphQLScalarType,
|
||||||
@ -26,7 +25,6 @@ import {
|
|||||||
BooleanFilterType,
|
BooleanFilterType,
|
||||||
BigFloatFilterType,
|
BigFloatFilterType,
|
||||||
RawJsonFilterType,
|
RawJsonFilterType,
|
||||||
IntFilterType,
|
|
||||||
} from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input';
|
} from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input';
|
||||||
import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum';
|
import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum';
|
||||||
import {
|
import {
|
||||||
@ -36,6 +34,8 @@ import {
|
|||||||
import { PositionScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar';
|
import { PositionScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar';
|
||||||
import { RawJSONScalar } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/raw-json.scalar';
|
import { RawJSONScalar } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/raw-json.scalar';
|
||||||
import { IDFilterType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/id-filter.input-type';
|
import { IDFilterType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/id-filter.input-type';
|
||||||
|
import { getNumberFilterType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-number-filter-type.util';
|
||||||
|
import { getNumberScalarType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-number-scalar-type.util';
|
||||||
|
|
||||||
export interface TypeOptions<T = any> {
|
export interface TypeOptions<T = any> {
|
||||||
nullable?: boolean;
|
nullable?: boolean;
|
||||||
@ -57,13 +57,6 @@ export class TypeMapperService {
|
|||||||
return GraphQLID;
|
return GraphQLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberScalar =
|
|
||||||
fieldMetadataType === FieldMetadataType.NUMBER &&
|
|
||||||
(settings as FieldMetadataSettings<FieldMetadataType.NUMBER>)
|
|
||||||
?.precision === 0
|
|
||||||
? GraphQLInt
|
|
||||||
: GraphQLFloat;
|
|
||||||
|
|
||||||
const typeScalarMapping = new Map<FieldMetadataType, GraphQLScalarType>([
|
const typeScalarMapping = new Map<FieldMetadataType, GraphQLScalarType>([
|
||||||
[FieldMetadataType.UUID, UUIDScalarType],
|
[FieldMetadataType.UUID, UUIDScalarType],
|
||||||
[FieldMetadataType.TEXT, GraphQLString],
|
[FieldMetadataType.TEXT, GraphQLString],
|
||||||
@ -72,7 +65,13 @@ export class TypeMapperService {
|
|||||||
[FieldMetadataType.DATE_TIME, GraphQLISODateTime],
|
[FieldMetadataType.DATE_TIME, GraphQLISODateTime],
|
||||||
[FieldMetadataType.DATE, GraphQLISODateTime],
|
[FieldMetadataType.DATE, GraphQLISODateTime],
|
||||||
[FieldMetadataType.BOOLEAN, GraphQLBoolean],
|
[FieldMetadataType.BOOLEAN, GraphQLBoolean],
|
||||||
[FieldMetadataType.NUMBER, numberScalar],
|
[
|
||||||
|
FieldMetadataType.NUMBER,
|
||||||
|
getNumberScalarType(
|
||||||
|
(settings as FieldMetadataSettings<FieldMetadataType.NUMBER>)
|
||||||
|
?.dataType,
|
||||||
|
),
|
||||||
|
],
|
||||||
[FieldMetadataType.NUMERIC, BigFloatScalarType],
|
[FieldMetadataType.NUMERIC, BigFloatScalarType],
|
||||||
[FieldMetadataType.PROBABILITY, GraphQLFloat],
|
[FieldMetadataType.PROBABILITY, GraphQLFloat],
|
||||||
[FieldMetadataType.POSITION, PositionScalarType],
|
[FieldMetadataType.POSITION, PositionScalarType],
|
||||||
@ -91,13 +90,6 @@ export class TypeMapperService {
|
|||||||
return IDFilterType;
|
return IDFilterType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberScalar =
|
|
||||||
fieldMetadataType === FieldMetadataType.NUMBER &&
|
|
||||||
(settings as FieldMetadataSettings<FieldMetadataType.NUMBER>)
|
|
||||||
?.precision === 0
|
|
||||||
? IntFilterType
|
|
||||||
: FloatFilterType;
|
|
||||||
|
|
||||||
const typeFilterMapping = new Map<
|
const typeFilterMapping = new Map<
|
||||||
FieldMetadataType,
|
FieldMetadataType,
|
||||||
GraphQLInputObjectType | GraphQLScalarType
|
GraphQLInputObjectType | GraphQLScalarType
|
||||||
@ -109,7 +101,13 @@ export class TypeMapperService {
|
|||||||
[FieldMetadataType.DATE_TIME, DateFilterType],
|
[FieldMetadataType.DATE_TIME, DateFilterType],
|
||||||
[FieldMetadataType.DATE, DateFilterType],
|
[FieldMetadataType.DATE, DateFilterType],
|
||||||
[FieldMetadataType.BOOLEAN, BooleanFilterType],
|
[FieldMetadataType.BOOLEAN, BooleanFilterType],
|
||||||
[FieldMetadataType.NUMBER, numberScalar],
|
[
|
||||||
|
FieldMetadataType.NUMBER,
|
||||||
|
getNumberFilterType(
|
||||||
|
(settings as FieldMetadataSettings<FieldMetadataType.NUMBER>)
|
||||||
|
?.dataType,
|
||||||
|
),
|
||||||
|
],
|
||||||
[FieldMetadataType.NUMERIC, BigFloatFilterType],
|
[FieldMetadataType.NUMERIC, BigFloatFilterType],
|
||||||
[FieldMetadataType.PROBABILITY, FloatFilterType],
|
[FieldMetadataType.PROBABILITY, FloatFilterType],
|
||||||
[FieldMetadataType.POSITION, FloatFilterType],
|
[FieldMetadataType.POSITION, FloatFilterType],
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { GraphQLInputObjectType } from 'graphql';
|
||||||
|
|
||||||
|
import { NumberDataType } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BigIntFilterType,
|
||||||
|
FloatFilterType,
|
||||||
|
IntFilterType,
|
||||||
|
} from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input';
|
||||||
|
|
||||||
|
export const getNumberFilterType = (
|
||||||
|
subType: NumberDataType | undefined,
|
||||||
|
): GraphQLInputObjectType => {
|
||||||
|
switch (subType) {
|
||||||
|
case NumberDataType.FLOAT:
|
||||||
|
return FloatFilterType;
|
||||||
|
case NumberDataType.BIGINT:
|
||||||
|
return BigIntFilterType;
|
||||||
|
case NumberDataType.INT:
|
||||||
|
return IntFilterType;
|
||||||
|
default:
|
||||||
|
return FloatFilterType;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { GraphQLInt, GraphQLFloat, GraphQLScalarType } from 'graphql';
|
||||||
|
import { GraphQLBigInt } from 'graphql-scalars';
|
||||||
|
|
||||||
|
import { NumberDataType } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
||||||
|
|
||||||
|
export const getNumberScalarType = (
|
||||||
|
dataType: NumberDataType,
|
||||||
|
): GraphQLScalarType => {
|
||||||
|
switch (dataType) {
|
||||||
|
case NumberDataType.FLOAT:
|
||||||
|
return GraphQLFloat;
|
||||||
|
case NumberDataType.BIGINT:
|
||||||
|
return GraphQLBigInt;
|
||||||
|
case NumberDataType.INT:
|
||||||
|
return GraphQLInt;
|
||||||
|
default:
|
||||||
|
return GraphQLFloat;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,11 +1,17 @@
|
|||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
|
||||||
|
export enum NumberDataType {
|
||||||
|
FLOAT = 'float',
|
||||||
|
INT = 'int',
|
||||||
|
BIGINT = 'bigint',
|
||||||
|
}
|
||||||
|
|
||||||
type FieldMetadataDefaultSettings = {
|
type FieldMetadataDefaultSettings = {
|
||||||
isForeignKey?: boolean;
|
isForeignKey?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FieldMetadataNumberSettings = {
|
type FieldMetadataNumberSettings = {
|
||||||
precision: number;
|
dataType: NumberDataType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FieldMetadataSettingsMapping = {
|
type FieldMetadataSettingsMapping = {
|
||||||
|
|||||||
@ -8,12 +8,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
|
|
||||||
import console from 'console';
|
import console from 'console';
|
||||||
|
|
||||||
import {
|
import { FindManyOptions, FindOneOptions, Repository } from 'typeorm';
|
||||||
DataSource,
|
|
||||||
FindManyOptions,
|
|
||||||
FindOneOptions,
|
|
||||||
Repository,
|
|
||||||
} from 'typeorm';
|
|
||||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||||
import { Query, QueryOptions } from '@ptc-org/nestjs-query-core';
|
import { Query, QueryOptions } from '@ptc-org/nestjs-query-core';
|
||||||
|
|
||||||
@ -57,7 +52,6 @@ import {
|
|||||||
import { createWorkspaceMigrationsForCustomObjectRelations } from 'src/engine/metadata-modules/object-metadata/utils/create-migrations-for-custom-object-relations.util';
|
import { createWorkspaceMigrationsForCustomObjectRelations } from 'src/engine/metadata-modules/object-metadata/utils/create-migrations-for-custom-object-relations.util';
|
||||||
import { createWorkspaceMigrationsForRemoteObjectRelations } from 'src/engine/metadata-modules/object-metadata/utils/create-workspace-migrations-for-remote-object-relations.util';
|
import { createWorkspaceMigrationsForRemoteObjectRelations } from 'src/engine/metadata-modules/object-metadata/utils/create-workspace-migrations-for-remote-object-relations.util';
|
||||||
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||||
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
|
|
||||||
import { validateObjectMetadataInputOrThrow } from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util';
|
import { validateObjectMetadataInputOrThrow } from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util';
|
||||||
import { mapUdtNameToFieldType } from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util';
|
import { mapUdtNameToFieldType } from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util';
|
||||||
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||||
@ -380,9 +374,6 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
await this.createObjectRelationsMetadataAndMigrations(
|
await this.createObjectRelationsMetadataAndMigrations(
|
||||||
objectMetadataInput,
|
objectMetadataInput,
|
||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
lastDataSourceMetadata,
|
|
||||||
workspaceDataSource,
|
|
||||||
objectMetadataInput.isRemote,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||||
@ -515,10 +506,9 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
private async createObjectRelationsMetadataAndMigrations(
|
private async createObjectRelationsMetadataAndMigrations(
|
||||||
objectMetadataInput: CreateObjectInput,
|
objectMetadataInput: CreateObjectInput,
|
||||||
createdObjectMetadata: ObjectMetadataEntity,
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
lastDataSourceMetadata: DataSourceEntity,
|
|
||||||
workspaceDataSource: DataSource | undefined,
|
|
||||||
isRemoteObject = false,
|
|
||||||
) {
|
) {
|
||||||
|
const isRemoteObject = objectMetadataInput.isRemote ?? false;
|
||||||
|
|
||||||
const { timelineActivityObjectMetadata } =
|
const { timelineActivityObjectMetadata } =
|
||||||
await this.createTimelineActivityRelation(
|
await this.createTimelineActivityRelation(
|
||||||
objectMetadataInput.workspaceId,
|
objectMetadataInput.workspaceId,
|
||||||
@ -527,6 +517,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
||||||
),
|
),
|
||||||
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
||||||
|
isRemoteObject,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { activityTargetObjectMetadata } =
|
const { activityTargetObjectMetadata } =
|
||||||
@ -537,6 +528,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
||||||
),
|
),
|
||||||
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
||||||
|
isRemoteObject,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { favoriteObjectMetadata } = await this.createFavoriteRelation(
|
const { favoriteObjectMetadata } = await this.createFavoriteRelation(
|
||||||
@ -544,6 +536,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
mapUdtNameToFieldType(objectMetadataInput.primaryKeyColumnType ?? 'uuid'),
|
mapUdtNameToFieldType(objectMetadataInput.primaryKeyColumnType ?? 'uuid'),
|
||||||
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
||||||
|
isRemoteObject,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { attachmentObjectMetadata } = await this.createAttachmentRelation(
|
const { attachmentObjectMetadata } = await this.createAttachmentRelation(
|
||||||
@ -551,6 +544,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
mapUdtNameToFieldType(objectMetadataInput.primaryKeyColumnType ?? 'uuid'),
|
mapUdtNameToFieldType(objectMetadataInput.primaryKeyColumnType ?? 'uuid'),
|
||||||
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
objectMetadataInput.primaryKeyFieldMetadataSettings,
|
||||||
|
isRemoteObject,
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.workspaceMigrationService.createCustomMigration(
|
return this.workspaceMigrationService.createCustomMigration(
|
||||||
@ -563,9 +557,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
attachmentObjectMetadata,
|
attachmentObjectMetadata,
|
||||||
timelineActivityObjectMetadata,
|
timelineActivityObjectMetadata,
|
||||||
favoriteObjectMetadata,
|
favoriteObjectMetadata,
|
||||||
lastDataSourceMetadata.schema,
|
|
||||||
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
objectMetadataInput.primaryKeyColumnType ?? 'uuid',
|
||||||
workspaceDataSource,
|
|
||||||
)
|
)
|
||||||
: createWorkspaceMigrationsForCustomObjectRelations(
|
: createWorkspaceMigrationsForCustomObjectRelations(
|
||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
@ -584,6 +576,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectPrimaryKeyFieldSettings:
|
objectPrimaryKeyFieldSettings:
|
||||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||||
| undefined,
|
| undefined,
|
||||||
|
isRemoteObject: boolean,
|
||||||
) {
|
) {
|
||||||
const activityTargetObjectMetadata =
|
const activityTargetObjectMetadata =
|
||||||
await this.objectMetadataRepository.findOneByOrFail({
|
await this.objectMetadataRepository.findOneByOrFail({
|
||||||
@ -591,88 +584,93 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const activityTargetRelationFieldMetadata =
|
await this.fieldMetadataRepository.save(
|
||||||
await this.fieldMetadataRepository.save([
|
// Foreign key
|
||||||
// FROM
|
{
|
||||||
|
standardId: createForeignKeyDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: activityTargetObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: objectPrimaryKeyType,
|
||||||
|
name: `${createdObjectMetadata.nameSingular}Id`,
|
||||||
|
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
||||||
|
description: `ActivityTarget ${createdObjectMetadata.labelSingular} id foreign key`,
|
||||||
|
icon: undefined,
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: true,
|
||||||
|
defaultValue: undefined,
|
||||||
|
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isRemoteObject) {
|
||||||
|
const activityTargetRelationFieldMetadata =
|
||||||
|
await this.fieldMetadataRepository.save([
|
||||||
|
// FROM
|
||||||
|
{
|
||||||
|
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.activityTargets,
|
||||||
|
objectMetadataId: createdObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: 'activityTargets',
|
||||||
|
label: 'Activities',
|
||||||
|
description: `Activities tied to the ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconCheckbox',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// TO
|
||||||
|
{
|
||||||
|
standardId: createRelationDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: activityTargetObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: createdObjectMetadata.nameSingular,
|
||||||
|
label: createdObjectMetadata.labelSingular,
|
||||||
|
description: `ActivityTarget ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconBuildingSkyscraper',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const activityTargetRelationFieldMetadataMap =
|
||||||
|
activityTargetRelationFieldMetadata.reduce(
|
||||||
|
(acc, fieldMetadata: FieldMetadataEntity) => {
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.relationMetadataRepository.save([
|
||||||
{
|
{
|
||||||
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.activityTargets,
|
|
||||||
objectMetadataId: createdObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
isCustom: false,
|
relationType: RelationMetadataType.ONE_TO_MANY,
|
||||||
isActive: true,
|
fromObjectMetadataId: createdObjectMetadata.id,
|
||||||
type: FieldMetadataType.RELATION,
|
toObjectMetadataId: activityTargetObjectMetadata.id,
|
||||||
name: 'activityTargets',
|
fromFieldMetadataId:
|
||||||
label: 'Activities',
|
activityTargetRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
||||||
description: `Activities tied to the ${createdObjectMetadata.labelSingular}`,
|
toFieldMetadataId:
|
||||||
icon: 'IconCheckbox',
|
activityTargetRelationFieldMetadataMap[
|
||||||
isNullable: true,
|
activityTargetObjectMetadata.id
|
||||||
},
|
].id,
|
||||||
// TO
|
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
||||||
{
|
|
||||||
standardId: createRelationDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: activityTargetObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: FieldMetadataType.RELATION,
|
|
||||||
name: createdObjectMetadata.nameSingular,
|
|
||||||
label: createdObjectMetadata.labelSingular,
|
|
||||||
description: `ActivityTarget ${createdObjectMetadata.labelSingular}`,
|
|
||||||
icon: 'IconBuildingSkyscraper',
|
|
||||||
isNullable: true,
|
|
||||||
},
|
|
||||||
// Foreign key
|
|
||||||
{
|
|
||||||
standardId: createForeignKeyDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: activityTargetObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: objectPrimaryKeyType,
|
|
||||||
name: `${createdObjectMetadata.nameSingular}Id`,
|
|
||||||
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
|
||||||
description: `ActivityTarget ${createdObjectMetadata.labelSingular} id foreign key`,
|
|
||||||
icon: undefined,
|
|
||||||
isNullable: true,
|
|
||||||
isSystem: true,
|
|
||||||
defaultValue: undefined,
|
|
||||||
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
const activityTargetRelationFieldMetadataMap =
|
|
||||||
activityTargetRelationFieldMetadata.reduce(
|
|
||||||
(acc, fieldMetadata: FieldMetadataEntity) => {
|
|
||||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
|
||||||
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.relationMetadataRepository.save([
|
|
||||||
{
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
relationType: RelationMetadataType.ONE_TO_MANY,
|
|
||||||
fromObjectMetadataId: createdObjectMetadata.id,
|
|
||||||
toObjectMetadataId: activityTargetObjectMetadata.id,
|
|
||||||
fromFieldMetadataId:
|
|
||||||
activityTargetRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
|
||||||
toFieldMetadataId:
|
|
||||||
activityTargetRelationFieldMetadataMap[
|
|
||||||
activityTargetObjectMetadata.id
|
|
||||||
].id,
|
|
||||||
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { activityTargetObjectMetadata };
|
return { activityTargetObjectMetadata };
|
||||||
}
|
}
|
||||||
@ -684,6 +682,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectPrimaryKeyFieldSettings:
|
objectPrimaryKeyFieldSettings:
|
||||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||||
| undefined,
|
| undefined,
|
||||||
|
isRemoteObject: boolean,
|
||||||
) {
|
) {
|
||||||
const attachmentObjectMetadata =
|
const attachmentObjectMetadata =
|
||||||
await this.objectMetadataRepository.findOneByOrFail({
|
await this.objectMetadataRepository.findOneByOrFail({
|
||||||
@ -691,86 +690,91 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const attachmentRelationFieldMetadata =
|
await this.fieldMetadataRepository.save(
|
||||||
await this.fieldMetadataRepository.save([
|
// Foreign key
|
||||||
// FROM
|
{
|
||||||
|
standardId: createForeignKeyDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: ATTACHMENT_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: attachmentObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: objectPrimaryKeyType,
|
||||||
|
name: `${createdObjectMetadata.nameSingular}Id`,
|
||||||
|
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
||||||
|
description: `Attachment ${createdObjectMetadata.labelSingular} id foreign key`,
|
||||||
|
icon: undefined,
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: true,
|
||||||
|
defaultValue: undefined,
|
||||||
|
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isRemoteObject) {
|
||||||
|
const attachmentRelationFieldMetadata =
|
||||||
|
await this.fieldMetadataRepository.save([
|
||||||
|
// FROM
|
||||||
|
{
|
||||||
|
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.attachments,
|
||||||
|
objectMetadataId: createdObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: 'attachments',
|
||||||
|
label: 'Attachments',
|
||||||
|
description: `Attachments tied to the ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconFileImport',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// TO
|
||||||
|
{
|
||||||
|
standardId: createRelationDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: ATTACHMENT_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: attachmentObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: createdObjectMetadata.nameSingular,
|
||||||
|
label: createdObjectMetadata.labelSingular,
|
||||||
|
description: `Attachment ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconBuildingSkyscraper',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const attachmentRelationFieldMetadataMap =
|
||||||
|
attachmentRelationFieldMetadata.reduce(
|
||||||
|
(acc, fieldMetadata: FieldMetadataEntity) => {
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.relationMetadataRepository.save([
|
||||||
{
|
{
|
||||||
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.attachments,
|
|
||||||
objectMetadataId: createdObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
isCustom: false,
|
relationType: RelationMetadataType.ONE_TO_MANY,
|
||||||
isActive: true,
|
fromObjectMetadataId: createdObjectMetadata.id,
|
||||||
type: FieldMetadataType.RELATION,
|
toObjectMetadataId: attachmentObjectMetadata.id,
|
||||||
name: 'attachments',
|
fromFieldMetadataId:
|
||||||
label: 'Attachments',
|
attachmentRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
||||||
description: `Attachments tied to the ${createdObjectMetadata.labelSingular}`,
|
toFieldMetadataId:
|
||||||
icon: 'IconFileImport',
|
attachmentRelationFieldMetadataMap[attachmentObjectMetadata.id].id,
|
||||||
isNullable: true,
|
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
||||||
},
|
|
||||||
// TO
|
|
||||||
{
|
|
||||||
standardId: createRelationDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: ATTACHMENT_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: attachmentObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: FieldMetadataType.RELATION,
|
|
||||||
name: createdObjectMetadata.nameSingular,
|
|
||||||
label: createdObjectMetadata.labelSingular,
|
|
||||||
description: `Attachment ${createdObjectMetadata.labelSingular}`,
|
|
||||||
icon: 'IconBuildingSkyscraper',
|
|
||||||
isNullable: true,
|
|
||||||
},
|
|
||||||
// Foreign key
|
|
||||||
{
|
|
||||||
standardId: createForeignKeyDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: ATTACHMENT_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: attachmentObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: objectPrimaryKeyType,
|
|
||||||
name: `${createdObjectMetadata.nameSingular}Id`,
|
|
||||||
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
|
||||||
description: `Attachment ${createdObjectMetadata.labelSingular} id foreign key`,
|
|
||||||
icon: undefined,
|
|
||||||
isNullable: true,
|
|
||||||
isSystem: true,
|
|
||||||
defaultValue: undefined,
|
|
||||||
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
const attachmentRelationFieldMetadataMap =
|
|
||||||
attachmentRelationFieldMetadata.reduce(
|
|
||||||
(acc, fieldMetadata: FieldMetadataEntity) => {
|
|
||||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
|
||||||
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.relationMetadataRepository.save([
|
|
||||||
{
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
relationType: RelationMetadataType.ONE_TO_MANY,
|
|
||||||
fromObjectMetadataId: createdObjectMetadata.id,
|
|
||||||
toObjectMetadataId: attachmentObjectMetadata.id,
|
|
||||||
fromFieldMetadataId:
|
|
||||||
attachmentRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
|
||||||
toFieldMetadataId:
|
|
||||||
attachmentRelationFieldMetadataMap[attachmentObjectMetadata.id].id,
|
|
||||||
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { attachmentObjectMetadata };
|
return { attachmentObjectMetadata };
|
||||||
}
|
}
|
||||||
@ -782,6 +786,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectPrimaryKeyFieldSettings:
|
objectPrimaryKeyFieldSettings:
|
||||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||||
| undefined,
|
| undefined,
|
||||||
|
isRemoteObject: boolean,
|
||||||
) {
|
) {
|
||||||
const timelineActivityObjectMetadata =
|
const timelineActivityObjectMetadata =
|
||||||
await this.objectMetadataRepository.findOneByOrFail({
|
await this.objectMetadataRepository.findOneByOrFail({
|
||||||
@ -789,88 +794,94 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const timelineActivityRelationFieldMetadata =
|
await this.fieldMetadataRepository.save(
|
||||||
await this.fieldMetadataRepository.save([
|
// Foreign key
|
||||||
// FROM
|
{
|
||||||
|
standardId: createForeignKeyDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: timelineActivityObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: objectPrimaryKeyType,
|
||||||
|
name: `${createdObjectMetadata.nameSingular}Id`,
|
||||||
|
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
||||||
|
description: `Timeline Activity ${createdObjectMetadata.labelSingular} id foreign key`,
|
||||||
|
icon: undefined,
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: true,
|
||||||
|
defaultValue: undefined,
|
||||||
|
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isRemoteObject) {
|
||||||
|
const timelineActivityRelationFieldMetadata =
|
||||||
|
await this.fieldMetadataRepository.save([
|
||||||
|
// FROM
|
||||||
|
{
|
||||||
|
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.timelineActivities,
|
||||||
|
objectMetadataId: createdObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: 'timelineActivities',
|
||||||
|
label: 'Timeline Activities',
|
||||||
|
description: `Timeline Activities tied to the ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconTimeline',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// TO
|
||||||
|
{
|
||||||
|
standardId: createRelationDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: timelineActivityObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: createdObjectMetadata.nameSingular,
|
||||||
|
label: createdObjectMetadata.labelSingular,
|
||||||
|
description: `Timeline Activity ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconBuildingSkyscraper',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const timelineActivityRelationFieldMetadataMap =
|
||||||
|
timelineActivityRelationFieldMetadata.reduce(
|
||||||
|
(acc, fieldMetadata: FieldMetadataEntity) => {
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.relationMetadataRepository.save([
|
||||||
{
|
{
|
||||||
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.timelineActivities,
|
|
||||||
objectMetadataId: createdObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
isCustom: false,
|
relationType: RelationMetadataType.ONE_TO_MANY,
|
||||||
isActive: true,
|
fromObjectMetadataId: createdObjectMetadata.id,
|
||||||
type: FieldMetadataType.RELATION,
|
toObjectMetadataId: timelineActivityObjectMetadata.id,
|
||||||
name: 'timelineActivities',
|
fromFieldMetadataId:
|
||||||
label: 'Timeline Activities',
|
timelineActivityRelationFieldMetadataMap[createdObjectMetadata.id]
|
||||||
description: `Timeline Activities tied to the ${createdObjectMetadata.labelSingular}`,
|
.id,
|
||||||
icon: 'IconTimeline',
|
toFieldMetadataId:
|
||||||
isNullable: true,
|
timelineActivityRelationFieldMetadataMap[
|
||||||
},
|
timelineActivityObjectMetadata.id
|
||||||
// TO
|
].id,
|
||||||
{
|
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
||||||
standardId: createRelationDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: timelineActivityObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: FieldMetadataType.RELATION,
|
|
||||||
name: createdObjectMetadata.nameSingular,
|
|
||||||
label: createdObjectMetadata.labelSingular,
|
|
||||||
description: `Timeline Activity ${createdObjectMetadata.labelSingular}`,
|
|
||||||
icon: 'IconBuildingSkyscraper',
|
|
||||||
isNullable: true,
|
|
||||||
},
|
|
||||||
// Foreign key
|
|
||||||
{
|
|
||||||
standardId: createForeignKeyDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: timelineActivityObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: objectPrimaryKeyType,
|
|
||||||
name: `${createdObjectMetadata.nameSingular}Id`,
|
|
||||||
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
|
||||||
description: `Timeline Activity ${createdObjectMetadata.labelSingular} id foreign key`,
|
|
||||||
icon: undefined,
|
|
||||||
isNullable: true,
|
|
||||||
isSystem: true,
|
|
||||||
defaultValue: undefined,
|
|
||||||
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
const timelineActivityRelationFieldMetadataMap =
|
|
||||||
timelineActivityRelationFieldMetadata.reduce(
|
|
||||||
(acc, fieldMetadata: FieldMetadataEntity) => {
|
|
||||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
|
||||||
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.relationMetadataRepository.save([
|
|
||||||
{
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
relationType: RelationMetadataType.ONE_TO_MANY,
|
|
||||||
fromObjectMetadataId: createdObjectMetadata.id,
|
|
||||||
toObjectMetadataId: timelineActivityObjectMetadata.id,
|
|
||||||
fromFieldMetadataId:
|
|
||||||
timelineActivityRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
|
||||||
toFieldMetadataId:
|
|
||||||
timelineActivityRelationFieldMetadataMap[
|
|
||||||
timelineActivityObjectMetadata.id
|
|
||||||
].id,
|
|
||||||
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { timelineActivityObjectMetadata };
|
return { timelineActivityObjectMetadata };
|
||||||
}
|
}
|
||||||
@ -882,6 +893,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
objectPrimaryKeyFieldSettings:
|
objectPrimaryKeyFieldSettings:
|
||||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||||
| undefined,
|
| undefined,
|
||||||
|
isRemoteObject: boolean,
|
||||||
) {
|
) {
|
||||||
const favoriteObjectMetadata =
|
const favoriteObjectMetadata =
|
||||||
await this.objectMetadataRepository.findOneByOrFail({
|
await this.objectMetadataRepository.findOneByOrFail({
|
||||||
@ -889,87 +901,92 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const favoriteRelationFieldMetadata =
|
await this.fieldMetadataRepository.save(
|
||||||
await this.fieldMetadataRepository.save([
|
// Foreign key
|
||||||
// FROM
|
{
|
||||||
|
standardId: createForeignKeyDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: FAVORITE_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: favoriteObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: objectPrimaryKeyType,
|
||||||
|
name: `${createdObjectMetadata.nameSingular}Id`,
|
||||||
|
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
||||||
|
description: `Favorite ${createdObjectMetadata.labelSingular} id foreign key`,
|
||||||
|
icon: undefined,
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: true,
|
||||||
|
defaultValue: undefined,
|
||||||
|
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isRemoteObject) {
|
||||||
|
const favoriteRelationFieldMetadata =
|
||||||
|
await this.fieldMetadataRepository.save([
|
||||||
|
// FROM
|
||||||
|
{
|
||||||
|
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.favorites,
|
||||||
|
objectMetadataId: createdObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
isSystem: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: 'favorites',
|
||||||
|
label: 'Favorites',
|
||||||
|
description: `Favorites tied to the ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconHeart',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// TO
|
||||||
|
{
|
||||||
|
standardId: createRelationDeterministicUuid({
|
||||||
|
objectId: createdObjectMetadata.id,
|
||||||
|
standardId: FAVORITE_STANDARD_FIELD_IDS.custom,
|
||||||
|
}),
|
||||||
|
objectMetadataId: favoriteObjectMetadata.id,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: createdObjectMetadata.nameSingular,
|
||||||
|
label: createdObjectMetadata.labelSingular,
|
||||||
|
description: `Favorite ${createdObjectMetadata.labelSingular}`,
|
||||||
|
icon: 'IconBuildingSkyscraper',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const favoriteRelationFieldMetadataMap =
|
||||||
|
favoriteRelationFieldMetadata.reduce(
|
||||||
|
(acc, fieldMetadata: FieldMetadataEntity) => {
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.relationMetadataRepository.save([
|
||||||
{
|
{
|
||||||
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.favorites,
|
|
||||||
objectMetadataId: createdObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
isCustom: false,
|
relationType: RelationMetadataType.ONE_TO_MANY,
|
||||||
isActive: true,
|
fromObjectMetadataId: createdObjectMetadata.id,
|
||||||
isSystem: true,
|
toObjectMetadataId: favoriteObjectMetadata.id,
|
||||||
type: FieldMetadataType.RELATION,
|
fromFieldMetadataId:
|
||||||
name: 'favorites',
|
favoriteRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
||||||
label: 'Favorites',
|
toFieldMetadataId:
|
||||||
description: `Favorites tied to the ${createdObjectMetadata.labelSingular}`,
|
favoriteRelationFieldMetadataMap[favoriteObjectMetadata.id].id,
|
||||||
icon: 'IconHeart',
|
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
||||||
isNullable: true,
|
|
||||||
},
|
|
||||||
// TO
|
|
||||||
{
|
|
||||||
standardId: createRelationDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: FAVORITE_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: favoriteObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: FieldMetadataType.RELATION,
|
|
||||||
name: createdObjectMetadata.nameSingular,
|
|
||||||
label: createdObjectMetadata.labelSingular,
|
|
||||||
description: `Favorite ${createdObjectMetadata.labelSingular}`,
|
|
||||||
icon: 'IconBuildingSkyscraper',
|
|
||||||
isNullable: true,
|
|
||||||
},
|
|
||||||
// Foreign key
|
|
||||||
{
|
|
||||||
standardId: createForeignKeyDeterministicUuid({
|
|
||||||
objectId: createdObjectMetadata.id,
|
|
||||||
standardId: FAVORITE_STANDARD_FIELD_IDS.custom,
|
|
||||||
}),
|
|
||||||
objectMetadataId: favoriteObjectMetadata.id,
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
isCustom: false,
|
|
||||||
isActive: true,
|
|
||||||
type: objectPrimaryKeyType,
|
|
||||||
name: `${createdObjectMetadata.nameSingular}Id`,
|
|
||||||
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
|
|
||||||
description: `Favorite ${createdObjectMetadata.labelSingular} id foreign key`,
|
|
||||||
icon: undefined,
|
|
||||||
isNullable: true,
|
|
||||||
isSystem: true,
|
|
||||||
defaultValue: undefined,
|
|
||||||
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
const favoriteRelationFieldMetadataMap =
|
|
||||||
favoriteRelationFieldMetadata.reduce(
|
|
||||||
(acc, fieldMetadata: FieldMetadataEntity) => {
|
|
||||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
|
||||||
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.relationMetadataRepository.save([
|
|
||||||
{
|
|
||||||
workspaceId: workspaceId,
|
|
||||||
relationType: RelationMetadataType.ONE_TO_MANY,
|
|
||||||
fromObjectMetadataId: createdObjectMetadata.id,
|
|
||||||
toObjectMetadataId: favoriteObjectMetadata.id,
|
|
||||||
fromFieldMetadataId:
|
|
||||||
favoriteRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
|
||||||
toFieldMetadataId:
|
|
||||||
favoriteRelationFieldMetadataMap[favoriteObjectMetadata.id].id,
|
|
||||||
onDeleteAction: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { favoriteObjectMetadata };
|
return { favoriteObjectMetadata };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export const createWorkspaceMigrationsForCustomObjectRelations = (
|
|||||||
createdObjectMetadata: ObjectMetadataEntity,
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
activityTargetObjectMetadata: ObjectMetadataEntity,
|
activityTargetObjectMetadata: ObjectMetadataEntity,
|
||||||
attachmentObjectMetadata: ObjectMetadataEntity,
|
attachmentObjectMetadata: ObjectMetadataEntity,
|
||||||
eventObjectMetadata: ObjectMetadataEntity,
|
timelineActivityObjectMetadata: ObjectMetadataEntity,
|
||||||
favoriteObjectMetadata: ObjectMetadataEntity,
|
favoriteObjectMetadata: ObjectMetadataEntity,
|
||||||
): WorkspaceMigrationTableAction[] => [
|
): WorkspaceMigrationTableAction[] => [
|
||||||
{
|
{
|
||||||
@ -80,9 +80,9 @@ export const createWorkspaceMigrationsForCustomObjectRelations = (
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// Add event relation
|
// Add timeline activity relation
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
name: computeObjectTargetTable(timelineActivityObjectMetadata),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ export const createWorkspaceMigrationsForCustomObjectRelations = (
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
name: computeObjectTargetTable(timelineActivityObjectMetadata),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { DataSource } from 'typeorm';
|
|
||||||
|
|
||||||
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||||
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 {
|
import {
|
||||||
@ -10,55 +8,14 @@ import {
|
|||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
|
|
||||||
const buildCommentForRemoteObjectForeignKey = async (
|
|
||||||
localObjectMetadataName: string,
|
|
||||||
remoteObjectMetadataName: string,
|
|
||||||
schema: string,
|
|
||||||
workspaceDataSource: DataSource | undefined,
|
|
||||||
): Promise<string> => {
|
|
||||||
const existingComment = await workspaceDataSource?.query(
|
|
||||||
`SELECT col_description('${schema}."${localObjectMetadataName}"'::regclass, 0)`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!existingComment[0]?.col_description) {
|
|
||||||
return `@graphql({"totalCount":{"enabled": true},"foreign_keys":[{"local_name":"${localObjectMetadataName}Collection","local_columns":["${remoteObjectMetadataName}Id"],"foreign_name":"${remoteObjectMetadataName}","foreign_schema":"${schema}","foreign_table":"${remoteObjectMetadataName}","foreign_columns":["id"]}]})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const commentWithoutGraphQL = existingComment[0].col_description
|
|
||||||
.replace('@graphql(', '')
|
|
||||||
.replace(')', '');
|
|
||||||
const parsedComment = JSON.parse(commentWithoutGraphQL);
|
|
||||||
|
|
||||||
const foreignKey = {
|
|
||||||
local_name: `${localObjectMetadataName}Collection`,
|
|
||||||
local_columns: [`${remoteObjectMetadataName}Id`],
|
|
||||||
foreign_name: `${remoteObjectMetadataName}`,
|
|
||||||
foreign_schema: schema,
|
|
||||||
foreign_table: remoteObjectMetadataName,
|
|
||||||
foreign_columns: ['id'],
|
|
||||||
};
|
|
||||||
|
|
||||||
if (parsedComment.foreign_keys) {
|
|
||||||
parsedComment.foreign_keys.push(foreignKey);
|
|
||||||
} else {
|
|
||||||
parsedComment.foreign_keys = [foreignKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
return `@graphql(${JSON.stringify(parsedComment)})`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createWorkspaceMigrationsForRemoteObjectRelations = async (
|
export const createWorkspaceMigrationsForRemoteObjectRelations = async (
|
||||||
createdObjectMetadata: ObjectMetadataEntity,
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
activityTargetObjectMetadata: ObjectMetadataEntity,
|
activityTargetObjectMetadata: ObjectMetadataEntity,
|
||||||
attachmentObjectMetadata: ObjectMetadataEntity,
|
attachmentObjectMetadata: ObjectMetadataEntity,
|
||||||
eventObjectMetadata: ObjectMetadataEntity,
|
timelineActivityObjectMetadata: ObjectMetadataEntity,
|
||||||
favoriteObjectMetadata: ObjectMetadataEntity,
|
favoriteObjectMetadata: ObjectMetadataEntity,
|
||||||
schema: string,
|
|
||||||
primaryKeyColumnType: string,
|
primaryKeyColumnType: string,
|
||||||
workspaceDataSource: DataSource | undefined,
|
|
||||||
): Promise<WorkspaceMigrationTableAction[]> => {
|
): Promise<WorkspaceMigrationTableAction[]> => {
|
||||||
const createdObjectName = createdObjectMetadata.nameSingular;
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
@ -74,22 +31,6 @@ export const createWorkspaceMigrationsForRemoteObjectRelations = async (
|
|||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
|
||||||
comment: await buildCommentForRemoteObjectForeignKey(
|
|
||||||
activityTargetObjectMetadata.nameSingular,
|
|
||||||
createdObjectName,
|
|
||||||
schema,
|
|
||||||
workspaceDataSource,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add attachment relation
|
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
@ -105,53 +46,7 @@ export const createWorkspaceMigrationsForRemoteObjectRelations = async (
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
name: computeObjectTargetTable(timelineActivityObjectMetadata),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
|
||||||
comment: await buildCommentForRemoteObjectForeignKey(
|
|
||||||
attachmentObjectMetadata.nameSingular,
|
|
||||||
createdObjectName,
|
|
||||||
schema,
|
|
||||||
workspaceDataSource,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add event relation
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: computeColumnName(createdObjectMetadata.nameSingular, {
|
|
||||||
isForeignKey: true,
|
|
||||||
}),
|
|
||||||
columnType: primaryKeyColumnType,
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
|
||||||
comment: await buildCommentForRemoteObjectForeignKey(
|
|
||||||
eventObjectMetadata.nameSingular,
|
|
||||||
createdObjectName,
|
|
||||||
schema,
|
|
||||||
workspaceDataSource,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add favorite relation
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@ -169,14 +64,13 @@ export const createWorkspaceMigrationsForRemoteObjectRelations = async (
|
|||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
comment: await buildCommentForRemoteObjectForeignKey(
|
columnName: computeColumnName(createdObjectMetadata.nameSingular, {
|
||||||
favoriteObjectMetadata.nameSingular,
|
isForeignKey: true,
|
||||||
createdObjectName,
|
}),
|
||||||
schema,
|
columnType: primaryKeyColumnType,
|
||||||
workspaceDataSource,
|
isNullable: true,
|
||||||
),
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
import {
|
||||||
|
FieldMetadataSettings,
|
||||||
|
NumberDataType,
|
||||||
|
} from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
||||||
|
|
||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
|
||||||
@ -8,8 +11,6 @@ export const mapUdtNameToFieldType = (udtName: string): FieldMetadataType => {
|
|||||||
return FieldMetadataType.UUID;
|
return FieldMetadataType.UUID;
|
||||||
case 'varchar':
|
case 'varchar':
|
||||||
case 'text':
|
case 'text':
|
||||||
case 'bigint':
|
|
||||||
case 'int8':
|
|
||||||
return FieldMetadataType.TEXT;
|
return FieldMetadataType.TEXT;
|
||||||
case 'bool':
|
case 'bool':
|
||||||
return FieldMetadataType.BOOLEAN;
|
return FieldMetadataType.BOOLEAN;
|
||||||
@ -19,6 +20,8 @@ export const mapUdtNameToFieldType = (udtName: string): FieldMetadataType => {
|
|||||||
case 'integer':
|
case 'integer':
|
||||||
case 'int2':
|
case 'int2':
|
||||||
case 'int4':
|
case 'int4':
|
||||||
|
case 'int8':
|
||||||
|
case 'bigint':
|
||||||
return FieldMetadataType.NUMBER;
|
return FieldMetadataType.NUMBER;
|
||||||
default:
|
default:
|
||||||
return FieldMetadataType.TEXT;
|
return FieldMetadataType.TEXT;
|
||||||
@ -33,7 +36,12 @@ export const mapUdtNameToFieldSettings = (
|
|||||||
case 'int2':
|
case 'int2':
|
||||||
case 'int4':
|
case 'int4':
|
||||||
return {
|
return {
|
||||||
precision: 0,
|
dataType: NumberDataType.INT,
|
||||||
|
} satisfies FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||||
|
case 'int8':
|
||||||
|
case 'bigint':
|
||||||
|
return {
|
||||||
|
dataType: NumberDataType.BIGINT,
|
||||||
} satisfies FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
} satisfies FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
12
yarn.lock
12
yarn.lock
@ -28910,6 +28910,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"graphql-scalars@npm:^1.23.0":
|
||||||
|
version: 1.23.0
|
||||||
|
resolution: "graphql-scalars@npm:1.23.0"
|
||||||
|
dependencies:
|
||||||
|
tslib: "npm:^2.5.0"
|
||||||
|
peerDependencies:
|
||||||
|
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||||
|
checksum: 7666c305b8367528c4fbb583a2731d93d52f36043d71f4957ecc1d2db71d710d268e25535243beb1b2497db921daa94d3cfa83daaf4a3101a667f358ddbf3436
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"graphql-shield@npm:^7.5.0":
|
"graphql-shield@npm:^7.5.0":
|
||||||
version: 7.6.5
|
version: 7.6.5
|
||||||
resolution: "graphql-shield@npm:7.6.5"
|
resolution: "graphql-shield@npm:7.6.5"
|
||||||
@ -46585,6 +46596,7 @@ __metadata:
|
|||||||
graphql-fields: "npm:^2.0.3"
|
graphql-fields: "npm:^2.0.3"
|
||||||
graphql-middleware: "npm:^6.1.35"
|
graphql-middleware: "npm:^6.1.35"
|
||||||
graphql-rate-limit: "npm:^3.3.0"
|
graphql-rate-limit: "npm:^3.3.0"
|
||||||
|
graphql-scalars: "npm:^1.23.0"
|
||||||
graphql-subscriptions: "npm:2.0.0"
|
graphql-subscriptions: "npm:2.0.0"
|
||||||
graphql-tag: "npm:^2.12.6"
|
graphql-tag: "npm:^2.12.6"
|
||||||
graphql-type-json: "npm:^0.3.2"
|
graphql-type-json: "npm:^0.3.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user