perfetto-ui: Move trace loading UI into mithril
- Remove dummy elements from index.html
- Create frontend/nav.html as a minimal nav bar.
- Move trace loading ui into frontend/home_page.ts
- Use m.route instead of m.mount.
Change-Id: I6a2acddb303d44fbe65dcbc9cf0c08864532188b
diff --git a/ui/index.html b/ui/index.html
index 9254be4..8027631 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -36,11 +36,6 @@
</style>
</head>
<body>
- <div id="console">
- WASM output goes here
- </div>
- <input type="file" id="trace" name="trace"/>
- <button id="query">Query</button>
<div id="frontend">
Loading...
</div>
diff --git a/ui/src/frontend/home_page.ts b/ui/src/frontend/home_page.ts
index e6bde62..1515a2e 100644
--- a/ui/src/frontend/home_page.ts
+++ b/ui/src/frontend/home_page.ts
@@ -13,10 +13,46 @@
// limitations under the License.
import * as m from 'mithril';
-import {Frontend} from './';
-export const HomePage = {
- view() {
- return m(Frontend, {width: 1000, height: 300});
+import {Engine} from '../engine';
+import {WasmEngineProxy} from '../engine/wasm_engine_proxy';
+
+import {createPage} from './pages';
+
+function extractBlob(e: Event): Blob|null {
+ if (!(e.target instanceof HTMLInputElement)) {
+ throw new Error('Not input element');
}
-} as m.Component;
+ if (!e.target.files) return null;
+ return e.target.files.item(0);
+}
+
+// TODO(hjd): Temporary while bringing up controller worker.
+let engine: Engine|null = null;
+
+export const HomePage = createPage({
+ view() {
+ return m(
+ 'div',
+ m('input[type=file]', {
+ onchange: (e: Event) => {
+ const blob = extractBlob(e);
+ if (!blob) return;
+ engine = WasmEngineProxy.create(blob);
+ },
+ }),
+ m('button',
+ {
+ disabled: engine === null,
+ onclick: () => {
+ if (!engine) return;
+ engine
+ .rawQuery({
+ sqlQuery: 'select * from sched;',
+ })
+ .then(console.log);
+ },
+ },
+ 'Query'));
+ }
+});
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index e573917..86ece0a 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -15,9 +15,10 @@
import * as m from 'mithril';
import {CanvasWrapper} from './canvas_wrapper';
+import {createPage} from './pages';
import {Track} from './track';
-export const Frontend = {
+const Frontend = {
view({attrs}) {
return m(
'.frontend',
@@ -32,3 +33,9 @@
m(Track, {name: 'Track 123'}), );
}
} as m.Component<{width: number, height: number}>;
+
+export const FrontendPage = createPage({
+ view() {
+ return m(Frontend, {width: 1000, height: 300});
+ }
+});
diff --git a/ui/src/frontend/pages.ts b/ui/src/frontend/pages.ts
new file mode 100644
index 0000000..f38a876
--- /dev/null
+++ b/ui/src/frontend/pages.ts
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 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 * as m from 'mithril';
+
+const Nav = {
+ view() {
+ return m(
+ 'ul',
+ m('li', m('a[href=/]', {oncreate: m.route.link}, 'Home')),
+ m('li', m('a[href=/viewer]', {oncreate: m.route.link}, 'Viewer')), );
+ }
+} as m.Component;
+
+/**
+ * Wrap component with common UI elements (nav bar etc).
+ */
+export function createPage(component: m.Component): m.Component {
+ return {
+ view() {
+ return [
+ m(Nav),
+ m(component),
+ ];
+ },
+ };
+}
diff --git a/ui/src/main.ts b/ui/src/main.ts
index 511da1c..44479da 100644
--- a/ui/src/main.ts
+++ b/ui/src/main.ts
@@ -15,11 +15,8 @@
import * as m from 'mithril';
import {createEmptyState} from './common/state';
-import {Engine} from './engine';
-import {
- warmupWasmEngineWorker,
- WasmEngineProxy
-} from './engine/wasm_engine_proxy';
+import {warmupWasmEngineWorker} from './engine/wasm_engine_proxy';
+import {FrontendPage} from './frontend';
import {gState} from './frontend/globals';
import {HomePage} from './frontend/home_page';
@@ -32,36 +29,21 @@
};
}
-function main(input: Element, button: Element) {
+function main() {
gState.set(createEmptyState());
createController();
warmupWasmEngineWorker();
- // tslint:disable-next-line:no-any
- input.addEventListener('change', (e: any) => {
- const blob: Blob = e.target.files.item(0);
- if (blob === null) return;
- const engine: Engine = WasmEngineProxy.create(blob);
- button.addEventListener('click', () => {
- engine
- .rawQuery({
- sqlQuery: 'select * from sched;',
- })
- .then(result => console.log(result));
- });
- });
-
const root = document.getElementById('frontend');
if (!root) {
console.error('root element not found.');
return;
}
- m.mount(root, HomePage);
+ m.route(root, '/', {
+ '/': HomePage,
+ '/viewer': FrontendPage,
+ });
}
-const input = document.querySelector('#trace');
-const button = document.querySelector('#query');
-if (input && button) {
- main(input, button);
-}
+main();