wip/72896-dataviz-afficher-les-filtres-boo #52

Manually merged
vdeniaud merged 2 commits from wip/72896-dataviz-afficher-les-filtres-boo into main 2023-02-28 10:26:57 +01:00
2 changed files with 98 additions and 47 deletions

View File

@ -75,11 +75,29 @@ class ChartFiltersMixin:
):
continue
initial = cell.filter_params.get(filter_id, filter_.get('default'))
required = filter_.get('required', False)
if required and {x['id'] for x in filter_['options'] if isinstance(x, dict)} == {'true', 'false'}:
field = self.build_boolean_field(cell, filter_, initial)
else:
field = self.build_choice_field(cell, filter_, initial)
fields[filter_id] = field
if filter_.get('deprecated'):
fields[filter_id].label += ' (%s)' % _('deprecated')
fields[filter_id].help_text = filter_.get('deprecation_hint')
fields[filter_id].is_filter_field = True
return fields
def build_choice_field(self, cell, filter_, initial):
filter_id = filter_['id']
has_option_groups = isinstance(filter_['options'][0], list)
if filter_['options'] and has_option_groups:
choices = {
group: [(opt['id'], opt['label']) for opt in options]
for group, options in filter_['options']
group: [(opt['id'], opt['label']) for opt in options] for group, options in filter_['options']
}
choices_to_complete = choices[None] = choices.get(None, [])
choices = list(choices.items())
@ -87,8 +105,6 @@ class ChartFiltersMixin:
choices = [(option['id'], option['label']) for option in filter_['options']]
choices_to_complete = choices
initial = cell.filter_params.get(filter_id, filter_.get('default'))
if filter_id == 'time_interval':
self.extend_time_interval_choices(choices)
@ -119,19 +135,20 @@ class ChartFiltersMixin:
field_class = forms.MultipleChoiceField if multiple else forms.ChoiceField
widget_class = MultiSelectWidget if multiple else forms.Select
fields[filter_id] = field_class(
return field_class(
label=filter_['label'],
choices=choices,
required=required,
initial=initial,
widget=widget_class,
)
if filter_.get('deprecated'):
fields[filter_id].label += ' (%s)' % _('deprecated')
fields[filter_id].help_text = filter_.get('deprecation_hint')
fields[filter_id].is_filter_field = True
return fields
def build_boolean_field(self, cell, filter_, initial):
return forms.BooleanField(
label=filter_['label'],
required=False,
initial=bool(initial == 'true'),
)
def extend_time_interval_choices(self, choices):
choice_ids = {choice_id for choice_id, _ in choices}
@ -224,7 +241,11 @@ class ChartNgForm(ChartFiltersMixin, forms.ModelForm):
else:
for filter_ in self.instance.available_filters:
if filter_['id'] in self.cleaned_data:
self.instance.filter_params[filter_['id']] = self.cleaned_data[filter_['id']]
value = self.cleaned_data[filter_['id']]
if isinstance(value, bool):
value = 'true' if value is True else 'false'
self.instance.filter_params[filter_['id']] = value
cell = super().save(*args, **kwargs)

View File

@ -564,6 +564,23 @@ STATISTICS_LIST = {
'id': 'deprecated',
'deprecated': True,
},
{
'url': 'https://authentic.example.com/api/statistics/required-boolean/',
'name': 'Required boolean choices',
'id': 'required-boolean',
"filters": [
{
"id": "test",
"label": "Test",
"options": [
{"id": "true", "label": "True"},
{"id": "false", "label": "False"},
],
"default": "true",
"required": True,
},
],
},
]
}
@ -1656,6 +1673,19 @@ def test_chartng_cell_manager_new_api(app, admin_user, new_api_statistics):
cell.refresh_from_db()
assert cell.filter_params == {'test': 'b'}
required_boolean_stat = Statistic.objects.get(slug='required-boolean')
resp.form[field_prefix + 'statistic'] = required_boolean_stat.pk
manager_submit_cell(resp.form)
assert resp.form[field_prefix + 'test'].checked is True
cell.refresh_from_db()
assert cell.filter_params == {'test': 'true'}
manager_submit_cell(resp.form)
resp.form[field_prefix + 'test'] = False
manager_submit_cell(resp.form)
cell.refresh_from_db()
assert cell.filter_params == {'test': 'false'}
deprecated_stat = Statistic.objects.get(slug='deprecated-filter')
resp.form[field_prefix + 'statistic'] = deprecated_stat.pk
manager_submit_cell(resp.form)