added community info and tag

This commit is contained in:
hannathkadher
2025-04-17 10:41:39 +04:00
parent 4810cc6f35
commit c677be400c
2 changed files with 79 additions and 58 deletions

View File

@ -8,7 +8,6 @@ import { SpaceLinkEntity } from './space-link.entity';
import { SceneEntity } from '../../scene/entities'; import { SceneEntity } from '../../scene/entities';
import { SpaceModelEntity } from '../../space-model'; import { SpaceModelEntity } from '../../space-model';
import { InviteUserSpaceEntity } from '../../Invite-user/entities'; import { InviteUserSpaceEntity } from '../../Invite-user/entities';
import { TagEntity } from './tag.entity';
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';
@ -103,9 +102,6 @@ export class SpaceEntity extends AbstractEntity<SpaceDto> {
) )
invitedUsers: InviteUserSpaceEntity[]; invitedUsers: InviteUserSpaceEntity[];
@OneToMany(() => TagEntity, (tag) => tag.space)
tags: TagEntity[];
@OneToMany( @OneToMany(
() => SpaceProductAllocationEntity, () => SpaceProductAllocationEntity,
(allocation) => allocation.space, (allocation) => allocation.space,

View File

@ -23,6 +23,7 @@ import { format } from '@fast-csv/format';
import { PassThrough } from 'stream'; import { PassThrough } from 'stream';
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity'; import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
import { SpaceService } from 'src/space/services'; import { SpaceService } from 'src/space/services';
import { ORPHAN_COMMUNITY_NAME } from '@app/common/constants/orphan-constant';
@Injectable() @Injectable()
export class ProjectService { export class ProjectService {
@ -229,7 +230,18 @@ export class ProjectService {
async exportToCsv(param: GetProjectParam): Promise<PassThrough> { async exportToCsv(param: GetProjectParam): Promise<PassThrough> {
const project = await this.projectRepository.findOne({ const project = await this.projectRepository.findOne({
where: { uuid: param.projectUuid }, where: { uuid: param.projectUuid },
relations: ['communities', 'communities.spaces'], relations: [
'communities',
'communities.spaces',
'communities.spaces.parent',
'communities.spaces.productAllocations',
'communities.spaces.productAllocations.product',
'communities.spaces.productAllocations.tags',
'communities.spaces.subspaces',
'communities.spaces.subspaces.productAllocations',
'communities.spaces.subspaces.productAllocations.product',
'communities.spaces.subspaces.productAllocations.tags',
],
}); });
if (!project) { if (!project) {
@ -239,25 +251,13 @@ export class ProjectService {
); );
} }
const allCommunitySpaces: SpaceEntity[] = [];
// Step 1: Load the entire space hierarchy for each community
for (const community of project.communities || []) {
const { data: spaceHierarchy } =
await this.spaceService.getSpacesHierarchyForCommunity(
{ communityUuid: community.uuid, projectUuid: project.uuid },
{ search: '', onlyWithDevices: false },
);
allCommunitySpaces.push(...(spaceHierarchy as SpaceEntity[]));
}
// Step 2: Setup CSV
const stream = new PassThrough(); const stream = new PassThrough();
const csvStream = format({ const csvStream = format({
headers: [ headers: [
'Project Name', 'Project Name',
'Project UUID', 'Project UUID',
'Community Name',
'Community UUID',
'Space Location', 'Space Location',
'Space Name', 'Space Name',
'Space UUID', 'Space UUID',
@ -267,53 +267,78 @@ export class ProjectService {
'Tag Product Name', 'Tag Product Name',
], ],
}); });
csvStream.pipe(stream); csvStream.pipe(stream);
// Step 3: Recursive flattening const allSpaces: SpaceEntity[] = [];
const writeSpaceData = (space: any, path: string[] = []) => { for (const community of project.communities) {
const location = path.join(' > '); if (community.name === `${ORPHAN_COMMUNITY_NAME}-${project.name}`)
continue;
for (const space of community.spaces) {
if (!space.disabled) {
space.community = community;
allSpaces.push(space);
}
}
}
const spaceMap = new Map<string, SpaceEntity>();
for (const space of allSpaces) {
spaceMap.set(space.uuid, space);
}
function buildSpaceLocation(space: SpaceEntity): string {
const path: string[] = [];
let current = space.parent;
while (current) {
path.unshift(current.spaceName);
current = current.parent ?? spaceMap.get(current.uuid)?.parent ?? null;
}
return path.join(' > ');
}
for (const space of allSpaces) {
const spaceLocation = buildSpaceLocation(space);
// 1. Subspaces and their tags
for (const subspace of space.subspaces || []) { for (const subspace of space.subspaces || []) {
for (const tag of subspace.tags || []) { if (subspace.disabled) continue;
csvStream.write({
'Project Name': project.name, for (const productAllocation of subspace.productAllocations || []) {
'Project UUID': project.uuid, for (const tag of productAllocation.tags || []) {
'Space Location': location, csvStream.write({
'Space Name': space.spaceName, 'Project Name': project.name,
'Space UUID': space.uuid, 'Project UUID': project.uuid,
'Subspace Name': subspace.subspaceName || '', 'Community Name': space.community?.name || '',
'Subspace UUID': subspace.uuid, 'Community UUID': space.community?.uuid || '',
Tag: tag.tag, 'Space Location': spaceLocation,
'Tag Product Name': tag.product?.productName || '', 'Space Name': space.spaceName,
}); 'Space UUID': space.uuid,
'Subspace Name': subspace.subspaceName || '',
'Subspace UUID': subspace.uuid,
Tag: tag.name,
'Tag Product Name': productAllocation.product.name || '',
});
}
} }
} }
// 2. Tags directly on the space for (const productAllocation of space.productAllocations || []) {
for (const tag of space.tags || []) { for (const tag of productAllocation.tags || []) {
csvStream.write({ csvStream.write({
'Project Name': project.name, 'Project Name': project.name,
'Project UUID': project.uuid, 'Project UUID': project.uuid,
'Space Location': location, 'Community Name': space.community?.name || '',
'Space Name': space.spaceName, 'Community UUID': space.community?.uuid || '',
'Space UUID': space.uuid, 'Space Location': spaceLocation,
'Subspace Name': '', 'Space Name': space.spaceName,
'Subspace UUID': '', 'Space UUID': space.uuid,
Tag: tag.tag, 'Subspace Name': '',
'Tag Product Name': tag.product?.productName || '', 'Subspace UUID': '',
}); Tag: tag.name,
'Tag Product Name': productAllocation.product.name || '',
});
}
} }
// 3. Recursively process children
for (const child of space.children || []) {
writeSpaceData(child, [...path, space.spaceName]);
}
};
// Step 4: Flatten the hierarchy starting from roots
for (const rootSpace of allCommunitySpaces) {
writeSpaceData(rootSpace, []);
} }
csvStream.end(); csvStream.end();