1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import {Component, ElementRef, Inject, Input} from '@angular/core'; 17import {assertDefined} from 'common/assert_utils'; 18import {Timestamp} from 'common/time'; 19import {DiffType} from 'viewers/common/diff_type'; 20import {UiPropertyTreeNode} from 'viewers/common/ui_property_tree_node'; 21import {TimestampClickDetail, ViewerEvents} from 'viewers/common/viewer_events'; 22import {propertyTreeNodeDataViewStyles} from 'viewers/components/styles/tree_node_data_view.styles'; 23import {timeButtonStyle} from './styles/clickable_property.styles'; 24 25@Component({ 26 selector: 'property-tree-node-data-view', 27 template: ` 28 <div class="mat-body-1 node-property" *ngIf="node"> 29 <span class="property-key"> {{ getKey(node) }} </span> 30 <div *ngIf="node?.formattedValue()" class="property-value" [class]="[timeClass()]"> 31 <button 32 *ngIf="isTimestamp()" 33 mat-button 34 color="primary" 35 (click)="onTimestampClicked(node)"> 36 {{ node.formattedValue() }} 37 </button> 38 <a *ngIf="!isTimestamp()" [class]="[valueClass()]" class="value new">{{ node.formattedValue() }}</a> 39 <s *ngIf="isModified()" class="old-value">{{ node.getOldValue() }}</s> 40 </div> 41 </div> 42 `, 43 styles: [ 44 ` 45 .property-value button { 46 white-space: normal; 47 } 48 `, 49 propertyTreeNodeDataViewStyles, 50 timeButtonStyle, 51 ], 52}) 53export class PropertyTreeNodeDataViewComponent { 54 @Input() node?: UiPropertyTreeNode; 55 56 constructor(@Inject(ElementRef) private elementRef: ElementRef) {} 57 58 getKey(node: UiPropertyTreeNode) { 59 if (!this.node?.formattedValue()) { 60 return node.getDisplayName(); 61 } 62 return node.getDisplayName() + ': '; 63 } 64 65 isTimestamp() { 66 return this.node?.getValue() instanceof Timestamp; 67 } 68 69 onTimestampClicked(timestamp: UiPropertyTreeNode) { 70 const customEvent = new CustomEvent(ViewerEvents.TimestampClick, { 71 bubbles: true, 72 detail: new TimestampClickDetail(timestamp.getValue(), undefined), 73 }); 74 this.elementRef.nativeElement.dispatchEvent(customEvent); 75 } 76 77 valueClass() { 78 const property = assertDefined(this.node).formattedValue(); 79 if (!property) { 80 return null; 81 } 82 83 if (property === 'null') { 84 return 'null'; 85 } 86 87 if (property === 'true') { 88 return 'true'; 89 } 90 91 if (property === 'false') { 92 return 'false'; 93 } 94 95 if (!isNaN(Number(property))) { 96 return 'number'; 97 } 98 99 return null; 100 } 101 102 timeClass() { 103 if (this.isTimestamp()) { 104 return 'time'; 105 } 106 107 return null; 108 } 109 110 isModified() { 111 return assertDefined(this.node).getDiff() === DiffType.MODIFIED; 112 } 113} 114