140 lines
3.7 KiB
TypeScript
Raw Normal View History

import {
Component,
OnInit,
Input,
ChangeDetectorRef,
2019-10-07 10:08:14 +09:00
ViewChild,
Output,
2019-10-31 10:13:30 +09:00
EventEmitter,
AfterViewInit
} from '@angular/core';
import { MatTreeFlattener, MatTree } from '@angular/material';
import { NGXLogger } from 'ngx-logger';
import { DeptInfo } from '@ucap-webmessenger/protocol-query';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { FlatTreeControl } from '@angular/cdk/tree';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { VirtualScrollTreeFlatDataSource } from '@ucap-webmessenger/ui';
interface OrganizationNode {
deptInfo: DeptInfo;
name: string;
children?: OrganizationNode[];
}
/** Flat node with expandable and level information */
interface FlatNode {
expandable: boolean;
name: string;
level: number;
deptInfo: DeptInfo;
}
2019-10-04 13:45:02 +09:00
@Component({
selector: 'ucap-organization-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.scss']
})
2019-10-31 10:13:30 +09:00
export class TreeComponent implements OnInit, AfterViewInit {
2019-10-07 10:08:14 +09:00
@Output()
selected = new EventEmitter<DeptInfo>();
@Input()
loginRes: LoginResponse;
2019-10-04 13:45:02 +09:00
@Input()
set oraganizationList(deptInfoList: DeptInfo[]) {
if (!deptInfoList || 0 === deptInfoList.length) {
return;
}
const nodeMap = new Map<number, OrganizationNode>();
const rootNodeList: OrganizationNode[] = [];
const remainChildNodeList: OrganizationNode[] = [];
let myNode: OrganizationNode;
deptInfoList.forEach(deptInfo => {
const node: OrganizationNode = {
deptInfo,
name: deptInfo.name,
children: []
};
if (nodeMap.has(deptInfo.seq)) {
this.logger.warn('duplicate seq', deptInfo.seq);
return;
}
nodeMap.set(deptInfo.seq, node);
if (deptInfo.seq === this.loginRes.departmentCode) {
myNode = node;
}
if (0 === deptInfo.parentSeq) {
rootNodeList.push(node);
return;
}
2019-10-04 13:45:02 +09:00
if (nodeMap.has(deptInfo.parentSeq)) {
nodeMap.get(deptInfo.parentSeq).children.push(node);
} else {
remainChildNodeList.push(node);
}
});
remainChildNodeList.forEach(node => {
if (nodeMap.has(node.deptInfo.parentSeq)) {
nodeMap.get(node.deptInfo.parentSeq).children.push(node);
}
});
this.dataSource.data = rootNodeList;
}
@ViewChild('cvsvOrganization', { static: false })
cvsvOrganization: CdkVirtualScrollViewport;
@ViewChild('orgranizationTree', { static: false })
orgranizationTree: MatTree<OrganizationNode>;
treeControl: FlatTreeControl<FlatNode>;
treeFlattener: MatTreeFlattener<OrganizationNode, FlatNode>;
dataSource: VirtualScrollTreeFlatDataSource<OrganizationNode, FlatNode>;
constructor(
private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger
) {
this.treeControl = new FlatTreeControl<FlatNode>(
node => node.level,
node => node.expandable
);
this.treeFlattener = new MatTreeFlattener<OrganizationNode, FlatNode>(
(node: OrganizationNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level,
deptInfo: node.deptInfo
};
},
node => node.level,
node => node.expandable,
node => node.children
);
this.dataSource = new VirtualScrollTreeFlatDataSource<
OrganizationNode,
FlatNode
>(this.treeControl, this.treeFlattener);
}
2019-10-04 13:45:02 +09:00
ngOnInit() {}
ngAfterViewInit(): void {
this.dataSource.cdkVirtualScrollViewport = this.cvsvOrganization;
}
hasChild = (_: number, node: FlatNode) => node.expandable;
2019-10-07 10:08:14 +09:00
onClickNode(node: OrganizationNode) {
2019-10-07 10:08:14 +09:00
this.selected.emit(node.deptInfo);
}
2019-10-04 13:45:02 +09:00
}