From 29b9023959ad3b2b0341ed2df7cd4e4677142d07 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 19 May 2026 01:09:10 +0800 Subject: [PATCH] Add DataViewer search bar integration --- bricks/build.sh | 4 +- bricks/dataviewer.js | 57 +++++++++++++++++++++- bricks/searchbar.js | 110 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 bricks/searchbar.js diff --git a/bricks/build.sh b/bricks/build.sh index b6350b6..a59afea 100755 --- a/bricks/build.sh +++ b/bricks/build.sh @@ -3,7 +3,7 @@ SOURCES=" page_data_loader.js factory.js uitypesdef.js utils.js uitype.js \ jsoncall.js myoperator.js scroll.js menu.js popup.js recorder.js \ modal.js running.js llmout.js glbviewer.js \ markdown_viewer.js audio.js toolbar.js tab.js \ - input.js registerfunction.js button.js accordion.js dataviewer.js \ + input.js registerfunction.js button.js accordion.js searchbar.js dataviewer.js \ tree.js multiple_state_image.js dynamiccolumn.js form.js message.js conform.js \ paging.js datagrid.js iframe.js cols.js echartsext.js \ floaticonbar.js miniform.js wterm.js dynamicaccordion.js \ @@ -11,7 +11,7 @@ SOURCES=" page_data_loader.js factory.js uitypesdef.js utils.js uitype.js \ llm.js websocket.js datarow.js tabular.js continueaudio.js \ line.js pie.js bar.js gobang.js period.js iconbarpage.js \ keypress.js asr.js webspeech.js countdown.js progressbar.js \ - qaframe.js svg.js videoplayer.js sctter.js radar.js kline.js \ + qaframe.js svg.js videoplayer.js scatter.js radar.js kline.js \ heatmap.js map.js qr.js textfiles.js agent.js " echo ${SOURCES} cat ${SOURCES} > ../dist/bricks.js diff --git a/bricks/dataviewer.js b/bricks/dataviewer.js index 59b2bf3..6ecdfab 100644 --- a/bricks/dataviewer.js +++ b/bricks/dataviewer.js @@ -17,6 +17,7 @@ bricks.DataViewer = class extends bricks.VBox { this.active_item = null; this.loading = false; this.data_offset = 0; + this.search_keyword = this.get_initial_search_keyword(); this.keyselectable = true; this.bind('row_check_changed', this.show_check_event_data.bind(this)); schedule_once(this.build_all.bind(this), 0.1); @@ -30,6 +31,7 @@ bricks.DataViewer = class extends bricks.VBox { this.build_title_widget(); this.build_description_widget(); this.build_toolbar_widget(); + this.build_searchbar_widget(); this.build_records_area(); await this.build_other(); this.check_changed_row = null; @@ -42,7 +44,7 @@ bricks.DataViewer = class extends bricks.VBox { async build_other(){ } async render(params) { - params = params || {}; + params = this.merge_search_params(params || {}); if (params == this.old_params){ return; } @@ -76,6 +78,59 @@ bricks.DataViewer = class extends bricks.VBox { this.scrollpanel = new bricks.VScrollPanel({}); this.filler_widget.add_widget(this.scrollpanel); } + get_initial_search_keyword(){ + if (!this.searchable){ + return ''; + } + if (this.search_value != null){ + return this.search_value; + } + if (typeof this.searchable == 'object' && this.searchable.value != null){ + return this.searchable.value; + } + return ''; + } + build_searchbar_widget(){ + if (!this.searchable){ + return; + } + var opts = {}; + if (typeof this.searchable == 'object'){ + opts = bricks.extend(opts, this.searchable); + } + opts.width = opts.width || this.search_width || '100%'; + opts.placeholder = opts.placeholder || this.search_placeholder; + opts.value = opts.value || this.search_value || this.search_keyword || ''; + opts.search_label = opts.search_label || this.search_label; + opts.clear_label = opts.clear_label || this.clear_label; + this.searchbar_w = new bricks.SearchBar(opts); + this.searchbar_w.bind('search', this.search_event_handle.bind(this)); + this.add_widget(this.searchbar_w); + } + merge_search_params(params){ + var merged = bricks.extend({}, params || {}); + if (this.searchable){ + var search_param = this.search_param || 'keyword'; + if (this.search_keyword){ + merged[search_param] = this.search_keyword; + } else { + delete merged[search_param]; + } + } + return merged; + } + async search_event_handle(event){ + var d = event.params || {}; + this.search_keyword = d.keyword || ''; + this.old_params = null; + this.select_row = null; + this.active_item = null; + this.data_offset = 0; + if (this.loader){ + this.loader.pages = []; + } + await this.render({}); + } async renderPageData(data, page){ var pos; if (! this.loader.is_max_page(page)){ diff --git a/bricks/searchbar.js b/bricks/searchbar.js new file mode 100644 index 0000000..013d0a8 --- /dev/null +++ b/bricks/searchbar.js @@ -0,0 +1,110 @@ +var bricks = window.bricks || {}; + +bricks.SearchBar = class extends bricks.HBox { + /* + options: + { + placeholder: input placeholder text, + value: initial keyword, + width: component width, + search_label: search button label, + clear_label: clear button label, + input_width: input width, default 100% + } + events: + search: {keyword: string} + */ + constructor(opts){ + opts = opts || {}; + if (!opts.width){ + opts.width = '100%'; + } + if (!opts.height){ + opts.height = 'auto'; + } + super(opts); + this.keyword = opts.value || ''; + this.set_style('alignItems', 'center'); + this.set_style('gap', opts.gap || '0.5rem'); + this.build_input(); + this.build_search_button(); + this.build_clear_button(); + } + build_input(){ + var input_opts = { + name:this.opts.name || 'keyword', + value:this.keyword, + placeholder:this.opts.placeholder || '', + width:this.opts.input_width || '100%', + css:this.opts.input_css || 'input', + flexShrink:1 + }; + this.input_w = new bricks.UiStr(input_opts); + this.input_w.set_style('minWidth', this.opts.input_min_width || '0'); + this.input_w.set_style('height', this.opts.input_height || 'auto'); + this.input_w.set_style('padding', this.opts.input_padding || '0.5rem'); + this.input_w.set_style('boxSizing', 'border-box'); + this.input_w.bind('changed', this.input_changed.bind(this)); + this.input_w.bind('blur', this.input_changed.bind(this)); + this.input_w.dom_element.addEventListener('keydown', this.keydown_handle.bind(this)); + this.add_widget(this.input_w); + } + build_search_button(){ + this.search_button = new bricks.Button({ + label:this.opts.search_label || 'Search', + orientation:'horizontal', + width:'auto', + height:'auto', + flexShrink:0 + }); + this.search_button.bind('click', this.do_search.bind(this)); + this.add_widget(this.search_button); + } + build_clear_button(){ + this.clear_button = new bricks.Button({ + label:this.opts.clear_label || 'Clear', + orientation:'horizontal', + width:'auto', + height:'auto', + flexShrink:0 + }); + this.clear_button.bind('click', this.clear_search.bind(this)); + this.add_widget(this.clear_button); + } + input_changed(event){ + var d = event.params || {}; + this.keyword = d[this.input_w.name] || ''; + } + keydown_handle(event){ + if (event.key == 'Enter'){ + this.do_search(event); + } + } + get_keyword(){ + this.keyword = this.input_w.resultValue() || ''; + return this.keyword; + } + set_keyword(keyword){ + this.keyword = keyword || ''; + this.input_w.setValue(this.keyword); + } + focus(){ + this.input_w.focus(); + } + do_search(event){ + var keyword = this.get_keyword(); + this.dispatch('search', {keyword:keyword}); + if (event && event.stopPropagation){ + event.stopPropagation(); + } + } + clear_search(event){ + this.set_keyword(''); + this.dispatch('search', {keyword:''}); + if (event && event.stopPropagation){ + event.stopPropagation(); + } + } +} + +bricks.Factory.register('SearchBar', bricks.SearchBar);