mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
/*!
|
|
* @license
|
|
* Copyright 2016 Alfresco Software, Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { Injectable } from '@angular/core';
|
|
import { CollectionViewer, SelectionChange } from '@angular/cdk/collections';
|
|
import { BehaviorSubject, merge, Observable } from 'rxjs';
|
|
import { map } from 'rxjs/operators';
|
|
import { FlatTreeControl } from '@angular/cdk/tree';
|
|
import { TreeBaseNode } from '../models/tree-view.model';
|
|
import { TreeViewService } from '../services/tree-view.service';
|
|
|
|
@Injectable()
|
|
export class TreeViewDataSource {
|
|
|
|
treeNodes: TreeBaseNode[];
|
|
dataChange = new BehaviorSubject<TreeBaseNode[]>([]);
|
|
childrenSubscription = null;
|
|
changeSubscription = null;
|
|
|
|
get data(): TreeBaseNode[] {
|
|
return this.treeNodes;
|
|
}
|
|
|
|
set data(value: TreeBaseNode[]) {
|
|
this.treeControl.dataNodes = value;
|
|
this.dataChange.next(value);
|
|
}
|
|
|
|
constructor(private treeControl: FlatTreeControl<TreeBaseNode>,
|
|
private treeViewService: TreeViewService) {
|
|
this.dataChange.subscribe((treeNodes) => this.treeNodes = treeNodes);
|
|
}
|
|
|
|
connect(collectionViewer: CollectionViewer): Observable<TreeBaseNode[]> {
|
|
this.changeSubscription = this.treeControl.expansionModel.onChange.subscribe((change) => {
|
|
if ((change as SelectionChange<TreeBaseNode>).added &&
|
|
(change as SelectionChange<TreeBaseNode>).added.length > 0) {
|
|
this.expandTreeNodes(change as SelectionChange<TreeBaseNode>);
|
|
} else if ((change as SelectionChange<TreeBaseNode>).removed) {
|
|
this.reduceTreeNodes(change as SelectionChange<TreeBaseNode>);
|
|
}
|
|
});
|
|
return merge(collectionViewer.viewChange, this.dataChange).pipe(map(() => this.data));
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.childrenSubscription) {
|
|
this.childrenSubscription.unsubscribe();
|
|
}
|
|
if (this.changeSubscription) {
|
|
this.changeSubscription.unsubscribe();
|
|
}
|
|
}
|
|
|
|
private expandTreeNodes(change: SelectionChange<TreeBaseNode>) {
|
|
change.added.forEach((node) => this.expandNode(node));
|
|
}
|
|
|
|
private reduceTreeNodes(change: SelectionChange<TreeBaseNode>) {
|
|
change.removed.slice().reverse().forEach((node) => this.toggleNode(node));
|
|
}
|
|
|
|
private expandNode(node: TreeBaseNode) {
|
|
this.childrenSubscription = this.treeViewService.getTreeNodes(node.nodeId)
|
|
.subscribe((children) => {
|
|
const index = this.data.indexOf(node);
|
|
if (!children || index < 0) {
|
|
node.expandable = false;
|
|
return;
|
|
}
|
|
const nodes = children.map((actualNode) => {
|
|
actualNode.level = node.level + 1;
|
|
return actualNode;
|
|
});
|
|
this.data.splice(index + 1, 0, ...nodes);
|
|
this.dataChange.next(this.data);
|
|
});
|
|
}
|
|
|
|
toggleNode(node: TreeBaseNode) {
|
|
const index = this.data.indexOf(node);
|
|
let count = 0;
|
|
for (let i = index + 1; i < this.data.length
|
|
&& this.data[i].level > node.level; i++ , count++) { }
|
|
this.data.splice(index + 1, count);
|
|
this.dataChange.next(this.data);
|
|
}
|
|
|
|
}
|