(core) Update sort and filter UI

Summary:
The sort and filter UI now has a more unified UI, with similar
capabilities that are accessible from different parts of Grist.
It's now also possible to pin individual filters to the filter bar,
which replaces the old toggle for showing all filters in the
filter bar.

Test Plan: Various tests (browser, migration, project).

Reviewers: jarek, dsagal

Reviewed By: jarek, dsagal

Subscribers: dsagal

Differential Revision: https://phab.getgrist.com/D3669
This commit is contained in:
George Gevoian
2022-11-17 15:17:51 -05:00
parent af462fc938
commit 1a6d427339
34 changed files with 1350 additions and 933 deletions

View File

@@ -1112,3 +1112,45 @@ def migration33(tdset):
]
return tdset.apply_doc_actions(doc_actions)
@migration(schema_version=34)
def migration34(tdset):
""""
Add pinned column to _grist_Filters and populate based on existing sections.
When populating, pinned will be set to true for filters that either belong to
a section where the filter bar is toggled or a raw view section.
From this version on, _grist_Views_section.options.filterBar is deprecated.
"""
doc_actions = [add_column('_grist_Filters', 'pinned', 'Bool')]
tables = list(actions.transpose_bulk_action(tdset.all_tables['_grist_Tables']))
sections = list(actions.transpose_bulk_action(tdset.all_tables['_grist_Views_section']))
filters = list(actions.transpose_bulk_action(tdset.all_tables['_grist_Filters']))
raw_section_ids = set(t.rawViewSectionRef for t in tables)
filter_bar_by_section_id = {
# Pre-migration, raw sections always showed the filter bar in the UI. Since we want
# existing raw section filters to continue appearing in the filter bar, we'll pretend
# here that raw sections have a filterBar value of True. Note that after this migration
# it will be possible for raw sections to have unpinned filters.
s.id: bool(s.id in raw_section_ids or safe_parse(s.options).get('filterBar', False))
for s in sections
}
# List of (filter_rec, pinned) pairs.
filter_updates = []
for filter_rec in filters:
filter_updates.append((
filter_rec,
filter_bar_by_section_id.get(filter_rec.viewSectionRef, False)
))
if filter_updates:
doc_actions.append(actions.BulkUpdateRecord(
'_grist_Filters',
[filter_rec.id for filter_rec, _ in filter_updates],
{'pinned': [pinned for _, pinned in filter_updates]},
))
return tdset.apply_doc_actions(doc_actions)

View File

@@ -15,7 +15,7 @@ import six
import actions
SCHEMA_VERSION = 33
SCHEMA_VERSION = 34
def make_column(col_id, col_type, formula='', isFormula=False):
return {
@@ -315,7 +315,10 @@ def schema_create_actions():
# `excluded` string to an array of column values:
# Ex1: { included: ['foo', 'bar'] }
# Ex2: { excluded: ['apple', 'orange'] }
make_column("filter", "Text")
make_column("filter", "Text"),
# Filters can be pinned to the filter bar, which causes a button to be displayed
# that opens the filter menu when clicked.
make_column("pinned", "Bool"),
]),
# Additional metadata for cells

View File

@@ -954,14 +954,16 @@ class TestUserActions(test_engine.EngineTestCase):
self.apply_user_action(['BulkAddRecord', '_grist_Filters', [None], {
"viewSectionRef": [1],
"colRef": [1],
"filter": [json.dumps({"included": ["b", "c"]})]
"filter": [json.dumps({"included": ["b", "c"]})],
"pinned": [True],
}])
# Add the same filter for second column (to make sure it is not renamed)
self.apply_user_action(['BulkAddRecord', '_grist_Filters', [None], {
"viewSectionRef": [1],
"colRef": [2],
"filter": [json.dumps({"included": ["b", "c"]})]
"filter": [json.dumps({"included": ["b", "c"]})],
"pinned": [False],
}])
# Rename choices
@@ -971,9 +973,9 @@ class TestUserActions(test_engine.EngineTestCase):
# Test filters
self.assertTableData('_grist_Filters', data=[
["id", "colRef", "filter", "setAutoRemove", "viewSectionRef"],
[1, 1, json.dumps({"included": ["z", "b"]}), None, 1],
[2, 2, json.dumps({"included": ["b", "c"]}), None, 1]
["id", "colRef", "filter", "setAutoRemove", "viewSectionRef", "pinned"],
[1, 1, json.dumps({"included": ["z", "b"]}), None, 1, True],
[2, 2, json.dumps({"included": ["b", "c"]}), None, 1, False]
])
def test_add_or_update(self):