Projet

Général

Profil

0001-dataviz-allow-disabling-filters-in-filters-cell-7165.patch

Valentin Deniaud, 12 décembre 2022 18:14

Télécharger (8,54 ko)

Voir les différences:

Subject: [PATCH] dataviz: allow disabling filters in filters cell (#71655)

 combo/apps/dataviz/forms.py                   | 51 +++++++++++++++-
 .../0026_chartfilterscell_filters.py          | 19 ++++++
 combo/apps/dataviz/models.py                  | 11 +++-
 .../combo/chartfilterscell_form.html          |  6 ++
 tests/test_dataviz.py                         | 58 +++++++++++++++++++
 5 files changed, 143 insertions(+), 2 deletions(-)
 create mode 100644 combo/apps/dataviz/migrations/0026_chartfilterscell_filters.py
 create mode 100644 combo/apps/dataviz/templates/combo/chartfilterscell_form.html
combo/apps/dataviz/forms.py
28 28

  
29 29
from combo.utils import cache_during_request, requests, spooler
30 30

  
31
from .models import ChartCell, ChartNgCell
31
from .models import ChartCell, ChartFiltersCell, ChartNgCell
32 32

  
33 33

  
34 34
class ChartForm(forms.ModelForm):
......
286 286

  
287 287
    def __init__(self, *args, **kwargs):
288 288
        page = kwargs.pop('page')
289
        filters_cell = kwargs.pop('filters_cell')
289 290
        filters_cell_id = kwargs.pop('filters_cell_id', None)
290 291
        super().__init__(*args, **kwargs)
291 292

  
......
337 338
            if 'time_range' in self.fields:
338 339
                self.update_time_range_choices(cell.statistic)
339 340

  
341
        self.update_backoffice_filter_choices(filters_cell, dynamic_fields)
342
        dynamic_fields = {
343
            name: field for name, field in dynamic_fields.items() if filters_cell.filters[name]['enabled']
344
        }
340 345
        self.fields.update(dynamic_fields)
346

  
347
    @staticmethod
348
    def update_backoffice_filter_choices(filters_cell, dynamic_fields):
349
        # remove absent filters from cell configuration, except if it was disabled
350
        filters_cell.filters = {
351
            k: v for k, v in filters_cell.filters.items() if k in dynamic_fields or not v['enabled']
352
        }
353

  
354
        # add filters to cell configuration
355
        for field_name, field in dynamic_fields.items():
356
            if not field_name in filters_cell.filters:
357
                filters_cell.filters[field_name] = {'label': str(field.label), 'enabled': True}
358
                continue
359

  
360
        filters_cell.save()
361

  
362

  
363
class ChartFiltersConfigForm(forms.ModelForm):
364
    filters = forms.MultipleChoiceField(
365
        label=_('Filters'), widget=forms.CheckboxSelectMultiple, required=False
366
    )
367

  
368
    class Meta:
369
        model = ChartFiltersCell
370
        fields = []
371

  
372
    def __init__(self, *args, **kwargs):
373
        super().__init__(*args, **kwargs)
374
        if not self.instance.filters:
375
            del self.fields['filters']
376
            return
377

  
378
        self.initial['filters'] = []
379
        self.fields['filters'].choices = []
380
        for filter_id, config in self.instance.filters.items():
381
            self.fields['filters'].choices.append((filter_id, config['label']))
382

  
383
            if config['enabled']:
384
                self.initial['filters'].append(filter_id)
385

  
386
    def save(self, *args, **kwargs):
387
        for filter_id in self.instance.filters:
388
            self.instance.filters[filter_id]['enabled'] = bool(filter_id in self.cleaned_data['filters'])
389
        return super().save(*args, **kwargs)
combo/apps/dataviz/migrations/0026_chartfilterscell_filters.py
1
# Generated by Django 2.2.26 on 2022-12-12 13:28
2

  
3
import django.contrib.postgres.fields.jsonb
4
from django.db import migrations
5

  
6

  
7
class Migration(migrations.Migration):
8

  
9
    dependencies = [
10
        ('dataviz', '0025_statistic_data_type'),
11
    ]
12

  
13
    operations = [
14
        migrations.AddField(
15
            model_name='chartfilterscell',
16
            name='filters',
17
            field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, verbose_name='Filters'),
18
        ),
19
    ]
combo/apps/dataviz/models.py
758 758

  
759 759
@register_cell_class
760 760
class ChartFiltersCell(CellBase):
761
    filters = JSONField(_('Filters'), default=dict)
762

  
761 763
    title = _('Filters')
762 764
    default_template_name = 'combo/chart-filters.html'
765
    manager_form_template = 'combo/chartfilterscell_form.html'
763 766
    max_one_by_page = True
764 767

  
765 768
    class Meta:
......
777 780
            ctx['form'] = ChartFiltersForm(
778 781
                data=context['request'].GET,
779 782
                page=self.page,
783
                filters_cell=self,
780 784
                filters_cell_id=context['request'].GET['filters_cell_id'],
781 785
            )
782 786
        else:
783
            ctx['form'] = ChartFiltersForm(page=self.page)
787
            ctx['form'] = ChartFiltersForm(page=self.page, filters_cell=self)
784 788

  
785 789
        return ctx
790

  
791
    def get_default_form_class(self):
792
        from .forms import ChartFiltersConfigForm
793

  
794
        return ChartFiltersConfigForm
combo/apps/dataviz/templates/combo/chartfilterscell_form.html
1
{% load gadjo %}
2

  
3
{% block cell-form %}
4
  {{form|with_template}}
5
{% endblock %}
6

  
tests/test_dataviz.py
2705 2705
    assert 'filter-menu' in resp.form.fields
2706 2706

  
2707 2707

  
2708
@with_httmock(new_api_mock)
2709
def test_chart_filters_cell_select_filters(new_api_statistics, app, admin_user, nocache):
2710
    page = Page.objects.create(title='One', slug='index')
2711
    filters_cell = ChartFiltersCell.objects.create(page=page, order=1, placeholder='content')
2712
    app = login(app)
2713

  
2714
    # no chart cell, filters cell configuration is empty
2715
    resp = app.get('/manage/pages/%s/' % page.id)
2716
    field_prefix = 'cdataviz_chartfilterscell-%s-' % filters_cell.id
2717
    assert field_prefix + 'filters' not in resp.form.fields
2718

  
2719
    # add chart cell
2720
    cell = ChartNgCell.objects.create(page=page, order=2, placeholder='content')
2721
    cell.statistic = Statistic.objects.get(slug='one-serie')
2722
    cell.save()
2723

  
2724
    resp = app.get('/')
2725
    assert len(resp.form.fields) == 7
2726
    assert 'filter-ou' in resp.form.fields
2727
    assert 'filter-service' in resp.form.fields
2728
    assert 'filter-time_range' in resp.form.fields
2729

  
2730
    # filters cell configuration shows filters
2731
    resp = app.get('/manage/pages/%s/' % page.id)
2732
    assert field_prefix + 'filters' in resp.forms[0].fields
2733

  
2734
    # all filters are active
2735
    assert all(resp.forms[0].get(field_prefix + 'filters', index=i).checked for i in range(3))
2736
    assert [resp.forms[0].get(field_prefix + 'filters', index=i).value for i in range(3)] == [
2737
        'ou',
2738
        'service',
2739
        'time_interval',
2740
    ]
2741

  
2742
    # disable OU filter
2743
    resp.forms[0].get(field_prefix + 'filters', index=0).checked = False
2744
    manager_submit_cell(resp.forms[0])
2745

  
2746
    resp = app.get('/')
2747
    assert len(resp.form.fields) == 6
2748
    assert 'filter-ou' not in resp.form.fields
2749
    assert 'filter-service' in resp.form.fields
2750
    assert 'filter-time_range' in resp.form.fields
2751

  
2752
    # choose other statistic with different filters
2753
    cell.statistic = Statistic.objects.get(slug='filter-multiple')
2754
    cell.save()
2755

  
2756
    # OU filter has been kept as it is disabled, but other disappeared
2757
    resp = app.get('/manage/pages/%s/' % page.id)
2758
    assert [resp.forms[0].get(field_prefix + 'filters', index=i).value for i in range(2)] == [
2759
        None,
2760
        'color',
2761
    ]
2762
    resp.forms[0].get(field_prefix + 'filters', index=0).checked = True
2763
    assert resp.forms[0].get(field_prefix + 'filters', index=0).value == 'ou'
2764

  
2765

  
2708 2766
@with_httmock(new_api_mock)
2709 2767
@pytest.mark.freeze_time('2021-10-06')
2710 2768
def test_chartng_cell_api_view_get_parameters(app, normal_user, new_api_statistics, nocache):
2711
-