add space linking when create or update space

This commit is contained in:
faris Aljohari
2025-03-06 02:33:48 +03:00
parent 0d4afc40f2
commit 6864e000b8
3 changed files with 81 additions and 10 deletions

View File

@ -40,6 +40,9 @@ import {
ORPHAN_SPACE_NAME, ORPHAN_SPACE_NAME,
} from '@app/common/constants/orphan-constant'; } from '@app/common/constants/orphan-constant';
import { DeviceRepository } from '@app/common/modules/device/repositories'; import { DeviceRepository } from '@app/common/modules/device/repositories';
import { SpaceProductAllocationEntity } from '@app/common/modules/space/entities/space-product-allocation.entity';
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity';
@Injectable() @Injectable()
export class SpaceModelService { export class SpaceModelService {
@ -387,10 +390,15 @@ export class SpaceModelService {
async linkToSpace( async linkToSpace(
space: SpaceEntity, space: SpaceEntity,
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
queryRunner?: QueryRunner, // Make queryRunner optional
): Promise<void> { ): Promise<void> {
try { try {
space.spaceModel = spaceModel; space.spaceModel = spaceModel;
if (queryRunner) {
await queryRunner.manager.save(SpaceEntity, space);
} else {
await this.spaceRepository.save(space); await this.spaceRepository.save(space);
}
const spaceProductAllocations = spaceModel.productAllocations.map( const spaceProductAllocations = spaceModel.productAllocations.map(
(modelAllocation) => (modelAllocation) =>
@ -401,8 +409,17 @@ export class SpaceModelService {
tags: modelAllocation.tags, tags: modelAllocation.tags,
}), }),
); );
await this.spaceProductAllocationRepository.save(spaceProductAllocations);
if (queryRunner) {
await queryRunner.manager.save(
SpaceProductAllocationEntity,
spaceProductAllocations,
);
} else {
await this.spaceProductAllocationRepository.save(
spaceProductAllocations,
);
}
await Promise.all( await Promise.all(
spaceModel.subspaceModels.map(async (subspaceModel) => { spaceModel.subspaceModels.map(async (subspaceModel) => {
const subspace = this.subspaceRepository.create({ const subspace = this.subspaceRepository.create({
@ -411,7 +428,11 @@ export class SpaceModelService {
space: space, space: space,
}); });
if (queryRunner) {
await queryRunner.manager.save(SubspaceEntity, subspace);
} else {
await this.subspaceRepository.save(subspace); await this.subspaceRepository.save(subspace);
}
const subspaceAllocations = subspaceModel.productAllocations.map( const subspaceAllocations = subspaceModel.productAllocations.map(
(modelAllocation) => (modelAllocation) =>
@ -424,10 +445,17 @@ export class SpaceModelService {
); );
if (subspaceAllocations.length) { if (subspaceAllocations.length) {
if (queryRunner) {
await queryRunner.manager.save(
SubspaceProductAllocationEntity,
subspaceAllocations,
);
} else {
await this.subspaceProductAllocationRepository.save( await this.subspaceProductAllocationRepository.save(
subspaceAllocations, subspaceAllocations,
); );
} }
}
}), }),
); );
} catch (error) { } catch (error) {

View File

@ -58,4 +58,11 @@ export class UpdateSpaceDto {
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => ModifyTagDto) @Type(() => ModifyTagDto)
tags?: ModifyTagDto[]; tags?: ModifyTagDto[];
@ApiProperty({
description: 'UUID of the Space',
example: 'd290f1ee-6c54-4b01-90e6-d701748f0851',
})
@IsString()
@IsOptional()
spaceModelUuid?: string;
} }

View File

@ -104,10 +104,23 @@ export class SpaceService {
this.subSpaceService.extractTagsFromSubspace(subspaces); this.subSpaceService.extractTagsFromSubspace(subspaces);
const allTags = [...tags, ...subspaceTags]; const allTags = [...tags, ...subspaceTags];
this.validateUniqueTags(allTags); this.validateUniqueTags(allTags);
if (spaceModelUuid) {
const hasDependencies = subspaces?.length > 0 || tags?.length > 0;
if (!hasDependencies && !newSpace.spaceModel) {
await this.spaceModelService.linkToSpace(
newSpace,
spaceModel,
queryRunner,
);
} else if (hasDependencies) {
throw new HttpException(
`Space cannot be linked to a model because it has existing dependencies (subspaces or tags).`,
HttpStatus.BAD_REQUEST,
);
}
}
await Promise.all([ await Promise.all([
spaceModelUuid &&
this.createFromModel(spaceModelUuid, queryRunner, newSpace),
direction && parent direction && parent
? this.spaceLinkService.saveSpaceLink( ? this.spaceLinkService.saveSpaceLink(
parent.uuid, parent.uuid,
@ -125,9 +138,8 @@ export class SpaceService {
projectUuid, projectUuid,
) )
: Promise.resolve(), : Promise.resolve(),
tags?.length tags?.length
? this.createTags(tags, projectUuid, queryRunner, space) ? this.createTags(tags, projectUuid, queryRunner, newSpace)
: Promise.resolve(), : Promise.resolve(),
]); ]);
@ -454,6 +466,30 @@ export class SpaceService {
this.updateSpaceProperties(space, updateSpaceDto); this.updateSpaceProperties(space, updateSpaceDto);
if (updateSpaceDto.spaceModelUuid) {
const spaceModel = await this.validationService.validateSpaceModel(
updateSpaceDto.spaceModelUuid,
);
const hasDependencies =
space.devices?.length > 0 ||
space.subspaces?.length > 0 ||
space.productAllocations?.length > 0;
if (!hasDependencies && !space.spaceModel) {
await this.spaceModelService.linkToSpace(
space,
spaceModel,
queryRunner,
);
} else if (hasDependencies) {
throw new HttpException(
`Space cannot be linked to a model because it has existing dependencies (devices, subspaces, or product allocations).`,
HttpStatus.BAD_REQUEST,
);
}
}
const hasSubspace = updateSpaceDto.subspace?.length > 0; const hasSubspace = updateSpaceDto.subspace?.length > 0;
const hasTags = updateSpaceDto.tags?.length > 0; const hasTags = updateSpaceDto.tags?.length > 0;