mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 03:51:36 +03:00
feat: refactor workspace sync fields (#6069)
This PR was first here to fix the issue related to ticket #5004, after some testing it seems that changing the name of a relation is actually properly working, if we rename `ONE-TO-MANY` side, the only things that is going to be updated is the FieldMetadata as the `joinColumn` is stored on the opposite object. For `MANY-TO-ONE` relations, the `joinColumn` migration is properly generated. We need to take care that if we rename a side of a relation, sometimes the opposite side doesn't have `inverseSideFieldKey` implemented and used by default the name of the opposite object, so this is going to throw an error as the field can't be found in the object. --------- Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
This commit is contained in:
parent
a163ccced6
commit
5b26452649
6
.vscode/twenty.code-workspace
vendored
6
.vscode/twenty.code-workspace
vendored
@ -43,21 +43,21 @@
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
|
@ -122,7 +122,7 @@ export class TimelineCalendarEventService {
|
||||
|
||||
return {
|
||||
totalNumberOfCalendarEvents: total,
|
||||
timelineCalendarEvents,
|
||||
timelineCalendarEvents: timelineCalendarEvents,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,9 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { StandardObjectFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory';
|
||||
import { computeStandardObject } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util';
|
||||
import { StandardFieldFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory';
|
||||
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
|
||||
import { computeStandardFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-fields.util';
|
||||
|
||||
interface RunCommandOptions {
|
||||
workspaceId?: string;
|
||||
@ -123,11 +123,8 @@ export class AddStandardIdCommand extends CommandRunner {
|
||||
continue;
|
||||
}
|
||||
|
||||
const computedStandardObjectMetadata = computeStandardObject(
|
||||
standardObjectMetadata ?? {
|
||||
...originalObjectMetadata,
|
||||
fields: standardFieldMetadataCollection,
|
||||
},
|
||||
const computedStandardFieldMetadataCollection = computeStandardFields(
|
||||
standardFieldMetadataCollection,
|
||||
originalObjectMetadata,
|
||||
customObjectMetadataCollection,
|
||||
);
|
||||
@ -135,13 +132,13 @@ export class AddStandardIdCommand extends CommandRunner {
|
||||
if (!originalObjectMetadata.isCustom) {
|
||||
updateObjectMetadataCollection.push({
|
||||
id: originalObjectMetadata.id,
|
||||
standardId: computedStandardObjectMetadata.standardId,
|
||||
standardId: originalObjectMetadata.standardId,
|
||||
});
|
||||
}
|
||||
|
||||
for (const fieldMetadata of originalObjectMetadata.fields) {
|
||||
const standardFieldMetadata =
|
||||
computedStandardObjectMetadata.fields.find(
|
||||
computedStandardFieldMetadataCollection.find(
|
||||
(field) => field.name === fieldMetadata.name && !field.isCustom,
|
||||
);
|
||||
|
||||
|
@ -36,7 +36,7 @@ describe('WorkspaceFieldComparator', () => {
|
||||
],
|
||||
} as any;
|
||||
|
||||
const result = comparator.compare(original, standard);
|
||||
const result = comparator.compare('', original.fields, standard.fields);
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
@ -65,7 +65,7 @@ describe('WorkspaceFieldComparator', () => {
|
||||
],
|
||||
} as any;
|
||||
|
||||
const result = comparator.compare(original, standard);
|
||||
const result = comparator.compare('', original.fields, standard.fields);
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
@ -88,7 +88,7 @@ describe('WorkspaceFieldComparator', () => {
|
||||
} as any;
|
||||
const standard = { fields: [] } as any;
|
||||
|
||||
const result = comparator.compare(original, standard);
|
||||
const result = comparator.compare('', original.fields, standard.fields);
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
@ -108,7 +108,7 @@ describe('WorkspaceFieldComparator', () => {
|
||||
fields: [createMockFieldMetadata({ standardId: '1' })],
|
||||
} as any;
|
||||
|
||||
const result = comparator.compare(original, standard);
|
||||
const result = comparator.compare('', original.fields, standard.fields);
|
||||
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
|
@ -7,9 +7,7 @@ import {
|
||||
FieldComparatorResult,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface';
|
||||
import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||
import { ComputedPartialWorkspaceEntity } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util';
|
||||
import {
|
||||
FieldMetadataEntity,
|
||||
@ -35,8 +33,9 @@ export class WorkspaceFieldComparator {
|
||||
constructor() {}
|
||||
|
||||
public compare(
|
||||
originalObjectMetadata: ObjectMetadataEntity,
|
||||
standardObjectMetadata: ComputedPartialWorkspaceEntity,
|
||||
originalObjectMetadataId: string,
|
||||
originalFieldMetadataCollection: FieldMetadataEntity[],
|
||||
standardFieldMetadataCollection: ComputedPartialFieldMetadata[],
|
||||
): FieldComparatorResult[] {
|
||||
const result: FieldComparatorResult[] = [];
|
||||
const fieldPropertiesToUpdateMap: Record<
|
||||
@ -46,7 +45,7 @@ export class WorkspaceFieldComparator {
|
||||
|
||||
// Double security to only compare non-custom fields
|
||||
const filteredOriginalFieldCollection =
|
||||
originalObjectMetadata.fields.filter((field) => !field.isCustom);
|
||||
originalFieldMetadataCollection.filter((field) => !field.isCustom);
|
||||
const originalFieldMetadataMap = transformMetadataForComparison(
|
||||
filteredOriginalFieldCollection,
|
||||
{
|
||||
@ -73,7 +72,7 @@ export class WorkspaceFieldComparator {
|
||||
},
|
||||
);
|
||||
const standardFieldMetadataMap = transformMetadataForComparison(
|
||||
standardObjectMetadata.fields,
|
||||
standardFieldMetadataCollection,
|
||||
{
|
||||
shouldIgnoreProperty: (property, originalMetadata) => {
|
||||
if (commonFieldPropertiesToIgnore.includes(property)) {
|
||||
@ -117,9 +116,9 @@ export class WorkspaceFieldComparator {
|
||||
};
|
||||
// Object shouldn't have thousands of fields, so we can use find here
|
||||
const standardFieldMetadata =
|
||||
standardObjectMetadata.fields.find(findField);
|
||||
standardFieldMetadataCollection.find(findField);
|
||||
const originalFieldMetadata =
|
||||
originalObjectMetadata.fields.find(findField);
|
||||
originalFieldMetadataCollection.find(findField);
|
||||
|
||||
switch (difference.type) {
|
||||
case 'CREATE': {
|
||||
@ -133,7 +132,7 @@ export class WorkspaceFieldComparator {
|
||||
action: ComparatorAction.CREATE,
|
||||
object: {
|
||||
...standardFieldMetadata,
|
||||
objectMetadataId: originalObjectMetadata.id,
|
||||
objectMetadataId: originalObjectMetadataId,
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
@ -27,8 +27,8 @@ export class WorkspaceObjectComparator {
|
||||
constructor() {}
|
||||
|
||||
public compare(
|
||||
originalObjectMetadata: ObjectMetadataEntity | undefined,
|
||||
standardObjectMetadata: ComputedPartialWorkspaceEntity,
|
||||
originalObjectMetadata: Omit<ObjectMetadataEntity, 'fields'> | undefined,
|
||||
standardObjectMetadata: Omit<ComputedPartialWorkspaceEntity, 'fields'>,
|
||||
): ObjectComparatorResult {
|
||||
// If the object doesn't exist in the original metadata, we need to create it
|
||||
if (!originalObjectMetadata) {
|
||||
|
@ -24,10 +24,53 @@ export class StandardFieldFactory {
|
||||
target: typeof BaseWorkspaceEntity,
|
||||
context: WorkspaceSyncContext,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
): Array<PartialFieldMetadata | PartialComputedFieldMetadata> {
|
||||
): (PartialFieldMetadata | PartialComputedFieldMetadata)[];
|
||||
|
||||
create(
|
||||
targets: (typeof BaseWorkspaceEntity)[],
|
||||
context: WorkspaceSyncContext,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap, // Map of standardId to field metadata
|
||||
): Map<string, (PartialFieldMetadata | PartialComputedFieldMetadata)[]>;
|
||||
|
||||
create(
|
||||
targetOrTargets:
|
||||
| typeof BaseWorkspaceEntity
|
||||
| (typeof BaseWorkspaceEntity)[],
|
||||
context: WorkspaceSyncContext,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
):
|
||||
| (PartialFieldMetadata | PartialComputedFieldMetadata)[]
|
||||
| Map<string, (PartialFieldMetadata | PartialComputedFieldMetadata)[]> {
|
||||
if (Array.isArray(targetOrTargets)) {
|
||||
return targetOrTargets.reduce((acc, target) => {
|
||||
const workspaceEntityMetadataArgs =
|
||||
metadataArgsStorage.filterEntities(target);
|
||||
|
||||
if (!workspaceEntityMetadataArgs) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
if (
|
||||
isGatedAndNotEnabled(
|
||||
workspaceEntityMetadataArgs.gate,
|
||||
workspaceFeatureFlagsMap,
|
||||
)
|
||||
) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
acc.set(
|
||||
workspaceEntityMetadataArgs.standardId,
|
||||
this.create(target, context, workspaceFeatureFlagsMap),
|
||||
);
|
||||
|
||||
return acc;
|
||||
}, new Map<string, (PartialFieldMetadata | PartialComputedFieldMetadata)[]>());
|
||||
}
|
||||
|
||||
const workspaceEntityMetadataArgs =
|
||||
metadataArgsStorage.filterEntities(target);
|
||||
const metadataCollections = this.collectMetadata(target);
|
||||
metadataArgsStorage.filterEntities(targetOrTargets);
|
||||
const metadataCollections = this.collectMetadata(targetOrTargets);
|
||||
|
||||
return [
|
||||
...this.processMetadata(
|
||||
|
@ -8,17 +8,13 @@ import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-syn
|
||||
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
|
||||
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
||||
|
||||
import { StandardFieldFactory } from './standard-field.factory';
|
||||
|
||||
@Injectable()
|
||||
export class StandardObjectFactory {
|
||||
constructor(private readonly standardFieldFactory: StandardFieldFactory) {}
|
||||
|
||||
create(
|
||||
standardObjectMetadataDefinitions: (typeof BaseWorkspaceEntity)[],
|
||||
context: WorkspaceSyncContext,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
): PartialWorkspaceEntity[] {
|
||||
): Omit<PartialWorkspaceEntity, 'fields'>[] {
|
||||
return standardObjectMetadataDefinitions
|
||||
.map((metadata) =>
|
||||
this.createObjectMetadata(metadata, context, workspaceFeatureFlagsMap),
|
||||
@ -30,7 +26,7 @@ export class StandardObjectFactory {
|
||||
target: typeof BaseWorkspaceEntity,
|
||||
context: WorkspaceSyncContext,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
): PartialWorkspaceEntity | undefined {
|
||||
): Omit<PartialWorkspaceEntity, 'fields'> | undefined {
|
||||
const workspaceEntityMetadataArgs =
|
||||
metadataArgsStorage.filterEntities(target);
|
||||
|
||||
@ -49,12 +45,6 @@ export class StandardObjectFactory {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const fields = this.standardFieldFactory.create(
|
||||
target,
|
||||
context,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
|
||||
return {
|
||||
...workspaceEntityMetadataArgs,
|
||||
// TODO: Remove targetTableName when we remove the old metadata
|
||||
@ -64,7 +54,6 @@ export class StandardObjectFactory {
|
||||
isCustom: false,
|
||||
isRemote: false,
|
||||
isSystem: workspaceEntityMetadataArgs.isSystem ?? false,
|
||||
fields,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ export interface ComparatorDeleteResult<T> {
|
||||
|
||||
export type ObjectComparatorResult =
|
||||
| ComparatorSkipResult
|
||||
| ComparatorCreateResult<ComputedPartialWorkspaceEntity>
|
||||
| ComparatorCreateResult<Omit<ComputedPartialWorkspaceEntity, 'fields'>>
|
||||
| ComparatorUpdateResult<
|
||||
Partial<ComputedPartialWorkspaceEntity> & { id: string }
|
||||
Partial<Omit<ComputedPartialWorkspaceEntity, 'fields'>> & { id: string }
|
||||
>;
|
||||
|
||||
export type FieldComparatorResult =
|
||||
|
@ -47,9 +47,6 @@ export class WorkspaceMetadataUpdaterService {
|
||||
storage.objectMetadataCreateCollection.map((objectMetadata) => ({
|
||||
...objectMetadata,
|
||||
isActive: true,
|
||||
fields: objectMetadata.fields.map((field) =>
|
||||
this.prepareFieldMetadataForCreation(field),
|
||||
),
|
||||
})) as DeepPartial<ObjectMetadataEntity>[],
|
||||
);
|
||||
const identifiers = createdPartialObjectMetadataCollection.map(
|
||||
|
@ -15,7 +15,9 @@ import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-syn
|
||||
import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory';
|
||||
import { StandardFieldFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory';
|
||||
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
|
||||
import { computeStandardObject } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util';
|
||||
import { computeStandardFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-fields.util';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { mapObjectMetadataByUniqueIdentifier } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceSyncFieldMetadataService {
|
||||
@ -47,56 +49,25 @@ export class WorkspaceSyncFieldMetadataService {
|
||||
},
|
||||
relations: ['dataSource', 'fields'],
|
||||
});
|
||||
|
||||
// Filter out non-custom objects
|
||||
const customObjectMetadataCollection =
|
||||
originalObjectMetadataCollection.filter(
|
||||
(objectMetadata) => objectMetadata.isCustom,
|
||||
);
|
||||
|
||||
// Create standard field metadata collection
|
||||
const standardFieldMetadataCollection = this.standardFieldFactory.create(
|
||||
CustomWorkspaceEntity,
|
||||
await this.synchronizeStandardObjectFields(
|
||||
context,
|
||||
originalObjectMetadataCollection,
|
||||
customObjectMetadataCollection,
|
||||
storage,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
|
||||
// Loop over all custom objects from the DB and compare their fields with standard fields
|
||||
for (const customObjectMetadata of customObjectMetadataCollection) {
|
||||
// Also, maybe it's better to refactor a bit and move generation part into a separate module ?
|
||||
const standardObjectMetadata = computeStandardObject(
|
||||
{
|
||||
...customObjectMetadata,
|
||||
fields: standardFieldMetadataCollection,
|
||||
},
|
||||
customObjectMetadata,
|
||||
);
|
||||
|
||||
/**
|
||||
* COMPARE FIELD METADATA
|
||||
*/
|
||||
const fieldComparatorResults = this.workspaceFieldComparator.compare(
|
||||
customObjectMetadata,
|
||||
standardObjectMetadata,
|
||||
);
|
||||
|
||||
for (const fieldComparatorResult of fieldComparatorResults) {
|
||||
switch (fieldComparatorResult.action) {
|
||||
case ComparatorAction.CREATE: {
|
||||
storage.addCreateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.UPDATE: {
|
||||
storage.addUpdateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.DELETE: {
|
||||
storage.addDeleteFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.synchronizeCustomObjectFields(
|
||||
context,
|
||||
customObjectMetadataCollection,
|
||||
storage,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
|
||||
this.logger.log('Updating workspace metadata');
|
||||
|
||||
@ -137,4 +108,120 @@ export class WorkspaceSyncFieldMetadataService {
|
||||
...deleteFieldWorkspaceMigrations,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be optimized to avoid import of standardObjectFactory here.
|
||||
* We should refactor the logic of the factory, so this one only create the objects and not the fields.
|
||||
* Then standardFieldFactory should be used to create the fields of standard objects.
|
||||
*/
|
||||
private async synchronizeStandardObjectFields(
|
||||
context: WorkspaceSyncContext,
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
customObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
storage: WorkspaceSyncStorage,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
): Promise<void> {
|
||||
// Create standard field metadata map
|
||||
const standardObjectStandardFieldMetadataMap =
|
||||
this.standardFieldFactory.create(
|
||||
standardObjectMetadataDefinitions,
|
||||
context,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
|
||||
// Create map of original and standard object metadata by standard ids
|
||||
const originalObjectMetadataMap = mapObjectMetadataByUniqueIdentifier(
|
||||
originalObjectMetadataCollection,
|
||||
);
|
||||
|
||||
this.logger.log('Comparing standard objects and fields metadata');
|
||||
|
||||
// Loop over all standard objects and compare them with the objects in DB
|
||||
for (const [
|
||||
standardObjectId,
|
||||
standardFieldMetadataCollection,
|
||||
] of standardObjectStandardFieldMetadataMap) {
|
||||
const originalObjectMetadata =
|
||||
originalObjectMetadataMap[standardObjectId];
|
||||
const computedStandardFieldMetadataCollection = computeStandardFields(
|
||||
standardFieldMetadataCollection,
|
||||
originalObjectMetadata,
|
||||
// We need to provide this for generated relations with custom objects
|
||||
customObjectMetadataCollection,
|
||||
);
|
||||
|
||||
const fieldComparatorResults = this.workspaceFieldComparator.compare(
|
||||
originalObjectMetadata.id,
|
||||
originalObjectMetadata.fields,
|
||||
computedStandardFieldMetadataCollection,
|
||||
);
|
||||
|
||||
for (const fieldComparatorResult of fieldComparatorResults) {
|
||||
switch (fieldComparatorResult.action) {
|
||||
case ComparatorAction.CREATE: {
|
||||
storage.addCreateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.UPDATE: {
|
||||
storage.addUpdateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.DELETE: {
|
||||
storage.addDeleteFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async synchronizeCustomObjectFields(
|
||||
context: WorkspaceSyncContext,
|
||||
customObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
storage: WorkspaceSyncStorage,
|
||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||
): Promise<void> {
|
||||
// Create standard field metadata collection
|
||||
const customObjectStandardFieldMetadataCollection =
|
||||
this.standardFieldFactory.create(
|
||||
CustomWorkspaceEntity,
|
||||
context,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
|
||||
// Loop over all custom objects from the DB and compare their fields with standard fields
|
||||
for (const customObjectMetadata of customObjectMetadataCollection) {
|
||||
// Also, maybe it's better to refactor a bit and move generation part into a separate module ?
|
||||
const standardFieldMetadataCollection = computeStandardFields(
|
||||
customObjectStandardFieldMetadataCollection,
|
||||
customObjectMetadata,
|
||||
);
|
||||
|
||||
/**
|
||||
* COMPARE FIELD METADATA
|
||||
*/
|
||||
const fieldComparatorResults = this.workspaceFieldComparator.compare(
|
||||
customObjectMetadata.id,
|
||||
customObjectMetadata.fields,
|
||||
standardFieldMetadataCollection,
|
||||
);
|
||||
|
||||
for (const fieldComparatorResult of fieldComparatorResults) {
|
||||
switch (fieldComparatorResult.action) {
|
||||
case ComparatorAction.CREATE: {
|
||||
storage.addCreateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.UPDATE: {
|
||||
storage.addUpdateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.DELETE: {
|
||||
storage.addDeleteFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,9 @@ import { mapObjectMetadataByUniqueIdentifier } from 'src/engine/workspace-manage
|
||||
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { StandardObjectFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory';
|
||||
import { WorkspaceObjectComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator';
|
||||
import { WorkspaceFieldComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator';
|
||||
import { WorkspaceMetadataUpdaterService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service';
|
||||
import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage';
|
||||
import { WorkspaceMigrationObjectFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory';
|
||||
import { computeStandardObject } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
|
||||
@Injectable()
|
||||
@ -26,7 +24,6 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
constructor(
|
||||
private readonly standardObjectFactory: StandardObjectFactory,
|
||||
private readonly workspaceObjectComparator: WorkspaceObjectComparator,
|
||||
private readonly workspaceFieldComparator: WorkspaceFieldComparator,
|
||||
private readonly workspaceMetadataUpdaterService: WorkspaceMetadataUpdaterService,
|
||||
private readonly workspaceMigrationObjectFactory: WorkspaceMigrationObjectFactory,
|
||||
) {}
|
||||
@ -49,10 +46,6 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
},
|
||||
relations: ['dataSource', 'fields'],
|
||||
});
|
||||
const customObjectMetadataCollection =
|
||||
originalObjectMetadataCollection.filter(
|
||||
(objectMetadata) => objectMetadata.isCustom,
|
||||
);
|
||||
|
||||
// Create standard object metadata collection
|
||||
const standardObjectMetadataCollection = this.standardObjectFactory.create(
|
||||
@ -87,11 +80,8 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
for (const standardObjectId in standardObjectMetadataMap) {
|
||||
const originalObjectMetadata =
|
||||
originalObjectMetadataMap[standardObjectId];
|
||||
const standardObjectMetadata = computeStandardObject(
|
||||
standardObjectMetadataMap[standardObjectId],
|
||||
originalObjectMetadata,
|
||||
customObjectMetadataCollection,
|
||||
);
|
||||
const standardObjectMetadata =
|
||||
standardObjectMetadataMap[standardObjectId];
|
||||
|
||||
/**
|
||||
* COMPARE OBJECT METADATA
|
||||
@ -109,35 +99,6 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
if (objectComparatorResult.action === ComparatorAction.UPDATE) {
|
||||
storage.addUpdateObjectMetadata(objectComparatorResult.object);
|
||||
}
|
||||
|
||||
/**
|
||||
* COMPARE FIELD METADATA
|
||||
* NOTE: This should be moved to WorkspaceSyncFieldMetadataService for more clarity since
|
||||
* this code only adds field metadata to the storage but it's actually used in the other service.
|
||||
* NOTE2: WorkspaceSyncFieldMetadataService has been added for custom fields sync, it should be refactored to handle
|
||||
* both custom and non-custom fields.
|
||||
*/
|
||||
const fieldComparatorResults = this.workspaceFieldComparator.compare(
|
||||
originalObjectMetadata,
|
||||
standardObjectMetadata,
|
||||
);
|
||||
|
||||
for (const fieldComparatorResult of fieldComparatorResults) {
|
||||
switch (fieldComparatorResult.action) {
|
||||
case ComparatorAction.CREATE: {
|
||||
storage.addCreateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.UPDATE: {
|
||||
storage.addUpdateFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
case ComparatorAction.DELETE: {
|
||||
storage.addDeleteFieldMetadata(fieldComparatorResult.object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.log('Updating workspace metadata');
|
||||
|
@ -28,6 +28,7 @@ import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/stan
|
||||
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
|
||||
|
||||
// TODO: Maybe we should automate this with the DiscoverService of Nest.JS
|
||||
export const standardObjectMetadataDefinitions = [
|
||||
ActivityTargetWorkspaceEntity,
|
||||
ActivityWorkspaceEntity,
|
||||
|
@ -8,9 +8,13 @@ import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/
|
||||
|
||||
export class WorkspaceSyncStorage {
|
||||
// Object metadata
|
||||
private readonly _objectMetadataCreateCollection: ComputedPartialWorkspaceEntity[] =
|
||||
[];
|
||||
private readonly _objectMetadataUpdateCollection: (Partial<ComputedPartialWorkspaceEntity> & {
|
||||
private readonly _objectMetadataCreateCollection: Omit<
|
||||
ComputedPartialWorkspaceEntity,
|
||||
'fields'
|
||||
>[] = [];
|
||||
private readonly _objectMetadataUpdateCollection: (Partial<
|
||||
Omit<ComputedPartialWorkspaceEntity, 'fields'>
|
||||
> & {
|
||||
id: string;
|
||||
})[] = [];
|
||||
private readonly _objectMetadataDeleteCollection: ObjectMetadataEntity[] = [];
|
||||
@ -88,7 +92,9 @@ export class WorkspaceSyncStorage {
|
||||
return this._indexMetadataDeleteCollection;
|
||||
}
|
||||
|
||||
addCreateObjectMetadata(object: ComputedPartialWorkspaceEntity) {
|
||||
addCreateObjectMetadata(
|
||||
object: Omit<ComputedPartialWorkspaceEntity, 'fields'>,
|
||||
) {
|
||||
this._objectMetadataCreateCollection.push(object);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {
|
||||
ComputedPartialWorkspaceEntity,
|
||||
PartialWorkspaceEntity,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface';
|
||||
import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||
ComputedPartialFieldMetadata,
|
||||
PartialComputedFieldMetadata,
|
||||
PartialFieldMetadata,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
@ -11,16 +11,18 @@ import {
|
||||
createRelationDeterministicUuid,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
|
||||
|
||||
export const computeStandardObject = (
|
||||
standardObjectMetadata: Omit<PartialWorkspaceEntity, 'standardId'> & {
|
||||
standardId: string | null;
|
||||
},
|
||||
export const computeStandardFields = (
|
||||
standardFieldMetadataCollection: (
|
||||
| PartialFieldMetadata
|
||||
| PartialComputedFieldMetadata
|
||||
)[],
|
||||
originalObjectMetadata: ObjectMetadataEntity,
|
||||
customObjectMetadataCollection: ObjectMetadataEntity[] = [],
|
||||
): ComputedPartialWorkspaceEntity => {
|
||||
): ComputedPartialFieldMetadata[] => {
|
||||
const fields: ComputedPartialFieldMetadata[] = [];
|
||||
|
||||
for (const partialFieldMetadata of standardObjectMetadata.fields) {
|
||||
for (const partialFieldMetadata of standardFieldMetadataCollection) {
|
||||
// Relation from standard object to custom object
|
||||
if ('argsFactory' in partialFieldMetadata) {
|
||||
// Compute standard fields of custom object
|
||||
for (const customObjectMetadata of customObjectMetadataCollection) {
|
||||
@ -63,6 +65,7 @@ export const computeStandardObject = (
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Relation from standard object to standard object
|
||||
const labelText =
|
||||
typeof partialFieldMetadata.label === 'function'
|
||||
? partialFieldMetadata.label(originalObjectMetadata)
|
||||
@ -80,8 +83,5 @@ export const computeStandardObject = (
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...standardObjectMetadata,
|
||||
fields,
|
||||
};
|
||||
return fields;
|
||||
};
|
Loading…
Reference in New Issue
Block a user