mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
feat(devtools): pass each datasource through to it's own material tree component
This commit is contained in:
parent
2d34a209a6
commit
6d0c4093c2
11 changed files with 70 additions and 188 deletions
|
|
@ -12,6 +12,11 @@ export enum PropertyViewFilterOptions {
|
|||
STATE,
|
||||
}
|
||||
|
||||
export interface DirectiveTreeData {
|
||||
dataSource: PropertyDataSource;
|
||||
treeControl: FlatTreeControl<FlatNode>;
|
||||
}
|
||||
|
||||
const expandable = (prop: Descriptor) => {
|
||||
if (!prop) {
|
||||
return false;
|
||||
|
|
@ -61,9 +66,9 @@ export class DirectivePropertyResolver {
|
|||
this._onReceivedNestedProperties
|
||||
);
|
||||
|
||||
_inputsDataSource: PropertyDataSource;
|
||||
_outputsDataSource: PropertyDataSource;
|
||||
_stateDataSource: PropertyDataSource;
|
||||
private _inputsDataSource: PropertyDataSource;
|
||||
private _outputsDataSource: PropertyDataSource;
|
||||
private _stateDataSource: PropertyDataSource;
|
||||
|
||||
constructor(
|
||||
private _messageBus: MessageBus<Events>,
|
||||
|
|
@ -82,15 +87,15 @@ export class DirectivePropertyResolver {
|
|||
};
|
||||
}
|
||||
|
||||
get directiveInputControls(): { dataSource: PropertyDataSource; treeControl: FlatTreeControl<FlatNode> } {
|
||||
get directiveInputControls(): DirectiveTreeData {
|
||||
return getDirectiveControls(this._inputsDataSource);
|
||||
}
|
||||
|
||||
get directiveOutputControls(): { dataSource: PropertyDataSource; treeControl: FlatTreeControl<FlatNode> } {
|
||||
get directiveOutputControls(): DirectiveTreeData {
|
||||
return getDirectiveControls(this._outputsDataSource);
|
||||
}
|
||||
|
||||
get directiveStateControls(): { dataSource: PropertyDataSource; treeControl: FlatTreeControl<FlatNode> } {
|
||||
get directiveStateControls(): DirectiveTreeData {
|
||||
return getDirectiveControls(this._stateDataSource);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { map } from 'rxjs/operators';
|
|||
import { DefaultIterableDiffer } from '@angular/core';
|
||||
import { diff } from '../../diffing';
|
||||
import { FlatNode, Property } from './element-property-resolver';
|
||||
import { PropertyViewFilterOptions } from './directive-property-resolver';
|
||||
|
||||
const expandable = (prop: Descriptor, messageBus?: MessageBus<Events>) => {
|
||||
if (!prop) {
|
||||
|
|
@ -32,8 +31,6 @@ export class PropertyDataSource extends DataSource<FlatNode> {
|
|||
private _expandedData = new BehaviorSubject<FlatNode[]>([]);
|
||||
private _differ = new DefaultIterableDiffer(trackBy);
|
||||
|
||||
private readonly _originalData: FlatNode[];
|
||||
|
||||
constructor(
|
||||
props: { [prop: string]: Descriptor },
|
||||
private _treeFlattener: MatTreeFlattener<Property, FlatNode>,
|
||||
|
|
@ -44,8 +41,7 @@ export class PropertyDataSource extends DataSource<FlatNode> {
|
|||
private _onReceivedNestedProperties: () => void
|
||||
) {
|
||||
super();
|
||||
this._originalData = this._treeFlattener.flattenNodes(this._arrayify(props));
|
||||
this._data.next(this._originalData);
|
||||
this._data.next(this._treeFlattener.flattenNodes(this._arrayify(props)));
|
||||
}
|
||||
|
||||
get data(): FlatNode[] {
|
||||
|
|
@ -130,24 +126,4 @@ export class PropertyDataSource extends DataSource<FlatNode> {
|
|||
this._onReceivedNestedProperties();
|
||||
});
|
||||
}
|
||||
|
||||
filterDataSource(filter: string[] | null): void {
|
||||
if (filter === null) {
|
||||
return;
|
||||
}
|
||||
let pushFlag = false;
|
||||
const filteredData: FlatNode[] = [];
|
||||
|
||||
// tslint:disable-next-line:prefer-for-of
|
||||
for (let i = 0; i < this._originalData.length; i++) {
|
||||
const node = this._originalData[i];
|
||||
if (node.level === 0) {
|
||||
pushFlag = filter.includes(node.prop.name);
|
||||
}
|
||||
if (pushFlag) {
|
||||
filteredData.push(node);
|
||||
}
|
||||
}
|
||||
this._data.next(filteredData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,26 @@
|
|||
<mat-tree *ngIf="treeControl" class="property-list" [dataSource]="dataSource" [treeControl]="treeControl">
|
||||
<mat-tree-node matTreeNodePaddingIndent="14" *matTreeNodeDef="let node" matTreeNodePadding>
|
||||
<span class="name non-expandable"> {{ node.prop.name }} </span>:
|
||||
<ng-container *ngIf="!node.prop.descriptor.editable; else editable">
|
||||
<span class="value">
|
||||
{{ node.prop.descriptor.preview }}
|
||||
</span>
|
||||
</ng-container>
|
||||
<ng-template #editable>
|
||||
<ng-property-editor
|
||||
[key]="node.prop.name"
|
||||
[initialValue]="node.prop.descriptor.value || node.prop.descriptor.preview"
|
||||
(updateValue)="updateValue(node, $event)"
|
||||
>
|
||||
</ng-property-editor>
|
||||
</ng-template>
|
||||
</mat-tree-node>
|
||||
<div *ngIf="directiveInputControls.dataSource.data.length > 0">
|
||||
Inputs
|
||||
<ng-property-view-tree
|
||||
[dataSource]="directiveInputControls.dataSource"
|
||||
[treeControl]="directiveInputControls.treeControl"
|
||||
(updateValue)="updateValue($event)"
|
||||
></ng-property-view-tree>
|
||||
</div>
|
||||
|
||||
<mat-tree-node matTreeNodePaddingIndent="14" *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
|
||||
<div (click)="toggle(node)">
|
||||
<span class="arrow">
|
||||
{{ treeControl.isExpanded(node) ? '▼' : '►' }}
|
||||
</span>
|
||||
|
||||
<span class="name"> {{ node.prop.name }} </span>:
|
||||
<span class="value">
|
||||
{{ treeControl.isExpanded(node) ? '' : node.prop.descriptor.preview }}
|
||||
</span>
|
||||
</div>
|
||||
</mat-tree-node>
|
||||
</mat-tree>
|
||||
<div *ngIf="directiveOutputControls.dataSource.data.length > 0">
|
||||
Outputs
|
||||
<ng-property-view-tree
|
||||
[dataSource]="directiveOutputControls.dataSource"
|
||||
[treeControl]="directiveOutputControls.treeControl"
|
||||
(updateValue)="updateValue($event)"
|
||||
></ng-property-view-tree>
|
||||
</div>
|
||||
|
||||
<div *ngIf="directiveStateControls.dataSource.data.length > 0">
|
||||
State
|
||||
<ng-property-view-tree
|
||||
[dataSource]="directiveStateControls.dataSource"
|
||||
[treeControl]="directiveStateControls.treeControl"
|
||||
(updateValue)="updateValue($event)"
|
||||
></ng-property-view-tree>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,47 +1,22 @@
|
|||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||
import { PropertyDataSource } from '../../../../property-resolver/property-data-source';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import {
|
||||
DirectivePropertyResolver,
|
||||
DirectiveTreeData,
|
||||
} from '../../../../property-resolver/directive-property-resolver';
|
||||
import { FlatNode } from '../../../../property-resolver/element-property-resolver';
|
||||
import { DirectivePropertyResolver } from '../../../../property-resolver/directive-property-resolver';
|
||||
|
||||
@Component({
|
||||
selector: 'ng-property-view-body',
|
||||
templateUrl: './property-view-body.component.html',
|
||||
styleUrls: ['./property-view-body.component.css'],
|
||||
})
|
||||
export class PropertyViewBodyComponent implements OnChanges {
|
||||
@Input() dataSource: PropertyDataSource;
|
||||
@Input() treeControl: FlatTreeControl<FlatNode>;
|
||||
export class PropertyViewBodyComponent {
|
||||
@Input() controller: DirectivePropertyResolver;
|
||||
@Input() filterList: string[] | null = null;
|
||||
@Input() directiveInputControls: DirectiveTreeData;
|
||||
@Input() directiveOutputControls: DirectiveTreeData;
|
||||
@Input() directiveStateControls: DirectiveTreeData;
|
||||
|
||||
hasChild = (_: number, node: FlatNode): boolean => node.expandable;
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.filterTreeNodes();
|
||||
}
|
||||
|
||||
filterTreeNodes(): void {
|
||||
this.dataSource.filterDataSource(this.filterList);
|
||||
}
|
||||
|
||||
toggle(node: FlatNode): void {
|
||||
if (this.treeControl.isExpanded(node)) {
|
||||
this.treeControl.collapse(node);
|
||||
return;
|
||||
}
|
||||
this.expand(node);
|
||||
}
|
||||
|
||||
expand(node: FlatNode): void {
|
||||
const { prop } = node;
|
||||
if (!prop.descriptor.expandable) {
|
||||
return;
|
||||
}
|
||||
this.treeControl.expand(node);
|
||||
}
|
||||
|
||||
updateValue(newValue: any, node: FlatNode): void {
|
||||
this.controller.updateValue(newValue, node);
|
||||
updateValue({ node, newValue }: { newValue: any; node: FlatNode }): void {
|
||||
this.controller.updateValue(node, newValue);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<mat-tree *ngIf="_treeControl" class="property-list" [dataSource]="_dataSource" [treeControl]="_treeControl">
|
||||
<mat-tree *ngIf="treeControl" class="property-list" [dataSource]="dataSource" [treeControl]="treeControl">
|
||||
<mat-tree-node matTreeNodePaddingIndent="14" *matTreeNodeDef="let node" matTreeNodePadding>
|
||||
<span class="name non-expandable"> {{ node.prop.name }} </span>:
|
||||
<ng-container *ngIf="!node.prop.descriptor.editable; else editable">
|
||||
|
|
@ -17,15 +17,14 @@
|
|||
</mat-tree-node>
|
||||
|
||||
<mat-tree-node matTreeNodePaddingIndent="14" *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
|
||||
LOL
|
||||
<div (click)="toggle(node)">
|
||||
<span class="arrow">
|
||||
{{ _treeControl.isExpanded(node) ? '▼' : '►' }}
|
||||
{{ treeControl.isExpanded(node) ? '▼' : '►' }}
|
||||
</span>
|
||||
|
||||
<span class="name"> {{ node.prop.name }} </span>:
|
||||
<span class="value">
|
||||
{{ _treeControl.isExpanded(node) ? '' : node.prop.descriptor.preview }}
|
||||
{{ treeControl.isExpanded(node) ? '' : node.prop.descriptor.preview }}
|
||||
</span>
|
||||
</div>
|
||||
</mat-tree-node>
|
||||
|
|
|
|||
|
|
@ -9,21 +9,15 @@ import { FlatTreeControl } from '@angular/cdk/tree';
|
|||
styleUrls: ['./property-view-tree.component.css'],
|
||||
})
|
||||
export class PropertyViewTreeComponent {
|
||||
@Input() set dataSource(dataSource: PropertyDataSource) {
|
||||
this._dataSource = dataSource;
|
||||
}
|
||||
@Input() dataSource: PropertyDataSource;
|
||||
@Input() treeControl: FlatTreeControl<FlatNode>;
|
||||
@Output() updateValue = new EventEmitter<any>();
|
||||
|
||||
_dataSource: PropertyDataSource;
|
||||
_treeControl: FlatTreeControl<FlatNode>;
|
||||
|
||||
hasChild = (_: number, node: FlatNode): boolean => {
|
||||
return node.expandable;
|
||||
};
|
||||
hasChild = (_: number, node: FlatNode): boolean => node.expandable;
|
||||
|
||||
toggle(node: FlatNode): void {
|
||||
if (this._treeControl.isExpanded(node)) {
|
||||
this._treeControl.collapse(node);
|
||||
if (this.treeControl.isExpanded(node)) {
|
||||
this.treeControl.collapse(node);
|
||||
return;
|
||||
}
|
||||
this.expand(node);
|
||||
|
|
@ -34,13 +28,13 @@ export class PropertyViewTreeComponent {
|
|||
if (!prop.descriptor.expandable) {
|
||||
return;
|
||||
}
|
||||
this._treeControl.expand(node);
|
||||
this.treeControl.expand(node);
|
||||
}
|
||||
|
||||
handleUpdate(node: FlatNode, updatedValue: any): void {
|
||||
handleUpdate(node: FlatNode, newValue: any): void {
|
||||
this.updateValue.emit({
|
||||
node,
|
||||
updatedValue,
|
||||
newValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,3 @@ header {
|
|||
line-height: 15px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
:host /deep/ .mat-button-toggle-appearance-standard .mat-button-toggle-label-content {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,5 @@
|
|||
<header>
|
||||
<span> Properties of {{ directive }} </span>
|
||||
<mat-button-toggle-group [multiple]="true" (change)="filterProperties($event)">
|
||||
<mat-button-toggle [value]="cmpFilterOptions.INPUTS" [checked]="true">
|
||||
Inputs
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="cmpFilterOptions.OUTPUTS" [checked]="true">
|
||||
Outputs
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="cmpFilterOptions.STATE" [checked]="true">
|
||||
State
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<button mat-icon-button (click)="copyPropData.emit(directive)">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { PropertyViewFilterOptions } from '../../../../property-resolver/directive-property-resolver';
|
||||
|
||||
@Component({
|
||||
selector: 'ng-property-view-header',
|
||||
|
|
@ -9,12 +7,5 @@ import { PropertyViewFilterOptions } from '../../../../property-resolver/directi
|
|||
})
|
||||
export class PropertyViewHeaderComponent {
|
||||
@Input() directive: string;
|
||||
@Output() filter = new EventEmitter<PropertyViewFilterOptions[]>();
|
||||
@Output() copyPropData = new EventEmitter<string>();
|
||||
|
||||
cmpFilterOptions = PropertyViewFilterOptions;
|
||||
|
||||
filterProperties(event: MatButtonToggleChange): void {
|
||||
this.filter.emit(event.value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
<ng-property-view-header
|
||||
[directive]="directive"
|
||||
(copyPropData)="copyPropData.emit($event)"
|
||||
(filter)="filter($event)"
|
||||
></ng-property-view-header>
|
||||
<ng-property-view-header [directive]="directive" (copyPropData)="copyPropData.emit($event)"></ng-property-view-header>
|
||||
<ng-property-view-body
|
||||
[controller]="controller"
|
||||
[dataSource]="dataSource"
|
||||
[filterList]="allowedList"
|
||||
[treeControl]="treeControl"
|
||||
[directiveInputControls]="directiveInputControls"
|
||||
[directiveOutputControls]="directiveOutputControls"
|
||||
[directiveStateControls]="directiveStateControls"
|
||||
></ng-property-view-body>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import {
|
||||
DirectivePropertyResolver,
|
||||
DirectiveTreeData,
|
||||
PropertyViewFilterOptions,
|
||||
} from '../../../property-resolver/directive-property-resolver';
|
||||
import { PropertyDataSource } from '../../../property-resolver/property-data-source';
|
||||
|
|
@ -16,56 +17,21 @@ export class PropertyViewComponent {
|
|||
@Input() directive: string;
|
||||
@Output() copyPropData = new EventEmitter<string>();
|
||||
|
||||
currentFilter: PropertyViewFilterOptions[] = [
|
||||
PropertyViewFilterOptions.INPUTS,
|
||||
PropertyViewFilterOptions.OUTPUTS,
|
||||
PropertyViewFilterOptions.STATE,
|
||||
];
|
||||
allowedList: string[] | null = null;
|
||||
|
||||
constructor(private _nestedProps: ElementPropertyResolver) {}
|
||||
|
||||
get controller(): DirectivePropertyResolver | undefined {
|
||||
return this._nestedProps.getDirectiveController(this.directive);
|
||||
}
|
||||
|
||||
get dataSource(): PropertyDataSource | void {
|
||||
if (!this.controller) {
|
||||
return;
|
||||
}
|
||||
return this.controller.getDirectiveControls1().dataSource;
|
||||
get directiveInputControls(): DirectiveTreeData | void {
|
||||
return this.controller?.directiveInputControls;
|
||||
}
|
||||
|
||||
get treeControl(): TreeControl<FlatNode> | void {
|
||||
if (!this.controller) {
|
||||
return;
|
||||
}
|
||||
return this.controller.getDirectiveControls1().treeControl;
|
||||
get directiveOutputControls(): DirectiveTreeData | void {
|
||||
return this.controller?.directiveOutputControls;
|
||||
}
|
||||
|
||||
filter(evt: PropertyViewFilterOptions[]): void {
|
||||
this.currentFilter = evt;
|
||||
this.computeAllowedList();
|
||||
}
|
||||
|
||||
computeAllowedList(): void {
|
||||
if (!this.controller || !this.controller.directiveProperties) {
|
||||
return;
|
||||
}
|
||||
const inputList = this.controller.directiveInputs1;
|
||||
const outputList = this.controller.directiveOutputs1;
|
||||
const stateList = Object.keys(this.controller.directiveProperties).filter(
|
||||
prop => !inputList.includes(prop) && !outputList.includes(prop)
|
||||
);
|
||||
const propList = {
|
||||
[PropertyViewFilterOptions.INPUTS]: inputList,
|
||||
[PropertyViewFilterOptions.OUTPUTS]: outputList,
|
||||
[PropertyViewFilterOptions.STATE]: stateList,
|
||||
};
|
||||
|
||||
this.allowedList = [].concat.apply(
|
||||
[],
|
||||
this.currentFilter.map(filterOption => propList[filterOption])
|
||||
);
|
||||
get directiveStateControls(): DirectiveTreeData | void {
|
||||
return this.controller?.directiveStateControls;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue