120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
|
|
import { BaseManager } from '../core/base-manager';
|
||
|
|
import { BimCollapse } from '../components/collapse/index';
|
||
|
|
import { BimDescription } from '../components/description/index';
|
||
|
|
|
||
|
|
export class ComponentDetailManager extends BaseManager {
|
||
|
|
private dialogId = 'component-detail-dialog';
|
||
|
|
private dialog: any = null;
|
||
|
|
|
||
|
|
constructor() {
|
||
|
|
super();
|
||
|
|
}
|
||
|
|
|
||
|
|
public show(modelUrl: string, componentId: string): void {
|
||
|
|
if (!this.registry.dialog) {
|
||
|
|
console.warn('[ComponentDetailManager] Dialog manager not initialized');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.isOpen()) {
|
||
|
|
this.hide();
|
||
|
|
}
|
||
|
|
|
||
|
|
this.createDialog();
|
||
|
|
this.showLoading();
|
||
|
|
|
||
|
|
this.registry.engine3d?.getComponentProperties(modelUrl, componentId, (data) => {
|
||
|
|
this.renderProperties(data, componentId);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private createDialog(): void {
|
||
|
|
const width = 400;
|
||
|
|
const x = document.body.clientWidth - width - 40;
|
||
|
|
|
||
|
|
this.dialog = this.registry.dialog?.create({
|
||
|
|
id: this.dialogId,
|
||
|
|
title: 'panel.componentDetail.title',
|
||
|
|
content: '',
|
||
|
|
width: `${width}px`,
|
||
|
|
height: '500px',
|
||
|
|
position: { x, y: 20 },
|
||
|
|
resizable: true,
|
||
|
|
onClose: () => this.hide()
|
||
|
|
} as any);
|
||
|
|
}
|
||
|
|
|
||
|
|
private showLoading(): void {
|
||
|
|
const container = document.createElement('div');
|
||
|
|
container.style.padding = '20px';
|
||
|
|
container.style.textAlign = 'center';
|
||
|
|
container.textContent = '加载中...';
|
||
|
|
this.dialog?.setContent(container);
|
||
|
|
}
|
||
|
|
|
||
|
|
private renderProperties(data: any, _componentId: string): void {
|
||
|
|
if (!this.dialog) return;
|
||
|
|
|
||
|
|
const container = document.createElement('div');
|
||
|
|
container.style.height = '100%';
|
||
|
|
container.style.overflowY = 'auto';
|
||
|
|
|
||
|
|
const properties = data?.properties || [];
|
||
|
|
|
||
|
|
if (properties.length === 0) {
|
||
|
|
container.innerHTML = '<div style="padding:20px;text-align:center;">无属性数据</div>';
|
||
|
|
this.dialog.setContent(container);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const collapseItems = properties.map((category: any, index: number) => ({
|
||
|
|
id: `category-${index}`,
|
||
|
|
title: category.name || `分类 ${index + 1}`,
|
||
|
|
content: this.createCategoryContent(category.children || [])
|
||
|
|
}));
|
||
|
|
|
||
|
|
new BimCollapse({
|
||
|
|
container,
|
||
|
|
accordion: false,
|
||
|
|
activeIds: collapseItems.length > 0 ? [collapseItems[0].id] : [],
|
||
|
|
items: collapseItems
|
||
|
|
});
|
||
|
|
|
||
|
|
this.dialog.setContent(container);
|
||
|
|
}
|
||
|
|
|
||
|
|
private createCategoryContent(items: any[]): HTMLElement {
|
||
|
|
const container = document.createElement('div');
|
||
|
|
|
||
|
|
const descItems = items.map((item: any) => ({
|
||
|
|
label: item.name || '-',
|
||
|
|
value: String(item.value ?? '-')
|
||
|
|
}));
|
||
|
|
|
||
|
|
new BimDescription({
|
||
|
|
container,
|
||
|
|
labelWidth: '120px',
|
||
|
|
bordered: true,
|
||
|
|
items: descItems
|
||
|
|
});
|
||
|
|
|
||
|
|
return container;
|
||
|
|
}
|
||
|
|
|
||
|
|
public isOpen(): boolean {
|
||
|
|
return this.dialog !== null;
|
||
|
|
}
|
||
|
|
|
||
|
|
public hide(): void {
|
||
|
|
if (this.dialog) {
|
||
|
|
this.dialog.destroy();
|
||
|
|
this.dialog = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public destroy(): void {
|
||
|
|
this.hide();
|
||
|
|
super.destroy();
|
||
|
|
}
|
||
|
|
}
|