Projet

Général

Profil

0002-backoffice-add-options-to-item-field-for-plotting-ch.patch

Frédéric Péters, 24 novembre 2020 16:19

Télécharger (10,7 ko)

Voir les différences:

Subject: [PATCH 2/3] backoffice: add options to item field for plotting
 choices on a map (#47066)

 tests/admin_pages/test_form.py       | 40 +++++++++++++
 wcs/data_sources.py                  |  2 +-
 wcs/fields.py                        | 90 ++++++++++++++++------------
 wcs/qommon/static/js/qommon.admin.js | 12 ++++
 4 files changed, 106 insertions(+), 38 deletions(-)
tests/admin_pages/test_form.py
1569 1569
    resp = app.get('/backoffice/forms/1/')
1570 1570

  
1571 1571

  
1572
def test_form_edit_item_field_geojson_data_source(pub, http_requests):
1573
    NamedDataSource.wipe()
1574
    create_superuser(pub)
1575
    create_role()
1576

  
1577
    NamedDataSource.wipe()
1578
    data_source = NamedDataSource(name='foobar')
1579
    data_source.data_source = {
1580
        'type': 'geojson',
1581
        'value': 'http://remote.example.net/geojson',
1582
    }
1583
    data_source.id_property = 'id'
1584
    data_source.label_template_property = '{{ text }}'
1585
    data_source.cache_duration = '5'
1586
    data_source.store()
1587

  
1588
    FormDef.wipe()
1589
    formdef = FormDef()
1590
    formdef.name = 'form title'
1591
    formdef.fields = [fields.ItemField(id='1', label='1st field', type='item')]
1592
    formdef.store()
1593

  
1594
    app = login(get_app(pub))
1595

  
1596
    resp = app.get('/backoffice/forms/1/fields/1/')
1597
    resp.form['display_mode'] = 'map'
1598
    assert resp.pyquery('option[value=foobar][data-type=geojson]')
1599
    resp.form['data_mode'] = 'data-source'
1600
    resp.form['data_source$type'] = 'foobar'
1601
    resp.form['min_zoom'] = 'Wide area'
1602
    resp.form['max_zoom'] = 'Small road'
1603
    resp = resp.form.submit('submit').follow()
1604
    formdef = FormDef.get(formdef.id)
1605
    assert formdef.fields[0].data_source == {'type': 'foobar'}
1606
    assert formdef.fields[0].min_zoom == '9'
1607

  
1608
    resp = app.get('/backoffice/forms/1/fields/1/')
1609
    assert resp.form['min_zoom'].value == 'Wide area'
1610

  
1611

  
1572 1612
def test_form_edit_items_field(pub):
1573 1613
    create_superuser(pub)
1574 1614
    create_role()
wcs/data_sources.py
68 68
                options.append(OptGroup(_('Cards')))
69 69
                options.extend(cards_options)
70 70

  
71
            nds_options = [(x.slug, x.name, x.slug) for x in NamedDataSource.select()]
71
            nds_options = [(x.slug, x.name, x.slug, {'data-type': x.type}) for x in NamedDataSource.select()]
72 72
            nds_options.sort(key=lambda x: misc.simplify(x[1]))
73 73
            if nds_options:
74 74
                options.append(OptGroup(_('Manually Configured Data Sources')))
wcs/fields.py
1428 1428
    return r.getvalue()
1429 1429

  
1430 1430

  
1431
class ItemField(WidgetField):
1431
class MapOptionsMixin:
1432
    initial_zoom = None
1433
    min_zoom = None
1434
    max_zoom = None
1435

  
1436
    def fill_zoom_admin_form(self, form, **kwargs):
1437
        # 0: whole world, 9: wide area, 11: area, 13: town, 16: small road
1438
        zoom_levels = [(None, '---'),
1439
                ('0', _('Whole world')),
1440
                ('6', _('Country')),
1441
                ('9', _('Wide area')),
1442
                ('11', _('Area')),
1443
                ('13', _('Town')),
1444
                ('16', _('Small road')),
1445
                ('18', _('Neighbourhood')),
1446
                ('19', _('Ant')),]
1447
        form.add(SingleSelectWidget, 'initial_zoom', title=_('Initial zoom level'),
1448
                value=self.initial_zoom or '13', options=zoom_levels, **kwargs)
1449
        form.add(SingleSelectWidget, 'min_zoom', title=_('Minimal zoom level'),
1450
                value=self.min_zoom, options=zoom_levels, required=False, **kwargs)
1451
        form.add(SingleSelectWidget, 'max_zoom', title=_('Maximal zoom level'),
1452
                value=self.max_zoom, options=zoom_levels, required=False, **kwargs)
1453

  
1454
    def check_zoom_admin_form(self, form):
1455
        initial_zoom = form.get_widget('initial_zoom').parse()
1456
        min_zoom = form.get_widget('min_zoom').parse()
1457
        max_zoom = form.get_widget('max_zoom').parse()
1458
        if min_zoom and max_zoom:
1459
            if int(min_zoom) > int(max_zoom):
1460
                form.get_widget('min_zoom').set_error(
1461
                        _('Minimal zoom level cannot be greater than maximal zoom level.'))
1462
        if (initial_zoom and min_zoom and int(initial_zoom) < int(min_zoom)) or (
1463
                (initial_zoom and max_zoom and int(initial_zoom) > int(max_zoom))):
1464
            form.get_widget('initial_zoom').set_error(
1465
                        _('Initial zoom level must be between minimal and maximal zoom levels.'))
1466

  
1467

  
1468
class ItemField(WidgetField, MapOptionsMixin):
1432 1469
    key = 'item'
1433 1470
    description = N_('List')
1434 1471

  
......
1628 1665
        WidgetField.fill_admin_form(self, form)
1629 1666
        form.add(CheckboxWidget, 'in_filters', title=_('Display in default filters'),
1630 1667
                value=self.in_filters, advanced=True)
1631
        options = [('list', _('List')),
1632
                   ('radio', _('Radio buttons')),
1633
                   ('autocomplete', _('Autocomplete')),
1668
        options = [('list', _('List'), 'list'),
1669
                   ('radio', _('Radio buttons'), 'radio'),
1670
                   ('autocomplete', _('Autocomplete'), 'autocomplete'),
1671
                   ('map', _('Map (requires geographical data)'), 'map'),
1634 1672
                  ]
1635 1673
        form.add(RadiobuttonsWidget, 'display_mode',
1636 1674
                title=_('Display Mode'),
1637 1675
                options=options,
1638
                value=self.display_mode)
1676
                value=self.display_mode,
1677
                attrs={'data-dynamic-display-parent': 'true'})
1639 1678
        real_data_source = data_sources.get_real(self.data_source)
1640 1679
        form.add(RadiobuttonsWidget, 'data_mode',
1641 1680
                title=_('Data'),
......
1663 1702
                title=_('Display disabled items'),
1664 1703
                value=self.display_disabled_items,
1665 1704
                advanced=not(self.display_disabled_items))
1705
        self.fill_zoom_admin_form(form,
1706
                attrs={'data-dynamic-display-child-of': 'display_mode',
1707
                       'data-dynamic-display-value': 'map'})
1666 1708

  
1667 1709
    def get_admin_attributes(self):
1668 1710
        return WidgetField.get_admin_attributes(self) + ['items',
1669 1711
                'display_mode', 'data_source', 'in_filters', 'anonymise',
1670
                'display_disabled_items']
1712
                'display_disabled_items', 'initial_zoom', 'min_zoom', 'max_zoom']
1671 1713

  
1672 1714
    def check_admin_form(self, form):
1673 1715
        data_mode = form.get_widget('data_mode').parse()
......
1684 1726
            data_source_type.set_value(None)
1685 1727
            data_source_type.transfer_form_value(get_request())
1686 1728

  
1729
        self.check_zoom_admin_form(form)
1730

  
1687 1731
    def stats(self, values):
1688 1732
        return item_items_stats(self, values)
1689 1733

  
......
2396 2440
register_field_class(TableRowsField)
2397 2441

  
2398 2442

  
2399
class MapField(WidgetField):
2443
class MapField(WidgetField, MapOptionsMixin):
2400 2444
    key = 'map'
2401 2445
    description = N_('Map')
2402 2446

  
2403
    initial_zoom = None
2404
    min_zoom = None
2405
    max_zoom = None
2406 2447
    default_position = None
2407 2448
    init_with_geoloc = False
2408 2449

  
......
2412 2453

  
2413 2454
    def fill_admin_form(self, form):
2414 2455
        WidgetField.fill_admin_form(self, form)
2415
        # 0: whole world, 9: wide area, 11: area, 13: town, 16: small road
2416
        zoom_levels = [(None, '---'),
2417
                ('0', _('Whole world')),
2418
                ('6', _('Country')),
2419
                ('9', _('Wide area')),
2420
                ('11', _('Area')),
2421
                ('13', _('Town')),
2422
                ('16', _('Small road')),
2423
                ('18', _('Neighbourhood')),
2424
                ('19', _('Ant')),]
2425
        form.add(SingleSelectWidget, 'initial_zoom', title=_('Initial zoom level'),
2426
                value=self.initial_zoom or '13', options=zoom_levels)
2427
        form.add(SingleSelectWidget, 'min_zoom', title=_('Minimal zoom level'),
2428
                value=self.min_zoom, options=zoom_levels, required=False)
2429
        form.add(SingleSelectWidget, 'max_zoom', title=_('Maximal zoom level'),
2430
                value=self.max_zoom, options=zoom_levels, required=False)
2456
        self.fill_zoom_admin_form(form)
2431 2457
        form.add(MapWidget, 'default_position', title=_('Initial Position'),
2432 2458
                value=self.default_position, default_zoom='9', required=False)
2433 2459
        form.add(CheckboxWidget, 'init_with_geoloc',
......
2435 2461
                value=self.init_with_geoloc, required=False)
2436 2462

  
2437 2463
    def check_admin_form(self, form):
2438
        initial_zoom = form.get_widget('initial_zoom').parse()
2439
        min_zoom = form.get_widget('min_zoom').parse()
2440
        max_zoom = form.get_widget('max_zoom').parse()
2441
        if min_zoom and max_zoom:
2442
            if int(min_zoom) > int(max_zoom):
2443
                form.get_widget('min_zoom').set_error(
2444
                        _('Minimal zoom level cannot be greater than maximal zoom level.'))
2445
        if (initial_zoom and min_zoom and int(initial_zoom) < int(min_zoom)) or (
2446
                (initial_zoom and max_zoom and int(initial_zoom) > int(max_zoom))):
2447
            form.get_widget('initial_zoom').set_error(
2448
                        _('Initial zoom level must be between minimal and maximal zoom levels.'))
2464
        self.check_zoom_admin_form(form)
2449 2465

  
2450 2466
    def get_admin_attributes(self):
2451 2467
        return WidgetField.get_admin_attributes(self) + ['initial_zoom',
wcs/qommon/static/js/qommon.admin.js
254 254
            panned_svg.resize();
255 255
        });
256 256
    }
257

  
258
    $('[type=radio][name=display_mode]').on('change', function() {
259
      if ($(this).val() == 'map') {
260
        $('input[name="data_mode"][value="data-source"]').click()
261
        $('select[name="data_source$type"] option:not([data-type="geojson"])').hide();
262
        if ($('select[name="data_source$type"] option:selected:visible').length == 0) {
263
          $('select[name="data_source$type"] option:visible').first().prop('selected', true);
264
        }
265
      } else {
266
        $('select[name="data_source$type"] option').show();
267
      }
268
    });
257 269
});
258
-