Remove viewGroup v1 implem (#16178)
# Introduction Removing v1 implementation of view groups and both view group and view field relicas front fetchers Related https://github.com/twentyhq/core-team-issues/issues/1911
This commit is contained in:
-327
@@ -1,327 +0,0 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import {
|
||||
ViewGroupException,
|
||||
ViewGroupExceptionCode,
|
||||
ViewGroupExceptionMessageKey,
|
||||
generateViewGroupExceptionMessage,
|
||||
generateViewGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
describe('ViewGroupService', () => {
|
||||
let viewGroupService: ViewGroupService;
|
||||
let viewGroupRepository: Repository<ViewGroupEntity>;
|
||||
|
||||
const mockViewGroup = {
|
||||
id: 'view-group-id',
|
||||
fieldMetadataId: 'field-id',
|
||||
viewId: 'view-id',
|
||||
workspaceId: 'workspace-id',
|
||||
fieldValue: 'group-value',
|
||||
isVisible: true,
|
||||
position: 0,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
deletedAt: null,
|
||||
} as ViewGroupEntity;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
ViewGroupService,
|
||||
{
|
||||
provide: getRepositoryToken(ViewGroupEntity),
|
||||
useValue: {
|
||||
find: jest.fn(),
|
||||
findOne: jest.fn(),
|
||||
create: jest.fn(),
|
||||
save: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceCacheStorageService,
|
||||
useValue: {
|
||||
flushGraphQLOperation: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
viewGroupService = module.get<ViewGroupService>(ViewGroupService);
|
||||
viewGroupRepository = module.get<Repository<ViewGroupEntity>>(
|
||||
getRepositoryToken(ViewGroupEntity),
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(viewGroupService).toBeDefined();
|
||||
});
|
||||
|
||||
describe('findByWorkspaceId', () => {
|
||||
it('should return view groups for a workspace', async () => {
|
||||
const workspaceId = 'workspace-id';
|
||||
const expectedViewGroups = [mockViewGroup];
|
||||
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'find')
|
||||
.mockResolvedValue(expectedViewGroups);
|
||||
|
||||
const result = await viewGroupService.findByWorkspaceId(workspaceId);
|
||||
|
||||
expect(viewGroupRepository.find).toHaveBeenCalledWith({
|
||||
where: {
|
||||
workspaceId,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
order: { position: 'ASC' },
|
||||
relations: ['workspace', 'view'],
|
||||
});
|
||||
expect(result).toEqual(expectedViewGroups);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findByViewId', () => {
|
||||
it('should return view groups for a view', async () => {
|
||||
const workspaceId = 'workspace-id';
|
||||
const viewId = 'view-id';
|
||||
const expectedViewGroups = [mockViewGroup];
|
||||
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'find')
|
||||
.mockResolvedValue(expectedViewGroups);
|
||||
|
||||
const result = await viewGroupService.findByViewId(workspaceId, viewId);
|
||||
|
||||
expect(viewGroupRepository.find).toHaveBeenCalledWith({
|
||||
where: {
|
||||
workspaceId,
|
||||
viewId,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
order: { position: 'ASC' },
|
||||
relations: ['workspace', 'view'],
|
||||
});
|
||||
expect(result).toEqual(expectedViewGroups);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findById', () => {
|
||||
it('should return a view group by id', async () => {
|
||||
const id = 'view-group-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'findOne')
|
||||
.mockResolvedValue(mockViewGroup);
|
||||
|
||||
const result = await viewGroupService.findById(id, workspaceId);
|
||||
|
||||
expect(viewGroupRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
deletedAt: expect.anything(),
|
||||
},
|
||||
relations: ['workspace', 'view'],
|
||||
});
|
||||
expect(result).toEqual(mockViewGroup);
|
||||
});
|
||||
|
||||
it('should return null when view group is not found', async () => {
|
||||
const id = 'non-existent-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
|
||||
jest.spyOn(viewGroupRepository, 'findOne').mockResolvedValue(null);
|
||||
|
||||
const result = await viewGroupService.findById(id, workspaceId);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
const validViewGroupData = {
|
||||
fieldMetadataId: 'field-id',
|
||||
viewId: 'view-id',
|
||||
workspaceId: 'workspace-id',
|
||||
fieldValue: 'group-value',
|
||||
isVisible: true,
|
||||
position: 0,
|
||||
};
|
||||
|
||||
it('should create a view group successfully', async () => {
|
||||
jest.spyOn(viewGroupRepository, 'create').mockReturnValue(mockViewGroup);
|
||||
jest.spyOn(viewGroupRepository, 'save').mockResolvedValue(mockViewGroup);
|
||||
|
||||
const result = await viewGroupService.create(validViewGroupData);
|
||||
|
||||
expect(viewGroupRepository.create).toHaveBeenCalledWith(
|
||||
validViewGroupData,
|
||||
);
|
||||
expect(viewGroupRepository.save).toHaveBeenCalledWith(mockViewGroup);
|
||||
expect(result).toEqual(mockViewGroup);
|
||||
});
|
||||
|
||||
it('should throw exception when workspaceId is missing', async () => {
|
||||
const invalidData = { ...validViewGroupData, workspaceId: undefined };
|
||||
|
||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
||||
new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw exception when viewId is missing', async () => {
|
||||
const invalidData = { ...validViewGroupData, viewId: undefined };
|
||||
|
||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
||||
new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw exception when fieldMetadataId is missing', async () => {
|
||||
const invalidData = { ...validViewGroupData, fieldMetadataId: undefined };
|
||||
|
||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
||||
new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a view group successfully', async () => {
|
||||
const id = 'view-group-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
const updateData = { isVisible: false };
|
||||
const updatedViewGroup = { ...mockViewGroup, ...updateData };
|
||||
|
||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(mockViewGroup);
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'save')
|
||||
.mockResolvedValue(updatedViewGroup);
|
||||
|
||||
const result = await viewGroupService.update(id, workspaceId, updateData);
|
||||
|
||||
expect(viewGroupService.findById).toHaveBeenCalledWith(id, workspaceId);
|
||||
expect(viewGroupRepository.save).toHaveBeenCalledWith({
|
||||
id,
|
||||
...updateData,
|
||||
});
|
||||
expect(result).toEqual({ ...mockViewGroup, ...updatedViewGroup });
|
||||
});
|
||||
|
||||
it('should throw exception when view group is not found', async () => {
|
||||
const id = 'non-existent-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
const updateData = { isVisible: false };
|
||||
|
||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(null);
|
||||
|
||||
await expect(
|
||||
viewGroupService.update(id, workspaceId, updateData),
|
||||
).rejects.toThrow(
|
||||
new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
||||
id,
|
||||
),
|
||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete', () => {
|
||||
it('should delete a view group successfully', async () => {
|
||||
const id = 'view-group-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
|
||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(mockViewGroup);
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'softDelete')
|
||||
.mockResolvedValue({} as any);
|
||||
|
||||
const result = await viewGroupService.delete(id, workspaceId);
|
||||
|
||||
expect(viewGroupService.findById).toHaveBeenCalledWith(id, workspaceId);
|
||||
expect(viewGroupRepository.softDelete).toHaveBeenCalledWith(id);
|
||||
expect(result).toEqual(mockViewGroup);
|
||||
});
|
||||
|
||||
it('should throw exception when view group is not found', async () => {
|
||||
const id = 'non-existent-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
|
||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(null);
|
||||
|
||||
await expect(viewGroupService.delete(id, workspaceId)).rejects.toThrow(
|
||||
new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
||||
id,
|
||||
),
|
||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy', () => {
|
||||
it('should destroy a view group successfully', async () => {
|
||||
const id = 'view-group-id';
|
||||
const workspaceId = 'workspace-id';
|
||||
|
||||
jest
|
||||
.spyOn(viewGroupRepository, 'findOne')
|
||||
.mockResolvedValue(mockViewGroup);
|
||||
jest.spyOn(viewGroupRepository, 'delete').mockResolvedValue({} as any);
|
||||
|
||||
const result = await viewGroupService.destroy(id, workspaceId);
|
||||
|
||||
expect(viewGroupRepository.findOne).toHaveBeenCalledWith({
|
||||
where: { id, workspaceId },
|
||||
relations: ['workspace', 'view'],
|
||||
withDeleted: true,
|
||||
});
|
||||
expect(viewGroupRepository.delete).toHaveBeenCalledWith(id);
|
||||
expect(result).toEqual(mockViewGroup);
|
||||
});
|
||||
});
|
||||
});
|
||||
-347
@@ -1,347 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util';
|
||||
import { fromDeleteViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util';
|
||||
import { fromDestroyViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util';
|
||||
import { fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util';
|
||||
import { CreateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/create-view-group.input';
|
||||
import { DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/delete-view-group.input';
|
||||
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
||||
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
||||
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
||||
import {
|
||||
ViewGroupException,
|
||||
ViewGroupExceptionCode,
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
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 ViewGroupV2Service {
|
||||
constructor(
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async createOne({
|
||||
createViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
createViewGroupInput: CreateViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const [createdViewGroup] = await this.createMany({
|
||||
workspaceId,
|
||||
createViewGroupInputs: [createViewGroupInput],
|
||||
});
|
||||
|
||||
if (!isDefined(createdViewGroup)) {
|
||||
throw new ViewGroupException(
|
||||
'Failed to create view group',
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
);
|
||||
}
|
||||
|
||||
return createdViewGroup;
|
||||
}
|
||||
|
||||
async createMany({
|
||||
createViewGroupInputs,
|
||||
workspaceId,
|
||||
}: {
|
||||
createViewGroupInputs: CreateViewGroupInput[];
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO[]> {
|
||||
if (createViewGroupInputs.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const flatViewGroupsToCreate = createViewGroupInputs.map(
|
||||
(createViewGroupInput) =>
|
||||
fromCreateViewGroupInputToFlatViewGroupToCreate({
|
||||
createViewGroupInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: flatViewGroupsToCreate,
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while creating view groups',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityIds: flatViewGroupsToCreate.map((el) => el.id),
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async updateOne({
|
||||
updateViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
updateViewGroupInput: UpdateViewGroupInput;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const optimisticallyUpdatedFlatViewGroup =
|
||||
fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow({
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
updateViewGroupInput,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [optimisticallyUpdatedFlatViewGroup],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while updating view group',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatViewGroup.id,
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async deleteOne({
|
||||
deleteViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
deleteViewGroupInput: DeleteViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const optimisticallyUpdatedFlatViewGroupWithDeletedAt =
|
||||
fromDeleteViewGroupInputToFlatViewGroupOrThrow({
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
deleteViewGroupInput,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [
|
||||
optimisticallyUpdatedFlatViewGroupWithDeletedAt,
|
||||
],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while deleting view group',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatViewGroupWithDeletedAt.id,
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async destroyOne({
|
||||
destroyViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
destroyViewGroupInput: DestroyViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const existingViewGroupToDelete =
|
||||
fromDestroyViewGroupInputToFlatViewGroupOrThrow({
|
||||
destroyViewGroupInput,
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [existingViewGroupToDelete],
|
||||
flatEntityToUpdate: [],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: {
|
||||
viewGroup: true,
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while destroying view group',
|
||||
);
|
||||
}
|
||||
|
||||
return existingViewGroupToDelete;
|
||||
}
|
||||
}
|
||||
+333
-143
@@ -4,25 +4,352 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util';
|
||||
import { fromDeleteViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util';
|
||||
import { fromDestroyViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util';
|
||||
import { fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util';
|
||||
import { CreateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/create-view-group.input';
|
||||
import { DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/delete-view-group.input';
|
||||
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
||||
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
||||
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import {
|
||||
ViewGroupException,
|
||||
ViewGroupExceptionCode,
|
||||
ViewGroupExceptionMessageKey,
|
||||
generateViewGroupExceptionMessage,
|
||||
generateViewGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||
import { FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION } from 'src/engine/metadata-modules/view/constants/find-all-core-views-graphql-operation.constant';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
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 ViewGroupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async createOne({
|
||||
createViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
createViewGroupInput: CreateViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const [createdViewGroup] = await this.createMany({
|
||||
workspaceId,
|
||||
createViewGroupInputs: [createViewGroupInput],
|
||||
});
|
||||
|
||||
if (!isDefined(createdViewGroup)) {
|
||||
throw new ViewGroupException(
|
||||
'Failed to create view group',
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
);
|
||||
}
|
||||
|
||||
return createdViewGroup;
|
||||
}
|
||||
|
||||
async createMany({
|
||||
createViewGroupInputs,
|
||||
workspaceId,
|
||||
}: {
|
||||
createViewGroupInputs: CreateViewGroupInput[];
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO[]> {
|
||||
if (createViewGroupInputs.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const flatViewGroupsToCreate = createViewGroupInputs.map(
|
||||
(createViewGroupInput) =>
|
||||
fromCreateViewGroupInputToFlatViewGroupToCreate({
|
||||
createViewGroupInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: flatViewGroupsToCreate,
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while creating view groups',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityIds: flatViewGroupsToCreate.map((el) => el.id),
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async updateOne({
|
||||
updateViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
updateViewGroupInput: UpdateViewGroupInput;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const optimisticallyUpdatedFlatViewGroup =
|
||||
fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow({
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
updateViewGroupInput,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [optimisticallyUpdatedFlatViewGroup],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while updating view group',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatViewGroup.id,
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async deleteOne({
|
||||
deleteViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
deleteViewGroupInput: DeleteViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const optimisticallyUpdatedFlatViewGroupWithDeletedAt =
|
||||
fromDeleteViewGroupInputToFlatViewGroupOrThrow({
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
deleteViewGroupInput,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [
|
||||
optimisticallyUpdatedFlatViewGroupWithDeletedAt,
|
||||
],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while deleting view group',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewGroupMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatViewGroupWithDeletedAt.id,
|
||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async destroyOne({
|
||||
destroyViewGroupInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
destroyViewGroupInput: DestroyViewGroupInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewGroupDTO> {
|
||||
const {
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatViewGroupMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const existingViewGroupToDelete =
|
||||
fromDestroyViewGroupInputToFlatViewGroupOrThrow({
|
||||
destroyViewGroupInput,
|
||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||
flatEntityMaps: existingFlatViewGroupMaps,
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [existingViewGroupToDelete],
|
||||
flatEntityToUpdate: [],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: {
|
||||
viewGroup: true,
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while destroying view group',
|
||||
);
|
||||
}
|
||||
|
||||
return existingViewGroupToDelete;
|
||||
}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewGroupEntity[]> {
|
||||
return this.viewGroupRepository.find({
|
||||
where: {
|
||||
@@ -64,141 +391,4 @@ export class ViewGroupService {
|
||||
|
||||
return viewGroup || null;
|
||||
}
|
||||
|
||||
async create(
|
||||
viewGroupData: Partial<ViewGroupEntity>,
|
||||
): Promise<ViewGroupEntity> {
|
||||
if (!isDefined(viewGroupData.workspaceId)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (!isDefined(viewGroupData.viewId)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (!isDefined(viewGroupData.fieldMetadataId)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
||||
),
|
||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||
{
|
||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const viewGroup = this.viewGroupRepository.create(viewGroupData);
|
||||
|
||||
await this.flushGraphQLCache(viewGroupData.workspaceId);
|
||||
|
||||
const savedViewGroup = await this.viewGroupRepository.save(viewGroup);
|
||||
|
||||
await this.flushGraphQLCache(viewGroupData.workspaceId);
|
||||
|
||||
return savedViewGroup;
|
||||
}
|
||||
|
||||
async update(
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
updateData: Partial<ViewGroupEntity>,
|
||||
): Promise<ViewGroupEntity> {
|
||||
const existingViewGroup = await this.findById(id, workspaceId);
|
||||
|
||||
if (!isDefined(existingViewGroup)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
||||
id,
|
||||
),
|
||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const updatedViewGroup = await this.viewGroupRepository.save({
|
||||
id,
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewGroup, ...updatedViewGroup };
|
||||
}
|
||||
|
||||
async delete(id: string, workspaceId: string): Promise<ViewGroupEntity> {
|
||||
const viewGroup = await this.findById(id, workspaceId);
|
||||
|
||||
if (!isDefined(viewGroup)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
||||
id,
|
||||
),
|
||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await this.viewGroupRepository.softDelete(id);
|
||||
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewGroup;
|
||||
}
|
||||
|
||||
async destroy(id: string, workspaceId: string): Promise<ViewGroupEntity> {
|
||||
const viewGroup = await this.viewGroupRepository.findOne({
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
},
|
||||
relations: ['workspace', 'view'],
|
||||
withDeleted: true,
|
||||
});
|
||||
|
||||
if (!isDefined(viewGroup)) {
|
||||
throw new ViewGroupException(
|
||||
generateViewGroupExceptionMessage(
|
||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
||||
id,
|
||||
),
|
||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await this.viewGroupRepository.delete(id);
|
||||
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewGroup;
|
||||
}
|
||||
|
||||
private async flushGraphQLCache(workspaceId: string): Promise<void> {
|
||||
await this.workspaceCacheStorageService.flushGraphQLOperation({
|
||||
operationName: FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user