diff --git a/src/app/treetable/component/treetable.component.html b/src/app/treetable/component/treetable.component.html index a354a30..144b4de 100644 --- a/src/app/treetable/component/treetable.component.html +++ b/src/app/treetable/component/treetable.component.html @@ -3,13 +3,17 @@
+ + {{ 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);