dataviz: allow disabling filters in filters cell (#71655)
gitea-wip/combo/pipeline/head Build started... Details

This commit is contained in:
Valentin Deniaud 2022-12-12 15:12:53 +01:00
parent dce44a268f
commit 68387fbe3b
5 changed files with 143 additions and 2 deletions

View File

@ -28,7 +28,7 @@ from django.utils.translation import gettext_lazy as _
from combo.utils import cache_during_request, requests, spooler
from .models import ChartCell, ChartNgCell
from .models import ChartCell, ChartFiltersCell, ChartNgCell
class ChartForm(forms.ModelForm):
@ -290,6 +290,7 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
def __init__(self, *args, **kwargs):
page = kwargs.pop('page')
filters_cell = kwargs.pop('filters_cell')
filters_cell_id = kwargs.pop('filters_cell_id', None)
super().__init__(*args, **kwargs)
@ -356,4 +357,52 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
if 'time_range' in self.fields:
self.update_time_range_choices(cell.statistic)
self.update_backoffice_filter_choices(filters_cell, dynamic_fields)
dynamic_fields = {
name: field for name, field in dynamic_fields.items() if filters_cell.filters[name]['enabled']
}
self.fields.update(dynamic_fields)
@staticmethod
def update_backoffice_filter_choices(filters_cell, dynamic_fields):
# remove absent filters from cell configuration, except if it was disabled
filters_cell.filters = {
k: v for k, v in filters_cell.filters.items() if k in dynamic_fields or not v['enabled']
}
# add filters to cell configuration
for field_name, field in dynamic_fields.items():
if not field_name in filters_cell.filters:
filters_cell.filters[field_name] = {'label': str(field.label), 'enabled': True}
continue
filters_cell.save()
class ChartFiltersConfigForm(forms.ModelForm):
filters = forms.MultipleChoiceField(
label=_('Filters'), widget=forms.CheckboxSelectMultiple, required=False
)
class Meta:
model = ChartFiltersCell
fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.instance.filters:
del self.fields['filters']
return
self.initial['filters'] = []
self.fields['filters'].choices = []
for filter_id, config in self.instance.filters.items():
self.fields['filters'].choices.append((filter_id, config['label']))
if config['enabled']:
self.initial['filters'].append(filter_id)
def save(self, *args, **kwargs):
for filter_id in self.instance.filters:
self.instance.filters[filter_id]['enabled'] = bool(filter_id in self.cleaned_data['filters'])
return super().save(*args, **kwargs)

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.26 on 2022-12-12 13:28
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('dataviz', '0025_statistic_data_type'),
]
operations = [
migrations.AddField(
model_name='chartfilterscell',
name='filters',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, verbose_name='Filters'),
),
]

View File

@ -739,8 +739,11 @@ class ChartNgCell(CellBase):
@register_cell_class
class ChartFiltersCell(CellBase):
filters = JSONField(_('Filters'), default=dict)
title = _('Filters')
default_template_name = 'combo/chart-filters.html'
manager_form_template = 'combo/chartfilterscell_form.html'
max_one_by_page = True
class Meta:
@ -758,9 +761,15 @@ class ChartFiltersCell(CellBase):
ctx['form'] = ChartFiltersForm(
data=context['request'].GET,
page=self.page,
filters_cell=self,
filters_cell_id=context['request'].GET['filters_cell_id'],
)
else:
ctx['form'] = ChartFiltersForm(page=self.page)
ctx['form'] = ChartFiltersForm(page=self.page, filters_cell=self)
return ctx
def get_default_form_class(self):
from .forms import ChartFiltersConfigForm
return ChartFiltersConfigForm

View File

@ -0,0 +1,6 @@
{% load gadjo %}
{% block cell-form %}
{{form|with_template}}
{% endblock %}

View File

@ -2778,6 +2778,64 @@ def test_chart_filters_cell_with_subfilters(new_api_statistics, app, admin_user,
assert 'filter-menu' in resp.form.fields
@with_httmock(new_api_mock)
def test_chart_filters_cell_select_filters(new_api_statistics, app, admin_user, nocache):
page = Page.objects.create(title='One', slug='index')
filters_cell = ChartFiltersCell.objects.create(page=page, order=1, placeholder='content')
app = login(app)
# no chart cell, filters cell configuration is empty
resp = app.get('/manage/pages/%s/' % page.id)
field_prefix = 'cdataviz_chartfilterscell-%s-' % filters_cell.id
assert field_prefix + 'filters' not in resp.form.fields
# add chart cell
cell = ChartNgCell.objects.create(page=page, order=2, placeholder='content')
cell.statistic = Statistic.objects.get(slug='one-serie')
cell.save()
resp = app.get('/')
assert len(resp.form.fields) == 7
assert 'filter-ou' in resp.form.fields
assert 'filter-service' in resp.form.fields
assert 'filter-time_range' in resp.form.fields
# filters cell configuration shows filters
resp = app.get('/manage/pages/%s/' % page.id)
assert field_prefix + 'filters' in resp.forms[0].fields
# all filters are active
assert all(resp.forms[0].get(field_prefix + 'filters', index=i).checked for i in range(3))
assert [resp.forms[0].get(field_prefix + 'filters', index=i).value for i in range(3)] == [
'ou',
'service',
'time_interval',
]
# disable OU filter
resp.forms[0].get(field_prefix + 'filters', index=0).checked = False
manager_submit_cell(resp.forms[0])
resp = app.get('/')
assert len(resp.form.fields) == 6
assert 'filter-ou' not in resp.form.fields
assert 'filter-service' in resp.form.fields
assert 'filter-time_range' in resp.form.fields
# choose other statistic with different filters
cell.statistic = Statistic.objects.get(slug='filter-multiple')
cell.save()
# OU filter has been kept as it is disabled, but other disappeared
resp = app.get('/manage/pages/%s/' % page.id)
assert [resp.forms[0].get(field_prefix + 'filters', index=i).value for i in range(2)] == [
None,
'color',
]
resp.forms[0].get(field_prefix + 'filters', index=0).checked = True
assert resp.forms[0].get(field_prefix + 'filters', index=0).value == 'ou'
@with_httmock(new_api_mock)
@pytest.mark.freeze_time('2021-10-06')
def test_chartng_cell_api_view_get_parameters(app, normal_user, new_api_statistics, nocache):