1// Copyright (C) 2023 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import m from 'mithril'; 16 17import {EngineProxy} from '../../common/engine'; 18import {Button} from '../../frontend/widgets/button'; 19import {Form, FormButtonBar, FormLabel} from '../../frontend/widgets/form'; 20import {Select} from '../../frontend/widgets/select'; 21import {TextInput} from '../../frontend/widgets/text_input'; 22 23import {addDebugTrack, SliceColumns} from './slice_track'; 24 25export const ARG_PREFIX = 'arg_'; 26 27export function uuidToViewName(uuid: string): string { 28 return `view_${uuid.split('-').join('_')}`; 29} 30 31interface AddDebugTrackMenuAttrs { 32 sqlViewName: string; 33 columns: string[]; 34 engine: EngineProxy; 35} 36 37export class AddDebugTrackMenu implements 38 m.ClassComponent<AddDebugTrackMenuAttrs> { 39 name: string = ''; 40 sliceColumns: SliceColumns; 41 42 constructor(vnode: m.Vnode<AddDebugTrackMenuAttrs>) { 43 const chooseDefaultOption = (name: string) => { 44 for (const column of vnode.attrs.columns) { 45 if (column === name) return column; 46 } 47 for (const column of vnode.attrs.columns) { 48 if (column.endsWith(`_${name}`)) return column; 49 } 50 return vnode.attrs.columns[0]; 51 }; 52 53 this.sliceColumns = { 54 ts: chooseDefaultOption('ts'), 55 dur: chooseDefaultOption('dur'), 56 name: chooseDefaultOption('name'), 57 }; 58 } 59 60 view(vnode: m.Vnode<AddDebugTrackMenuAttrs>) { 61 const renderSelect = (name: 'ts'|'dur'|'name') => { 62 const options = []; 63 for (const column of vnode.attrs.columns) { 64 options.push( 65 m('option', 66 { 67 selected: this.sliceColumns[name] === column ? true : undefined, 68 }, 69 column)); 70 } 71 return [ 72 m(FormLabel, 73 {for: name, 74 }, 75 name), 76 m(Select, 77 { 78 id: name, 79 oninput: (e: Event) => { 80 if (!e.target) return; 81 this.sliceColumns[name] = (e.target as HTMLSelectElement).value; 82 }, 83 }, 84 options), 85 ]; 86 }; 87 return m( 88 Form, 89 m(FormLabel, 90 {for: 'track_name', 91 }, 92 'Name'), 93 m(TextInput, { 94 id: 'track_name', 95 onkeydown: (e: KeyboardEvent) => { 96 // Allow Esc to close popup. 97 if (e.key === 'Escape') return; 98 e.stopPropagation(); 99 }, 100 oninput: (e: KeyboardEvent) => { 101 if (!e.target) return; 102 this.name = (e.target as HTMLInputElement).value; 103 }, 104 }), 105 renderSelect('ts'), 106 renderSelect('dur'), 107 renderSelect('name'), 108 m( 109 FormButtonBar, 110 m(Button, { 111 label: 'Show', 112 dismissPopup: true, 113 onclick: (e: Event) => { 114 e.preventDefault(); 115 addDebugTrack( 116 vnode.attrs.engine, 117 vnode.attrs.sqlViewName, 118 this.name, 119 this.sliceColumns, 120 vnode.attrs.columns); 121 }, 122 }), 123 ), 124 ); 125 } 126} 127