0001-settings-configure-user-search-result-template-51343.patch
tests/admin_pages/test_settings.py | ||
---|---|---|
359 | 359 |
resp = app.get('/backoffice/settings/users').follow().follow() |
360 | 360 | |
361 | 361 |
# add a field |
362 |
resp.forms[2]['label'] = 'foobar'
|
|
363 |
resp = resp.forms[2].submit()
|
|
362 |
resp.forms[3]['label'] = 'foobar'
|
|
363 |
resp = resp.forms[3].submit()
|
|
364 | 364 |
assert resp.location == 'http://example.net/backoffice/settings/users/fields/' |
365 | 365 |
resp = resp.follow() |
366 | 366 |
assert b'foobar' in pub.cfg['users']['formdef'] |
... | ... | |
381 | 381 |
assert pub.cfg['users']['field_email'] is None |
382 | 382 | |
383 | 383 |
# add a comment field |
384 |
resp.forms[2]['label'] = 'barfoo'
|
|
385 |
resp.forms[2]['type'] = 'comment'
|
|
386 |
resp = resp.forms[2].submit()
|
|
384 |
resp.forms[3]['label'] = 'barfoo'
|
|
385 |
resp.forms[3]['type'] = 'comment'
|
|
386 |
resp = resp.forms[3].submit()
|
|
387 | 387 |
assert resp.location == 'http://example.net/backoffice/settings/users/fields/' |
388 | 388 |
resp = resp.follow() |
389 | 389 |
assert b'barfoo' in pub.cfg['users']['formdef'] |
... | ... | |
414 | 414 |
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}' |
415 | 415 |
assert 'syntax error in Django template' in resp |
416 | 416 | |
417 |
# set a search result template |
|
418 |
resp = app.get('/backoffice/settings/users/fields/') |
|
419 |
assert 'search_result_template' not in pub.cfg['users'] |
|
420 |
assert resp.forms['search_result_template']['search_result_template'].value.replace('\n', '') == ( |
|
421 |
'{{ user_email|default:"" }}' |
|
422 |
'{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %}' |
|
423 |
'{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %}' |
|
424 |
'{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %}' |
|
425 |
'{% if user_var_address %} {{ user_var_address }}{% endif %}' |
|
426 |
'{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}' |
|
427 |
'{% if user_var_city %} {{ user_var_city }}{% endif %}' |
|
428 |
) |
|
429 |
resp.forms['search_result_template']['search_result_template'] = '{{ user_email|default:"" }} Foo Bar' |
|
430 |
resp = resp.forms['search_result_template'].submit().follow() |
|
431 |
assert pub.cfg['users']['search_result_template'] == '{{ user_email|default:"" }} Foo Bar' |
|
432 | ||
417 | 433 |
# disable users screen |
418 | 434 |
if not pub.site_options.has_section('options'): |
419 | 435 |
pub.site_options.add_section('options') |
tests/api/test_user.py | ||
---|---|---|
10 | 10 |
from utilities import get_app |
11 | 11 | |
12 | 12 |
from wcs import fields |
13 |
from wcs.admin.settings import UserFieldsFormDef |
|
13 | 14 |
from wcs.formdef import FormDef |
14 | 15 |
from wcs.qommon.http_request import HTTPRequest |
15 | 16 |
from wcs.qommon.ident.password_accounts import PasswordAccount |
... | ... | |
124 | 125 |
resp = get_app(pub).get(sign_uri('/api/users/?q=foobar')) |
125 | 126 |
assert len(resp.json['data']) == 0 |
126 | 127 | |
127 |
from wcs.admin.settings import UserFieldsFormDef |
|
128 | ||
129 | 128 |
formdef = UserFieldsFormDef(pub) |
130 | 129 |
formdef.fields.append(fields.StringField(id='3', label='test', type='string')) |
131 | 130 |
formdef.store() |
... | ... | |
156 | 155 |
assert len(resp.json['data']) == 0 |
157 | 156 | |
158 | 157 | |
158 |
def test_users_description(pub, local_user): |
|
159 |
assert 'search_result_template' not in pub.cfg['users'] |
|
160 | ||
161 |
formdef = UserFieldsFormDef(pub) |
|
162 |
formdef.fields = [ |
|
163 |
fields.StringField(id='1', label='phone', type='string', varname='phone'), |
|
164 |
fields.StringField(id='2', label='mobile', type='string', varname='mobile'), |
|
165 |
fields.StringField(id='3', label='address', type='string', varname='address'), |
|
166 |
fields.StringField(id='4', label='zipcode', type='string', varname='zipcode'), |
|
167 |
fields.StringField(id='5', label='city', type='string', varname='city'), |
|
168 |
] |
|
169 |
formdef.store() |
|
170 | ||
171 |
local_user.form_data = { |
|
172 |
'1': '0505050505', |
|
173 |
'2': '0606060606', |
|
174 |
'3': 'rue du Chateau', |
|
175 |
'4': '75014', |
|
176 |
'5': 'PARIS', |
|
177 |
} |
|
178 |
local_user.set_attributes_from_formdata(local_user.form_data) |
|
179 |
local_user.store() |
|
180 | ||
181 |
resp = get_app(pub).get(sign_uri('/api/users/')) |
|
182 |
assert resp.json['data'][0]['user_id'] == local_user.id |
|
183 |
assert ( |
|
184 |
resp.json['data'][0]['description'].replace('\n', '') |
|
185 |
== 'jean.darmette@triffouilis.fr 📞 0505050505 📱 0606060606 📨 rue du Chateau 75014 PARIS' |
|
186 |
) |
|
187 | ||
188 |
pub.cfg['users'][ |
|
189 |
'search_result_template' |
|
190 |
] = """{{ user_email|default:"" }}{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %} foo bar""" |
|
191 |
pub.write_cfg() |
|
192 |
resp = get_app(pub).get(sign_uri('/api/users/')) |
|
193 |
assert resp.json['data'][0]['user_id'] == local_user.id |
|
194 |
assert ( |
|
195 |
resp.json['data'][0]['description'].replace('\n', '') |
|
196 |
== 'jean.darmette@triffouilis.fr 📞 0505050505 foo bar' |
|
197 |
) |
|
198 | ||
199 | ||
159 | 200 |
def test_user_by_nameid(pub, local_user): |
160 | 201 |
resp = get_app(pub).get(sign_uri('/api/users/xyz/', user=local_user), status=404) |
161 | 202 |
local_user.name_identifiers = ['xyz'] |
wcs/admin/settings.py | ||
---|---|---|
148 | 148 | |
149 | 149 | |
150 | 150 |
class UserFieldsDirectory(FieldsDirectory): |
151 |
_q_exports = ['', 'update_order', 'new', 'mapping', 'template'] |
|
151 |
_q_exports = ['', 'update_order', 'new', 'mapping', 'template', 'search_result_template']
|
|
152 | 152 | |
153 | 153 |
section = 'settings' |
154 | 154 |
field_def_page_class = UserFieldDefPage |
... | ... | |
170 | 170 |
r += htmltext('<h2>%s</h2>') % _('Sidebar Template') |
171 | 171 |
r += self.sidebar_template_form().render() |
172 | 172 |
r += htmltext('</div>') |
173 |
r += htmltext('<div class="bo-block">') |
|
174 |
r += htmltext('<h2>%s</h2>') % _('User search result template') |
|
175 |
r += self.search_result_template_form().render() |
|
176 |
r += htmltext('</div>') |
|
173 | 177 |
return r.getvalue() |
174 | 178 | |
175 | 179 |
def mapping_form(self): |
... | ... | |
226 | 230 |
cfg_submit(form, 'users', ['sidebar_template']) |
227 | 231 |
return redirect('.') |
228 | 232 | |
233 |
@classmethod |
|
234 |
def search_result_template_form(cls, action='search_result_template'): |
|
235 |
users_cfg = get_cfg('users', {}) |
|
236 |
form = Form(action=action, id='search_result_template') |
|
237 |
form.add( |
|
238 |
TextWidget, |
|
239 |
'search_result_template', |
|
240 |
value=users_cfg.get('search_result_template') |
|
241 |
or get_publisher().user_class.default_search_result_template, |
|
242 |
required=False, |
|
243 |
validation_function=ComputedExpressionWidget.validate_template, |
|
244 |
rows=7, |
|
245 |
) |
|
246 |
form.add_submit('submit', _('Submit')) |
|
247 |
return form |
|
248 | ||
249 |
def search_result_template(self): |
|
250 |
form = self.search_result_template_form() |
|
251 |
if form.has_errors(): |
|
252 |
get_session().message = ('error', form.get_widget('search_result_template').get_error()) |
|
253 |
return redirect('.') |
|
254 |
cfg_submit(form, 'users', ['search_result_template']) |
|
255 |
return redirect('.') |
|
256 | ||
229 | 257 | |
230 | 258 |
class UserFieldsFormDef(FormDef): |
231 | 259 |
"""Class to handle custom user fields, it loads and saves from/to |
wcs/api.py | ||
---|---|---|
46 | 46 |
from wcs.data_sources import get_object as get_data_source_object |
47 | 47 |
from wcs.formdef import FormDef |
48 | 48 |
from wcs.forms.common import FormStatusPage |
49 |
from wcs.qommon import get_cfg |
|
49 | 50 |
from wcs.qommon.afterjobs import AfterJob |
50 | 51 |
from wcs.roles import logged_users_role |
52 |
from wcs.variables import LazyUser |
|
51 | 53 | |
52 | 54 |
from .backoffice.data_management import CardPage as BackofficeCardPage |
53 | 55 |
from .backoffice.management import FormPage as BackofficeFormPage |
... | ... | |
62 | 64 |
from .qommon.form import ComputedExpressionWidget |
63 | 65 |
from .qommon.storage import Equal |
64 | 66 |
from .qommon.storage import NotEqual |
67 |
from .qommon.template import Template |
|
68 |
from .qommon.template import TemplateError |
|
65 | 69 | |
66 | 70 | |
67 | 71 |
def posted_json_data_to_formdata_data(formdef, data): |
... | ... | |
979 | 983 |
criterias.append(st.Or(criteria_fields)) |
980 | 984 | |
981 | 985 |
def as_dict(user): |
986 |
users_cfg = get_cfg('users', {}) |
|
987 |
template = ( |
|
988 |
users_cfg.get('search_result_template') |
|
989 |
or get_publisher().user_class.default_search_result_template |
|
990 |
) |
|
991 | ||
982 | 992 |
user_info = user.get_substitution_variables(prefix='') |
983 | 993 |
del user_info['user'] |
984 | 994 |
user_info['user_id'] = user.id |
... | ... | |
987 | 997 |
# add attributes to be usable as datasource |
988 | 998 |
user_info['id'] = user.id |
989 | 999 |
user_info['text'] = user_info['user_display_name'] |
1000 |
if Template.is_template_string(template): |
|
1001 |
try: |
|
1002 |
user_info['description'] = Template(template).render(user_info) |
|
1003 |
except TemplateError: |
|
1004 |
pass |
|
990 | 1005 |
return user_info |
991 | 1006 | |
992 | 1007 |
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.id || !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 |
return $('<span>' + state.text + '</span><br /><span>' + state.description + '</span>'); |
|
189 | 166 |
} |
190 | 167 |
} |
191 | 168 |
if ($('div.submit-user-selection').length) { |
wcs/users.py | ||
---|---|---|
47 | 47 | |
48 | 48 |
last_seen = None |
49 | 49 | |
50 |
default_search_result_template = """{{ user_email|default:"" }} |
|
51 |
{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %} |
|
52 |
{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %} |
|
53 |
{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %} |
|
54 |
{% if user_var_address %} {{ user_var_address }}{% endif %} |
|
55 |
{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %} |
|
56 |
{% if user_var_city %} {{ user_var_city }}{% endif %}""" |
|
57 | ||
50 | 58 |
def __init__(self, name=None): |
51 | 59 |
StorableObject.__init__(self) |
52 | 60 |
self.name = name |
53 |
- |