From 96a0f2b9ee9230928417ab85bd219ec0001f0016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Tue, 19 Apr 2016 10:50:37 +0200 Subject: [PATCH] admin: display configuration and preview on data source page (#10705) --- tests/test_admin_pages.py | 55 +++++++++++++++++++++++++++++++++---- wcs/admin/data_sources.py | 50 +++++++++++++++++++++++++++++++-- wcs/data_sources.py | 2 +- wcs/qommon/static/css/dc2/admin.css | 14 ++++++++++ 4 files changed, 111 insertions(+), 10 deletions(-) diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index 65f9398..6b8e187 100644 --- a/tests/test_admin_pages.py +++ b/tests/test_admin_pages.py @@ -1,4 +1,7 @@ +# -*- coding: utf-8 -*- + import datetime +import json import os import re import shutil @@ -2655,7 +2658,7 @@ def test_data_sources_new(pub): resp = resp.click('New Data Source') resp.forms[0]['name'] = 'a new data source' resp.forms[0]['description'] = 'description of the data source' - resp.forms[0]['data_source$type'] = 'Formula (Python)' + resp.forms[0]['data_source$type'] = 'Python Expression' resp = resp.forms[0].submit('data_source$apply') resp.forms[0]['data_source$value'] = repr( [{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}]) @@ -2676,7 +2679,7 @@ def test_data_sources_new(pub): resp = resp.click('New Data Source') resp.forms[0]['name'] = 'an other data source' resp.forms[0]['description'] = 'description of the data source' - resp.forms[0]['data_source$type'] = 'Formula (Python)' + resp.forms[0]['data_source$type'] = 'Python Expression' resp = resp.forms[0].submit('data_source$apply') resp.forms[0]['data_source$value'] = repr( [{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}]) @@ -2684,6 +2687,46 @@ def test_data_sources_new(pub): assert NamedDataSource.count() == 2 +def test_data_sources_view(pub): + create_superuser(pub) + NamedDataSource.wipe() + + data_source = NamedDataSource(name='foobar') + app = login(get_app(pub)) + + data_source.data_source = {'type': 'formula', 'value': '[]'} + data_source.store() + resp = app.get('/backoffice/settings/data-sources/%s/' % data_source.id) + assert 'Type of source: Python Expression' in resp.body + assert 'Python Expression' in resp.body + assert not 'Preview' in resp.body + + data_source.data_source = {'type': 'formula', 'value': '["aaa", "bbb"]'} + data_source.store() + resp = app.get('/backoffice/settings/data-sources/%s/' % data_source.id) + assert 'Preview' in resp.body + assert resp.body.count('aaa') == 3 # expression + id + text + + # check unicode + data_source.data_source = {'type': 'formula', + 'value': repr([('Y', 'Domicilié'), ('N', u'Pas domicilié')])} + data_source.store() + resp = app.get('/backoffice/settings/data-sources/%s/' % data_source.id) + assert 'Preview' in resp.body + assert 'error: not a string' in resp.body + + # check json + json_file_path = os.path.join(pub.app_dir, 'test.json') + json_file = open(json_file_path, 'w') + json.dump({'data': [{'id': '1', 'text': 'foo'}, {'id': '2', 'text': 'bar'}]}, json_file) + json_file.close() + + data_source.data_source = {'type': 'json', 'value': 'file://%s' % json_file_path} + data_source.store() + resp = app.get('/backoffice/settings/data-sources/%s/' % data_source.id) + assert 'Preview' in resp.body + assert 'foo' in resp.body + def test_data_sources_edit(pub): create_superuser(pub) NamedDataSource.wipe() @@ -2698,7 +2741,7 @@ def test_data_sources_edit(pub): assert resp.forms[0]['name'].value == 'foobar' resp.forms[0]['description'] = 'data source description' resp = resp.forms[0].submit('submit') - assert resp.location == 'http://example.net/backoffice/settings/data-sources/' + assert resp.location == 'http://example.net/backoffice/settings/data-sources/1/' resp = resp.follow() resp = resp.click('foobar') @@ -2723,7 +2766,7 @@ def test_data_sources_edit_duplicate_name(pub): assert 'This name is already used' in resp.body resp = resp.forms[0].submit('cancel') - assert resp.location == 'http://example.net/backoffice/settings/data-sources/' + assert resp.location == 'http://example.net/backoffice/settings/data-sources/1/' def test_data_sources_delete(pub): create_superuser(pub) @@ -2763,7 +2806,7 @@ def test_data_sources_edit_slug(pub): assert resp.forms[0]['name'].value == 'foobar' resp.forms[0]['slug'] = 'foo_bar' resp = resp.forms[0].submit('submit') - assert resp.location == 'http://example.net/backoffice/settings/data-sources/' + assert resp.location == 'http://example.net/backoffice/settings/data-sources/1/' assert NamedDataSource.get(1).slug == 'foo_bar' data_source = NamedDataSource(name='barfoo') @@ -2779,7 +2822,7 @@ def test_data_sources_edit_slug(pub): resp.forms[0]['slug'] = 'foobar' resp = resp.forms[0].submit('submit') - assert resp.location == 'http://example.net/backoffice/settings/data-sources/' + assert resp.location == 'http://example.net/backoffice/settings/data-sources/1/' def test_settings_permissions(pub): create_superuser(pub) diff --git a/wcs/admin/data_sources.py b/wcs/admin/data_sources.py index 232e4ff..48607cf 100644 --- a/wcs/admin/data_sources.py +++ b/wcs/admin/data_sources.py @@ -18,9 +18,10 @@ from quixote import redirect from quixote.directory import Directory from quixote.html import TemplateIO, htmltext -from wcs.data_sources import NamedDataSource, DataSourceSelectionWidget from qommon.form import * from qommon.backoffice.menu import html_top +from wcs.data_sources import (NamedDataSource, DataSourceSelectionWidget, + get_structured_items) class NamedDataSourceUI(object): def __init__(self, datasource): @@ -99,6 +100,49 @@ class NamedDataSourcePage(Directory): r += self.datasource.description r += htmltext('') + data_source_labels = { + 'json': _('JSON'), + 'jsonp': _('JSONP'), + 'formula': _('Python Expression'), + } + + if self.datasource.data_source and self.datasource.data_source.get('type') in data_source_labels: + data_source_type = self.datasource.data_source.get('type') + r += htmltext('

%s

') % _('Configuration') + r += htmltext('') + + if data_source_type in ('json', 'formula'): + items = get_structured_items(self.datasource.data_source) + if items: + r += htmltext('

%s

') % _('Preview') + r += htmltext('
') + else: + # the data source field is required so this should never happen + r += htmltext('

%s

') % _('Not configured') + return r.getvalue() def get_sidebar(self): @@ -112,7 +156,7 @@ class NamedDataSourcePage(Directory): def edit(self): form = self.datasource_ui.get_form() if form.get_submit() == 'cancel': - return redirect('..') + return redirect('.') if form.get_submit() == 'submit' and not form.has_errors(): try: @@ -120,7 +164,7 @@ class NamedDataSourcePage(Directory): except ValueError: pass else: - return redirect('..') + return redirect('.') get_response().breadcrumb.append( ('edit', _('Edit')) ) html_top('datasources', title = _('Edit Data Source')) diff --git a/wcs/data_sources.py b/wcs/data_sources.py index 3a673fa..980c174 100644 --- a/wcs/data_sources.py +++ b/wcs/data_sources.py @@ -46,7 +46,7 @@ class DataSourceSelectionWidget(CompositeWidget): value = {} options = [('none', _('None')), - ('formula', _('Formula (Python)')), + ('formula', _('Python Expression')), ('json', _('JSON URL'))] if allow_jsonp: options.append(('jsonp', _('JSONP URL'))) diff --git a/wcs/qommon/static/css/dc2/admin.css b/wcs/qommon/static/css/dc2/admin.css index 59be445..d659c7d 100644 --- a/wcs/qommon/static/css/dc2/admin.css +++ b/wcs/qommon/static/css/dc2/admin.css @@ -1318,3 +1318,17 @@ ul#evolutions li div.msg li { ul#evolutions li div.msg li::after { content: none; } + +div.bo-block.data-source-preview ul { + margin: 0; + padding: 0; + padding-left: 1em; +} + +div.bo-block.data-source-preview ul li { + margin: 1ex 0; +} + +div.bo-block.data-source-preview tt { + padding-right: 1ex; +} -- 2.8.0.rc3