Skip to content
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

Open
wants to merge 11 commits into
base: dev/fix_dash_persistence
Choose a base branch
from

Conversation

nadijagraca
Copy link
Contributor

Description

PR refactors how the "ALL" is handled in the backend for filters and parameters

Current behaviour:

  • When ALL is selected, a full list of options is sent to the backend.
  • When ALL is deselected, all values are removed, and an empty list is sent to the backend.
  • If all values are selected, the ALL checkbox is automatically marked as checked.
  • When the ALL checkbox is checked, and the user unchecks any value, the ALL checkbox is automatically unchecked.

Screenshot

Notice

  • I acknowledge and agree that, by checking this box and clicking "Submit Pull Request":

    • I submit this contribution under the Apache 2.0 license and represent that I am entitled to do so on behalf of myself, my employer, or relevant third parties, as applicable.
    • I certify that (a) this contribution is my original creation and / or (b) to the extent it is not my original creation, I am authorized to submit this contribution on behalf of the original creator(s) or their licensees.
    • I certify that the use of this contribution as authorized by the Apache 2.0 license does not violate the intellectual property rights of anyone else.
    • I have not referenced individuals, products or companies in any commits, directly or indirectly.
    • I have not added data or restricted code in any commits, directly or indirectly.

Copy link
Contributor

@petar-qb petar-qb left a 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 😁

Comment on lines -75 to -81
if (
action.function._function.__name__ != "_filter"
or target not in action.function["targets"]
or ALL_OPTION in selector_value
):
continue

Copy link
Contributor

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

Copy link
Contributor

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.

Comment on lines +14 to +22
# [{"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]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# [{"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})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dict_options.insert(0, {"label": ALL_OPTION, "value": ALL_OPTION})
dict_options = [{"label": ALL_OPTION, "value": ALL_OPTION}, *dict_options]

Copy link
Contributor

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`."""
Copy link
Contributor

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.

Comment on lines +78 to +79
options=options,
value=self.value if self.value is not None else options,
Copy link
Contributor

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:

Suggested change
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,

Copy link
Contributor

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(
Copy link
Contributor

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 = []) {
Copy link
Contributor

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 [[], []];
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this TODO done?

Comment on lines +16 to +17
const isTriggeredByChecklist = triggeredId.includes("_checklist_all");
const hasAllSelected = value.includes("ALL");
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants