blob: cd9af4b00271419a715c63e765dc64d9ecc6520f [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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 { Component, Input, Inject, ElementRef } from "@angular/core";
import { TraceTreeNode } from "common/trace/trace_tree_node";
import { UserOptions } from "viewers/common/user_options";
import { ViewerEvents } from "viewers/common/viewer_events";
import { PropertiesTreeNode, Terminal} from "viewers/common/ui_tree_utils";
@Component({
selector: "properties-view",
template: `
<mat-card-header class="view-header">
<div class="title-filter">
<span class="properties-title">Properties</span>
<mat-form-field class="filter-field">
<mat-label>Filter...</mat-label>
<input
matInput
[(ngModel)]="filterString"
(ngModelChange)="filterTree()"
name="filter"
/>
</mat-form-field>
</div>
<div class="view-controls">
<mat-checkbox
*ngFor="let option of objectKeys(userOptions)"
class="trace-box"
[(ngModel)]="userOptions[option].enabled"
(ngModelChange)="updateTree()"
[matTooltip]="userOptions[option].tooltip ?? ''"
>{{userOptions[option].name}}</mat-checkbox>
</div>
<div *ngIf="itemIsSelected() && propertyGroups" class="element-summary">
<property-groups
[item]="selectedFlickerItem"
></property-groups>
</div>
</mat-card-header>
<mat-card-content class="properties-content" [style]="maxPropertiesHeight()">
<span *ngIf="objectKeys(propertiesTree).length > 0 && isProtoDump" class="properties-title"> Properties - Proto Dump </span>
<div class="tree-wrapper">
<tree-view
class="tree-view"
[item]="propertiesTree"
[showNode]="showNode"
[isLeaf]="isLeaf"
*ngIf="objectKeys(propertiesTree).length > 0"
[isAlwaysCollapsed]="true"
></tree-view>
</div>
</mat-card-content>
`,
styles: [
`
.view-header {
display: block;
width: 100%;
min-height: 3.75rem;
align-items: center;
border-bottom: 1px solid lightgrey;
}
.title-filter {
position: relative;
display: flex;
align-items: center;
width: 100%;
margin-bottom: 12px;
}
.properties-title {
font-size: 16px;
}
.filter-field {
font-size: 16px;
transform: scale(0.7);
right: 0px;
position: absolute;
}
.view-controls {
display: inline-block;
font-size: 12px;
font-weight: normal;
margin-left: 5px;
}
.properties-content{
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x:hidden
}
.element-summary {
padding: 1rem;
border-bottom: thin solid rgba(0,0,0,.12);
}
.element-summary .key {
font-weight: 500;
}
.element-summary .value {
color: rgba(0, 0, 0, 0.75);
}
.tree-view {
white-space: pre-line;
flex: 1 0 0;
height: 100%;
overflow-y: auto
}
`,
],
})
export class PropertiesComponent {
objectKeys = Object.keys;
filterString = "";
@Input() userOptions: UserOptions = {};
@Input() propertiesTree: PropertiesTreeNode = {};
@Input() selectedFlickerItem: TraceTreeNode | null = null;
@Input() propertyGroups = false;
@Input() isProtoDump = false;
constructor(
@Inject(ElementRef) private elementRef: ElementRef,
) {}
public maxPropertiesHeight() {
const headerHeight = this.elementRef.nativeElement.querySelector(".view-header").clientHeight;
return {
height: `${800 - headerHeight}px`
};
}
public filterTree() {
const event: CustomEvent = new CustomEvent(
ViewerEvents.PropertiesFilterChange,
{
bubbles: true,
detail: { filterString: this.filterString }
});
this.elementRef.nativeElement.dispatchEvent(event);
}
public updateTree() {
const event: CustomEvent = new CustomEvent(
ViewerEvents.PropertiesUserOptionsChange,
{
bubbles: true,
detail: { userOptions: this.userOptions }
});
this.elementRef.nativeElement.dispatchEvent(event);
}
public showNode(item: any) {
return !(item instanceof Terminal)
&& !(item.name instanceof Terminal)
&& !(item.propertyKey instanceof Terminal);
}
public isLeaf(item: any) {
return !item.children || item.children.length === 0
|| item.children.filter((c: any) => !(c instanceof Terminal)).length === 0;
}
public itemIsSelected() {
return this.selectedFlickerItem && Object.keys(this.selectedFlickerItem).length > 0;
}
}