0001-settings-configure-user-search-result-template-51343.patch
tests/admin_pages/test_settings.py | ||
---|---|---|
354 | 354 |
resp = app.get('/backoffice/settings/users').follow().follow() |
355 | 355 | |
356 | 356 |
# add a field |
357 |
resp.forms[2]['label'] = 'foobar'
|
|
358 |
resp = resp.forms[2].submit()
|
|
357 |
resp.forms[3]['label'] = 'foobar'
|
|
358 |
resp = resp.forms[3].submit()
|
|
359 | 359 |
assert resp.location == 'http://example.net/backoffice/settings/users/fields/' |
360 | 360 |
resp = resp.follow() |
361 | 361 |
assert b'foobar' in pub.cfg['users']['formdef'] |
... | ... | |
376 | 376 |
assert pub.cfg['users']['field_email'] is None |
377 | 377 | |
378 | 378 |
# add a comment field |
379 |
resp.forms[2]['label'] = 'barfoo'
|
|
380 |
resp.forms[2]['type'] = 'comment'
|
|
381 |
resp = resp.forms[2].submit()
|
|
379 |
resp.forms[3]['label'] = 'barfoo'
|
|
380 |
resp.forms[3]['type'] = 'comment'
|
|
381 |
resp = resp.forms[3].submit()
|
|
382 | 382 |
assert resp.location == 'http://example.net/backoffice/settings/users/fields/' |
383 | 383 |
resp = resp.follow() |
384 | 384 |
assert b'barfoo' in pub.cfg['users']['formdef'] |
... | ... | |
409 | 409 |
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}' |
410 | 410 |
assert 'syntax error in Django template' in resp |
411 | 411 | |
412 |
# set a search result template |
|
413 |
resp = app.get('/backoffice/settings/users/fields/') |
|
414 |
assert 'search_result_template' not in pub.cfg['users'] |
|
415 |
assert resp.forms['search_result_template']['search_result_template'].value.replace('\n', '') == ( |
|
416 |
'{{ user_email|default:"" }}' |
|
417 |
'{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %}' |
|
418 |
'{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %}' |
|
419 |
'{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %}' |
|
420 |
'{% if user_var_address %} {{ user_var_address }}{% endif %}' |
|
421 |
'{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}' |
|
422 |
'{% if user_var_city %} {{ user_var_city }}{% endif %}' |
|
423 |
) |
|
424 |
resp.forms['search_result_template']['search_result_template'] = '{{ user_email|default:"" }} Foo Bar' |
|
425 |
resp = resp.forms['search_result_template'].submit().follow() |
|
426 |
assert pub.cfg['users']['search_result_template'] == '{{ user_email|default:"" }} Foo Bar' |
|
427 | ||
412 | 428 |
# disable users screen |
413 | 429 |
if not pub.site_options.has_section('options'): |
414 | 430 |
pub.site_options.add_section('options') |
tests/api/test_user.py | ||
---|---|---|
8 | 8 |
from utilities import clean_temporary_pub, create_temporary_pub, get_app |
9 | 9 | |
10 | 10 |
from wcs import fields |
11 |
from wcs.admin.settings import UserFieldsFormDef |
|
11 | 12 |
from wcs.formdef import FormDef |
12 | 13 |
from wcs.qommon.http_request import HTTPRequest |
13 | 14 |
from wcs.qommon.ident.password_accounts import PasswordAccount |
... | ... | |
121 | 122 |
resp = get_app(pub).get(sign_uri('/api/users/?q=foobar')) |
122 | 123 |
assert len(resp.json['data']) == 0 |
123 | 124 | |
124 |
from wcs.admin.settings import UserFieldsFormDef |
|
125 | ||
126 | 125 |
formdef = UserFieldsFormDef(pub) |
127 | 126 |
formdef.fields.append(fields.StringField(id='3', label='test', type='string')) |
128 | 127 |
formdef.store() |
... | ... | |
157 | 156 |
assert len(resp.json['data']) == 0 |
158 | 157 | |
159 | 158 | |
159 |
def test_users_description(pub, local_user): |
|
160 |
assert 'users' not in pub.cfg |
|
161 | ||
162 |
formdef = UserFieldsFormDef(pub) |
|
163 |
formdef.fields = [ |
|
164 |
fields.StringField(id='1', label='phone', type='string', varname='phone'), |
|
165 |
fields.StringField(id='2', label='mobile', type='string', varname='mobile'), |
|
166 |
fields.StringField(id='3', label='address', type='string', varname='address'), |
|
167 |
fields.StringField(id='4', label='zipcode', type='string', varname='zipcode'), |
|
168 |
fields.StringField(id='5', label='city', type='string', varname='city'), |
|
169 |
] |
|
170 |
formdef.store() |
|
171 | ||
172 |
local_user.form_data = { |
|
173 |
'1': '0505050505', |
|
174 |
'2': '0606060606', |
|
175 |
'3': 'rue du Chateau', |
|
176 |
'4': '75014', |
|
177 |
'5': 'PARIS', |
|
178 |
} |
|
179 |
local_user.set_attributes_from_formdata(local_user.form_data) |
|
180 |
local_user.store() |
|
181 | ||
182 |
resp = get_app(pub).get(sign_uri('/api/users/')) |
|
183 |
assert resp.json['data'][0]['user_id'] == local_user.id |
|
184 |
assert ( |
|
185 |
resp.json['data'][0]['description'].replace('\n', '') |
|
186 |
== 'jean.darmette@triffouilis.fr 📞 0505050505 📱 0606060606 📨 rue du Chateau 75014 PARIS' |
|
187 |
) |
|
188 | ||
189 |
pub.cfg['users'][ |
|
190 |
'search_result_template' |
|
191 |
] = """{{ user_email|default:"" }}{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %} foo bar""" |
|
192 |
pub.write_cfg() |
|
193 |
resp = get_app(pub).get(sign_uri('/api/users/')) |
|
194 |
assert resp.json['data'][0]['user_id'] == local_user.id |
|
195 |
assert ( |
|
196 |
resp.json['data'][0]['description'].replace('\n', '') |
|
197 |
== 'jean.darmette@triffouilis.fr 📞 0505050505 foo bar' |
|
198 |
) |
|
199 | ||
200 | ||
160 | 201 |
def test_user_by_nameid(pub, local_user): |
161 | 202 |
resp = get_app(pub).get(sign_uri('/api/users/xyz/', user=local_user), status=404) |
162 | 203 |
local_user.name_identifiers = ['xyz'] |
wcs/admin/settings.py | ||
---|---|---|
136 | 136 | |
137 | 137 | |
138 | 138 |
class UserFieldsDirectory(FieldsDirectory): |
139 |
_q_exports = ['', 'update_order', 'new', 'mapping', 'template'] |
|
139 |
_q_exports = ['', 'update_order', 'new', 'mapping', 'template', 'search_result_template']
|
|
140 | 140 | |
141 | 141 |
section = 'settings' |
142 | 142 |
field_def_page_class = UserFieldDefPage |
... | ... | |
158 | 158 |
r += htmltext('<h2>%s</h2>') % _('Sidebar Template') |
159 | 159 |
r += self.sidebar_template_form().render() |
160 | 160 |
r += htmltext('</div>') |
161 |
r += htmltext('<div class="bo-block">') |
|
162 |
r += htmltext('<h2>%s</h2>') % _('User search result template') |
|
163 |
r += self.search_result_template_form().render() |
|
164 |
r += htmltext('</div>') |
|
161 | 165 |
return r.getvalue() |
162 | 166 | |
163 | 167 |
def mapping_form(self): |
... | ... | |
214 | 218 |
cfg_submit(form, 'users', ['sidebar_template']) |
215 | 219 |
return redirect('.') |
216 | 220 | |
221 |
@classmethod |
|
222 |
def search_result_template_form(cls, action='search_result_template'): |
|
223 |
users_cfg = get_cfg('users', {}) |
|
224 |
form = Form(action=action, id='search_result_template') |
|
225 |
form.add( |
|
226 |
TextWidget, |
|
227 |
'search_result_template', |
|
228 |
value=users_cfg.get('search_result_template') |
|
229 |
or get_publisher().user_class.default_search_result_template, |
|
230 |
required=False, |
|
231 |
validation_function=ComputedExpressionWidget.validate_template, |
|
232 |
rows=7, |
|
233 |
) |
|
234 |
form.add_submit('submit', _('Submit')) |
|
235 |
return form |
|
236 | ||
237 |
def search_result_template(self): |
|
238 |
form = self.search_result_template_form() |
|
239 |
if form.has_errors(): |
|
240 |
get_session().message = ('error', form.get_widget('search_result_template').get_error()) |
|
241 |
return redirect('.') |
|
242 |
cfg_submit(form, 'users', ['search_result_template']) |
|
243 |
return redirect('.') |
|
244 | ||
217 | 245 | |
218 | 246 |
class UserFieldsFormDef(FormDef): |
219 | 247 |
"""Class to handle custom user fields, it loads and saves from/to |
wcs/api.py | ||
---|---|---|
37 | 37 |
from wcs.data_sources import get_object as get_data_source_object |
38 | 38 |
from wcs.formdef import FormDef |
39 | 39 |
from wcs.forms.common import FormStatusPage |
40 |
from wcs.qommon import get_cfg |
|
40 | 41 |
from wcs.qommon.afterjobs import AfterJob |
41 | 42 |
from wcs.roles import logged_users_role |
42 | 43 | |
... | ... | |
53 | 54 |
) |
54 | 55 |
from .qommon.form import ComputedExpressionWidget |
55 | 56 |
from .qommon.storage import Equal, NotEqual |
57 |
from .qommon.template import Template, TemplateError |
|
56 | 58 | |
57 | 59 | |
58 | 60 |
def posted_json_data_to_formdata_data(formdef, data): |
... | ... | |
970 | 972 |
criterias.append(st.Or(criteria_fields)) |
971 | 973 | |
972 | 974 |
def as_dict(user): |
975 |
users_cfg = get_cfg('users', {}) |
|
976 |
template = ( |
|
977 |
users_cfg.get('search_result_template') |
|
978 |
or get_publisher().user_class.default_search_result_template |
|
979 |
) |
|
980 | ||
973 | 981 |
user_info = user.get_substitution_variables(prefix='') |
974 | 982 |
del user_info['user'] |
975 | 983 |
user_info['user_id'] = user.id |
... | ... | |
978 | 986 |
# add attributes to be usable as datasource |
979 | 987 |
user_info['id'] = user.id |
980 | 988 |
user_info['text'] = user_info['user_display_name'] |
989 |
if Template.is_template_string(template): |
|
990 |
try: |
|
991 |
user_info['description'] = Template(template).render(user_info) |
|
992 |
except TemplateError: |
|
993 |
pass |
|
981 | 994 |
return user_info |
982 | 995 | |
983 | 996 |
limit = misc.get_int_or_400(get_request().form.get('limit')) |
wcs/qommon/static/js/qommon.admin.js | ||
---|---|---|
159 | 159 |
}, |
160 | 160 |
placeholder: '-', |
161 | 161 |
templateResult: function (state) { |
162 |
console.log(state); |
|
163 |
if (!state.id) { |
|
162 |
if (!state.description) { |
|
164 | 163 |
return state.text; |
165 | 164 |
} |
166 |
var details = ''; |
|
167 |
if (state.user_email) { |
|
168 |
details += ' ' + state.user_email; |
|
169 |
} |
|
170 |
if (state.user_var_phone) { |
|
171 |
details += ' 📞 ' + state.user_var_phone; |
|
172 |
} |
|
173 |
if (state.user_var_mobile) { |
|
174 |
details += ' 📱 ' + state.user_var_mobile; |
|
175 |
} |
|
176 |
if (state.user_var_address || state.user_var_zipcode || state.user_var_city) { |
|
177 |
details += ' 📨'; |
|
178 |
} |
|
179 |
if (state.user_var_address) { |
|
180 |
details += ' ' + state.user_var_address; |
|
181 |
} |
|
182 |
if (state.user_var_zipcode) { |
|
183 |
details += ' ' + state.user_var_zipcode; |
|
184 |
} |
|
185 |
if (state.user_var_city) { |
|
186 |
details += ' ' + state.user_var_city; |
|
187 |
} |
|
188 |
return $('<span>' + state.text + '</span><br /><span>' + details + '</span>'); |
|
165 |
var $template_string = $('<span>'); |
|
166 |
$template_string.append( |
|
167 |
$('<span>', {text: state.text})).append( |
|
168 |
$('<br>')).append( |
|
169 |
$('<span>' + state.description + '</span>')); |
|
170 |
return $template_string; |
|
189 | 171 |
} |
190 | 172 |
} |
191 | 173 |
if ($('div.submit-user-selection').length) { |
wcs/users.py | ||
---|---|---|
44 | 44 | |
45 | 45 |
last_seen = None |
46 | 46 | |
47 |
default_search_result_template = """{{ user_email|default:"" }} |
|
48 |
{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %} |
|
49 |
{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %} |
|
50 |
{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %} |
|
51 |
{% if user_var_address %} {{ user_var_address }}{% endif %} |
|
52 |
{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %} |
|
53 |
{% if user_var_city %} {{ user_var_city }}{% endif %}""" |
|
54 | ||
47 | 55 |
def __init__(self, name=None): |
48 | 56 |
StorableObject.__init__(self) |
49 | 57 |
self.name = name |
50 |
- |