-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Dev] Update select ALL logic for controls #1000
base: dev/fix_dash_persistence
Are you sure you want to change the base?
[Dev] Update select ALL logic for controls #1000
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great work @nadijagraca!! 🚀
We're so close to remove the ALL_OPTION handling from the backend side 😁
if ( | ||
action.function._function.__name__ != "_filter" | ||
or target not in action.function["targets"] | ||
or ALL_OPTION in selector_value | ||
): | ||
continue | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave it like:
if (
action.function._function.__name__ != "_filter"
or target not in action.function["targets"]
):
continue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also adjust the code from the line #192.
# [{"label": "Option 1", "value": "Option 1"}, {"label": "Option 2", "value": "Option 2"}] | ||
dict_options = [ | ||
option if isinstance(option, dict) else {"label": str(option), "value": option} for option in options | ||
] | ||
|
||
# ["Option 1", "Option 2", ...] | ||
all_values = [dict_option["value"] for dict_option in dict_options] | ||
default_value = all_values if multi else all_values[0] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# [{"label": "Option 1", "value": "Option 1"}, {"label": "Option 2", "value": "Option 2"}] | |
dict_options = [ | |
option if isinstance(option, dict) else {"label": str(option), "value": option} for option in options | |
] | |
# ["Option 1", "Option 2", ...] | |
all_values = [dict_option["value"] for dict_option in dict_options] | |
default_value = all_values if multi else all_values[0] | |
dict_options = [ | |
option if isinstance(option, dict) else {"label": str(option), "value": option} for option in options | |
] | |
list_value = [dict_option["value"] for dict_option in dict_options] | |
default_value = list_value if multi else list_value[0] |
default_value = options[0]["value"] # type: ignore[index] | ||
else: | ||
default_value = options[0] | ||
dict_options.insert(0, {"label": ALL_OPTION, "value": ALL_OPTION}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dict_options.insert(0, {"label": ALL_OPTION, "value": ALL_OPTION}) | |
dict_options = [{"label": ALL_OPTION, "value": ALL_OPTION}, *dict_options] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think we should remove handling of ALL_OPTION from this function.
It just adds a confusion. ALL_OPTION is added only for vm.Dropdown(multi=True)
and vm.Checklist
, and then, both Checklist and Dropdown apply different and custom logic on top of that in their __call__
and helper functions. As those two classes they treat the ALL_OPTION differently, we might have try to remove inserting the ALL_OPTION in this function.
@@ -11,19 +11,19 @@ | |||
|
|||
def get_options_and_default(options: OptionsType, multi: bool = False) -> tuple[OptionsType, SingleValueType]: | |||
"""Gets list of full options and default value based on user input type of `options`.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should highlight in the docstring or maybe even in the function name that returned options are in list[dict] format.
options=options, | ||
value=self.value if self.value is not None else options, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we remove ALL_OPTION handling from the get_options_and_default
(as I mentioned in the previous comment), then this could look like:
options=options, | |
value=self.value if self.value is not None else options, | |
options=full_options # (or dict_options if we rename it then), | |
value=self.value if self.value else default_value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or even final_value
can be calculated before as final_value = self.value if self.value else default_value
, and then reuse final_value
here and above as: value=["ALL"] if final_value == full_options esle [],
@@ -44,16 +44,31 @@ def validate_multi(multi, info: ValidationInfo): | |||
return multi | |||
|
|||
|
|||
def _add_select_all_option(full_options: OptionsType) -> OptionsType: | |||
def _add_select_all_option( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function looks like also could be simplified a bit if we decide to remove ALL_OPTION handling from the get_options_and_default
function
@@ -0,0 +1,25 @@ | |||
function update_checklist_values(value1 = [], value2 = [], options = []) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May you rename value1
and value2
?
const options_list = options.map((dict) => dict["value"]); | ||
const updated_options = options_list.filter((element) => element !== "ALL"); | ||
|
||
if (!value.length) return [[], []]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What case does this line cover?
@@ -0,0 +1,40 @@ | |||
// TO-DO: Check if this function triggered when a page is opened |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this TODO done?
const isTriggeredByChecklist = triggeredId.includes("_checklist_all"); | ||
const hasAllSelected = value.includes("ALL"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between isTriggeredByChecklist and hasAllSelected?
Description
PR refactors how the "ALL" is handled in the backend for filters and parameters
Current behaviour:
Screenshot
Notice
I acknowledge and agree that, by checking this box and clicking "Submit Pull Request":