Skip to content

Commit

Permalink
Merge "ui: Add proper interface for area selection details tabs" into…
Browse files Browse the repository at this point in the history
… main
  • Loading branch information
stevegolton authored and Gerrit Code Review committed Feb 20, 2025
2 parents 7a40d85 + e3baf62 commit 072b48f
Show file tree
Hide file tree
Showing 36 changed files with 874 additions and 827 deletions.
69 changes: 69 additions & 0 deletions ui/src/components/aggregation_adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) 2025 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 {AggregationPanel} from './aggregation_panel';
import {
AreaSelection,
AreaSelectionAggregator,
areaSelectionsEqual,
AreaSelectionTab,
} from '../public/selection';
import {Trace} from '../public/trace';
import {SelectionAggregationManager} from './selection_aggregation_manager';

/**
* Creates an adapter that adapts an old style aggregation to a new area
* selection sub-tab.
*/
export function createAggregationToTabAdaptor(
trace: Trace,
aggregator: AreaSelectionAggregator,
): AreaSelectionTab {
const schemaSpecificity =
(aggregator.schema && Object.keys(aggregator.schema).length) ?? 0;
const kindRating = aggregator.trackKind === undefined ? 0 : 100;
const priority = kindRating + schemaSpecificity;
const aggMan = new SelectionAggregationManager(trace.engine, aggregator);
let currentSelection: AreaSelection | undefined;

return {
id: aggregator.id,
name: aggregator.getTabName(),
priority,
render(selection: AreaSelection) {
if (
currentSelection === undefined ||
!areaSelectionsEqual(selection, currentSelection)
) {
aggMan.aggregateArea(selection);
currentSelection = selection;
}

const data = aggMan.aggregatedData;
if (!data) {
return undefined;
}

return {
isLoading: false,
content: m(AggregationPanel, {
data,
trace,
model: aggMan,
}),
};
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,35 @@ import m from 'mithril';
import {
AggregateData,
Column,
Sorting,
ThreadStateExtra,
isEmptyData,
} from '../public/aggregation';
import {colorForState} from '../components/colorizer';
import {DurationWidget} from '../components/widgets/duration';
import {EmptyState} from '../widgets/empty_state';
import {Anchor} from '../widgets/anchor';
import {Icons} from '../base/semantic_icons';
import {translateState} from '../components/sql_utils/thread_state';
import {TraceImpl} from '../core/trace_impl';
import {colorForState} from './colorizer';
import {DurationWidget} from './widgets/duration';
import {translateState} from './sql_utils/thread_state';
import {Trace} from '../public/trace';

export interface AggregationPanelAttrs {
data?: AggregateData;
aggregatorId: string;
trace: TraceImpl;
readonly trace: Trace;
readonly data: AggregateData;
readonly model: AggState;
}

export interface AggState {
getSortingPrefs(): Sorting | undefined;
toggleSortingColumn(column: string): void;
}

export class AggregationPanel
implements m.ClassComponent<AggregationPanelAttrs>
{
private trace: TraceImpl;
private trace: Trace;

constructor({attrs}: m.CVnode<AggregationPanelAttrs>) {
this.trace = attrs.trace;
}

view({attrs}: m.CVnode<AggregationPanelAttrs>) {
if (!attrs.data || isEmptyData(attrs.data)) {
return m(
EmptyState,
{
className: 'pf-noselection',
title: 'No relevant tracks in selection',
},
m(
Anchor,
{
icon: Icons.ChangeTab,
onclick: () => {
this.trace.tabs.showCurrentSelectionTab();
},
},
'Go to current selection tab',
),
);
}

return m(
'.details-panel',
m(
Expand All @@ -77,7 +59,7 @@ export class AggregationPanel
m(
'tr',
attrs.data.columns.map((col) =>
this.formatColumnHeading(attrs.trace, col, attrs.aggregatorId),
this.formatColumnHeading(col, attrs.model),
),
),
m(
Expand All @@ -93,8 +75,8 @@ export class AggregationPanel
);
}

formatColumnHeading(trace: TraceImpl, col: Column, aggregatorId: string) {
const pref = trace.selection.aggregation.getSortingPrefs(aggregatorId);
formatColumnHeading(col: Column, model: AggState) {
const pref = model.getSortingPrefs();
let sortIcon = '';
if (pref && pref.column === col.columnId) {
sortIcon =
Expand All @@ -104,10 +86,7 @@ export class AggregationPanel
'th',
{
onclick: () => {
trace.selection.aggregation.toggleSortingColumn(
aggregatorId,
col.columnId,
);
model.toggleSortingColumn(col.columnId);
},
},
col.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// limitations under the License.

import m from 'mithril';
import {showModal} from '../../widgets/modal';
import {ArgumentPopup} from '../pivot_table_argument_popup';
import {showModal} from '../widgets/modal';
import {ArgumentPopup} from './pivot_table/pivot_table_argument_popup';

export class AttributeModalHolder {
typedArgument = '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
// limitations under the License.

import m from 'mithril';
import {SortDirection} from '../base/comparison_utils';
import {sqliteString} from '../base/string_utils';
import {DropDirection} from '../core/pivot_table_manager';
import {SortDirection} from '../../base/comparison_utils';
import {sqliteString} from '../../base/string_utils';
import {DropDirection} from './pivot_table_manager';
import {
PivotTableResult,
Aggregation,
Expand All @@ -24,37 +24,38 @@ import {
PivotTree,
TableColumn,
COUNT_AGGREGATION,
} from '../core/pivot_table_types';
import {AreaSelection} from '../public/selection';
import {ColumnType} from '../trace_processor/query_result';
} from './pivot_table_types';
import {AreaSelection} from '../../public/selection';
import {ColumnType} from '../../trace_processor/query_result';
import {
aggregationIndex,
areaFilters,
sliceAggregationColumns,
tables,
} from '../core/pivot_table_query_generator';
} from './pivot_table_query_generator';
import {ReorderableCell, ReorderableCellGroup} from './reorderable_cells';
import {AttributeModalHolder} from './tables/attribute_modal_holder';
import {DurationWidget} from '../components/widgets/duration';
import {getSqlTableDescription} from '../components/widgets/sql/legacy_table/sql_table_registry';
import {assertExists, assertFalse} from '../base/logging';
import {TraceImpl} from '../core/trace_impl';
import {PivotTableManager} from '../core/pivot_table_manager';
import {extensions} from '../components/extensions';
import {MenuItem, PopupMenu} from '../widgets/menu';
import {Button} from '../widgets/button';
import {popupMenuIcon} from '../widgets/table';
import {SqlColumn} from '../components/widgets/sql/legacy_table/sql_column';
import {Filter} from '../components/widgets/sql/legacy_table/filters';
import {AttributeModalHolder} from '../attribute_modal_holder';
import {DurationWidget} from '../widgets/duration';
import {getSqlTableDescription} from '../widgets/sql/legacy_table/sql_table_registry';
import {assertExists, assertFalse} from '../../base/logging';
import {PivotTableManager} from './pivot_table_manager';
import {extensions} from '../extensions';
import {MenuItem, PopupMenu} from '../../widgets/menu';
import {Button} from '../../widgets/button';
import {popupMenuIcon} from '../../widgets/table';
import {SqlColumn} from '../widgets/sql/legacy_table/sql_column';
import {Filter} from '../widgets/sql/legacy_table/filters';
import {Trace} from '../../public/trace';

interface PathItem {
tree: PivotTree;
nextKey: ColumnType;
}

interface PivotTableAttrs {
trace: TraceImpl;
selectionArea: AreaSelection;
readonly trace: Trace;
readonly selectionArea: AreaSelection;
readonly pivotMgr: PivotTableManager;
}

interface DrillFilter {
Expand Down Expand Up @@ -117,7 +118,7 @@ export class PivotTable implements m.ClassComponent<PivotTableAttrs> {
private pivotMgr: PivotTableManager;

constructor({attrs}: m.CVnode<PivotTableAttrs>) {
this.pivotMgr = attrs.trace.pivotTable;
this.pivotMgr = attrs.pivotMgr;
this.attributeModalHolder = new AttributeModalHolder((arg) =>
this.pivotMgr.setPivotSelected({
column: {kind: 'argument', argument: arg},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {SortDirection} from '../../base/comparison_utils';
import {assertTrue} from '../../base/logging';
import {featureFlags} from '../../core/feature_flags';
import {AreaSelection} from '../../public/selection';
import {Engine} from '../../trace_processor/engine';
import {ColumnType} from '../../trace_processor/query_result';
import {
aggregationIndex,
generateQueryFromState,
} from './pivot_table_query_generator';
import {
Aggregation,
AggregationFunction,
COUNT_AGGREGATION,
PivotTableQuery,
PivotTableQueryMetadata,
PivotTableResult,
PivotTableState,
COUNT_AGGREGATION,
PivotTree,
TableColumn,
toggleEnabled,
tableColumnEquals,
AggregationFunction,
toggleEnabled,
} from './pivot_table_types';
import {AreaSelection} from '../public/selection';
import {
aggregationIndex,
generateQueryFromState,
} from './pivot_table_query_generator';
import {Aggregation, PivotTree} from './pivot_table_types';
import {Engine} from '../trace_processor/engine';
import {ColumnType} from '../trace_processor/query_result';
import {SortDirection} from '../base/comparison_utils';
import {assertTrue} from '../base/logging';
import {featureFlags} from './feature_flags';

export const PIVOT_TABLE_REDUX_FLAG = featureFlags.register({
id: 'pivotTable',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {sqliteString} from '../base/string_utils';
import {sqliteString} from '../../base/string_utils';
import {
PivotTableQuery,
PivotTableState,
Aggregation,
TableColumn,
} from './pivot_table_types';
import {AreaSelection} from '../public/selection';
import {SLICE_TRACK_KIND} from '../public/track_kinds';
import {AreaSelection} from '../../public/selection';
import {SLICE_TRACK_KIND} from '../../public/track_kinds';

interface Table {
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {SortDirection} from '../base/comparison_utils';
import {AreaSelection} from '../public/selection';
import {ColumnType} from '../trace_processor/query_result';
import {SortDirection} from '../../base/comparison_utils';
import {AreaSelection} from '../../public/selection';
import {ColumnType} from '../../trace_processor/query_result';

// Auxiliary metadata needed to parse the query result, as well as to render it
// correctly. Generated together with the text of query and passed without the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import m from 'mithril';
import {DropDirection} from '../core/pivot_table_manager';
import {DropDirection} from './pivot_table_manager';

export interface ReorderableCell {
content: m.Children;
Expand Down
Loading

0 comments on commit 072b48f

Please sign in to comment.