diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index 4cd1456c0..fde9fd463 100644 --- a/tests/test_admin_pages.py +++ b/tests/test_admin_pages.py @@ -4727,31 +4727,31 @@ def test_settings_user(pub): resp = app.get('/backoffice/settings/users').follow().follow() # add a field - resp.forms[1]['label'] = 'foobar' - resp = resp.forms[1].submit() + resp.forms[2]['label'] = 'foobar' + resp = resp.forms[2].submit() assert resp.location == 'http://example.net/backoffice/settings/users/fields/' resp = resp.follow() assert b'foobar' in pub.cfg['users']['formdef'] assert 'foobar' in resp.text # set field as email - resp.forms[0]['field_email'] = '1' - resp = resp.forms[0].submit() + resp.forms['mapping']['field_email'] = '1' + resp = resp.forms['mapping'].submit() assert resp.location == 'http://example.net/backoffice/settings/users/fields/' resp = resp.follow() assert pub.cfg['users']['field_email'] == '1' # and unset it - resp.forms[0]['field_email'] = '' - resp = resp.forms[0].submit() + resp.forms['mapping']['field_email'] = '' + resp = resp.forms['mapping'].submit() assert resp.location == 'http://example.net/backoffice/settings/users/fields/' resp = resp.follow() assert pub.cfg['users']['field_email'] == None # add a comment field - resp.forms[1]['label'] = 'barfoo' - resp.forms[1]['type'] = 'Comment' - resp = resp.forms[1].submit() + resp.forms[2]['label'] = 'barfoo' + resp.forms[2]['type'] = 'Comment' + resp = resp.forms[2].submit() assert resp.location == 'http://example.net/backoffice/settings/users/fields/' resp = resp.follow() assert b'barfoo' in pub.cfg['users']['formdef'] @@ -4760,16 +4760,43 @@ def test_settings_user(pub): # check fields are present in edit form resp = app.get('/backoffice/users/%s/edit' % user.id) assert 'barfoo' in resp.text - assert 'f1' in resp.forms[0].fields - assert 'email' in resp.forms[0].fields + assert 'f1' in resp.form.fields + assert 'email' in resp.form.fields # check the email field is not displayed if it's overridden by a custom # field. pub.cfg['users']['field_email'] = '1' pub.write_cfg() resp = app.get('/backoffice/users/%s/edit' % user.id) - assert 'f1' in resp.forms[0].fields - assert 'email' not in resp.forms[0].fields + assert 'f1' in resp.form.fields + assert 'email' not in resp.form.fields + + # set a sidebar template + app = login(get_app(pub)) + resp = app.get('/backoffice/settings/users').follow().follow() + resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}' + resp = resp.forms['template'].submit().follow() + assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}' + resp.forms['template']['sidebar_template'] = '{% if True %}' + resp = resp.forms['template'].submit().follow() + assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}' + assert 'syntax error in Django template' in resp + + # disable users screen + if not pub.site_options.has_section('options'): + pub.site_options.add_section('options') + pub.site_options.set('options', 'settings-disabled-screens', 'users') + with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd: + pub.site_options.write(fd) + + resp = app.get('/backoffice/settings/') + resp = resp.click('Users', href='user-template') + resp.forms['template']['sidebar_template'] = '{% if True %}' + resp = resp.forms['template'].submit() + assert 'syntax error in Django template' in resp + resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}' + resp = resp.forms['template'].submit() + assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}' # restore config pub.cfg['users']['field_email'] = None diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py index 6a5307c04..c7a611ef0 100644 --- a/tests/test_backoffice_pages.py +++ b/tests/test_backoffice_pages.py @@ -1913,6 +1913,32 @@ def test_backoffice_submission_context(pub): assert 'by %s' % user.get_display_name() in resp.text +def test_backoffice_sidebar_user_template(pub): + user = create_user(pub) + create_environment(pub) + form_class = FormDef.get_by_urlname('form-title').data_class() + number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0] + number31.user_id = user.id + number31.store() + app = login(get_app(pub)) + resp = app.get('/backoffice/management/form-title/') + resp = resp.click(href='%s/' % number31.id) + assert 'Associated User' in resp.text + assert '

admin

' in resp.text + pub.cfg['users'] = {'sidebar_template': 'XXX{{ form_user_display_name }}YYY'} + pub.write_cfg() + resp = app.get(resp.request.url) + assert '

XXXadminYYY

' in resp.text + pub.cfg['users'] = {'sidebar_template': 'XXX{{ form_user_display_name }}YYY'} + pub.write_cfg() + resp = app.get(resp.request.url) + assert '

XXXadminYYY

' in resp.text + user.name = 'admn' + user.store() + resp = app.get(resp.request.url) + assert '

XXXadm<i>nYYY

' in resp.text + + def test_backoffice_geolocation_info(pub): user = create_user(pub) create_environment(pub) diff --git a/wcs/admin/settings.py b/wcs/admin/settings.py index 0c13dd284..7640dce74 100644 --- a/wcs/admin/settings.py +++ b/wcs/admin/settings.py @@ -118,7 +118,7 @@ class UserFieldDefPage(FieldDefPage): class UserFieldsDirectory(FieldsDirectory): - _q_exports = ['', 'update_order', 'new', 'mapping'] + _q_exports = ['', 'update_order', 'new', 'mapping', 'template'] section = 'settings' field_def_page_class = UserFieldDefPage @@ -128,11 +128,15 @@ class UserFieldsDirectory(FieldsDirectory): def index_bottom(self): r = TemplateIO(html=True) + r += get_session().display_message() r += htmltext('
') r += htmltext('

%s

') % _('Fields Mapping') r += htmltext('

%s

') % _('These settings make it possible to assign custom user fields to standard user fields.') - form = self.mapping_form() - r += form.render() + r += self.mapping_form().render() + r += htmltext('
') + r += htmltext('
') + r += htmltext('

%s

') % _('Sidebar Template') + r += self.sidebar_template_form().render() r += htmltext('
') return r.getvalue() @@ -141,7 +145,7 @@ class UserFieldsDirectory(FieldsDirectory): options = [(None, _('None'), '')] + [ (x.id, x.label, x.id) for x in self.objectdef.fields] - form = Form(action = 'mapping', enctype='multipart/form-data') + form = Form(action='mapping', id='mapping') field_name_value = users_cfg.get('field_name') if type(field_name_value) is str: field_name_value = [field_name_value] @@ -161,6 +165,26 @@ class UserFieldsDirectory(FieldsDirectory): cfg_submit(form, 'users', ['field_name', 'field_email']) return redirect('.') + @classmethod + def sidebar_template_form(cls, action='template'): + users_cfg = get_cfg('users', {}) + form = Form(action=action, id='template') + form.add(TextWidget, 'sidebar_template', + value=users_cfg.get('sidebar_template') or '{{ form_user_display_name }}', + required=False, + validation_function=ComputedExpressionWidget.validate_template, + rows=4) + form.add_submit('submit', _('Submit')) + return form + + def template(self): + form = self.sidebar_template_form() + if form.has_errors(): + get_session().message = ('error', form.get_widget('sidebar_template').get_error()) + return redirect('.') + cfg_submit(form, 'users', ['sidebar_template']) + return redirect('.') + class UserFieldsFormDef(FormDef): '''Class to handle custom user fields, it loads and saves from/to @@ -405,6 +429,7 @@ class SettingsDirectory(QommonSettingsDirectory): 'session', 'download_theme', 'smstest', 'postgresql', ('admin-permissions', 'admin_permissions'), 'geolocation', 'theme_preview', 'filetypes', + ('user-template', 'user_template'), ('data-sources', 'data_sources'), 'wscalls', 'logs'] emails = EmailsDirectory() @@ -517,6 +542,10 @@ class SettingsDirectory(QommonSettingsDirectory): if enabled('users'): r += htmltext('
%s
%s
') % ( _('Users'), _('Configure users')) + else: + # minimal options + r += htmltext('
%s
%s
') % ( + _('Users'), _('Configure sidebar template for users')) if enabled('emails'): r += htmltext('
%s
%s
') % ( _('Emails'), _('Configure email settings')) @@ -1223,3 +1252,23 @@ class SettingsDirectory(QommonSettingsDirectory): r += htmltext('

%s

') % _('Geolocation Settings') r += form.render() return r.getvalue() + + def user_template(self): + users_cfg = get_cfg('users', {}) + form = UserFieldsDirectory.sidebar_template_form(action='user-template') + form.get_widget('sidebar_template').set_title(_('Sidebar Template')) + form.add_submit('cancel', _('Cancel')) + + if form.get_widget('cancel').parse(): + return redirect('.') + + if form.is_submitted() and not form.has_errors(): + cfg_submit(form, 'users', ['sidebar_template']) + return redirect('.') + + get_response().breadcrumb.append(('user-template', _('Users'))) + html_top('settings', title=_('Users')) + r = TemplateIO(html=True) + r += htmltext('

%s

') % _('Users') + r += form.render() + return r.getvalue() diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py index 10a84785b..ac70afb29 100644 --- a/wcs/backoffice/management.py +++ b/wcs/backoffice/management.py @@ -53,6 +53,7 @@ from ..qommon import ods from ..qommon.form import * from ..qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or, Intersects, ILike, FtsMatch, Contains, Null, NotNull) +from ..qommon.template import Template from wcs.api_utils import get_user_from_api_query_string from wcs.carddef import CardDef @@ -2661,7 +2662,16 @@ class FormBackOfficeStatusPage(FormStatusPage): if formdata.user_id and formdata.get_user(): r += htmltext('
') r += htmltext('

%s

') % _('Associated User') - r += htmltext('

%s

') % formdata.get_user().display_name + users_cfg = get_cfg('users', {}) + sidebar_user_template = users_cfg.get('sidebar_template') + if sidebar_user_template: + variables = get_publisher().substitutions.get_context_variables(mode='lazy') + sidebar_user = Template(sidebar_user_template).render(variables) + if not sidebar_user.startswith('<'): + sidebar_user = htmltext('

%s

' % sidebar_user) + r += sidebar_user + else: + r += htmltext('

%s

') % formdata.get_user().display_name r += htmltext('
') if formdata.formdef.geolocations and formdata.geolocations: