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="node-property" *ngIf="node"> 29 <span class=" mat-body-1 property-key"> {{ getKey(node) }} </span> 30 <div *ngIf="node?.formattedValue()" class="property-value" [class]="[timeClass()]"> 31 <button 32 *ngIf="isTimestamp()" 33 class="time-button" 34 mat-button 35 color="primary" 36 (click)="onTimestampClicked(node)"> 37 {{ node.formattedValue() }} 38 </button> 39 <a *ngIf="!isTimestamp()" [class]="[valueClass()]" class="mat-body-2 value new">{{ node.formattedValue() }}</a> 40 <s *ngIf="isModified()" class="old-value">{{ node.getOldValue() }}</s> 41 </div> 42 </div> 43 `, 44 styles: [ 45 ` 46 .property-value button { 47 white-space: normal; 48 } 49 `, 50 propertyTreeNodeDataViewStyles, 51 timeButtonStyle, 52 ], 53}) 54export class PropertyTreeNodeDataViewComponent { 55 @Input() node?: UiPropertyTreeNode; 56 57 constructor(@Inject(ElementRef) private elementRef: ElementRef) {} 58 59 getKey(node: UiPropertyTreeNode) { 60 if (!this.node?.formattedValue()) { 61 return node.getDisplayName(); 62 } 63 return node.getDisplayName() + ': '; 64 } 65 66 isTimestamp() { 67 return this.node?.getValue() instanceof Timestamp; 68 } 69 70 onTimestampClicked(timestampNode: UiPropertyTreeNode) { 71 const timestamp: Timestamp = timestampNode.getValue(); 72 const customEvent = new CustomEvent(ViewerEvents.TimestampClick, { 73 bubbles: true, 74 detail: new TimestampClickDetail(undefined, timestamp), 75 }); 76 this.elementRef.nativeElement.dispatchEvent(customEvent); 77 } 78 79 valueClass() { 80 const property = assertDefined(this.node).formattedValue(); 81 if (!property) { 82 return null; 83 } 84 85 if (property === 'null') { 86 return 'null'; 87 } 88 89 if (property === 'true') { 90 return 'true'; 91 } 92 93 if (property === 'false') { 94 return 'false'; 95 } 96 97 if (!isNaN(Number(property))) { 98 return 'number'; 99 } 100 101 return null; 102 } 103 104 timeClass() { 105 if (this.isTimestamp()) { 106 return 'time'; 107 } 108 109 return null; 110 } 111 112 isModified() { 113 return assertDefined(this.node).getDiff() === DiffType.MODIFIED; 114 } 115} 116