blob: 7afcbaf20503af6f4ac928e8a220b5b3fbcb8a4e [file] [log] [blame]
// Copyright (C) 2020 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 {Disposable} from '../base/disposable';
import {SimpleResizeObserver} from '../base/resize_observer';
import {undoCommonChatAppReplacements} from '../base/string_utils';
import {QueryResponse, runQuery} from '../common/queries';
import {raf} from '../core/raf_scheduler';
import {EngineProxy} from '../trace_processor/engine';
import {Callout} from '../widgets/callout';
import {Editor} from '../widgets/editor';
import {globals} from './globals';
import {createPage} from './pages';
import {QueryHistoryComponent, queryHistoryStorage} from './query_history';
import {addQueryResultsTab} from './query_result_tab';
import {QueryTable} from './query_table';
interface QueryPageState {
enteredText: string;
executedQuery?: string;
queryResult?: QueryResponse;
heightPx: string;
generation: number;
}
const state: QueryPageState = {
enteredText: '',
heightPx: '100px',
generation: 0,
};
function runManualQuery(query: string) {
state.executedQuery = query;
state.queryResult = undefined;
const engine = getEngine();
if (engine) {
runQuery(undoCommonChatAppReplacements(query), engine).then(
(resp: QueryResponse) => {
addQueryResultsTab(
{
query: query,
title: 'Standalone Query',
prefetchedResponse: resp,
},
'analyze_page_query',
);
// We might have started to execute another query. Ignore it in that
// case.
if (state.executedQuery !== query) {
return;
}
state.queryResult = resp;
raf.scheduleFullRedraw();
},
);
}
raf.scheduleDelayedFullRedraw();
}
function getEngine(): EngineProxy | undefined {
const engineId = globals.getCurrentEngine()?.id;
if (engineId === undefined) {
return undefined;
}
const engine = globals.engines.get(engineId)?.getProxy('QueryPage');
return engine;
}
class QueryInput implements m.ClassComponent {
private resize?: Disposable;
oncreate({dom}: m.CVnodeDOM): void {
this.resize = new SimpleResizeObserver(dom, () => {
state.heightPx = (dom as HTMLElement).style.height;
});
(dom as HTMLElement).style.height = state.heightPx;
}
onremove(): void {
if (this.resize) {
this.resize.dispose();
this.resize = undefined;
}
}
view() {
return m(Editor, {
generation: state.generation,
initialText: state.enteredText,
onExecute: (text: string) => {
if (!text) {
return;
}
queryHistoryStorage.saveQuery(text);
runManualQuery(text);
},
onUpdate: (text: string) => {
state.enteredText = text;
},
});
}
}
export const QueryPage = createPage({
view() {
return m(
'.query-page',
m(Callout, 'Enter query and press Cmd/Ctrl + Enter'),
m(QueryInput),
state.executedQuery === undefined
? null
: m(QueryTable, {
query: state.executedQuery,
resp: state.queryResult,
fillParent: false,
}),
m(QueryHistoryComponent, {
runQuery: runManualQuery,
setQuery: (q: string) => {
state.enteredText = q;
state.generation++;
raf.scheduleFullRedraw();
},
}),
);
},
});