59fbe35a8c
# Introduction Preparing view-filter and view-group introduction in v2 core engine Moving view from `core-modules` to `metadata-modules` ## What happened ### Created dedicated modules for each view entity: - ViewFieldModule - ViewFilterModule - ViewFilterGroupModule - ViewGroupModule - ViewSortModule ### Each module is now completely independent with its own: - Controller - Resolver - Service - Entity ### Created dedicated abstraction metadata module folder for: - flat-view-field - flat-view ### Dependencies - Eleminated circular dep on ViewModule to all others ones - Granular import not importing the whole viewModule anymore everywhere close https://github.com/twentyhq/core-team-issues/issues/1703
287 lines
9.9 KiB
TypeScript
287 lines
9.9 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
import { isDefined } from 'twenty-shared/utils';
|
|
|
|
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
|
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
|
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
|
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
|
import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util';
|
|
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
|
import { fromCreateViewInputToFlatViewToCreate } from 'src/engine/metadata-modules/flat-view/utils/from-create-view-input-to-flat-view-to-create.util';
|
|
import { fromDeleteViewInputToFlatViewOrThrow } from 'src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util';
|
|
import { fromDestroyViewInputToFlatViewOrThrow } from 'src/engine/metadata-modules/flat-view/utils/from-destroy-view-input-to-flat-view-or-throw.util';
|
|
import { fromUpdateViewInputToFlatViewToUpdateOrThrow } from 'src/engine/metadata-modules/flat-view/utils/from-update-view-input-to-flat-view-to-update-or-throw.util';
|
|
import { CreateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/create-view.input';
|
|
import { DeleteViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/delete-view.input';
|
|
import { DestroyViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/destroy-view.input';
|
|
import { UpdateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/update-view.input';
|
|
import { ViewDTO } from 'src/engine/metadata-modules/view/dtos/view.dto';
|
|
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
|
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
|
|
|
@Injectable()
|
|
export class ViewV2Service {
|
|
constructor(
|
|
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
|
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
|
) {}
|
|
|
|
async createOne({
|
|
createViewInput,
|
|
workspaceId,
|
|
}: {
|
|
createViewInput: CreateViewInput;
|
|
workspaceId: string;
|
|
}): Promise<ViewDTO> {
|
|
const { flatObjectMetadataMaps, flatViewMaps: existingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatObjectMetadataMaps', 'flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
const flatViewFromCreateInput = fromCreateViewInputToFlatViewToCreate({
|
|
createViewInput,
|
|
workspaceId,
|
|
});
|
|
|
|
const toFlatViewMaps = addFlatEntityToFlatEntityMapsOrThrow({
|
|
flatEntity: flatViewFromCreateInput,
|
|
flatEntityMaps: existingFlatViewMaps,
|
|
});
|
|
|
|
const validateAndBuildResult =
|
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
{
|
|
fromToAllFlatEntityMaps: {
|
|
flatViewMaps: {
|
|
from: existingFlatViewMaps,
|
|
to: toFlatViewMaps,
|
|
},
|
|
},
|
|
dependencyAllFlatEntityMaps: {
|
|
flatObjectMetadataMaps: flatObjectMetadataMaps,
|
|
},
|
|
buildOptions: {
|
|
isSystemBuild: false,
|
|
inferDeletionFromMissingEntities: false,
|
|
},
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
if (isDefined(validateAndBuildResult)) {
|
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
validateAndBuildResult,
|
|
'Multiple validation errors occurred while creating view',
|
|
);
|
|
}
|
|
|
|
const { flatViewMaps: recomputedExistingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
flatEntityId: flatViewFromCreateInput.id,
|
|
flatEntityMaps: recomputedExistingFlatViewMaps,
|
|
});
|
|
}
|
|
|
|
async updateOne({
|
|
updateViewInput,
|
|
workspaceId,
|
|
}: {
|
|
updateViewInput: UpdateViewInput;
|
|
workspaceId: string;
|
|
}): Promise<ViewDTO> {
|
|
const { flatViewMaps: existingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
const flatViewFromUpdateInput =
|
|
fromUpdateViewInputToFlatViewToUpdateOrThrow({
|
|
updateViewInput,
|
|
flatViewMaps: existingFlatViewMaps,
|
|
});
|
|
|
|
const fromFlatViewMaps = getSubFlatEntityMapsOrThrow({
|
|
flatEntityIds: [flatViewFromUpdateInput.id],
|
|
flatEntityMaps: existingFlatViewMaps,
|
|
});
|
|
const toFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
|
|
flatEntity: flatViewFromUpdateInput,
|
|
flatEntityMaps: fromFlatViewMaps,
|
|
});
|
|
|
|
const validateAndBuildResult =
|
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
{
|
|
fromToAllFlatEntityMaps: {
|
|
flatViewMaps: {
|
|
from: fromFlatViewMaps,
|
|
to: toFlatViewMaps,
|
|
},
|
|
},
|
|
buildOptions: {
|
|
isSystemBuild: false,
|
|
inferDeletionFromMissingEntities: false,
|
|
},
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
if (isDefined(validateAndBuildResult)) {
|
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
validateAndBuildResult,
|
|
'Multiple validation errors occurred while updating view',
|
|
);
|
|
}
|
|
|
|
const { flatViewMaps: recomputedExistingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
flatEntityId: updateViewInput.id,
|
|
flatEntityMaps: recomputedExistingFlatViewMaps,
|
|
});
|
|
}
|
|
|
|
async deleteOne({
|
|
deleteViewInput,
|
|
workspaceId,
|
|
}: {
|
|
deleteViewInput: DeleteViewInput;
|
|
workspaceId: string;
|
|
}): Promise<ViewDTO> {
|
|
const { flatViewMaps: existingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
const flatViewFromDeleteInput = fromDeleteViewInputToFlatViewOrThrow({
|
|
deleteViewInput,
|
|
flatViewMaps: existingFlatViewMaps,
|
|
});
|
|
|
|
const fromFlatViewMaps = getSubFlatEntityMapsOrThrow({
|
|
flatEntityIds: [flatViewFromDeleteInput.id],
|
|
flatEntityMaps: existingFlatViewMaps,
|
|
});
|
|
const toFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
|
|
flatEntity: flatViewFromDeleteInput,
|
|
flatEntityMaps: fromFlatViewMaps,
|
|
});
|
|
|
|
const validateAndBuildResult =
|
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
{
|
|
fromToAllFlatEntityMaps: {
|
|
flatViewMaps: {
|
|
from: fromFlatViewMaps,
|
|
to: toFlatViewMaps,
|
|
},
|
|
},
|
|
buildOptions: {
|
|
isSystemBuild: false,
|
|
inferDeletionFromMissingEntities: true,
|
|
},
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
if (isDefined(validateAndBuildResult)) {
|
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
validateAndBuildResult,
|
|
'Multiple validation errors occurred while deleting view',
|
|
);
|
|
}
|
|
|
|
const { flatViewMaps: recomputedExistingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
flatEntityId: deleteViewInput.id,
|
|
flatEntityMaps: recomputedExistingFlatViewMaps,
|
|
});
|
|
}
|
|
|
|
async destroyOne({
|
|
destroyViewInput,
|
|
workspaceId,
|
|
}: {
|
|
destroyViewInput: DestroyViewInput;
|
|
workspaceId: string;
|
|
}): Promise<ViewDTO> {
|
|
const { flatViewMaps: existingFlatViewMaps } =
|
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
{
|
|
workspaceId,
|
|
flatMapsKeys: ['flatViewMaps'],
|
|
},
|
|
);
|
|
|
|
const flatViewFromDestroyInput = fromDestroyViewInputToFlatViewOrThrow({
|
|
destroyViewInput,
|
|
flatViewMaps: existingFlatViewMaps,
|
|
});
|
|
|
|
const fromFlatViewMaps = getSubFlatEntityMapsOrThrow({
|
|
flatEntityIds: [flatViewFromDestroyInput.id],
|
|
flatEntityMaps: existingFlatViewMaps,
|
|
});
|
|
const toFlatViewMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({
|
|
flatEntityMaps: fromFlatViewMaps,
|
|
entityToDeleteId: flatViewFromDestroyInput.id,
|
|
});
|
|
|
|
const validateAndBuildResult =
|
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
{
|
|
fromToAllFlatEntityMaps: {
|
|
flatViewMaps: {
|
|
from: fromFlatViewMaps,
|
|
to: toFlatViewMaps,
|
|
},
|
|
},
|
|
buildOptions: {
|
|
isSystemBuild: false,
|
|
inferDeletionFromMissingEntities: true,
|
|
},
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
if (isDefined(validateAndBuildResult)) {
|
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
validateAndBuildResult,
|
|
'Multiple validation errors occurred while destroying view',
|
|
);
|
|
}
|
|
|
|
return flatViewFromDestroyInput;
|
|
}
|
|
}
|