Projet

Général

Profil

0001-backoffice-add-an-inspect-view-to-forms-card-models-.patch

Frédéric Péters, 10 mai 2022 11:26

Télécharger (31,4 ko)

Voir les différences:

Subject: [PATCH] backoffice: add an inspect view to forms/card models (#30381)

 tests/admin_pages/test_form.py                | 122 +++++++++++++-
 wcs/admin/forms.py                            |  67 ++++++--
 wcs/categories.py                             |   9 +
 wcs/fields.py                                 | 159 +++++++++++++++++-
 wcs/formdef.py                                |   3 +
 wcs/qommon/static/css/dc2/admin.scss          |  47 +++++-
 .../wcs/backoffice/formdef-inspect.html       |  86 ++++++++++
 7 files changed, 464 insertions(+), 29 deletions(-)
 create mode 100644 wcs/templates/wcs/backoffice/formdef-inspect.html
tests/admin_pages/test_form.py
16 16
from wcs.formdef import FormDef
17 17
from wcs.qommon.errors import ConnectionError
18 18
from wcs.qommon.http_request import HTTPRequest
19
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef
19
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef, WorkflowVariablesFieldsFormDef
20 20
from wcs.wscalls import NamedWsCall
21 21

  
22 22
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
......
895 895

  
896 896
    Workflow.wipe()
897 897
    workflow = Workflow(name='Workflow One')
898
    from wcs.workflows import WorkflowVariablesFieldsFormDef
899

  
900 898
    workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
901 899
    workflow.variables_formdef.fields.append(
902 900
        fields.StringField(id='1', varname='test', label='Test', type='string')
......
947 945

  
948 946
    Workflow.wipe()
949 947
    workflow = Workflow(name='Workflow One')
950
    from wcs.workflows import WorkflowVariablesFieldsFormDef
951

  
952 948
    workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
953 949
    workflow.variables_formdef.fields.append(
954 950
        fields.TableRowsField(id='1', varname='test', label='Test2', type='tablerows', columns=['a'])
......
996 992
    Workflow.wipe()
997 993

  
998 994
    workflow = Workflow(name='Workflow One')
999
    from wcs.workflows import WorkflowVariablesFieldsFormDef
1000

  
1001 995
    workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
1002 996
    workflow.variables_formdef.fields = [
1003 997
        fields.StringField(id='1', varname='test', label='Test', type='string')
......
3421 3415
        resp.form['varname'] = 'var_%s' % i
3422 3416
        resp = resp.form.submit('submit')
3423 3417
        assert 'statistics' in FormDef.get(formdef.id).fields[i].display_locations
3418

  
3419

  
3420
def test_admin_form_inspect(pub):
3421
    create_superuser(pub)
3422
    create_role(pub)
3423

  
3424
    NamedDataSource.wipe()
3425
    data_source = NamedDataSource(name='Foobar')
3426
    data_source.data_source = {'type': 'json', 'value': 'http://remote.example.net/404'}
3427
    data_source.store()
3428

  
3429
    CardDef.wipe()
3430
    carddef = CardDef()
3431
    carddef.name = 'Baz'
3432
    carddef.digest_templates = {'default': 'plop'}
3433
    carddef.store()
3434

  
3435
    Workflow.wipe()
3436
    workflow = Workflow(name='Workflow One')
3437
    workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
3438
    workflow.variables_formdef.fields.append(
3439
        fields.StringField(id='1', varname='test', label='Test', type='string')
3440
    )
3441
    workflow.store()
3442

  
3443
    FormDef.wipe()
3444
    formdef = FormDef()
3445
    formdef.name = 'form title'
3446
    formdef.workflow_id = workflow.id
3447
    formdef.fields = [
3448
        fields.PageField(
3449
            id='0',
3450
            label='1st page',
3451
            type='page',
3452
            post_conditions=[
3453
                {'condition': {'type': 'django', 'value': 'false'}, 'error_message': 'You shall not pass.'}
3454
            ],
3455
        ),
3456
        fields.StringField(
3457
            id='1', label='String field', varname='var_1', condition={'type': 'django', 'value': 'true'}
3458
        ),
3459
        fields.StringField(id='2', label='String field digits', validation={'type': 'digits'}),
3460
        fields.StringField(id='3', label='String field regex', validation={'type': 'regex', 'value': r'\d+'}),
3461
        fields.ItemField(
3462
            id='4',
3463
            label='Date field',
3464
            type='date',
3465
        ),
3466
        fields.ItemField(id='5', label='Item field', type='item', items=['One', 'Two', 'Three']),
3467
        fields.ItemField(
3468
            id='6', label='Item field named data source', type='item', data_source={'type': 'foobar'}
3469
        ),
3470
        fields.ItemField(
3471
            id='7', label='Item field carddef data source', type='item', data_source={'type': 'carddef:baz'}
3472
        ),
3473
        fields.ItemField(
3474
            id='8',
3475
            label='Item field json data source',
3476
            type='item',
3477
            data_source={'type': 'json', 'value': 'http://test'},
3478
        ),
3479
        fields.ItemsField(id='9', label='Items field', type='items', items=['One', 'Two', 'Three']),
3480
        fields.StringField(id='10', label='prefill', prefill={'type': 'user', 'value': 'email'}),
3481
        fields.StringField(
3482
            id='11', label='prefill2', prefill={'type': 'string', 'value': '{{plop}}', 'locked': True}
3483
        ),
3484
        fields.FileField(
3485
            id='12', label='file', automatic_image_resize=True, display_locations=['validation']
3486
        ),
3487
    ]
3488
    formdef.workflow_options = {'test': 'plop'}
3489
    formdef.store()
3490

  
3491
    app = login(get_app(pub))
3492
    resp = app.get('/backoffice/forms/%s/inspect' % formdef.id)
3493

  
3494
    assert 'Test → plop' in resp.text  # workflow option
3495
    assert (
3496
        resp.pyquery('[data-field-id="0"] .parameter-post_conditions').text()
3497
        == 'Post Conditions:\nfalse - You shall not pass.'
3498
    )
3499
    assert (
3500
        resp.pyquery('[data-field-id="1"] .parameter-condition').text() == 'Display Condition: true (Django)'
3501
    )
3502
    assert resp.pyquery('[data-field-id="2"] .parameter-validation').text() == 'Validation: Digits'
3503
    assert (
3504
        resp.pyquery('[data-field-id="3"] .parameter-validation').text()
3505
        == 'Validation: Regular Expression - \\d+'
3506
    )
3507
    assert resp.pyquery('[data-field-id="5"] .parameter-items').text() == 'Choices: One, Two, Three'
3508
    assert resp.pyquery('[data-field-id="6"] .parameter-data_source').text() == 'Data source: Foobar'
3509
    assert (
3510
        resp.pyquery('[data-field-id="7"] .parameter-data_source').text() == 'Data source: card model - Baz'
3511
    )
3512
    assert (
3513
        resp.pyquery('[data-field-id="8"] .parameter-data_source').text()
3514
        == 'Data source: JSON URL - http://test'
3515
    )
3516
    assert (
3517
        resp.pyquery('[data-field-id="10"] .parameter-prefill').text()
3518
        == 'Prefill:\nType: User Field\nValue: Email (builtin)'
3519
    )
3520
    assert (
3521
        resp.pyquery('[data-field-id="11"] .parameter-prefill').text()
3522
        == 'Prefill:\nType: String / Template\nValue: {{plop}}\nLocked'
3523
    )
3524
    assert (
3525
        resp.pyquery('[data-field-id="12"] .parameter-automatic_image_resize').text()
3526
        == 'Automatically resize uploaded images: Yes'
3527
    )
3528
    assert (
3529
        resp.pyquery('[data-field-id="12"] .parameter-display_locations').text()
3530
        == 'Display Locations: Validation Page'
3531
    )
wcs/admin/forms.py
596 596

  
597 597

  
598 598
class FormDefPage(Directory):
599
    do_not_call_in_templates = True
599 600
    _q_exports = [
600 601
        '',
601 602
        'fields',
......
616 617
        'overwrite',
617 618
        'qrcode',
618 619
        'information',
620
        'inspect',
619 621
        ('public-url', 'public_url'),
620 622
        ('backoffice-submission-roles', 'backoffice_submission_roles'),
621 623
        ('logged-errors', 'logged_errors_dir'),
......
640 642
    )
641 643
    readonly_message = _('This form is readonly.')
642 644
    management_view_label = _('Management view')
645
    inspect_template_name = 'wcs/backoffice/formdef-inspect.html'
643 646

  
644 647
    def __init__(self, component, instance=None):
645 648
        try:
......
758 761
                    r += self.add_option_line('workflow-options', _('Options'), '')
759 762

  
760 763
        if self.formdef.workflow.roles:
761
            if not self.formdef.workflow_roles:
762
                self.formdef.workflow_roles = {}
763
            workflow_roles = list((self.formdef.workflow.roles or {}).items())
764
            workflow_roles.sort(key=lambda x: '' if x[0] == '_receiver' else misc.simplify(x[1]))
765
            for (wf_role_id, wf_role_label) in workflow_roles:
766
                role_id = self.formdef.workflow_roles.get(wf_role_id)
767
                if role_id:
768
                    try:
769
                        role = get_publisher().role_class.get(role_id)
770
                        role_label = role.name
771
                    except KeyError:
772
                        # removed role ?
773
                        role_label = _('Unknown role (%s)') % role_id
774
                else:
775
                    role_label = '-'
764
            for (wf_role_id, wf_role_label, role_label) in self.get_workflow_roles_elements():
776 765
                r += self.add_option_line('role/%s' % wf_role_id, wf_role_label, role_label)
777 766

  
778
        r += self.add_option_line('roles', _('User Roles'), self._get_roles_label_and_auth_context('roles'))
767
        r += self.add_option_line('roles', _('User Roles'), self.get_roles_label_and_auth_context())
779 768
        r += self.add_option_line(
780 769
            'backoffice-submission-roles',
781 770
            _('Backoffice Submission Role'),
......
880 869
        r += htmltext('</div>')
881 870
        return r.getvalue()
882 871

  
872
    def get_workflow_roles_elements(self):
873
        if not self.formdef.workflow_roles:
874
            self.formdef.workflow_roles = {}
875
        workflow_roles = list((self.formdef.workflow.roles or {}).items())
876
        workflow_roles.sort(key=lambda x: '' if x[0] == '_receiver' else misc.simplify(x[1]))
877
        for (wf_role_id, wf_role_label) in workflow_roles:
878
            role_id = self.formdef.workflow_roles.get(wf_role_id)
879
            if role_id:
880
                try:
881
                    role = get_publisher().role_class.get(role_id)
882
                    role_label = role.name
883
                except KeyError:
884
                    # removed role ?
885
                    role_label = _('Unknown role (%s)') % role_id
886
            else:
887
                role_label = '-'
888
            yield (wf_role_id, wf_role_label, role_label)
889

  
883 890
    def _get_roles_label(self, attribute):
884 891
        if getattr(self.formdef, attribute):
885 892
            roles = []
......
897 904
            value = C_('roles|None')
898 905
        return value
899 906

  
900
    def _get_roles_label_and_auth_context(self, attribute):
901
        value = self._get_roles_label(attribute)
907
    def get_roles_label_and_auth_context(self):
908
        value = self._get_roles_label('roles')
902 909
        if self.formdef.required_authentication_contexts:
903 910
            auth_contexts = get_publisher().get_supported_authentication_contexts()
904 911
            value += ' (%s)' % ', '.join(
......
924 931
        if get_publisher().snapshot_class:
925 932
            r += htmltext('<li><a rel="popup" href="history/save">%s</a></li>') % _('Save snapshot')
926 933
            r += htmltext('<li><a href="history/">%s</a></li>') % _('History')
934
        r += htmltext('<li><a href="inspect">%s</a></li>') % _('Inspector')
927 935
        if not get_publisher().is_using_postgresql() and self.formdef_class == FormDef:
928 936
            r += htmltext('<li><a href="archive">%s</a></li>') % _('Archive')
929 937
        r += htmltext('</ul>')
......
1742 1750
            self.formdef.workflow_options[widget.name] = widget.parse()
1743 1751
        self.formdef.store(comment=_('Change in workflow options'))
1744 1752

  
1753
    def inspect(self):
1754
        self.html_top(self.formdef.name)
1755
        get_response().breadcrumb.append(('inspect', _('Inspector')))
1756
        context = {'formdef': self.formdef, 'view': self}
1757
        if self.formdef.workflow.variables_formdef:
1758
            context['workflow_options'] = {}
1759
            variables_form_data = self.formdef.get_variable_options_for_form()
1760
            for field in self.formdef.workflow.variables_formdef.fields:
1761
                context['workflow_options'][field.label] = htmltext('%s') % field.get_view_value(
1762
                    variables_form_data.get(field.id)
1763
                )
1764
        context['workflow_roles'] = list(self.get_workflow_roles_elements())
1765
        context['backoffice_submission_roles'] = self._get_roles_label('backoffice_submission_roles')
1766
        if self.formdef.tracking_code_verify_fields:
1767
            context['tracking_code_verify_fields_labels'] = ', '.join(
1768
                [
1769
                    x.label
1770
                    for x in self.formdef.fields
1771
                    if str(x.id) in self.formdef.tracking_code_verify_fields
1772
                ]
1773
            )
1774
        return template.QommonTemplateResponse(templates=[self.inspect_template_name], context=context)
1775

  
1745 1776

  
1746 1777
class NamedDataSourcesDirectoryInForms(NamedDataSourcesDirectory):
1747 1778
    pass
wcs/categories.py
30 30
    _names = 'categories'
31 31
    xml_root_node = 'category'
32 32
    backoffice_class = 'wcs.admin.categories.CategoryPage'
33
    backoffice_base_url = 'forms/categories/'
33 34

  
34 35
    name = None
35 36
    url_name = None
......
92 93
            return True
93 94
        return False
94 95

  
96
    def get_admin_url(self):
97
        return '%s/%s%s/' % (get_publisher().get_backoffice_url(), self.backoffice_base_url, self.id)
98

  
95 99
    def store(self, *args, comment=None, snapshot_store_user=True, **kwargs):
96 100
        if not self.url_name:
97 101
            existing_slugs = {
......
214 218
    _names = 'carddef_categories'
215 219
    xml_root_node = 'carddef_category'
216 220
    backoffice_class = 'wcs.admin.categories.CardDefCategoryPage'
221
    backoffice_base_url = 'cards/categories/'
217 222

  
218 223
    # declarations for serialization
219 224
    XML_NODES = [
......
236 241
    _names = 'workflow_categories'
237 242
    xml_root_node = 'workflow_category'
238 243
    backoffice_class = 'wcs.admin.categories.WorkflowCategoryPage'
244
    backoffice_base_url = 'workflows/categories/'
239 245

  
240 246
    # declarations for serialization
241 247
    XML_NODES = [
......
257 263
    _names = 'block_categories'
258 264
    xml_root_node = 'block_category'
259 265
    backoffice_class = 'wcs.admin.categories.BlockCategoryPage'
266
    backoffice_base_url = 'forms/blocks/categories/'
260 267

  
261 268
    # declarations for serialization
262 269
    XML_NODES = [
......
277 284
    _names = 'mail_template_categories'
278 285
    xml_root_node = 'mail_template_category'
279 286
    backoffice_class = 'wcs.admin.categories.MailTemplateCategoryPage'
287
    backoffice_base_url = 'workflows/mail-templates/categories/'
280 288

  
281 289
    # declarations for serialization
282 290
    XML_NODES = [
......
297 305
    _names = 'data_source_categories'
298 306
    xml_root_node = 'data_source_category'
299 307
    backoffice_class = 'wcs.admin.categories.DataSourceCategoryPage'
308
    backoffice_base_url = 'forms/data-sources/categories/'
300 309

  
301 310
    # declarations for serialization
302 311
    XML_NODES = [
wcs/fields.py
48 48
    EmailWidget,
49 49
    FileSizeWidget,
50 50
    FileWithPreviewWidget,
51
    Form,
51 52
    HiddenWidget,
52 53
    HtmlWidget,
53 54
    IntWidget,
......
137 138
        if not self.value or self.value.get('type') == 'none':
138 139
            self.value = {}
139 140

  
140
        prefill_types = collections.OrderedDict(options)
141
        self.prefill_types = prefill_types = collections.OrderedDict(options)
141 142
        self.add(
142 143
            StringWidget,
143 144
            'value_string',
......
691 692

  
692 693
                yield NamedDataSource.get_by_slug(data_source_type, ignore_errors=True)
693 694

  
695
    def get_parameters_view(self):
696
        r = TemplateIO(html=True)
697
        form = Form()
698
        self.fill_admin_form(form)
699
        parameters = [x for x in self.get_admin_attributes() if getattr(self, x, None) is not None]
700
        r += htmltext('<ul>')
701
        for parameter in parameters:
702
            widget = form.get_widget(parameter)
703
            if not widget:
704
                continue
705
            label = self.get_parameter_view_label(widget, parameter)
706
            if not label:
707
                continue
708
            value = getattr(self, parameter, Ellipsis)
709
            if value is None or value == getattr(self.__class__, parameter, Ellipsis):
710
                continue
711
            parameter_view_value = self.get_parameter_view_value(widget, parameter)
712
            if parameter_view_value:
713
                r += htmltext('<li class="parameter-%s">' % parameter)
714
                r += htmltext('<span class="parameter">%s</span> ') % _('%s:') % label
715
                r += parameter_view_value
716
                r += htmltext('</li>')
717
        r += htmltext('</ul>')
718
        return r.getvalue()
719

  
720
    def get_parameter_view_label(self, widget, parameter):
721
        if hasattr(self, 'get_%s_parameter_view_label' % parameter):
722
            return getattr(self, 'get_%s_parameter_view_label' % parameter)()
723
        return widget.get_title()
724

  
725
    def get_parameter_view_value(self, widget, parameter):
726
        if hasattr(self, 'get_%s_parameter_view_value' % parameter):
727
            return getattr(self, 'get_%s_parameter_view_value' % parameter)(widget)
728
        value = getattr(self, parameter)
729
        if isinstance(value, bool):
730
            return str(_('Yes') if value else _('No'))
731
        elif hasattr(widget, 'options') and value:
732
            if not isinstance(widget, CheckboxesWidget):
733
                value = [value]
734
            value_labels = []
735
            for option in widget.options:
736
                if isinstance(option, tuple):
737
                    if option[0] in value:
738
                        value_labels.append(str(option[1]))
739
                else:
740
                    if option in value:
741
                        value_labels.append(str(option))
742
            return ', '.join(value_labels) if value_labels else '-'
743
        elif isinstance(value, list):
744
            return ', '.join(value)
745
        else:
746
            return str(value)
747

  
748
    def get_prefill_parameter_view_value(self, widget):
749
        value = getattr(self, 'prefill', None)
750
        if not value or value.get('type') == 'none':
751
            return
752
        r = TemplateIO(html=True)
753
        r += htmltext('<ul>')
754
        r += htmltext('<li><span class="parameter">%s%s</span> %s</li>') % (
755
            _('Type'),
756
            _(':'),
757
            widget.prefill_types.get(value.get('type')),
758
        )
759
        if value.get('type') in ('user', 'geolocation'):
760
            select_widget = widget.get_widget('value_%s' % value['type'])
761
            labels = {x[0]: x[1] for x in select_widget.options}
762
            r += htmltext('<li><span class="parameter">%s%s</span> %s</li>') % (
763
                _('Value'),
764
                _(':'),
765
                labels.get(value.get('value'), '-'),
766
            )
767
        else:
768
            r += htmltext('<li><span class="parameter">%s%s</span> %s</li>') % (
769
                _('Value'),
770
                _(':'),
771
                value.get('value'),
772
            )
773
        if value.get('locked'):
774
            r += htmltext('<li>%s</li>') % _('Locked')
775
        r += htmltext('</ul>')
776
        return r.getvalue()
777

  
778
    def get_data_source_parameter_view_value(self, widget):
779
        value = getattr(self, 'data_source', None)
780
        if not value or value.get('type') == 'none':
781
            return
782

  
783
        if value.get('type').startswith('carddef:'):
784
            from wcs.carddef import CardDef
785

  
786
            parts = value['type'].split(':')
787
            try:
788
                carddef = CardDef.get_by_urlname(parts[1])
789
            except KeyError:
790
                return _('deleted card model')
791
            custom_view = CardDef.get_data_source_custom_view(value['type'], carddef=carddef)
792
            if custom_view:
793
                return _('card model: %s, custom view: %s') % (carddef.name, custom_view.title)
794
            return '%s - %s' % (_('card model'), carddef.name)
795

  
796
        data_source_types = {
797
            'json': _('JSON URL'),
798
            'jsonp': _('JSONP URL'),
799
            'geojson': _('GeoJSON URL'),
800
            'formula': _('Python Expression'),
801
        }
802
        if value.get('type') in data_source_types:
803
            return '%s - %s' % (data_source_types[value.get('type')], value.get('value'))
804

  
805
        from wcs.data_sources import NamedDataSource
806

  
807
        data_source = NamedDataSource.get_by_slug(value['type'])
808
        return data_source.name
809

  
810
    def get_condition_parameter_view_value(self, widget):
811
        if not self.condition or self.condition.get('type') == 'none':
812
            return
813
        return htmltext('<tt class="condition">%s</tt> <span class="condition-type">(%s)</span>') % (
814
            self.condition['value'],
815
            {'django': 'Django', 'python': 'Python'}.get(self.condition['type']),
816
        )
817

  
694 818
    def __repr__(self):
695 819
        return '<%s %s %r>' % (self.__class__.__name__, self.id, self.label and self.label[:64])
696 820

  
......
1169 1293
        super().init_with_xml(elem, charset, include_id=include_id)
1170 1294
        self.migrate()
1171 1295

  
1296
    def get_validation_parameter_view_value(self, widget):
1297
        if not self.validation:
1298
            return
1299
        validation_type = self.validation['type']
1300
        validation_types = {x: y['title'] for x, y in ValidationWidget.validation_methods.items()}
1301
        if validation_type in ('regex', 'django'):
1302
            return '%s - %s' % (validation_types.get(validation_type), self.validation['value'])
1303
        return str(validation_types.get(validation_type))
1304

  
1172 1305

  
1173 1306
register_field_class(StringField)
1174 1307

  
......
1906 2039
            data_source_type.set_value(None)
1907 2040
            data_source_type.transfer_form_value(get_request())
1908 2041

  
2042
    def get_items_parameter_view_label(self):
2043
        if self.data_source:
2044
            # skip field if there's a data source
2045
            return None
2046
        return str(_('Choices'))
2047

  
2048
    def get_data_source_parameter_view_label(self):
2049
        return str(_('Data source'))
2050

  
1909 2051

  
1910 2052
class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
1911 2053
    key = 'item'
......
2226 2368

  
2227 2369
    def get_admin_attributes(self):
2228 2370
        return WidgetField.get_admin_attributes(self) + [
2229
            'items',
2230 2371
            'display_mode',
2372
            'items',
2231 2373
            'data_source',
2232 2374
            'in_filters',
2233 2375
            'anonymise',
......
2742 2884
        for post_condition in self.post_conditions or []:
2743 2885
            yield post_condition.get('condition')
2744 2886

  
2887
    def get_post_conditions_parameter_view_value(self, widget):
2888
        if not self.post_conditions:
2889
            return
2890
        r = TemplateIO(html=True)
2891
        r += htmltext('<ul>')
2892
        for post_condition in self.post_conditions:
2893
            r += htmltext('<li>%s - %s</li>') % (
2894
                post_condition.get('condition').get('value'),
2895
                post_condition.get('error_message'),
2896
            )
2897
        r += htmltext('</ul>')
2898
        return r.getvalue()
2899

  
2745 2900

  
2746 2901
register_field_class(PageField)
2747 2902

  
wcs/formdef.py
873 873
    def get_page(self, page_no):
874 874
        return [x for x in self.fields if x.type == 'page'][page_no]
875 875

  
876
    def page_count(self):
877
        return len([x for x in self.fields if x.type == 'page']) or 1
878

  
876 879
    def create_view_form(self, dict=None, use_tokens=True, visible=True):
877 880
        dict = dict or {}
878 881
        form = Form(enctype='multipart/form-data', use_tokens=use_tokens)
wcs/qommon/static/css/dc2/admin.scss
1662 1662
	font-size: 90%;
1663 1663
}
1664 1664

  
1665
div.expanded-statuses div.status ul span.parameter {
1666
	color: #666;
1665
div.inspect-form-tabs,
1666
div.inspect-field,
1667
div.expanded-statuses div.status {
1668
	ul span.parameter {
1669
		color: #666;
1670
	}
1671
}
1672

  
1673
.inspect-field {
1674
	margin: 0.5em 0 1em 0;
1675
	h4 {
1676
		margin: 0.5em 0;
1677
		&:first-child {
1678
			margin-top: 0;
1679
		}
1680
	}
1681
	&.inspect-field--page:not(.inspect-field--first) {
1682
		border-top: 1px solid #ccc;
1683
		padding-top: 0.5em;
1684
	}
1685
}
1686

  
1687
[role=tabpanel] {
1688
	> .pk-information:first-child {
1689
		margin-top: 0;
1690
	}
1691
}
1692

  
1693
.condition-type,
1694
.inspect-field-type {
1695
	font-weight: normal;
1696
	font-size: 90%;
1667 1697
}
1668 1698

  
1669 1699
pre.wrapping-pre {
......
1702 1732
	}
1703 1733
}
1704 1734

  
1735
.inspect-tabs {
1736
	ul {
1737
		margin: 0;
1738
		padding: 0;
1739
	}
1740
	li {
1741
		margin-left: 1em;
1742
		&::marker {
1743
			color: #666;
1744
		}
1745
	}
1746
}
1747

  
1705 1748
ul.biglist.form-inspector {
1706 1749
	padding-top: 0;
1707 1750
}
wcs/templates/wcs/backoffice/formdef-inspect.html
1
{% extends "wcs/backoffice/base.html" %}
2
{% load i18n %}
3

  
4
{% block appbar %}{% endblock %}
5

  
6
{% block content %}
7

  
8
<div class="pk-tabs inspect-tabs inspect-form-tabs">
9
 <div class="pk-tabs--tab-list" role="tablist">
10
  <button role="tab" aria-selected="true" aria-controls="inspect-infos" id="tab-infos" tabindex="0">{% trans "Information" %}</button>
11
  <button role="tab" aria-selected="false" aria-controls="inspect-workflow" id="tab-workflow" tabindex="-1">{% trans "Workflow" %}</button>
12
  <button role="tab" aria-selected="false" aria-controls="inspect-options" id="tab-options" tabindex="-1">{% trans "Options" %}</button>
13
  <button role="tab" aria-selected="false" aria-controls="inspect-fields" id="tab-fields" tabindex="-1">{% trans "Fields" %}</button>
14
 </div>
15
 <div class="pk-tabs--container">
16

  
17
 <div id="inspect-infos" role="tabpanel" tabindex="0" aria-labelledby="tab-info">
18
<ul>
19
<li><span class="parameter">{% trans "Title" %}{% trans ":" %}</span> {{ formdef.name|default:"-" }}</li>
20
<li><span class="parameter">{% trans "Description" %}{% trans ":" %}</span> {{ formdef.description|default:"-"|safe }}</li>
21
<li><span class="parameter">{% trans "Keywords" %}{% trans ":" %}</span> {{ formdef.keywords|default:"-" }}</li>
22
<li><span class="parameter">{% trans "Category" %}{% trans ":" %}</span> {% if formdef.category %}<a href="{{ formdef.category.get_admin_url }}">{{ formdef.category.name }}</a>{% else %}-{% endif %}</li>
23
</ul>
24
</div>
25

  
26
<div id="inspect-workflow" role="tabpanel" tabindex="0" aria-labelledby="tab-workflow" hidden>
27
<ul>
28
<li><span class="parameter">{% trans "Workflow" %}{% trans ":" %}</span> <a href="{{ formdef.workflow.get_admin_url }}">{{ formdef.workflow.name }}</a></li>
29
<li><span class="parameter">{% trans "Options" %}{% trans ":" %}</span> {% if not workflow_options %}-{% else %}<ul>
30
  {% for label, value in workflow_options.items %}
31
  <li>{{ label }} → {{ value|safe|default:"-" }}</li>
32
  {% endfor %}
33
</ul>{% endif %}</li>
34
{% for wf_role_id, wf_role_label, role_label in workflow_roles %}
35
<li><span class="parameter">{{ wf_role_label }}{% trans ":" %}</span> {{ role_label|default:"-" }}</li>
36
{% endfor %}
37
<li><span class="parameter">{% trans "User Roles" %}{% trans ":" %}</span> {{ view.get_roles_label_and_auth_context|default:"-" }}</li>
38
<li><span class="parameter">{% trans "Backoffice Submission Role" %}{% trans ":" %}</span> {{ backoffice_submission_roles|default:"-" }}</li>
39
</ul>
40
</div>
41

  
42
<div id="inspect-options" role="tabpanel" tabindex="0" aria-labelledby="tab-options" hidden>
43
<ul>
44
 <li><span class="parameter">{% trans "Confirmation Page" %}{% trans ":" %}</span> {{ formdef.confirmation|yesno }}</li>
45
 <li><span class="parameter">{% trans "Limit to one form" %}{% trans ":" %}</span> {{ formdef.only_allow_one|yesno }}</li>
46
 {% if formdef.roles %}
47
 <li><span class="parameter">{% trans "Display to unlogged users" %}{% trans ":" %}</span> {{ formdef.always_advertise|yesno }}</li>
48
 {% endif %}
49
 <li><span class="parameter">{% trans "Include button to download all files" %}{% trans ":" %}</span> {{ formdef.include_download_all_button|yesno }}</li>
50
 <li><span class="parameter">{% trans "Skip from per user view" %}{% trans ":" %}</span> {{ formdef.skip_from_360_view|yesno }}</li>
51
 <li><span class="parameter">{% trans "Tracking codes" %}{% trans ":" %}</span> {{ formdef.enable_tracking_codes|yesno }}</li>
52
 {% if formdef.enable_tracking_codes %}
53
 <li><span class="parameter">{% trans "Fields to check after entering the tracking code" %}{% trans ":" %}</span> {{ tracking_code_verify_fields_labels|default:"-" }}</li>
54
 {% endif %}
55
 <li><span class="parameter">{% trans "Lifespan of drafts (in days)" %}{% trans ":" %}</span> {{ formdef.drafts_lifespan|default_if_none:_('default value') }}</li>
56
 <li><span class="parameter">{% trans "Templates" %}</span>
57
   <ul>
58
     <li><span class="parameter">{% trans "Digest" %}{% trans ":" %}</span> {{ formdef.default_digest_template|default:"-" }}</li>
59
     <li><span class="parameter">{% trans "Lateral Block" %}{% trans ":" %}</span> {{ formdef.lateral_template|default:"-" }}</li>
60
     <li><span class="parameter">{% trans "Submission Lateral Block" %}{% trans ":" %}</span> {{ formdef.submission_lateral_template|default:"-" }}</li>
61
   </ul>
62
 </li>
63
 <li><span class="parameter">{% trans "Disable access to form" %}{% trans ":" %}</span> {{ formdef.disabled|yesno }}</li>
64
 <li><span class="parameter">{% trans "Redirection when disabled" %}{% trans ":" %}</span> {{ formdef.disabled_redirection|default:"-" }}</li>
65
 <li><span class="parameter">{% trans "Publication date" %}{% trans ":" %}</span> {{ formdef.publication_date|default:"-" }}</li>
66
 <li><span class="parameter">{% trans "Expiration date" %}{% trans ":" %}</span> {{ formdef.expiration_date|default:"-" }}</li>
67

  
68
</ul>
69
</div>
70

  
71
<div id="inspect-fields" role="tabpanel" tabindex="0" aria-labelledby="tab-fields" hidden>
72
<div class="pk-information"><p>
73
{% blocktrans count page_count=formdef.page_count %}{{ page_count }} page{% plural %}{{ page_count }} pages{% endblocktrans %},
74
{% blocktrans count fields_count=formdef.fields|count %}{{ fields_count }} field{% plural %}{{ fields_count }} fields.{% endblocktrans %}
75
</p></div>
76
{% for field in formdef.fields %}
77
<div class="inspect-field inspect-field--{{ field.key }} {% if forloop.first %}inspect-field--first{% endif %}" data-field-id="{{ field.id }}">
78
<h4><a href="fields/{{ field.id }}/">{{ field.ellipsized_label }}</a> <span class="inspect-field-type">- {{ field.get_type_label }}</span></h4>
79
{{ field.get_parameters_view|safe }}
80
</div>
81
{% endfor %}
82
</div>
83
</div>
84

  
85
</div>
86
{% endblock %}
0
-