UI: Add query table, omnibox search and progress bar
This CL adds the initial ability to perform arbitrary
SQL queries using the UI and adds a progress bar to the
omnibox. The UI is still very rough but it's a starting
point.
Change-Id: Iabc8520403169459f70676d30315100441db4e8d
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index f8b5294..f49e8ea 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -13,16 +13,22 @@
// limitations under the License.
import * as m from 'mithril';
-import { globals } from './globals';
-import { quietDispatch } from './mithril_helpers';
-import { navigate } from '../common/actions';
+
+import {deleteQuery, executeQuery} from '../common/actions';
+import {QueryResponse} from '../common/queries';
+import {EngineConfig} from '../common/state';
+
+import {globals} from './globals';
+
+const QUERY_ID = 'quicksearch';
let selResult = 0;
let numResults = 0;
let mode: 'search'|'command' = 'search';
function clearOmniboxResults() {
- // TODO(primiano): Implement in next CLs.
+ globals.queryResults.delete(QUERY_ID);
+ globals.dispatch(deleteQuery(QUERY_ID));
}
function onKeyDown(e: Event) {
@@ -35,8 +41,7 @@
e.preventDefault();
return;
}
- const txt =
- (e.target as HTMLElement).querySelector('input') as HTMLInputElement;
+ const txt = (e.target as HTMLInputElement);
if (key === ':' && txt.value === '') {
mode = 'command';
m.redraw();
@@ -54,7 +59,6 @@
m.redraw();
return;
}
- // TODO(primiano): add query handling here.
}
function onKeyUp(e: Event) {
@@ -74,7 +78,15 @@
m.redraw();
return;
}
- // TODO(primiano): add query handling here.
+ if (mode === 'search') {
+ const name = txt.value.replace(/'/g, '\\\'').replace(/[*]/g, '%');
+ const query =
+ `select name from process where name like '%${name}%' limit 10`;
+ globals.dispatch(executeQuery('0', QUERY_ID, query));
+ }
+ if (mode === 'command' && key === 'Enter') {
+ globals.dispatch(executeQuery('0', 'command', txt.value));
+ }
}
@@ -87,6 +99,15 @@
},
view() {
// TODO(primiano): handle query results here.
+ const results = [];
+ const resp = globals.queryResults.get(QUERY_ID) as QueryResponse;
+ if (resp !== undefined) {
+ numResults = resp.rows ? resp.rows.length : 0;
+ for (let i = 0; i < resp.rows.length; i++) {
+ const clazz = (i === selResult) ? '.selected' : '';
+ results.push(m(`div${clazz}`, resp.rows[i][resp.columns[0]]));
+ }
+ }
const placeholder = {
search: 'Search or type : to enter command mode',
command: 'e.g., select * from sched left join thread using(utid) limit 10'
@@ -94,12 +115,20 @@
const commandMode = mode === 'command';
return m(
`.omnibox${commandMode ? '.command-mode' : ''}`,
- m(`input[type=text][placeholder=${placeholder[mode]}]`));
+ m(`input[type=text][placeholder=${placeholder[mode]}]`),
+ m('.omnibox-results', results));
},
};
export const Topbar: m.Component = {
view() {
- return m('.topbar', m(Omnibox));
+ const progBar = [];
+ const engine: EngineConfig = globals.state.engines['0'];
+ if (globals.state.queries[QUERY_ID] !== undefined ||
+ (engine !== undefined && !engine.ready)) {
+ progBar.push(m('.progress'));
+ }
+
+ return m('.topbar', m(Omnibox), ...progBar);
},
};
\ No newline at end of file