dataviz: allow disabling filters in filters cell (#71655)
gitea-wip/combo/pipeline/head Build started...
Details
gitea-wip/combo/pipeline/head Build started...
Details
This commit is contained in:
parent
dce44a268f
commit
68387fbe3b
|
@ -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)
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{% load gadjo %}
|
||||
|
||||
{% block cell-form %}
|
||||
{{form|with_template}}
|
||||
{% endblock %}
|
||||
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue