dataviz: merge grouped choices properly in filters cell (#72929)

This commit is contained in:
Valentin Deniaud 2023-01-04 11:27:22 +01:00 committed by Gitea
parent f07d72f3ab
commit dce44a268f
2 changed files with 76 additions and 3 deletions

View File

@ -331,12 +331,27 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
# ensure compatible choices lists
for field_name, field in cell_filter_fields.items():
if field_name in dynamic_fields:
if field_name not in dynamic_fields:
continue
has_option_groups = isinstance(dynamic_fields[field_name].choices[0][1], list)
if has_option_groups and isinstance(field.choices[0][1], list):
new_choices = []
field_choices = {group_label: choices for group_label, choices in field.choices}
for group_label, choices in dynamic_fields[field_name].choices:
if group_label not in field_choices:
continue
new_choices.append(
(group_label, [x for x in choices if x in field_choices[group_label]])
)
dynamic_fields[field_name].choices = new_choices
else:
dynamic_fields[field_name].choices = [
x for x in dynamic_fields[field_name].choices if x in field.choices
]
if dynamic_fields[field_name].choices == []:
del dynamic_fields[field_name]
if dynamic_fields[field_name].choices == []:
del dynamic_fields[field_name]
if 'time_range' in self.fields:
self.update_time_range_choices(cell.statistic)

View File

@ -483,6 +483,22 @@ STATISTICS_LIST = {
},
],
},
{
'url': 'https://authentic.example.com/api/statistics/option-groups-2/',
'name': 'Option groups 2',
'id': 'option-groups-2',
"filters": [
{
"id": "form",
"label": "Form",
"required": True,
"options": [
[None, [{'id': 'all', 'label': 'All'}]],
['Category A', [{'id': 'test', 'label': 'Test'}, {'id': 'other', 'label': 'Other'}]],
],
},
],
},
{
'url': 'https://authentic.example.com/api/statistics/deprecated-filter/',
'name': 'Deprecated filter',
@ -2671,6 +2687,48 @@ def test_chart_filters_cell_range_template(new_api_statistics, app, admin_user,
assert 'filter-time_range_end' not in resp.form.fields
@with_httmock(new_api_mock)
def test_chart_filters_cell_grouped_choices_intersection(new_api_statistics, app, admin_user, nocache):
page = Page.objects.create(title='One', slug='index')
cell = ChartNgCell(page=page, order=1, placeholder='content')
cell.statistic = Statistic.objects.get(slug='option-groups')
cell.save()
ChartFiltersCell.objects.create(page=page, order=2, placeholder='content')
app = login(app)
resp = app.get('/')
assert 'filter-cards_count' in resp.form.fields
assert resp.form['filter-form'].options == [
('', True, '---------'),
('all', False, 'All'),
('test', False, 'Test'),
('test-2', False, 'test 2'),
]
cell2 = ChartNgCell(page=page, order=3, placeholder='content')
cell2.statistic = Statistic.objects.get(slug='option-groups-2')
cell2.save()
resp = app.get('/')
assert 'filter-cards_count' not in resp.form.fields
assert resp.form['filter-form'].options == [
('all', False, 'All'),
('test', False, 'Test'),
]
cell.filter_params['form'] = 'unknown'
cell.save()
cell2.filter_params['form'] = 'unknown'
cell2.save()
resp = app.get('/')
assert resp.form['filter-form'].options == [
('all', False, 'All'),
('unknown', True, 'unknown (unavailable)'),
('test', False, 'Test'),
]
@with_httmock(new_api_mock)
def test_chart_filters_cell_with_subfilters(new_api_statistics, app, admin_user, nocache):
page = Page.objects.create(title='One', slug='index')