dataviz: hide future time range choices by default (#62862)
This commit is contained in:
parent
6f040993b2
commit
73e345a89d
|
@ -27,7 +27,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from combo.utils import cache_during_request, requests, spooler
|
||||
|
||||
from .models import TIME_FILTERS, ChartCell, ChartNgCell
|
||||
from .models import ChartCell, ChartNgCell
|
||||
|
||||
|
||||
class ChartForm(forms.ModelForm):
|
||||
|
@ -110,6 +110,17 @@ class ChartFiltersMixin:
|
|||
if choice[0] not in choice_ids:
|
||||
choices.append(choice)
|
||||
|
||||
def update_time_range_choices(self, statistic, exclude_template_choice=False):
|
||||
choices = self.fields['time_range'].choices
|
||||
|
||||
if not statistic.has_future_data:
|
||||
choices = [choice for choice in choices if not choice[0].startswith('next')]
|
||||
|
||||
if exclude_template_choice:
|
||||
choices = [choice for choice in choices if choice[0] != 'range-template']
|
||||
|
||||
self.fields['time_range'].choices = choices
|
||||
|
||||
|
||||
class ChartNgForm(ChartFiltersMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
|
@ -136,16 +147,6 @@ class ChartNgForm(ChartFiltersMixin, forms.ModelForm):
|
|||
trigger_statistics_list_refresh()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if not self.instance.statistic or self.instance.statistic.service_slug == 'bijoe':
|
||||
for field in (
|
||||
'time_range',
|
||||
'time_range_start',
|
||||
'time_range_end',
|
||||
'time_range_start_template',
|
||||
'time_range_end_template',
|
||||
):
|
||||
del self.fields[field]
|
||||
|
||||
stat_field = self.fields['statistic']
|
||||
if not self.instance.statistic:
|
||||
stat_field.queryset = stat_field.queryset.filter(available=True)
|
||||
|
@ -155,6 +156,17 @@ class ChartNgForm(ChartFiltersMixin, forms.ModelForm):
|
|||
Q(available=True) | Q(pk=self.instance.statistic.pk)
|
||||
)
|
||||
self.add_filter_fields()
|
||||
self.update_time_range_choices(self.instance.statistic)
|
||||
|
||||
if not self.instance.statistic or self.instance.statistic.service_slug == 'bijoe':
|
||||
for field in (
|
||||
'time_range',
|
||||
'time_range_start',
|
||||
'time_range_end',
|
||||
'time_range_start_template',
|
||||
'time_range_end_template',
|
||||
):
|
||||
del self.fields[field]
|
||||
|
||||
def add_filter_fields(self):
|
||||
new_fields = OrderedDict()
|
||||
|
@ -248,7 +260,6 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
|
|||
def __init__(self, *args, **kwargs):
|
||||
page = kwargs.pop('page')
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['time_range'].choices = BLANK_CHOICE_DASH + TIME_FILTERS
|
||||
|
||||
chart_cells = list(ChartNgCell.objects.filter(page=page, statistic__isnull=False).order_by('order'))
|
||||
if not chart_cells:
|
||||
|
@ -260,6 +271,7 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
|
|||
self.fields[field].initial = getattr(first_cell, field)
|
||||
dynamic_fields = self.get_filter_fields(first_cell)
|
||||
dynamic_fields_values = {k: v for k, v in first_cell.filter_params.items()}
|
||||
self.update_time_range_choices(first_cell.statistic, exclude_template_choice=True)
|
||||
|
||||
for cell in chart_cells[1:]:
|
||||
cell_filter_fields = self.get_filter_fields(cell)
|
||||
|
@ -285,4 +297,7 @@ class ChartFiltersForm(ChartFiltersMixin, forms.ModelForm):
|
|||
if dynamic_fields[field_name].choices == []:
|
||||
del dynamic_fields[field_name]
|
||||
|
||||
if 'time_range' in self.fields:
|
||||
self.update_time_range_choices(cell.statistic)
|
||||
|
||||
self.fields.update(dynamic_fields)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from django.db import migrations, models
|
||||
|
||||
from combo.apps.dataviz.models import TIME_FILTERS, TIME_FILTERS_TEMPLATE
|
||||
from combo.apps.dataviz.models import TIME_FILTERS
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -17,7 +17,7 @@ class Migration(migrations.Migration):
|
|||
name='time_range',
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=TIME_FILTERS + TIME_FILTERS_TEMPLATE,
|
||||
choices=TIME_FILTERS,
|
||||
max_length=20,
|
||||
verbose_name='Shown period',
|
||||
),
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.19 on 2022-03-17 10:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dataviz', '0022_chartngcell_subfilters'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='statistic',
|
||||
name='has_future_data',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -139,6 +139,7 @@ class Statistic(models.Model):
|
|||
site_title = models.CharField(_('Site title'), max_length=256)
|
||||
url = models.URLField(_('Data URL'))
|
||||
filters = JSONField(default=list)
|
||||
has_future_data = models.BooleanField(default=False)
|
||||
available = models.BooleanField(_('Available data'), default=True)
|
||||
last_update = models.DateTimeField(_('Last update'), null=True, auto_now=True)
|
||||
|
||||
|
@ -178,8 +179,8 @@ TIME_FILTERS = [
|
|||
('current-week', _('Current week')),
|
||||
('next-week', _('Next week')),
|
||||
('range', _('Free range (date)')),
|
||||
('range-template', _('Free range (template)')),
|
||||
]
|
||||
TIME_FILTERS_TEMPLATE = [('range-template', _('Free range (template)'))]
|
||||
|
||||
|
||||
@register_cell_class
|
||||
|
@ -202,7 +203,7 @@ class ChartNgCell(CellBase):
|
|||
_('Shown period'),
|
||||
max_length=20,
|
||||
blank=True,
|
||||
choices=TIME_FILTERS + TIME_FILTERS_TEMPLATE,
|
||||
choices=TIME_FILTERS,
|
||||
)
|
||||
time_range_start = models.DateField(_('From'), null=True, blank=True)
|
||||
time_range_end = models.DateField(_('To'), null=True, blank=True)
|
||||
|
|
|
@ -45,11 +45,12 @@ def update_available_statistics():
|
|||
url=stat.get('data-url') or stat['url'],
|
||||
site_title=site_dict.get('title', ''),
|
||||
filters=stat.get('filters', []),
|
||||
has_future_data=stat.get('future_data', False),
|
||||
available=True,
|
||||
)
|
||||
)
|
||||
|
||||
update_fields = ('label', 'url', 'site_title', 'filters', 'available')
|
||||
update_fields = ('label', 'url', 'site_title', 'filters', 'available', 'has_future_data')
|
||||
all_statistics = {stat.natural_key(): stat for stat in Statistic.objects.all()}
|
||||
statistics_to_create = []
|
||||
statistics_to_update = {}
|
||||
|
|
|
@ -433,6 +433,12 @@ STATISTICS_LIST = {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'url': 'https://authentic.example.com/api/statistics/future-data/',
|
||||
'name': 'With future data',
|
||||
'id': 'with-future-data',
|
||||
'future_data': True,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -521,6 +527,14 @@ def new_api_mock(url, request):
|
|||
if 'form=error' in url.query:
|
||||
return {'content': b'', 'request': request, 'status_code': 404}
|
||||
return {'content': json.dumps(response), 'request': request, 'status_code': 200}
|
||||
if url.path == '/api/statistics/future-data/':
|
||||
response = {
|
||||
'data': {
|
||||
'series': [{'data': [None, 16, 2], 'label': 'Serie 1'}],
|
||||
'x_labels': ['2020-10', '2020-11', '2020-12'],
|
||||
},
|
||||
}
|
||||
return {'content': json.dumps(response), 'request': request, 'status_code': 200}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -1368,6 +1382,51 @@ def test_chartng_cell_manager_new_api(app, admin_user, new_api_statistics):
|
|||
assert cell.get_filter_params() == {}
|
||||
|
||||
|
||||
@with_httmock(new_api_mock)
|
||||
def test_chartng_cell_manager_future_data(app, admin_user, new_api_statistics):
|
||||
page = Page.objects.create(title='One', slug='index')
|
||||
cell = ChartNgCell(page=page, order=1, placeholder='content')
|
||||
cell.statistic = Statistic.objects.get(slug='one-serie')
|
||||
cell.save()
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/pages/%s/' % page.id)
|
||||
field_prefix = 'cdataviz_chartngcell-%s-' % cell.id
|
||||
time_range_field = resp.form[field_prefix + 'time_range']
|
||||
assert time_range_field.value == ''
|
||||
assert time_range_field.options == [
|
||||
('', True, '---------'),
|
||||
('previous-year', False, 'Previous year'),
|
||||
('current-year', False, 'Current year'),
|
||||
('previous-month', False, 'Previous month'),
|
||||
('current-month', False, 'Current month'),
|
||||
('previous-week', False, 'Previous week'),
|
||||
('current-week', False, 'Current week'),
|
||||
('range', False, 'Free range (date)'),
|
||||
('range-template', False, 'Free range (template)'),
|
||||
]
|
||||
|
||||
stat_with_future_data = Statistic.objects.get(slug='with-future-data')
|
||||
resp.form[field_prefix + 'statistic'] = stat_with_future_data.pk
|
||||
resp = resp.form.submit().follow()
|
||||
time_range_field = resp.form[field_prefix + 'time_range']
|
||||
assert time_range_field.value == ''
|
||||
assert time_range_field.options == [
|
||||
('', True, '---------'),
|
||||
('previous-year', False, 'Previous year'),
|
||||
('current-year', False, 'Current year'),
|
||||
('next-year', False, 'Next year'),
|
||||
('previous-month', False, 'Previous month'),
|
||||
('current-month', False, 'Current month'),
|
||||
('next-month', False, 'Next month'),
|
||||
('previous-week', False, 'Previous week'),
|
||||
('current-week', False, 'Current week'),
|
||||
('next-week', False, 'Next week'),
|
||||
('range', False, 'Free range (date)'),
|
||||
('range-template', False, 'Free range (template)'),
|
||||
]
|
||||
|
||||
|
||||
@with_httmock(new_api_mock)
|
||||
def test_chartng_cell_manager_subfilters(app, admin_user, new_api_statistics):
|
||||
page = Page.objects.create(title='One', slug='index')
|
||||
|
@ -2092,13 +2151,10 @@ def test_chart_filters_cell(new_api_statistics, app, admin_user, nocache):
|
|||
('', True, '---------'),
|
||||
('previous-year', False, 'Previous year'),
|
||||
('current-year', False, 'Current year'),
|
||||
('next-year', False, 'Next year'),
|
||||
('previous-month', False, 'Previous month'),
|
||||
('current-month', False, 'Current month'),
|
||||
('next-month', False, 'Next month'),
|
||||
('previous-week', False, 'Previous week'),
|
||||
('current-week', False, 'Current week'),
|
||||
('next-week', False, 'Next week'),
|
||||
('range', False, 'Free range (date)'),
|
||||
]
|
||||
|
||||
|
@ -2161,7 +2217,7 @@ def test_chart_filters_cell(new_api_statistics, app, admin_user, nocache):
|
|||
assert resp.form[field].options == old_resp.form[field].options
|
||||
|
||||
# changing time_interval value makes interval fields disappear
|
||||
cell.time_range = 'next-year'
|
||||
cell.time_range = 'previous-year'
|
||||
cell.save()
|
||||
old_resp = resp
|
||||
resp = app.get('/')
|
||||
|
@ -2171,10 +2227,10 @@ def test_chart_filters_cell(new_api_statistics, app, admin_user, nocache):
|
|||
assert resp.form['time_interval'].options == old_resp.form['time_interval'].options
|
||||
|
||||
# setting the same value for the other cell makes it appear again
|
||||
first_cell.time_range = 'next-year'
|
||||
first_cell.time_range = 'previous-year'
|
||||
first_cell.save()
|
||||
resp = app.get('/')
|
||||
assert resp.form['time_range'].value == 'next-year'
|
||||
assert resp.form['time_range'].value == 'previous-year'
|
||||
assert resp.form['time_interval'].options == old_resp.form['time_interval'].options
|
||||
|
||||
# only common choices are shown
|
||||
|
@ -2191,7 +2247,7 @@ def test_chart_filters_cell(new_api_statistics, app, admin_user, nocache):
|
|||
first_cell.statistic.save()
|
||||
resp = app.get('/')
|
||||
assert 'time_interval' not in resp.form.fields
|
||||
assert resp.form['time_range'].value == 'next-year'
|
||||
assert resp.form['time_range'].value == 'previous-year'
|
||||
|
||||
# form is not shown if no common filters exist
|
||||
first_cell.time_range = 'current-year'
|
||||
|
@ -2200,6 +2256,52 @@ def test_chart_filters_cell(new_api_statistics, app, admin_user, nocache):
|
|||
assert 'No filters are available' in resp.text
|
||||
|
||||
|
||||
@with_httmock(new_api_mock)
|
||||
def test_chart_filters_cell_future_data(app, admin_user, new_api_statistics):
|
||||
page = Page.objects.create(title='One', slug='index')
|
||||
cell = ChartNgCell(page=page, order=1, placeholder='content')
|
||||
cell.statistic = Statistic.objects.get(slug='with-future-data')
|
||||
cell.save()
|
||||
ChartFiltersCell.objects.create(page=page, order=2, placeholder='content')
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/')
|
||||
time_range_field = resp.form['time_range']
|
||||
assert time_range_field.value == ''
|
||||
assert time_range_field.options == [
|
||||
('', True, '---------'),
|
||||
('previous-year', False, 'Previous year'),
|
||||
('current-year', False, 'Current year'),
|
||||
('next-year', False, 'Next year'),
|
||||
('previous-month', False, 'Previous month'),
|
||||
('current-month', False, 'Current month'),
|
||||
('next-month', False, 'Next month'),
|
||||
('previous-week', False, 'Previous week'),
|
||||
('current-week', False, 'Current week'),
|
||||
('next-week', False, 'Next week'),
|
||||
('range', False, 'Free range (date)'),
|
||||
]
|
||||
|
||||
# adding cell without future data makes choice disappear
|
||||
cell = ChartNgCell(page=page, order=3, placeholder='content')
|
||||
cell.statistic = Statistic.objects.get(slug='one-serie')
|
||||
cell.save()
|
||||
|
||||
resp = app.get('/')
|
||||
time_range_field = resp.form['time_range']
|
||||
assert time_range_field.value == ''
|
||||
assert time_range_field.options == [
|
||||
('', True, '---------'),
|
||||
('previous-year', False, 'Previous year'),
|
||||
('current-year', False, 'Current year'),
|
||||
('previous-month', False, 'Previous month'),
|
||||
('current-month', False, 'Current month'),
|
||||
('previous-week', False, 'Previous week'),
|
||||
('current-week', False, 'Current week'),
|
||||
('range', False, 'Free range (date)'),
|
||||
]
|
||||
|
||||
|
||||
@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')
|
||||
|
|
Loading…
Reference in New Issue