settings: configure user search result template (#51343)
This commit is contained in:
parent
1b215ec7fd
commit
824dce61dc
|
@ -354,8 +354,8 @@ def test_settings_user(pub):
|
|||
resp = app.get('/backoffice/settings/users').follow().follow()
|
||||
|
||||
# add a field
|
||||
resp.forms[2]['label'] = 'foobar'
|
||||
resp = resp.forms[2].submit()
|
||||
resp.forms[3]['label'] = 'foobar'
|
||||
resp = resp.forms[3].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
|
||||
resp = resp.follow()
|
||||
assert b'foobar' in pub.cfg['users']['formdef']
|
||||
|
@ -376,9 +376,9 @@ def test_settings_user(pub):
|
|||
assert pub.cfg['users']['field_email'] is None
|
||||
|
||||
# add a comment field
|
||||
resp.forms[2]['label'] = 'barfoo'
|
||||
resp.forms[2]['type'] = 'comment'
|
||||
resp = resp.forms[2].submit()
|
||||
resp.forms[3]['label'] = 'barfoo'
|
||||
resp.forms[3]['type'] = 'comment'
|
||||
resp = resp.forms[3].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
|
||||
resp = resp.follow()
|
||||
assert b'barfoo' in pub.cfg['users']['formdef']
|
||||
|
@ -409,6 +409,22 @@ def test_settings_user(pub):
|
|||
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
|
||||
assert 'syntax error in Django template' in resp
|
||||
|
||||
# set a search result template
|
||||
resp = app.get('/backoffice/settings/users/fields/')
|
||||
assert 'search_result_template' not in pub.cfg['users']
|
||||
assert resp.forms['search_result_template']['search_result_template'].value.replace('\n', '') == (
|
||||
'{{ user_email|default:"" }}'
|
||||
'{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %}'
|
||||
'{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %}'
|
||||
'{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %}'
|
||||
'{% if user_var_address %} {{ user_var_address }}{% endif %}'
|
||||
'{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}'
|
||||
'{% if user_var_city %} {{ user_var_city }}{% endif %}'
|
||||
)
|
||||
resp.forms['search_result_template']['search_result_template'] = '{{ user_email|default:"" }} Foo Bar'
|
||||
resp = resp.forms['search_result_template'].submit().follow()
|
||||
assert pub.cfg['users']['search_result_template'] == '{{ user_email|default:"" }} Foo Bar'
|
||||
|
||||
# disable users screen
|
||||
if not pub.site_options.has_section('options'):
|
||||
pub.site_options.add_section('options')
|
||||
|
|
|
@ -8,6 +8,7 @@ from quixote import get_publisher
|
|||
from utilities import clean_temporary_pub, create_temporary_pub, get_app
|
||||
|
||||
from wcs import fields
|
||||
from wcs.admin.settings import UserFieldsFormDef
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.qommon.ident.password_accounts import PasswordAccount
|
||||
|
@ -121,8 +122,6 @@ def test_users(pub, local_user):
|
|||
resp = get_app(pub).get(sign_uri('/api/users/?q=foobar'))
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
from wcs.admin.settings import UserFieldsFormDef
|
||||
|
||||
formdef = UserFieldsFormDef(pub)
|
||||
formdef.fields.append(fields.StringField(id='3', label='test', type='string'))
|
||||
formdef.store()
|
||||
|
@ -157,6 +156,48 @@ def test_users_unaccent(pub, local_user):
|
|||
assert len(resp.json['data']) == 0
|
||||
|
||||
|
||||
def test_users_description(pub, local_user):
|
||||
assert 'users' not in pub.cfg
|
||||
|
||||
formdef = UserFieldsFormDef(pub)
|
||||
formdef.fields = [
|
||||
fields.StringField(id='1', label='phone', type='string', varname='phone'),
|
||||
fields.StringField(id='2', label='mobile', type='string', varname='mobile'),
|
||||
fields.StringField(id='3', label='address', type='string', varname='address'),
|
||||
fields.StringField(id='4', label='zipcode', type='string', varname='zipcode'),
|
||||
fields.StringField(id='5', label='city', type='string', varname='city'),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
local_user.form_data = {
|
||||
'1': '0505050505',
|
||||
'2': '0606060606',
|
||||
'3': 'rue du Chateau',
|
||||
'4': '75014',
|
||||
'5': 'PARIS',
|
||||
}
|
||||
local_user.set_attributes_from_formdata(local_user.form_data)
|
||||
local_user.store()
|
||||
|
||||
resp = get_app(pub).get(sign_uri('/api/users/'))
|
||||
assert resp.json['data'][0]['user_id'] == local_user.id
|
||||
assert (
|
||||
resp.json['data'][0]['description'].replace('\n', '')
|
||||
== 'jean.darmette@triffouilis.fr 📞 0505050505 📱 0606060606 📨 rue du Chateau 75014 PARIS'
|
||||
)
|
||||
|
||||
pub.cfg['users'][
|
||||
'search_result_template'
|
||||
] = """{{ user_email|default:"" }}{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %} foo bar"""
|
||||
pub.write_cfg()
|
||||
resp = get_app(pub).get(sign_uri('/api/users/'))
|
||||
assert resp.json['data'][0]['user_id'] == local_user.id
|
||||
assert (
|
||||
resp.json['data'][0]['description'].replace('\n', '')
|
||||
== 'jean.darmette@triffouilis.fr 📞 0505050505 foo bar'
|
||||
)
|
||||
|
||||
|
||||
def test_user_by_nameid(pub, local_user):
|
||||
resp = get_app(pub).get(sign_uri('/api/users/xyz/', user=local_user), status=404)
|
||||
local_user.name_identifiers = ['xyz']
|
||||
|
|
|
@ -136,7 +136,7 @@ class UserFieldDefPage(FieldDefPage):
|
|||
|
||||
|
||||
class UserFieldsDirectory(FieldsDirectory):
|
||||
_q_exports = ['', 'update_order', 'new', 'mapping', 'template']
|
||||
_q_exports = ['', 'update_order', 'new', 'mapping', 'template', 'search_result_template']
|
||||
|
||||
section = 'settings'
|
||||
field_def_page_class = UserFieldDefPage
|
||||
|
@ -158,6 +158,10 @@ class UserFieldsDirectory(FieldsDirectory):
|
|||
r += htmltext('<h2>%s</h2>') % _('Sidebar Template')
|
||||
r += self.sidebar_template_form().render()
|
||||
r += htmltext('</div>')
|
||||
r += htmltext('<div class="bo-block">')
|
||||
r += htmltext('<h2>%s</h2>') % _('User search result template')
|
||||
r += self.search_result_template_form().render()
|
||||
r += htmltext('</div>')
|
||||
return r.getvalue()
|
||||
|
||||
def mapping_form(self):
|
||||
|
@ -214,6 +218,30 @@ class UserFieldsDirectory(FieldsDirectory):
|
|||
cfg_submit(form, 'users', ['sidebar_template'])
|
||||
return redirect('.')
|
||||
|
||||
@classmethod
|
||||
def search_result_template_form(cls, action='search_result_template'):
|
||||
users_cfg = get_cfg('users', {})
|
||||
form = Form(action=action, id='search_result_template')
|
||||
form.add(
|
||||
TextWidget,
|
||||
'search_result_template',
|
||||
value=users_cfg.get('search_result_template')
|
||||
or get_publisher().user_class.default_search_result_template,
|
||||
required=False,
|
||||
validation_function=ComputedExpressionWidget.validate_template,
|
||||
rows=7,
|
||||
)
|
||||
form.add_submit('submit', _('Submit'))
|
||||
return form
|
||||
|
||||
def search_result_template(self):
|
||||
form = self.search_result_template_form()
|
||||
if form.has_errors():
|
||||
get_session().message = ('error', form.get_widget('search_result_template').get_error())
|
||||
return redirect('.')
|
||||
cfg_submit(form, 'users', ['search_result_template'])
|
||||
return redirect('.')
|
||||
|
||||
|
||||
class UserFieldsFormDef(FormDef):
|
||||
"""Class to handle custom user fields, it loads and saves from/to
|
||||
|
|
13
wcs/api.py
13
wcs/api.py
|
@ -37,6 +37,7 @@ from wcs.data_sources import NamedDataSource
|
|||
from wcs.data_sources import get_object as get_data_source_object
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.forms.common import FormStatusPage
|
||||
from wcs.qommon import get_cfg
|
||||
from wcs.qommon.afterjobs import AfterJob
|
||||
from wcs.roles import logged_users_role
|
||||
|
||||
|
@ -53,6 +54,7 @@ from .qommon.errors import (
|
|||
)
|
||||
from .qommon.form import ComputedExpressionWidget
|
||||
from .qommon.storage import Equal, NotEqual
|
||||
from .qommon.template import Template, TemplateError
|
||||
|
||||
|
||||
def posted_json_data_to_formdata_data(formdef, data):
|
||||
|
@ -970,6 +972,12 @@ class ApiUsersDirectory(Directory):
|
|||
criterias.append(st.Or(criteria_fields))
|
||||
|
||||
def as_dict(user):
|
||||
users_cfg = get_cfg('users', {})
|
||||
template = (
|
||||
users_cfg.get('search_result_template')
|
||||
or get_publisher().user_class.default_search_result_template
|
||||
)
|
||||
|
||||
user_info = user.get_substitution_variables(prefix='')
|
||||
del user_info['user']
|
||||
user_info['user_id'] = user.id
|
||||
|
@ -978,6 +986,11 @@ class ApiUsersDirectory(Directory):
|
|||
# add attributes to be usable as datasource
|
||||
user_info['id'] = user.id
|
||||
user_info['text'] = user_info['user_display_name']
|
||||
if Template.is_template_string(template):
|
||||
try:
|
||||
user_info['description'] = Template(template).render(user_info)
|
||||
except TemplateError:
|
||||
pass
|
||||
return user_info
|
||||
|
||||
limit = misc.get_int_or_400(get_request().form.get('limit'))
|
||||
|
|
|
@ -159,33 +159,15 @@ $(function() {
|
|||
},
|
||||
placeholder: '-',
|
||||
templateResult: function (state) {
|
||||
console.log(state);
|
||||
if (!state.id) {
|
||||
if (!state.description) {
|
||||
return state.text;
|
||||
}
|
||||
var details = '';
|
||||
if (state.user_email) {
|
||||
details += ' ' + state.user_email;
|
||||
}
|
||||
if (state.user_var_phone) {
|
||||
details += ' 📞 ' + state.user_var_phone;
|
||||
}
|
||||
if (state.user_var_mobile) {
|
||||
details += ' 📱 ' + state.user_var_mobile;
|
||||
}
|
||||
if (state.user_var_address || state.user_var_zipcode || state.user_var_city) {
|
||||
details += ' 📨';
|
||||
}
|
||||
if (state.user_var_address) {
|
||||
details += ' ' + state.user_var_address;
|
||||
}
|
||||
if (state.user_var_zipcode) {
|
||||
details += ' ' + state.user_var_zipcode;
|
||||
}
|
||||
if (state.user_var_city) {
|
||||
details += ' ' + state.user_var_city;
|
||||
}
|
||||
return $('<span>' + state.text + '</span><br /><span>' + details + '</span>');
|
||||
var $template_string = $('<span>');
|
||||
$template_string.append(
|
||||
$('<span>', {text: state.text})).append(
|
||||
$('<br>')).append(
|
||||
$('<span>' + state.description + '</span>'));
|
||||
return $template_string;
|
||||
}
|
||||
}
|
||||
if ($('div.submit-user-selection').length) {
|
||||
|
|
|
@ -44,6 +44,14 @@ class User(StorableObject):
|
|||
|
||||
last_seen = None
|
||||
|
||||
default_search_result_template = """{{ user_email|default:"" }}
|
||||
{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %}
|
||||
{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %}
|
||||
{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %}
|
||||
{% if user_var_address %} {{ user_var_address }}{% endif %}
|
||||
{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}
|
||||
{% if user_var_city %} {{ user_var_city }}{% endif %}"""
|
||||
|
||||
def __init__(self, name=None):
|
||||
StorableObject.__init__(self)
|
||||
self.name = name
|
||||
|
|
Loading…
Reference in New Issue