Skip to content

Commit

Permalink
Do not recompute data when local pagination is enabled (#3854)
Browse files Browse the repository at this point in the history
* Do not update data, style or selected when page parameter changes with local pagination

* Ensure filters update data on local pagination

* Re-enable xfail
  • Loading branch information
philippjfr committed Sep 16, 2022
1 parent 77943b1 commit e44b1dc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
26 changes: 20 additions & 6 deletions panel/tests/ui/widgets/test_tabulator.py
Expand Up @@ -2769,15 +2769,16 @@ def test_tabulator_edit_event_and_header_filters_same_column(page, port):
assert len(widget.current_view) == 2


def test_tabulator_edit_event_and_header_filters_same_column_remote(page, port):
@pytest.mark.parametrize('pagination', ['remote', 'local'])
def test_tabulator_edit_event_and_header_filters_same_column_pagination(page, port, pagination):
df = pd.DataFrame({
'values': ['A', 'A', 'B', 'B', 'B', 'B'],
}, index=['idx0', 'idx1', 'idx2', 'idx3', 'idx4', 'idx5'])

widget = Tabulator(
df,
header_filters={'values': {'type': 'input', 'func': 'like'}},
pagination='remote',
pagination=pagination,
page_size=2,
)

Expand All @@ -2795,6 +2796,18 @@ def test_tabulator_edit_event_and_header_filters_same_column_remote(page, port):
header.fill('B')
header.press('Enter')

cell = page.locator('text="B"').first
cell.click()
editable_cell = page.locator('input[type="text"]')
editable_cell.fill("Q")
editable_cell.press('Enter')

wait_until(lambda: len(values) == 1, page)
assert values[-1] == ('values', 2, 'B', 'Q')
assert df.at['idx2', 'values'] == 'Q'
# current_view should show Y and Z, there's no more B
assert len(widget.current_view) == 4

page.locator('text="Last"').click()
page.wait_for_timeout(200)

Expand All @@ -2808,8 +2821,8 @@ def test_tabulator_edit_event_and_header_filters_same_column_remote(page, port):
editable_cell.fill("X")
editable_cell.press('Enter')

wait_until(lambda: len(values) == 1, page)
assert values[0] == ('values', len(df) - 1, 'B', 'X')
wait_until(lambda: len(values) == 2, page)
assert values[-1] == ('values', len(df) - 1, 'B', 'X')
assert df.at['idx5', 'values'] == 'X'
# The current view should show the edited value
assert len(widget.current_view) == 4
Expand All @@ -2821,7 +2834,7 @@ def test_tabulator_edit_event_and_header_filters_same_column_remote(page, port):
editable_cell.fill("Y")
editable_cell.press('Enter')

wait_until(lambda: len(values) == 2, page)
wait_until(lambda: len(values) == 3, page)
assert values[-1] == ('values', len(df) - 1, 'X', 'Y')
assert df.at['idx5', 'values'] == 'Y'
assert len(widget.current_view) == 4
Expand All @@ -2833,13 +2846,14 @@ def test_tabulator_edit_event_and_header_filters_same_column_remote(page, port):
editable_cell.fill("Z")
editable_cell.press('Enter')

wait_until(lambda: len(values) == 3, page)
wait_until(lambda: len(values) == 4, page)
assert values[-1] == ('values', len(df) - 2, 'B', 'Z')
assert df.at['idx4', 'values'] == 'Z'
# current_view should show Y and Z, there's no more B
assert len(widget.current_view) == 4



@pytest.mark.parametrize('sorter', ['sorter', 'no_sorter'])
@pytest.mark.parametrize('python_filter', ['python_filter', 'no_python_filter'])
@pytest.mark.parametrize('header_filter', ['header_filter', 'no_header_filter'])
Expand Down
11 changes: 6 additions & 5 deletions panel/widgets/tables.py
Expand Up @@ -363,7 +363,9 @@ def _filter_dataframe(self, df: DataFrameType) -> DataFrameType:
else:
val = filt
column = df[col_name]
if np.isscalar(val):
if val is None:
continue
elif np.isscalar(val):
mask = column == val
elif isinstance(val, (list, set)):
if not val:
Expand Down Expand Up @@ -1239,9 +1241,6 @@ def _process_data(self, data):
# the old value in a table-edit event.
self._old_value = self.value.copy()

return super()._process_data(data)

print(self._old_value, data)
import pandas as pd
df = pd.DataFrame(data)
filters = self._get_header_filters(df)
Expand Down Expand Up @@ -1441,7 +1440,9 @@ def _update_cds(self, *events):
page_events = ('page', 'page_size', 'sorters', 'filters')
if self._updating:
return
elif (events and all(e.name in page_events for e in events) and not self.pagination):
elif events and all(e.name in page_events[:-1] for e in events) and self.pagination == 'local':
return
elif events and all(e.name in page_events for e in events) and not self.pagination:
self._processed, _ = self._get_data()
return
recompute = not all(
Expand Down

0 comments on commit e44b1dc

Please sign in to comment.