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

Ensure WidgetFilter sync_with_url uses Widget parameter to serialize values #494

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lumen/filters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class Filter(MultiTypeComponent):

def __init__(self, **params):
super().__init__(**params)
self._setup_sync()

def _setup_sync(self):
if self._sync_with_url:
pn.state.location.sync(self, {'value': self.field}, on_error=self._url_sync_error)

Expand Down Expand Up @@ -241,6 +244,14 @@ class BaseWidgetFilter(Filter):

__abstract = True

def __init__(self, **params):
self.widget = None
super().__init__(**params)

def _setup_sync(self):
if self._sync_with_url and self.widget is not None:
pn.state.location.sync(self.widget, {'value': self.field}, on_error=self._url_sync_error)

def _url_sync_error(self, values):
value = values['value']
if value is self.widget.value:
Expand Down Expand Up @@ -323,6 +334,7 @@ def __init__(self, **params):
self.widget.value = val
elif self.default is not None:
self.widget.value = self.default
self._setup_sync()

@classmethod
def _validate_widget(cls, widget: str, spec: Dict[str, Any], context: Dict[str, Any]) -> str:
Expand Down Expand Up @@ -407,6 +419,7 @@ def __init__(self, **params):
value = tuple(self.default)
self.widget = widget(name=self.label, options=options, value=value)
self.widget.link(self, value='value', visible='visible', disabled='disabled', bidirectional=True)
self._setup_sync()

@property
def query(self) -> Any:
Expand Down Expand Up @@ -443,6 +456,7 @@ def __init__(self, **params):
self.param.set_param(**param_overrides)
self.widget = widget_type(**self._widget_kwargs(as_date=self._as_date))
self.widget.link(self, value='value', visible='visible', disabled='disabled', bidirectional=True)
self._setup_sync()

def _widget_kwargs(self, as_date: bool) -> Dict[str, Any]:
field_schema = self.schema.get(self.field, {})
Expand Down
10 changes: 5 additions & 5 deletions lumen/tests/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ def test_dashboard_with_url_sync_filters(set_root, document):
layout = dashboard.layouts[0]
f1, f2 = list(layout._pipelines.values())[0].filters
f1.value = (0.1, 0.7)
assert pn.state.location.search == '?A=%5B0.1%2C+0.7%5D'
assert pn.state.location.query_params == {'A': [0.1, 0.7], 'C': []}
pn.state.location.search = '?A=%5B0.3%2C+0.8%5D'
assert f1.value == (0.3, 0.8)
f2.value = ['foo1', 'foo2']
assert pn.state.location.search == '?A=%5B0.3%2C+0.8%5D&C=%5B%22foo1%22%2C+%22foo2%22%5D'
assert pn.state.location.query_params == {'A': [0.3, 0.8], 'C': ['foo1', 'foo2']}
pn.state.location.search = '?A=%5B0.3%2C+0.8%5D&C=%5B%22foo1%22%2C+%22foo2%22%2C+%22foo3%22%5D'
assert f2.value == ['foo1', 'foo2', 'foo3']

Expand All @@ -98,14 +98,14 @@ def test_dashboard_with_url_sync_filters_with_default(set_root, document):
layout = dashboard.layouts[0]
f1, f2 = list(layout._pipelines.values())[0].filters
f1.value = (0.1, 0.7)
assert pn.state.location.search == '?C=%5B%27foo1%27%5D&A=%5B0.1%2C+0.7%5D'
assert pn.state.location.query_params == {'C': ['foo1'], 'A': [0.1, 0.7]}
pn.state.location.search = '?A=%5B0.3%2C+0.8%5D'
assert f1.value == (0.3, 0.8)
assert f2.value == ['foo1']
assert f1.widget.value == (0.3, 0.8)
assert f2.widget.value == ['foo1']
f2.value = ['foo1', 'foo2']
assert pn.state.location.search == '?A=%5B0.3%2C+0.8%5D&C=%5B%22foo1%22%2C+%22foo2%22%5D'
assert pn.state.location.query_params == {'C': ['foo1', 'foo2'], 'A': [0.3, 0.8]}
pn.state.location.search = '?A=%5B0.3%2C+0.8%5D&C=%5B%22foo1%22%2C+%22foo2%22%2C+%22foo3%22%5D'
assert f2.value == ['foo1', 'foo2', 'foo3']
assert f2.widget.value == ['foo1', 'foo2', 'foo3']
Expand All @@ -119,7 +119,7 @@ def test_dashboard_with_url_sync_filters_with_overwritten_default(set_root, docu
f1, f2 = list(layout._pipelines.values())[0].filters
f1.value = (0.1, 0.7)
f2.value = [] # overwriting default with empty list
assert pn.state.location.search == '?C=%5B%5D&A=%5B0.1%2C+0.7%5D'
assert pn.state.location.query_params == {'C': [], 'A': [0.1, 0.7]}
assert f2.widget.value == []

@sql_available
Expand Down