File
Implements
Index
Properties
|
|
Methods
|
|
Inputs
|
|
inputObject
|
Type : object
|
Default value : {}
|
|
Methods
inputLength
|
inputLength(inputObject: object)
|
|
Parameters :
Name |
Type |
Optional |
inputObject |
object
|
No
|
|
Private
transformObject
|
transformObject(inputObject: object)
|
|
Parameters :
Name |
Type |
Optional |
inputObject |
object
|
No
|
|
Private
_transformer
|
Default value : () => {...}
|
|
dataSource
|
Default value : new MatTreeFlatDataSource(
this.viewableTreeControl,
this.treeFlattener,
)
|
|
hasChild
|
Default value : () => {...}
|
|
treeFlattener
|
Default value : new MatTreeFlattener(
this._transformer,
(node) => node.level,
(node) => node.expandable,
(node) => node.children,
)
|
|
viewableTreeControl
|
Default value : new FlatTreeControl<ExampleFlatNode>(
(node) => node.level,
(node) => node.expandable,
)
|
|
import { FlatTreeControl } from '@angular/cdk/tree';
import { Component, Input, OnInit } from '@angular/core';
import {
MatTreeFlatDataSource,
MatTreeFlattener,
MatTreeModule,
} from '@angular/material/tree';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
/**
* Food data with nested structure.
* Each node has a name and an optional list of children.
*/
interface ObjectNode {
name: string;
value: any;
children?: ObjectNode[];
}
/** Flat node with expandable and level information */
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
@Component({
selector: 'cobbler-viewable-tree',
templateUrl: './viewable-tree.component.html',
styleUrls: ['./viewable-tree.component.scss'],
standalone: true,
imports: [MatTreeModule, MatButtonModule, MatIconModule],
})
export class ViewableTreeComponent implements OnInit {
@Input() inputObject: object = {};
viewableTreeControl = new FlatTreeControl<ExampleFlatNode>(
(node) => node.level,
(node) => node.expandable,
);
private _transformer = (node: ObjectNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
value: node.value,
level: level,
};
};
treeFlattener = new MatTreeFlattener(
this._transformer,
(node) => node.level,
(node) => node.expandable,
(node) => node.children,
);
dataSource = new MatTreeFlatDataSource(
this.viewableTreeControl,
this.treeFlattener,
);
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
constructor() {}
inputLength(inputObject: object): number {
return Object.keys(inputObject).length;
}
private transformObject(inputObject: object): ObjectNode[] {
const resultStructure = [];
let children = [];
Object.keys(inputObject).forEach((key) => {
if (
!Array.isArray(inputObject[key]) &&
typeof inputObject[key] === 'object'
) {
children = this.transformObject(inputObject[key]);
}
resultStructure.push({
name: key,
value: inputObject[key],
children: children,
});
});
return resultStructure;
}
ngOnInit(): void {
this.dataSource.data = this.transformObject(this.inputObject);
}
}
@if (inputLength(inputObject) > 0) {
<mat-tree [dataSource]="dataSource" [treeControl]="viewableTreeControl">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
{{ node.name }}: {{ node.value }}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node
*matTreeNodeDef="let node; when: hasChild"
matTreeNodePadding
>
<button
mat-icon-button
matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name"
>
<mat-icon class="mat-icon-rtl-mirror">
{{
viewableTreeControl.isExpanded(node)
? "expand_more"
: "chevron_right"
}}
</mat-icon>
</button>
{{ node.name }}
</mat-tree-node>
</mat-tree>
}
@if (inputLength(inputObject) === 0) {
<span class="settings-values"> { } </span>
}
Legend
Html element with directive