|
+
+ {{ allElementsVisible() ? '-' : '+'}}
+
{{options.capitalisedHeader ? (column | titlecase) : column}}
|
-
+
{{element.isExpanded ? 'keyboard_arrow_down' : 'keyboard_arrow_right'}}
{{element.value[column]}}
diff --git a/src/app/treetable/component/treetable.component.scss b/src/app/treetable/component/treetable.component.scss
index d24a222..88103ad 100644
--- a/src/app/treetable/component/treetable.component.scss
+++ b/src/app/treetable/component/treetable.component.scss
@@ -15,6 +15,13 @@ mat-icon {
background-color: #f0f0f5;
}
+.expand-all {
+ position: relative;
+ left: -15px;
+ cursor: pointer;
+ padding: 10px;
+}
+
td[class*=' mat-column']{
width: 10vw;
min-width: 10vw;;
diff --git a/src/app/treetable/component/treetable.component.spec.ts b/src/app/treetable/component/treetable.component.spec.ts
index cfa166e..2a047e7 100644
--- a/src/app/treetable/component/treetable.component.spec.ts
+++ b/src/app/treetable/component/treetable.component.spec.ts
@@ -36,7 +36,7 @@ describe('TreetableComponent', () => {
it('should emit an event when a node is clicked', () => {
const clickedNode = (component as any).treeTable[0];
component.nodeClicked.subscribe(n => expect(n).toBe(clickedNode));
- component.onNodeClick(clickedNode);
+ component.onNodeClick(clickedNode, new Event('click'));
});
});
diff --git a/src/app/treetable/component/treetable.component.ts b/src/app/treetable/component/treetable.component.ts
index a5258ff..4bc69e7 100644
--- a/src/app/treetable/component/treetable.component.ts
+++ b/src/app/treetable/component/treetable.component.ts
@@ -1,4 +1,12 @@
-import { Component, OnInit, Input, Output, ElementRef } from '@angular/core';
+import {
+ Component,
+ OnInit,
+ Input,
+ Output,
+ ElementRef,
+ OnChanges,
+ SimpleChanges,
+} from '@angular/core';
import { Node, TreeTableNode, Options, SearchableNode } from '../models';
import { TreeService } from '../services/tree/tree.service';
import { MatTableDataSource } from '@angular/material';
@@ -14,7 +22,7 @@ import { Subject } from 'rxjs';
templateUrl: './treetable.component.html',
styleUrls: ['./treetable.component.scss']
})
-export class TreetableComponent implements OnInit {
+export class TreetableComponent implements OnInit, OnChanges {
@Input() @Required tree: Node | Node[];
@Input() options: Options = {};
@Output() nodeClicked: Subject> = new Subject();
@@ -53,6 +61,17 @@ export class TreetableComponent implements OnInit {
this.dataSource = this.generateDataSource();
}
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes.tree.isFirstChange()) {
+ return;
+ }
+ this.tree = Array.isArray(this.tree) ? this.tree : [this.tree];
+ this.searchableTree = this.tree.map(t => this.converterService.toSearchableTree(t));
+ const treeTableTree = this.searchableTree.map(st => this.converterService.toTreeTableTree(st));
+ this.treeTable = flatMap(treeTableTree, this.treeService.flatten);
+ this.dataSource = this.generateDataSource();
+ }
+
extractNodeProps(tree: Node & { value: { [k: string]: any } }): string[] {
return Object.keys(tree.value).filter(x => typeof tree.value[x] !== 'object');
}
@@ -69,7 +88,8 @@ export class TreetableComponent implements OnInit {
return `mat-elevation-z${this.options.elevation}`;
}
- onNodeClick(clickedNode: TreeTableNode): void {
+ onNodeClick(clickedNode: TreeTableNode, $event: Event): void {
+ $event.stopPropagation();
clickedNode.isExpanded = !clickedNode.isExpanded;
this.treeTable.forEach(el => {
el.isVisible = this.searchableTree.every(st => {
@@ -82,6 +102,27 @@ export class TreetableComponent implements OnInit {
this.nodeClicked.next(clickedNode);
}
+ toggleAll() {
+ if (!this.allElementsVisible()) {
+ this.treeTable.forEach(item => {
+ item.isExpanded = true;
+ item.isVisible = true;
+ });
+ } else {
+ this.treeTable.forEach((item, index) => {
+ item.isExpanded = false;
+ if (index > 0) {
+ item.isVisible = false;
+ }
+ });
+ }
+ this.dataSource = this.generateDataSource();
+ }
+
+ allElementsVisible(): boolean {
+ return this.treeTable.slice(1).every(item => item.isVisible);
+ }
+
// Overrides default options with those specified by the user
parseOptions(defaultOpts: Options): Options {
return defaults(this.options, defaultOpts);
|