175 lines
4.6 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,
2019-11-21 10:29:19 +09:00
AfterViewInit,
OnDestroy
} 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';
2019-11-25 09:34:12 +09:00
import { ucapAnimations } from '@ucap-webmessenger/ui';
import { trigger, transition, style, animate } from '@angular/animations';
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',
2019-11-25 09:34:12 +09:00
styleUrls: ['./tree.component.scss'],
animations: [
ucapAnimations,
trigger('romvoeAdd', [
transition('remove <=> add', [
style({
transform: `rotate(45deg)`,
opacity: 0
}),
animate('.2s 0s ease-out')
])
])
]
2019-10-04 13:45:02 +09:00
})
2019-11-21 10:29:19 +09:00
export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
2019-10-07 10:08:14 +09:00
@Output()
selected = new EventEmitter<DeptInfo>();
@Input()
loginRes: LoginResponse;
2019-11-21 10:29:19 +09:00
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() {}
2019-11-21 10:29:19 +09:00
ngOnDestroy(): void {
this.logger.debug('-----------------------TreeComponent ngOnDestroy');
}
ngAfterViewInit(): void {
this.dataSource.cdkVirtualScrollViewport = this.cvsvOrganization;
}
hasChild = (_: number, node: FlatNode) => node.expandable;
2019-10-07 10:08:14 +09:00
2019-11-25 09:34:12 +09:00
isLastNode(node: FlatNode): boolean {
const i = this.dataSource.expandedDataSubject.value.findIndex(n => {
return node.deptInfo.seq === n.deptInfo.seq;
});
if (i === this.dataSource.expandedDataSubject.value.length - 1) {
return true;
}
if (node.level !== this.dataSource.expandedDataSubject.value[i + 1].level) {
return true;
}
return false;
}
onClickNode(node: OrganizationNode) {
2019-10-07 10:08:14 +09:00
this.selected.emit(node.deptInfo);
}
2019-10-04 13:45:02 +09:00
}