From 0df5f60f0269228ca2e993efd154edfa5b83b562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sun, 8 Nov 2015 23:11:43 +0100 Subject: [PATCH] backoffice: make global listing sortable (#8542) --- tests/test_sql.py | 69 +++++++++++++++++++++++++++++++++++-- wcs/backoffice/management.py | 21 ++++++----- wcs/qommon/static/css/dc2/admin.css | 16 +++++++++ wcs/sql.py | 13 +++++-- 4 files changed, 106 insertions(+), 13 deletions(-) diff --git a/tests/test_sql.py b/tests/test_sql.py index d8773ea..b3f8040 100644 --- a/tests/test_sql.py +++ b/tests/test_sql.py @@ -40,6 +40,7 @@ def setup_module(module): cur.close() pub.cfg['postgresql'] = {'database': dbname, 'user': os.environ['USER']} + pub.initialize_sql() formdef = formdef.FormDef() formdef.name = 'tests' @@ -54,8 +55,6 @@ def setup_module(module): ] formdef.store() - pub.initialize_sql() - conn.close() @@ -1103,3 +1102,69 @@ def test_last_update_time(): cur.execute('''SELECT id FROM wcs_all_forms WHERE last_update_time = '2015-01-04 00:00' ''') assert bool(cur.fetchone()[0] == formdata2.id) + +@postgresql +def test_view_formdef_name(): + drop_formdef_tables() + conn, cur = sql.get_connection_and_cursor() + + formdef1 = FormDef() + formdef1.name = 'test formdef name 1' + formdef1.fields = [] + formdef1.store() + + data_class = formdef1.data_class() + formdata1 = data_class() + formdata1.just_created() + formdata1.store() + + formdef2 = FormDef() + formdef2.name = 'test formdef name 2' + formdef2.fields = [] + formdef2.store() + + data_class = formdef2.data_class() + formdata2 = data_class() + formdata2.just_created() + formdata2.store() + + cur.execute('''SELECT COUNT(*) FROM wcs_all_forms''') + assert bool(cur.fetchone()[0] == 2) + + cur.execute('''SELECT formdef_id FROM wcs_all_forms WHERE formdef_name = 'test formdef name 1' ''') + assert bool(str(cur.fetchone()[0]) == str(formdef1.id)) + + cur.execute('''SELECT formdef_id FROM wcs_all_forms WHERE formdef_name = 'test formdef name 2' ''') + assert bool(str(cur.fetchone()[0]) == str(formdef2.id)) + +@postgresql +def test_view_user_name(): + drop_formdef_tables() + conn, cur = sql.get_connection_and_cursor() + + formdef1 = FormDef() + formdef1.name = 'test user name' + formdef1.fields = [] + formdef1.store() + + sql.SqlUser.wipe() + user = sql.SqlUser() + user.name = 'Foobar' + user.store() + + data_class = formdef1.data_class() + formdata1 = data_class() + formdata1.just_created() + formdata1.store() + + data_class = formdef1.data_class() + formdata2 = data_class() + formdata2.user_id = user.id + formdata2.just_created() + formdata2.store() + + cur.execute('''SELECT user_name FROM wcs_all_forms WHERE id = %s ''', (formdata1.id,)) + assert bool(cur.fetchone()[0] is None) + + cur.execute('''SELECT user_name FROM wcs_all_forms WHERE id = %s ''', (formdata2.id,)) + assert bool(cur.fetchone()[0] == user.name) diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py index ff97c31..1d4d6f5 100644 --- a/wcs/backoffice/management.py +++ b/wcs/backoffice/management.py @@ -150,7 +150,7 @@ class ManagementDirectory(Directory): r += htmltext('') return r.getvalue() - def get_global_listing_sidebar(self, limit=None, offset=None): + def get_global_listing_sidebar(self, limit=None, offset=None, order_by=None): get_response().add_javascript(['jquery.js']) DateWidget.prepare_javascript() form = Form(use_tokens=False, id='listing-settings') @@ -165,6 +165,7 @@ class ManagementDirectory(Directory): limit = int(get_publisher().get_site_option('default-page-size') or 20) form.add_hidden('offset', offset) form.add_hidden('limit', limit) + form.add_hidden('order_by', order_by) form.add_submit('submit', _('Submit')) @@ -332,11 +333,12 @@ class ManagementDirectory(Directory): limit = int(get_request().form.get('limit', get_publisher().get_site_option('default-page-size') or 20)) offset = int(get_request().form.get('offset', 0)) + order_by = get_request().form.get('order_by', 'receipt_time') criterias = self.get_global_listing_criterias() total_count = sql.AnyFormData.count(criterias) formdatas = sql.AnyFormData.select(criterias, - order_by='receipt_time', limit=limit, offset=offset) + order_by=order_by, limit=limit, offset=offset) include_submission_channel = bool( get_publisher().get_site_option('welco_url', 'variables')) @@ -344,12 +346,12 @@ class ManagementDirectory(Directory): r += htmltext('') r += htmltext('') if include_submission_channel: - r += htmltext('') % _('Channel') - r += htmltext('') % _('Form') - r += htmltext('') % _('Created') - r += htmltext('') % _('Last Modified') - r += htmltext('') % _('User') - r += htmltext('') % _('Status') + r += htmltext('') % _('Channel') + r += htmltext('') % _('Form') + r += htmltext('') % _('Created') + r += htmltext('') % _('Last Modified') + r += htmltext('') % _('User') + r += htmltext('') % _('Status') r += htmltext('') r += htmltext('') workflows = {} @@ -399,7 +401,8 @@ class ManagementDirectory(Directory): get_response().filter = None return r.getvalue() - get_response().filter['sidebar'] = self.get_global_listing_sidebar() + get_response().filter['sidebar'] = self.get_global_listing_sidebar( + limit=limit, offset=offset, order_by=order_by) rt = TemplateIO(html=True) rt += htmltext('

%s

') % _('Global View') rt += get_session().display_message() diff --git a/wcs/qommon/static/css/dc2/admin.css b/wcs/qommon/static/css/dc2/admin.css index ec3272f..6c8ea8e 100644 --- a/wcs/qommon/static/css/dc2/admin.css +++ b/wcs/qommon/static/css/dc2/admin.css @@ -356,6 +356,22 @@ table#listing.activity { text-align: left; } +table.main th { + cursor: pointer; +} + +table.main th.nosort { + cursor: inherit; +} + +table.main th.headerSortUp span:after { + content: " \23f7"; /* down pointing triangle */ +} + +table.main th.headerSortDown span:after { + content: " \23f6"; /* up pointing triangle */ +} + div.letters-nav { text-align: center; border: 1px solid #888; diff --git a/wcs/sql.py b/wcs/sql.py index db08bd7..0e9fc16 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -598,6 +598,12 @@ def do_views(formdef, conn, cur, rebuild_global_views=True): (table_name, )*3), 'last_update_time')) + view_fields.append(( + cur.mogrify('(SELECT text %s)', (formdef.name,)), 'formdef_name')) + + view_fields.append(('''(SELECT name FROM users + WHERE users.id = CAST(user_id AS INTEGER))''', 'user_name')) + view_fields.append(('concerned_roles_array', 'concerned_roles_array')) view_fields.append(('actions_roles_array', 'actions_roles_array')) view_fields.append(('fts', 'fts')) @@ -648,6 +654,8 @@ def do_global_views(conn, cur): common_fields.append(('fts', 'fts')) common_fields.append(('is_at_endpoint', 'is_at_endpoint')) common_fields.append(('last_update_time', 'last_update_time')) + common_fields.append(('formdef_name', 'formdef_name')) + common_fields.append(('user_name', 'user_name')) union = ' UNION '.join(['''SELECT %s FROM %s''' % ( ', '.join([y[1] for y in common_fields]), x) for x in view_names]) @@ -1686,7 +1694,7 @@ def get_yearly_totals(period_start=None, period_end=None, criterias=None): return result -SQL_LEVEL = 10 +SQL_LEVEL = 11 def migrate_global_views(conn, cur): cur.execute('''SELECT COUNT(*) FROM information_schema.tables @@ -1735,11 +1743,12 @@ def migrate(): migrate_views(conn, cur) for formdef in FormDef.select(): formdef.data_class().rebuild_security() - if sql_level < 10: + if sql_level < 11: # 7: add backoffice_submission to tables and views # 8: add submission_context to tables # 9: add last_update_time to views # 10: add submission_channel to tables + # 11: add formdef_name and user_name to views migrate_views(conn, cur) cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', ( -- 2.6.2
%s%s%s%s%s%s%s%s%s%s%s%s