mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-10 07:07:21 +00:00
add order space API (#459)
This commit is contained in:
@ -220,6 +220,11 @@ export class ControllerRoute {
|
|||||||
public static readonly UPDATE_SPACE_DESCRIPTION =
|
public static readonly UPDATE_SPACE_DESCRIPTION =
|
||||||
'Updates a space by its UUID and community ID. You can update the name, parent space, and other properties. If a parent space is provided and not already a parent, its `isParent` flag will be set to true.';
|
'Updates a space by its UUID and community ID. You can update the name, parent space, and other properties. If a parent space is provided and not already a parent, its `isParent` flag will be set to true.';
|
||||||
|
|
||||||
|
public static readonly UPDATE_CHILDREN_SPACES_ORDER_OF_A_SPACE_SUMMARY =
|
||||||
|
'Update the order of child spaces under a specific parent space';
|
||||||
|
public static readonly UPDATE_CHILDREN_SPACES_ORDER_OF_A_SPACE_DESCRIPTION =
|
||||||
|
'Updates the order of child spaces under a specific parent space. You can provide a new order for the child spaces.';
|
||||||
|
|
||||||
public static readonly GET_HEIRARCHY_SUMMARY = 'Get space hierarchy';
|
public static readonly GET_HEIRARCHY_SUMMARY = 'Get space hierarchy';
|
||||||
public static readonly GET_HEIRARCHY_DESCRIPTION =
|
public static readonly GET_HEIRARCHY_DESCRIPTION =
|
||||||
'This endpoint retrieves the hierarchical structure of spaces under a given space ID. It returns all the child spaces nested within the specified space, organized by their parent-child relationships. ';
|
'This endpoint retrieves the hierarchical structure of spaces under a given space ID. It returns all the child spaces nested within the specified space, organized by their parent-child relationships. ';
|
||||||
|
@ -6,9 +6,9 @@ import {
|
|||||||
OneToMany,
|
OneToMany,
|
||||||
OneToOne,
|
OneToOne,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import { SpaceDto } from '../dtos';
|
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { AqiSpaceDailyPollutantStatsEntity } from '../../aqi/entities';
|
import { AqiSpaceDailyPollutantStatsEntity } from '../../aqi/entities';
|
||||||
|
import { BookableSpaceEntity } from '../../booking/entities';
|
||||||
import { CommunityEntity } from '../../community/entities';
|
import { CommunityEntity } from '../../community/entities';
|
||||||
import { DeviceEntity } from '../../device/entities';
|
import { DeviceEntity } from '../../device/entities';
|
||||||
import { InviteUserSpaceEntity } from '../../Invite-user/entities';
|
import { InviteUserSpaceEntity } from '../../Invite-user/entities';
|
||||||
@ -17,9 +17,9 @@ import { PresenceSensorDailySpaceEntity } from '../../presence-sensor/entities';
|
|||||||
import { SceneEntity } from '../../scene/entities';
|
import { SceneEntity } from '../../scene/entities';
|
||||||
import { SpaceModelEntity } from '../../space-model';
|
import { SpaceModelEntity } from '../../space-model';
|
||||||
import { UserSpaceEntity } from '../../user/entities';
|
import { UserSpaceEntity } from '../../user/entities';
|
||||||
|
import { SpaceDto } from '../dtos';
|
||||||
import { SpaceProductAllocationEntity } from './space-product-allocation.entity';
|
import { SpaceProductAllocationEntity } from './space-product-allocation.entity';
|
||||||
import { SubspaceEntity } from './subspace/subspace.entity';
|
import { SubspaceEntity } from './subspace/subspace.entity';
|
||||||
import { BookableSpaceEntity } from '../../booking/entities';
|
|
||||||
|
|
||||||
@Entity({ name: 'space' })
|
@Entity({ name: 'space' })
|
||||||
export class SpaceEntity extends AbstractEntity<SpaceDto> {
|
export class SpaceEntity extends AbstractEntity<SpaceDto> {
|
||||||
@ -64,6 +64,12 @@ export class SpaceEntity extends AbstractEntity<SpaceDto> {
|
|||||||
})
|
})
|
||||||
public disabled: boolean;
|
public disabled: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
type: Number,
|
||||||
|
})
|
||||||
|
public order?: number;
|
||||||
|
|
||||||
@OneToMany(() => SubspaceEntity, (subspace) => subspace.space, {
|
@OneToMany(() => SubspaceEntity, (subspace) => subspace.space, {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
|
||||||
import { SpaceService } from '../services';
|
|
||||||
import { ControllerRoute } from '@app/common/constants/controller-route';
|
import { ControllerRoute } from '@app/common/constants/controller-route';
|
||||||
|
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||||
import {
|
import {
|
||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
@ -12,12 +11,14 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { AddSpaceDto, CommunitySpaceParam, UpdateSpaceDto } from '../dtos';
|
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
|
||||||
import { GetSpaceParam } from '../dtos/get.space.param';
|
|
||||||
import { PermissionsGuard } from 'src/guards/permissions.guard';
|
|
||||||
import { Permissions } from 'src/decorators/permissions.decorator';
|
import { Permissions } from 'src/decorators/permissions.decorator';
|
||||||
|
import { PermissionsGuard } from 'src/guards/permissions.guard';
|
||||||
|
import { AddSpaceDto, CommunitySpaceParam, UpdateSpaceDto } from '../dtos';
|
||||||
import { GetSpaceDto } from '../dtos/get.space.dto';
|
import { GetSpaceDto } from '../dtos/get.space.dto';
|
||||||
|
import { GetSpaceParam } from '../dtos/get.space.param';
|
||||||
|
import { OrderSpacesDto } from '../dtos/order.spaces.dto';
|
||||||
|
import { SpaceService } from '../services';
|
||||||
|
|
||||||
@ApiTags('Space Module')
|
@ApiTags('Space Module')
|
||||||
@Controller({
|
@Controller({
|
||||||
@ -65,6 +66,26 @@ export class SpaceController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(PermissionsGuard)
|
||||||
|
@Permissions('SPACE_UPDATE')
|
||||||
|
@ApiOperation({
|
||||||
|
summary:
|
||||||
|
ControllerRoute.SPACE.ACTIONS
|
||||||
|
.UPDATE_CHILDREN_SPACES_ORDER_OF_A_SPACE_SUMMARY,
|
||||||
|
description:
|
||||||
|
ControllerRoute.SPACE.ACTIONS
|
||||||
|
.UPDATE_CHILDREN_SPACES_ORDER_OF_A_SPACE_DESCRIPTION,
|
||||||
|
})
|
||||||
|
@Post(':parentSpaceUuid/spaces/order')
|
||||||
|
async updateSpacesOrder(
|
||||||
|
@Body() orderSpacesDto: OrderSpacesDto,
|
||||||
|
@Param() communitySpaceParam: CommunitySpaceParam,
|
||||||
|
@Param('parentSpaceUuid') parentSpaceUuid: string,
|
||||||
|
) {
|
||||||
|
return this.spaceService.updateSpacesOrder(parentSpaceUuid, orderSpacesDto);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(PermissionsGuard)
|
@UseGuards(PermissionsGuard)
|
||||||
@Permissions('SPACE_DELETE')
|
@Permissions('SPACE_DELETE')
|
||||||
|
13
src/space/dtos/order.spaces.dto.ts
Normal file
13
src/space/dtos/order.spaces.dto.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ArrayUnique, IsNotEmpty, IsUUID } from 'class-validator';
|
||||||
|
|
||||||
|
export class OrderSpacesDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'List of children spaces associated with the space',
|
||||||
|
type: [String],
|
||||||
|
})
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ArrayUnique()
|
||||||
|
@IsUUID('4', { each: true, message: 'Invalid space UUID provided' })
|
||||||
|
spacesUuids: string[];
|
||||||
|
}
|
@ -33,6 +33,7 @@ import {
|
|||||||
} from '../dtos';
|
} from '../dtos';
|
||||||
import { CreateProductAllocationDto } from '../dtos/create-product-allocation.dto';
|
import { CreateProductAllocationDto } from '../dtos/create-product-allocation.dto';
|
||||||
import { GetSpaceDto } from '../dtos/get.space.dto';
|
import { GetSpaceDto } from '../dtos/get.space.dto';
|
||||||
|
import { OrderSpacesDto } from '../dtos/order.spaces.dto';
|
||||||
import { SpaceWithParentsDto } from '../dtos/space.parents.dto';
|
import { SpaceWithParentsDto } from '../dtos/space.parents.dto';
|
||||||
import { SpaceProductAllocationService } from './space-product-allocation.service';
|
import { SpaceProductAllocationService } from './space-product-allocation.service';
|
||||||
import { ValidationService } from './space-validation.service';
|
import { ValidationService } from './space-validation.service';
|
||||||
@ -355,6 +356,32 @@ export class SpaceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateSpacesOrder(
|
||||||
|
parentSpaceUuid: string,
|
||||||
|
{ spacesUuids }: OrderSpacesDto,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await this.spaceRepository.update(
|
||||||
|
{ uuid: In(spacesUuids), parent: { uuid: parentSpaceUuid } },
|
||||||
|
{
|
||||||
|
order: () =>
|
||||||
|
'CASE ' +
|
||||||
|
spacesUuids
|
||||||
|
.map((s, index) => `WHEN uuid = '${s}' THEN ${index + 1}`)
|
||||||
|
.join(' ') +
|
||||||
|
' END',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating spaces order:', error);
|
||||||
|
throw new HttpException(
|
||||||
|
'An error occurred while updating spaces order',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async delete(params: GetSpaceParam): Promise<BaseResponseDto> {
|
async delete(params: GetSpaceParam): Promise<BaseResponseDto> {
|
||||||
const queryRunner = this.dataSource.createQueryRunner();
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
@ -709,10 +736,21 @@ export class SpaceService {
|
|||||||
rootSpaces.push(map.get(space.uuid)!); // Push only root spaces
|
rootSpaces.push(map.get(space.uuid)!); // Push only root spaces
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
rootSpaces.forEach(this.sortSpaceChildren.bind(this));
|
||||||
return rootSpaces;
|
return rootSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sortSpaceChildren(space: SpaceEntity) {
|
||||||
|
if (space.children && space.children.length > 0) {
|
||||||
|
space.children.sort((a, b) => {
|
||||||
|
const aOrder = a.order ?? Infinity;
|
||||||
|
const bOrder = b.order ?? Infinity;
|
||||||
|
return aOrder - bOrder;
|
||||||
|
});
|
||||||
|
space.children.forEach(this.sortSpaceChildren.bind(this)); // Recursively sort children of children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private validateSpaceCreationCriteria({
|
private validateSpaceCreationCriteria({
|
||||||
spaceModelUuid,
|
spaceModelUuid,
|
||||||
productAllocations,
|
productAllocations,
|
||||||
|
Reference in New Issue
Block a user