Projet

Général

Profil

0001-admin-redesign-list-of-form-options-8048.patch

Frédéric Péters, 14 août 2015 12:25

Télécharger (18 ko)

Voir les différences:

Subject: [PATCH 1/5] admin: redesign list of form options (#8048)

 tests/test_admin_pages.py           | 101 +++++++++++++++--
 wcs/admin/forms.py                  | 210 ++++++++++++++++++++++--------------
 wcs/qommon/static/css/dc2/admin.css |  10 ++
 3 files changed, 232 insertions(+), 89 deletions(-)
tests/test_admin_pages.py
1 1
import datetime
2 2
import os
3
import re
3 4
import shutil
4 5
import StringIO
5 6
import tarfile
......
168 169
    assert formdef.disabled == True
169 170
    assert formdef.last_modification_user_id == 'admin'
170 171

  
172
def assert_option_display(resp, label, value):
173
    option_line = re.findall('%s.*%s' % (label, value), resp.body, re.DOTALL)
174
    assert option_line
175
    assert not '</li>' in option_line
176

  
171 177
def test_forms_edit():
178
    create_superuser()
172 179
    create_role()
173 180

  
174 181
    FormDef.wipe()
......
181 188
    resp = app.get('/backoffice/forms/1/')
182 189

  
183 190
    # try changing an option
184
    assert 'Include confirmation page' in resp.body
185
    resp = resp.click(href='options')
191

  
192
    # confirmation page
193
    assert_option_display(resp, 'Confirmation Page', 'Enabled')
194
    resp = resp.click('Confirmation Page')
186 195
    assert resp.forms[0]['confirmation'].checked
187 196
    resp.forms[0]['confirmation'].checked = False
188 197
    resp = resp.forms[0].submit()
189 198
    assert resp.location == 'http://example.net/backoffice/forms/1/'
190 199
    resp = resp.follow()
191
    assert not 'Include confirmation page' in resp.body
200
    assert_option_display(resp, 'Confirmation Page', 'Disabled')
201
    assert FormDef.get(1).confirmation == False
202

  
203
    # try cancel button
204
    resp = resp.click('Confirmation Page')
205
    assert resp.forms[0]['confirmation'].checked is False
206
    resp.forms[0]['confirmation'].checked = True
207
    resp = resp.forms[0].submit('cancel')
208
    assert resp.location == 'http://example.net/backoffice/forms/1/'
209
    resp = resp.follow()
210
    assert_option_display(resp, 'Confirmation Page', 'Disabled')
192 211
    assert FormDef.get(1).confirmation == False
193 212

  
213
    # history and status
214
    assert_option_display(resp, 'History and Status', 'Public')
215
    resp = resp.click('History and Status')
216
    assert resp.forms[0]['private_status_and_history'].checked is False
217
    resp.forms[0]['private_status_and_history'].checked = True
218
    resp = resp.forms[0].submit()
219
    assert resp.location == 'http://example.net/backoffice/forms/1/'
220
    resp = resp.follow()
221
    assert_option_display(resp, 'History and Status', 'Private')
222
    assert FormDef.get(1).private_status_and_history is True
223

  
224
    # Limit to one form
225
    assert_option_display(resp, 'Limit to one form', 'Disabled')
226
    resp = resp.click('Limit to one form')
227
    assert resp.forms[0]['only_allow_one'].checked is False
228
    resp.forms[0]['only_allow_one'].checked = True
229
    resp = resp.forms[0].submit()
230
    assert resp.location == 'http://example.net/backoffice/forms/1/'
231
    resp = resp.follow()
232
    assert_option_display(resp, 'Limit to one form', 'Enabled')
233
    assert FormDef.get(1).only_allow_one is True
234

  
235
    # Tracking code
236
    assert_option_display(resp, 'Tracking Code', 'Disabled')
237
    resp = resp.click('Tracking Code')
238
    assert resp.forms[0]['enable_tracking_codes'].checked is False
239
    resp.forms[0]['enable_tracking_codes'].checked = True
240
    resp = resp.forms[0].submit()
241
    assert resp.location == 'http://example.net/backoffice/forms/1/'
242
    resp = resp.follow()
243
    assert_option_display(resp, 'Tracking Code', 'Enabled')
244
    assert FormDef.get(1).enable_tracking_codes is True
245

  
246
    # Publication
247
    assert_option_display(resp, 'Online Status', 'Published')
248
    resp = resp.click('Online Status')
249
    assert resp.forms[0]['disabled'].checked is False
250
    resp.forms[0]['disabled'].checked = True
251
    resp = resp.forms[0].submit()
252
    assert resp.location == 'http://example.net/backoffice/forms/1/'
253
    resp = resp.follow()
254
    assert_option_display(resp, 'Online Status', 'Disabled')
255
    assert FormDef.get(1).disabled is True
256

  
257
    resp = resp.click('Online Status')
258
    assert resp.forms[0]['disabled'].checked is True
259
    resp.forms[0]['disabled_redirection'] = 'http://www.example.net'
260
    resp = resp.forms[0].submit()
261
    assert resp.location == 'http://example.net/backoffice/forms/1/'
262
    resp = resp.follow()
263
    assert_option_display(resp, 'Online Status', 'Redirected')
264
    assert FormDef.get(1).disabled is True
265
    assert FormDef.get(1).disabled_redirection == 'http://www.example.net'
266

  
267
    resp = resp.click('Online Status')
268
    resp.forms[0]['disabled'].checked = False
269
    resp.forms[0]['expiration_date'] = '2000-01-01' # this is past(tm)
270
    resp = resp.forms[0].submit()
271
    assert resp.location == 'http://example.net/backoffice/forms/1/'
272
    resp = resp.follow()
273
    assert_option_display(resp, 'Online Status', 'Disabled by date')
274

  
194 275
    # try changing title
195 276
    resp = app.get('/backoffice/forms/1/')
196 277
    resp = resp.click('change title')
......
481 562

  
482 563
    app = login(get_app(pub))
483 564
    resp = app.get('/backoffice/forms/1/')
484
    resp = resp.click(href='options')
485
    assert resp.forms[0]['always_advertise'].attrs.get('disabled') is None
486 565

  
566
    # Display to unlogged users
487 567
    formdef.roles = [role.id]
488 568
    formdef.store()
489 569
    resp = app.get('/backoffice/forms/1/')
490
    resp = resp.click(href='options')
491
    assert resp.forms[0]['always_advertise'].attrs.get('disabled') is None
570
    assert_option_display(resp, 'Display to unlogged users', 'Disabled')
571
    resp = resp.click('Display to unlogged users')
572
    assert resp.forms[0]['always_advertise'].checked is False
492 573
    resp.forms[0]['always_advertise'].checked = True
493 574
    resp = resp.forms[0].submit()
494

  
495
    assert FormDef.get(formdef.id).always_advertise is True
575
    assert resp.location == 'http://example.net/backoffice/forms/1/'
576
    resp = resp.follow()
577
    assert_option_display(resp, 'Display to unlogged users', 'Enabled')
578
    assert FormDef.get(1).always_advertise is True
496 579

  
497 580
def test_form_delete():
498 581
    create_role()
wcs/admin/forms.py
130 130
            return r.getvalue()
131 131

  
132 132

  
133
class OptionsDirectory(Directory):
134
    _q_exports = ['confirmation', 'private_status', 'only_allow_one',
135
            'always_advertise', 'tracking_code', 'online_status']
136

  
137
    def __init__(self, formdef):
138
        self.formdef = formdef
139

  
140
    def confirmation(self):
141
        form = Form(enctype='multipart/form-data')
142
        form.add(CheckboxWidget, 'confirmation', title=_('Include confirmation page'),
143
                value=self.formdef.confirmation)
144
        return self.handle(form, _('Confirmation Page'))
145

  
146
    def private_status(self):
147
        form = Form(enctype='multipart/form-data')
148
        form.add(CheckboxWidget, 'private_status_and_history',
149
                title=_('Keep workflow status and history private'),
150
                hint=_('Restrict the possibility to see status and history to the recipients'),
151
                value=self.formdef.private_status_and_history)
152
        return self.handle(form, _('History and Status'))
153

  
154
    def only_allow_one(self):
155
        form = Form(enctype='multipart/form-data')
156
        form.add(CheckboxWidget, 'only_allow_one',
157
                title=_('Only allow one form per user'),
158
                value=self.formdef.only_allow_one)
159
        return self.handle(form, _('Limit to one form'))
160

  
161
    def always_advertise(self):
162
        form = Form(enctype='multipart/form-data')
163
        form.add(CheckboxWidget, 'always_advertise',
164
                title=_('Advertise to unlogged users'),
165
                value=self.formdef.always_advertise)
166
        return self.handle(form, _('Dispaly to unlogged users'))
167

  
168
    def tracking_code(self):
169
        form = Form(enctype='multipart/form-data')
170
        form.add(CheckboxWidget, 'enable_tracking_codes',
171
                title=_('Enable support for tracking codes'),
172
                value=self.formdef.enable_tracking_codes)
173
        return self.handle(form, _('Tracking Code'))
174

  
175
    def online_status(self):
176
        form = Form(enctype='multipart/form-data')
177
        form.add(CheckboxWidget, 'disabled',
178
                title=_('Disable access to form'),
179
                value=self.formdef.disabled)
180
        form.add(StringWidget, 'disabled_redirection',
181
                title=_('If disabled, redirect to this URL'), size=40,
182
                hint=_('Redirection will only be performed if the form is disabled and a URL is given. '\
183
                       'Common substitution variables are available with the [variable] syntax.'),
184
                value=self.formdef.disabled_redirection)
185
        form.add(DateTimeWidget, 'publication_date',
186
                 title=_('Publication Date'),
187
                 value=self.formdef.publication_date)
188
        form.add(DateTimeWidget, 'expiration_date',
189
                 title=_('Expiration Date'),
190
                 value=self.formdef.expiration_date)
191
        return self.handle(form, _('Online Status'))
192

  
193
    def handle(self, form, title):
194
        form.add_submit('submit', _('Submit'))
195
        form.add_submit('cancel', _('Cancel'))
196
        if form.get_widget('cancel').parse():
197
            return redirect('..')
198

  
199
        if form.is_submitted() and not form.has_errors():
200
            attrs = ['confirmation', 'only_allow_one', 'disabled',
201
                    'enable_tracking_codes', 'private_status_and_history',
202
                    'always_advertise', 'disabled_redirection',
203
                    'publication_date', 'expiration_date']
204
            for f in attrs:
205
                widget = form.get_widget(f)
206
                if widget:
207
                    setattr(self.formdef, str(f), widget.parse())
208
            self.formdef.store()
209
            return redirect('..')
210

  
211
        html_top('forms', title=self.formdef.name)
212
        r = TemplateIO(html=True)
213
        r += htmltext('<h2>%s</h2>') % title
214
        r += form.render()
215
        return r.getvalue()
216

  
217

  
133 218
class WorkflowRoleDirectory(Directory):
134 219
    def __init__(self, formdef):
135 220
        self.formdef = formdef
......
189 274
        self.fields.html_top = self.html_top
190 275
        self.role = WorkflowRoleDirectory(self.formdef)
191 276
        self.role.html_top = self.html_top
277
        self.options = OptionsDirectory(self.formdef)
192 278

  
193 279
    def html_top(self, title):
194 280
        return html_top('forms', title)
......
318 404

  
319 405
        r += htmltext('<div class="splitcontent-right">')
320 406
        r += htmltext('<div class="bo-block">')
321
        r += htmltext('<h3>%s') % _('Options')
322
        r += htmltext(' <span class="change">(<a rel="popup" href="options">%s</a>)</span></h3>') % _('change')
323
        r += htmltext('<ul>')
324
        if self.formdef.confirmation:
325
            r += htmltext('<li>%s</li>') % _('Include confirmation page')
326
        if self.formdef.private_status_and_history:
327
            r += htmltext('<li>%s</li>') % _('Keep workflow status and history private')
328
        if self.formdef.only_allow_one:
329
            r += htmltext('<li>%s</li>') % _('Only allow one form per user')
330
        if self.formdef.roles and self.formdef.always_advertise:
331
            r += htmltext('<li>%s</li>') % _('Advertise to unlogged users')
332
        if self.formdef.enable_tracking_codes:
333
            r += htmltext('<li>%s</li>') % _('Has support for tracking codes')
407
        r += htmltext('<h3>%s</h3>') % _('Options')
408
        r += htmltext('<ul class="biglist optionslist">')
409

  
410
        def add_option_line(link, label, current_value):
411
            return htmltext(
412
                    '<li><a rel="popup" href="%(link)s">'
413
                    '<span class="label">%(label)s</span> '
414
                    '<span class="value">%(current_value)s</span>'
415
                    '</a></li>' % {
416
                              'link': link,
417
                              'label': label,
418
                              'current_value': current_value})
419

  
420
        r += add_option_line('options/confirmation', _('Confirmation Page'),
421
            self.formdef.confirmation and _('Enabled') or _('Disabled'))
422

  
423
        r += add_option_line('options/private_status',
424
                _('History and Status'),
425
                self.formdef.private_status_and_history and _('Private') or _('Public'))
426

  
427
        r += add_option_line('options/only_allow_one',
428
                _('Limit to one form'),
429
                self.formdef.only_allow_one and _('Enabled') or _('Disabled'))
430

  
431
        if self.formdef.roles:
432
            r += add_option_line('options/always_advertise',
433
                    _('Display to unlogged users'),
434
                    self.formdef.always_advertise and _('Enabled') or _('Disabled'))
435

  
436
        r += add_option_line('options/tracking_code',
437
                _('Tracking Code'),
438
                self.formdef.enable_tracking_codes and _('Enabled') or _('Disabled'))
439

  
440
        online_status = _('Published')
334 441
        if self.formdef.disabled:
335
            r += htmltext('<li>%s ') % _('Disabled')
442
            # manually disabled
443
            online_status = _('Disabled')
336 444
            if self.formdef.disabled_redirection:
337
                r += htmltext('(<a href="%s">') % self.formdef.disabled_redirection
338
                r += _('redirection')
339
                r += htmltext('</a>) ')
340
            r += htmltext(' (<a href="enable">%s</a>)</li>') % _('enable')
341
        if self.formdef.publication_date:
342
            r += htmltext('<li>%s</li>') % _('Publication Date: %s') % self.formdef.publication_date
343
        if self.formdef.expiration_date:
344
            r += htmltext('<li>%s</li>') % _('Expiration Date: %s') % self.formdef.expiration_date
445
                online_status = _('Redirected')
446
        elif self.formdef.is_disabled():
447
            # disabled by date
448
            online_status = _('Disabled by date')
449
        r += add_option_line('options/online_status',
450
                _('Online Status'),
451
                online_status)
452

  
345 453
        r += htmltext('</ul>')
346 454
        r += htmltext('</div>')
347 455
        r += htmltext('</div>')
......
581 689
        r += form.render()
582 690
        return r.getvalue()
583 691

  
584
    def options(self):
585
        form = Form(enctype='multipart/form-data')
586
        form.add(CheckboxWidget, 'confirmation', title=_('Include confirmation page'),
587
                value=self.formdef.confirmation)
588
        form.add(CheckboxWidget, 'private_status_and_history',
589
                title=_('Keep workflow status and history private'),
590
                hint=_('Restrict the possibility to see status and history to the recipients'),
591
                value=self.formdef.private_status_and_history)
592
        form.add(CheckboxWidget, 'only_allow_one',
593
                title=_('Only allow one form per user'),
594
                value=self.formdef.only_allow_one)
595
        kwargs = {}
596
        form.add(CheckboxWidget, 'always_advertise',
597
                title=_('Advertise to unlogged users'),
598
                value=self.formdef.always_advertise,
599
                **kwargs)
600
        form.add(CheckboxWidget, 'enable_tracking_codes',
601
                title=_('Enable support for tracking codes'),
602
                value=self.formdef.enable_tracking_codes)
603
        form.add(CheckboxWidget, 'disabled',
604
                title=_('Disable access to form'),
605
                value=self.formdef.disabled)
606
        form.add(StringWidget, 'disabled_redirection',
607
                title=_('If disabled, redirect to this URL'), size=40,
608
                hint=_('Redirection will only be performed if the form is disabled and a URL is given. '\
609
                       'Common substitution variables are available with the [variable] syntax.'),
610
                value=self.formdef.disabled_redirection)
611
        form.add(DateTimeWidget, 'publication_date',
612
                 title=_('Publication Date'),
613
                 value=self.formdef.publication_date)
614
        form.add(DateTimeWidget, 'expiration_date',
615
                 title=_('Expiration Date'),
616
                 value=self.formdef.expiration_date)
617

  
618
        form.add_submit('submit', _('Submit'))
619
        form.add_submit('cancel', _('Cancel'))
620
        if form.get_widget('cancel').parse():
621
            return redirect('.')
622

  
623
        if form.is_submitted() and not form.has_errors():
624
            attrs = ['confirmation', 'only_allow_one', 'disabled',
625
                    'enable_tracking_codes', 'private_status_and_history',
626
                    'disabled_redirection', 'publication_date',
627
                    'expiration_date', 'always_advertise']
628
            for f in attrs:
629
                widget = form.get_widget(f)
630
                if widget:
631
                    setattr(self.formdef, str(f), widget.parse())
632
            self.formdef.store()
633
            return redirect('.')
634

  
635
        get_response().breadcrumb.append( ('options', _('Options')) )
636
        self.html_top(title=self.formdef.name)
637
        r = TemplateIO(html=True)
638
        r += htmltext('<h2>%s</h2>') % _('Options')
639
        r += form.render()
640
        return r.getvalue()
641

  
642 692
    def workflow(self):
643 693
        form = Form(enctype='multipart/form-data')
644 694
        workflows = get_workflows(condition=lambda x: x.possible_status)
wcs/qommon/static/css/dc2/admin.css
95 95
	padding-right: 0.5ex;
96 96
}
97 97

  
98
ul.biglist.optionslist span.value {
99
	float: right;
100
}
101

  
98 102
ul.themes p.details {
99 103
	display: block;
100 104
	float: none;
......
544 548
	margin: 0;
545 549
}
546 550

  
551
div.bo-block > h3 {
552
	padding: 1ex 0ex;
553
	font-weight: normal;
554
	margin: 0;
555
}
556

  
547 557
div.bo-block ul.biglist li.disabled {
548 558
	background: none;
549 559
}
550
-