blob: 559598168a976946a497bce82721a1822af9e6f4 [file] [log] [blame]
// Copyright (C) 2023 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 m from 'mithril';
import {TrackEventDetailsPanel} from '../public/details_panel';
import {ColumnType} from '../trace_processor/query_result';
import {sqlValueToReadableString} from '../trace_processor/sql_utils';
import {DetailsShell} from '../widgets/details_shell';
import {GridLayout} from '../widgets/grid_layout';
import {Section} from '../widgets/section';
import {SqlRef} from '../widgets/sql_ref';
import {dictToTree, Tree, TreeNode} from '../widgets/tree';
import {Trace} from '../public/trace';
export interface ColumnConfig {
readonly displayName?: string;
}
export type Columns = {
readonly [columnName: string]: ColumnConfig;
};
// A details tab, which fetches slice-like object from a given SQL table by id
// and renders it according to the provided config, specifying which columns
// need to be rendered and how.
export class GenericSliceDetailsTab implements TrackEventDetailsPanel {
private data?: {[key: string]: ColumnType};
constructor(
private readonly trace: Trace,
private readonly sqlTableName: string,
private readonly id: number,
private readonly title: string,
private readonly columns?: Columns,
) {}
async load() {
const result = await this.trace.engine.query(
`select * from ${this.sqlTableName} where id = ${this.id}`,
);
this.data = result.firstRow({});
}
render() {
if (!this.data) {
return m('h2', 'Loading');
}
const args: {[key: string]: m.Child} = {};
if (this.columns !== undefined) {
for (const key of Object.keys(this.columns)) {
let argKey = key;
if (this.columns[key].displayName !== undefined) {
argKey = this.columns[key].displayName!;
}
args[argKey] = sqlValueToReadableString(this.data[key]);
}
} else {
for (const key of Object.keys(this.data)) {
args[key] = sqlValueToReadableString(this.data[key]);
}
}
const details = dictToTree(args);
return m(
DetailsShell,
{
title: this.title,
},
m(
GridLayout,
m(Section, {title: 'Details'}, m(Tree, details)),
m(
Section,
{title: 'Metadata'},
m(Tree, [
m(TreeNode, {
left: 'SQL ID',
right: m(SqlRef, {
table: this.sqlTableName,
id: this.id,
}),
}),
]),
),
),
);
}
}