Projet

Général

Profil

0001-settings-configure-user-search-result-template-51343.patch

Lauréline Guérin, 01 avril 2021 10:31

Télécharger (12 ko)

Voir les différences:

Subject: [PATCH] settings: configure user search result template (#51343)

 tests/admin_pages/test_settings.py   | 26 ++++++++++++----
 tests/api/test_user.py               | 45 ++++++++++++++++++++++++++--
 wcs/admin/settings.py                | 30 ++++++++++++++++++-
 wcs/api.py                           | 13 ++++++++
 wcs/qommon/static/js/qommon.admin.js | 32 +++++---------------
 wcs/users.py                         |  8 +++++
 6 files changed, 121 insertions(+), 33 deletions(-)
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
-