From 84704b0f8d10099c1c70ec8fc130b42139408266 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Simonard Date: Wed, 28 Aug 2024 08:02:29 +0200 Subject: [PATCH] Nbr of papers in filters + UI improvements --- web/dashboard/components/select_picker.py | 35 ++++++++++++++++++++--- web/dashboard/main_dashboard.py | 27 +++++++---------- web/dashboard/ui.py | 8 +++++- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/web/dashboard/components/select_picker.py b/web/dashboard/components/select_picker.py index a328223d..fb676a1e 100644 --- a/web/dashboard/components/select_picker.py +++ b/web/dashboard/components/select_picker.py @@ -12,6 +12,8 @@ class SelectPicker(ReactiveHTML, Widget): ) value = param.List(doc="The actual list of selected values", default=[]) + annotations = param.Dict(default={}) + filter_str = param.String(default="") trigger_rendering = param.Integer(default=0) @@ -197,7 +199,7 @@ def filtered_options_did_change(self): rgba(0, 0, 0, 0.12) 0px 3px 14px 2px; position: absolute; z-index: 1001; - width: 270px; + width: 300px; top: 30%; left: 15%; } @@ -271,6 +273,15 @@ def filtered_options_did_change(self): overflow: hidden; } + .sp_options_list_container label span.label { + width: 60%; + } + + .sp_options_list_container label span.annotation { + width: 25%; + text-align:right; + } + .sp_filter_clear_btn { padding-top: 4px; padding-right: 4px; @@ -364,16 +375,26 @@ def filtered_options_did_change(self): """, "input_change": """ - /*console.log("input_change", data, model, state, view); - console.log(model.checkboxes_list);*/ + /* console.log("input_change") , data, model, state, view);*/ + console.log(model.checkboxes_list); */ let new_value = []; + let removed_values = []; model.checkboxes_list.forEach((cb, idx) => { if (cb.checked) { new_value.push(cb.value); + } else if (!cb.checked && data.value.includes(cb.value)) { + removed_values.push(cb.value); } }); - data.value = new_value; + + if ( filter_text_input.value.length > 0) { + /* When a filter is applied ... */ + data.value = data.value.concat(new_value).filter((v) => !removed_values.includes(v)); + } else { + data.value = new_value; + } + setTimeout(function() { @@ -446,10 +467,16 @@ def filtered_options_did_change(self): lbl.htmlFor = `cb${idx}`; let lblspan = document.createElement("span"); + lblspan.classList.add("label"); lblspan.innerHTML = opt; + let lblannotation = document.createElement("span"); + lblannotation.classList.add("annotation"); + lblannotation.innerHTML = data.annotations[opt]; + lbl.appendChild(cb); lbl.appendChild(lblspan); + lbl.appendChild(lblannotation); checkboxes_container.appendChild(lbl); /* checkboxes_container.appendChild(document.createElement("br")); diff --git a/web/dashboard/main_dashboard.py b/web/dashboard/main_dashboard.py index 069cbb9c..de499451 100644 --- a/web/dashboard/main_dashboard.py +++ b/web/dashboard/main_dashboard.py @@ -140,6 +140,7 @@ def __init__(self, datasets, **params): self.journal_select_picker = SelectPicker.from_param( self.param.filter_journal, + annotations=self.get_col_values_with_count("journal"), update_title_callback=lambda select_picker, values, options: self.new_picker_title("journals", select_picker, values, options), @@ -147,6 +148,7 @@ def __init__(self, datasets, **params): self.affiliation_country_select_picker = SelectPicker.from_param( self.param.filter_affiliation_country, + annotations=self.get_col_values_with_count("affiliation_country"), update_title_callback=lambda select_picker, values, options: self.new_picker_title( @@ -156,6 +158,7 @@ def __init__(self, datasets, **params): self.funder_select_picker = SelectPicker.from_param( self.param.filter_funder, + annotations=self.get_col_values_with_count("funder"), update_title_callback=lambda select_picker, values, options: self.new_picker_title("funders", select_picker, values, options), @@ -163,6 +166,7 @@ def __init__(self, datasets, **params): self.tags_select_picker = SelectPicker.from_param( self.param.filter_tags, + annotations=self.get_col_values_with_count("data_tags"), update_title_callback=lambda select_picker, values, options: self.new_picker_title("tags", select_picker, values, options), @@ -229,9 +233,7 @@ def did_change_extraction_tool(self): self.param.filter_journal.objects = self.raw_data.journal.unique() ## affiliation country - countries_with_count = self.get_col_values_with_count( - "affiliation_country", lambda x: "None" in x - ) + countries_with_count = self.get_col_values_with_count("affiliation_country") def country_sorter(c): return countries_with_count[c] @@ -241,9 +243,7 @@ def country_sorter(c): ) ## funder - funders_with_count = self.get_col_values_with_count( - "funder", lambda x: "None" in x - ) + funders_with_count = self.get_col_values_with_count("funder") def funder_sorter(c): return funders_with_count[c] @@ -253,9 +253,7 @@ def funder_sorter(c): ) ## Tags - tags_with_count = self.get_col_values_with_count( - "data_tags", lambda x: "None" in x - ) + tags_with_count = self.get_col_values_with_count("data_tags") def tags_sorter(c): return tags_with_count[c] @@ -269,7 +267,7 @@ def tags_sorter(c): self.splitting_var = self.param.splitting_var.objects[0] @lru_cache - def get_col_values_with_count(self, col, none_test): + def get_col_values_with_count(self, col, none_test=lambda row: "None" in row): values = {} for row in self.raw_data[col].values: if none_test(row): @@ -304,10 +302,7 @@ def did_change_splitting_var(self): if splitting_var == "affiliation_country": # We want to show all countries, but pre-select only the top 10 - countries_with_count = self.get_col_values_with_count( - "affiliation_country", - lambda x: "None" in x, - ) + countries_with_count = self.get_col_values_with_count("affiliation_country") # pre-filter the countries because there are a lot countries_with_count = { @@ -336,9 +331,7 @@ def did_change_splitting_var(self): if splitting_var == "funder": # We want to show all funders, but pre-select only the top 10 - funders_with_count = self.get_col_values_with_count( - "funder", lambda x: "None" in x - ) + funders_with_count = self.get_col_values_with_count("funder") top_5_min = sorted( [ diff --git a/web/dashboard/ui.py b/web/dashboard/ui.py index 4e3dfdfc..b1d01c78 100644 --- a/web/dashboard/ui.py +++ b/web/dashboard/ui.py @@ -23,7 +23,13 @@ def css(selector: Union[str, Iterable[str]], declarations: dict[str, str]) -> st }, ) -CSS_GLOBAL = css("#header.shadow", {"box-shadow": "unset"}) +CSS_GLOBAL = "\n".join( + [ + css("#header.shadow", {"box-shadow": "unset"}), + css("#sidebar", {"overflow-y": "visible !important"}), + css("*", {"font-family": "'Roboto' !important"}), + ] +) """ the structure of css_modifiers is as follows: