• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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 {
24  inlineButtonStyle,
25  timeButtonStyle,
26} from './styles/clickable_property.styles';
27
28@Component({
29  selector: 'property-tree-node-data-view',
30  template: `
31    <div class="node-property" *ngIf="node">
32      <span class=" mat-body-1 property-key"> {{ getKey(node) }} </span>
33      <div *ngIf="node?.formattedValue()" class="property-value" [class]="[timeClass()]">
34        <button
35          *ngIf="isTimestamp()"
36          class="time-button"
37          mat-button
38          color="primary"
39          (click)="onTimestampClicked(node)">
40          {{ node.formattedValue() }}
41        </button>
42        <div *ngIf="!isTimestamp() && node?.canPropagate()" class="inline">
43          <button
44            mat-button
45            color="primary"
46            (click)="onPropagateButtonClicked(node)">
47            {{ node.formattedValue() }}
48          </button>
49        </div>
50        <a *ngIf="!isTimestamp() && !node?.canPropagate()" [class]="[valueClass()]" class="mat-body-2 value new">{{ node.formattedValue() }}</a>
51        <s *ngIf="isModified()" class="mat-body-2 old-value">{{ node.getOldValue() }}</s>
52      </div>
53    </div>
54  `,
55  styles: [
56    `
57      .property-value button {
58        white-space: normal;
59      }
60    `,
61    propertyTreeNodeDataViewStyles,
62    timeButtonStyle,
63    inlineButtonStyle,
64  ],
65})
66export class PropertyTreeNodeDataViewComponent {
67  @Input() node?: UiPropertyTreeNode;
68
69  constructor(@Inject(ElementRef) private elementRef: ElementRef) {}
70
71  getKey(node: UiPropertyTreeNode) {
72    if (!this.node?.formattedValue()) {
73      return node.getDisplayName();
74    }
75    return node.getDisplayName() + ': ';
76  }
77
78  isTimestamp() {
79    return this.node?.getValue() instanceof Timestamp;
80  }
81
82  onTimestampClicked(timestampNode: UiPropertyTreeNode) {
83    const timestamp: Timestamp = timestampNode.getValue();
84    const customEvent = new CustomEvent(ViewerEvents.TimestampClick, {
85      bubbles: true,
86      detail: new TimestampClickDetail(undefined, timestamp),
87    });
88    this.elementRef.nativeElement.dispatchEvent(customEvent);
89  }
90
91  onPropagateButtonClicked(node: UiPropertyTreeNode) {
92    const event = new CustomEvent(ViewerEvents.PropagatePropertyClick, {
93      bubbles: true,
94      detail: node,
95    });
96    this.elementRef.nativeElement.dispatchEvent(event);
97  }
98
99  valueClass() {
100    const property = assertDefined(this.node).formattedValue();
101    if (!property) {
102      return null;
103    }
104
105    if (property === 'null') {
106      return 'null';
107    }
108
109    if (property === 'true') {
110      return 'true';
111    }
112
113    if (property === 'false') {
114      return 'false';
115    }
116
117    if (!isNaN(Number(property))) {
118      return 'number';
119    }
120
121    return null;
122  }
123
124  timeClass() {
125    if (this.isTimestamp()) {
126      return 'time';
127    }
128
129    return null;
130  }
131
132  isModified() {
133    return assertDefined(this.node).getDiff() === DiffType.MODIFIED;
134  }
135}
136