Projet

Général

Profil

0004-fields-add-new-option-to-align-datetimes-selection-o.patch

Frédéric Péters, 11 janvier 2021 21:09

Télécharger (8,58 ko)

Voir les différences:

Subject: [PATCH 4/4] fields: add new option to align datetimes selection on a
 date (#50035)

 tests/form_pages/test_all.py                  | 88 +++++++++++++++++++
 wcs/fields.py                                 | 24 ++++-
 .../forms/widgets/select-datetimes.html       | 18 +++-
 3 files changed, 128 insertions(+), 2 deletions(-)
tests/form_pages/test_all.py
9414 9414
    data_id = formdef.data_class().select()[0].id
9415 9415
    formdata = formdef.data_class().get(data_id)
9416 9416
    assert formdata.data['1_structured']['geometry']['coordinates'] == [1, 2]
9417

  
9418

  
9419
def test_form_item_datetimes_data_source(pub, http_requests):
9420
    NamedDataSource.wipe()
9421
    data_source = NamedDataSource(name='foobar')
9422
    data_source.data_source = {
9423
        'type': 'json',
9424
        'value': 'http://remote.example.net/api/datetimes',
9425
    }
9426
    data_source.store()
9427

  
9428
    formdef = create_formdef()
9429
    formdef.fields = [
9430
        fields.ItemField(id='1', label='datetime', display_mode='datetimes', data_source={'type': 'foobar'}),
9431
    ]
9432
    formdef.store()
9433
    formdef.data_class().wipe()
9434
    app = get_app(pub)
9435

  
9436
    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
9437
        data = {
9438
            "data": [
9439
                {"id": "1", "datetime": "2021-01-12 10:00:00", "text": "event 1"},
9440
                {"id": "2", "datetime": "2021-01-13 10:20:00", "text": "event 2"},
9441
                {"id": "3", "datetime": "2021-01-14 10:40:00", "text": "event 3"},
9442
            ]
9443
        }
9444
        urlopen.side_effect = lambda *args: StringIO(json.dumps(data))
9445

  
9446
        resp = app.get('/test/')
9447
        assert 'data-date="2021-01-12"' in resp and 'data-time="10:00"' in resp
9448
        assert 'data-date="2021-01-13"' in resp and 'data-time="10:20"' in resp
9449
        assert 'data-date="2021-01-14"' in resp and 'data-time="10:40"' in resp
9450
        resp.form['f1'] = '2'  # would happen via javascript
9451
        resp = resp.form.submit('submit')
9452
        resp = resp.form.submit('submit')
9453

  
9454
        assert formdef.data_class().count() == 1
9455
        data_id = formdef.data_class().select()[0].id
9456
        formdata = formdef.data_class().get(data_id)
9457
        assert formdata.data == {
9458
            '1': '2',
9459
            '1_display': 'event 2',
9460
            '1_structured': {'id': '2', 'datetime': '2021-01-13 10:20:00', 'text': 'event 2'},
9461
        }
9462

  
9463

  
9464
def test_form_item_datetimes_data_source_with_date_alignment(pub, http_requests):
9465
    NamedDataSource.wipe()
9466
    data_source = NamedDataSource(name='foobar')
9467
    data_source.data_source = {
9468
        'type': 'json',
9469
        'value': 'http://remote.example.net/api/datetimes',
9470
    }
9471
    data_source.store()
9472

  
9473
    formdef = create_formdef()
9474
    formdef.fields = [
9475
        fields.PageField(id='1', label='page1', type='page'),
9476
        fields.DateField(id='2', label='date', type='date', varname='date'),
9477
        fields.PageField(id='3', label='page2', type='page'),
9478
        fields.ItemField(id='4', label='datetime', display_mode='datetimes',
9479
            data_source={'type': 'foobar'},
9480
            initial_date_alignment='{{ form_var_date }}'),
9481
    ]
9482
    formdef.store()
9483
    formdef.data_class().wipe()
9484
    app = get_app(pub)
9485

  
9486
    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
9487
        data = {
9488
            "data": [
9489
                {"id": "1", "datetime": "2021-01-12 10:00:00", "text": "event 1"},
9490
                {"id": "2", "datetime": "2021-01-13 10:20:00", "text": "event 2"},
9491
                {"id": "3", "datetime": "2021-01-14 10:40:00", "text": "event 3"},
9492
            ]
9493
        }
9494
        urlopen.side_effect = lambda *args: StringIO(json.dumps(data))
9495

  
9496
        resp = app.get('/test/')
9497
        resp.form['f2'] = '2021-01-14'
9498
        resp = resp.form.submit('submit')  # -> 2nd page
9499

  
9500
        assert 'var ALIGN_DATE = "2021-01-14";' in resp
9501
        resp.form['f4'] = '2'  # would happen via javascript
9502
        resp = resp.form.submit('submit')
9503
        resp = resp.form.submit('submit')
9504
        assert formdef.data_class().count() == 1
wcs/fields.py
1488 1488
    in_filters = False
1489 1489
    display_disabled_items = False
1490 1490
    display_mode = 'list'
1491
    initial_date_alignment = None
1491 1492

  
1492 1493
    def __init__(self, **kwargs):
1493 1494
        self.items = []
......
1726 1727
                title=_('Display disabled items'),
1727 1728
                value=self.display_disabled_items,
1728 1729
                advanced=not(self.display_disabled_items))
1730
        widget = form.add(StringWidget, 'initial_date_alignment',
1731
                title=_('Initial date alignment'),
1732
                value=self.initial_date_alignment,
1733
                validation_function=ComputedExpressionWidget.validate_template,
1734
                attrs={'data-dynamic-display-child-of': 'display_mode',
1735
                       'data-dynamic-display-value': 'datetimes'})
1729 1736
        self.fill_zoom_admin_form(form,
1730 1737
                attrs={'data-dynamic-display-child-of': 'display_mode',
1731 1738
                       'data-dynamic-display-value': 'map'})
......
1733 1740
    def get_admin_attributes(self):
1734 1741
        return WidgetField.get_admin_attributes(self) + ['items',
1735 1742
                'display_mode', 'data_source', 'in_filters', 'anonymise',
1736
                'display_disabled_items', 'initial_zoom', 'min_zoom', 'max_zoom']
1743
                'display_disabled_items', 'initial_zoom', 'min_zoom', 'max_zoom',
1744
                'initial_date_alignment']
1737 1745

  
1738 1746
    def check_admin_form(self, form):
1739 1747
        data_mode = form.get_widget('data_mode').parse()
......
1755 1763
    def stats(self, values):
1756 1764
        return item_items_stats(self, values)
1757 1765

  
1766
    def get_initial_date_alignment(self):
1767
        if not self.initial_date_alignment:
1768
            return
1769
        import wcs.workflows
1770
        try:
1771
            date = wcs.workflows.template_on_formdata(
1772
                    None, self.initial_date_alignment, autoescape=False)
1773
        except TemplateError as e:
1774
            return
1775
        try:
1776
            return misc.get_as_datetime(date)
1777
        except ValueError:
1778
            return
1779

  
1758 1780
    def feed_session(self, value, display_value):
1759 1781
        real_data_source = data_sources.get_real(self.data_source)
1760 1782
        if real_data_source and real_data_source.get('type') == 'jsonp':
wcs/qommon/templates/qommon/forms/widgets/select-datetimes.html
18 18
</div>
19 19
<script>
20 20
$(function() {
21
  var ALIGN_DATE = null;
22
  {% with widget.field.get_initial_date_alignment as alignment_date %}
23
    {% if alignment_date %}var ALIGN_DATE = "{{ alignment_date|date:"Y-m-d" }}";{% endif %}
24
  {% endwith %}
21 25
  var WEEKDAYS = ["{% trans "Sunday" %}", "{% trans "Monday" %}",
22 26
                  "{% trans "Tuesday" %}", "{% trans "Wednesday" %}",
23 27
                  "{% trans "Thursday" %}", "{% trans "Friday" %}",
......
50 54
  var options = $select.find('option');
51 55
  var current_date = null;
52 56
  var current_day_div = null;
53
  var current_offset = 0;
57
  var current_offset = null;
58
  var alignment_offset = null;
54 59
  var nb_days = 0;
55 60

  
56 61
  for (var i=0; i<options.length; i++) {
......
80 85
      current_offset = nb_days - 1;
81 86
      $(option_span).addClass('on');
82 87
    }
88
    if (current_offset === null && ALIGN_DATE !== null && alignment_offset === null && option_date >= ALIGN_DATE) {
89
      alignment_offset = nb_days - 1;
90
    }
91
  }
92
  if (current_offset === null && ALIGN_DATE !== null && alignment_offset === null) {
93
    alignment_offset = nb_days - 1;
94
  }
95
  if (current_offset === null && alignment_offset !== null) {
96
    current_offset = Math.max(Math.min(alignment_offset, nb_days-column_count), 0);
97
  } else if (current_offset === null) {
98
    current_offset = 0;
83 99
  }
84 100
  var go_prev = $('<button class="prev">←</button>');
85 101
  var go_next = $('<button class="next">→</button>');
86
-