From 0e6a92f0aab89acea1c3e7538a7c1d0cf54285d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Mon, 13 Jun 2022 23:12:24 +0200
Subject: [PATCH] backoffice: add inspector view for blocks (#65545)

---
 tests/admin_pages/test_block.py               | 17 ++++++++++
 tests/admin_pages/test_form.py                | 14 +++++++++
 wcs/admin/blocks.py                           | 10 ++++++
 .../wcs/backoffice/block-inspect.html         | 31 +++++++++++++++++++
 .../wcs/backoffice/formdef-inspect.html       |  5 +--
 .../backoffice/includes/inspect-field.html    | 11 +++++++
 .../wcs/backoffice/workflow-inspect.html      | 10 ++----
 7 files changed, 86 insertions(+), 12 deletions(-)
 create mode 100644 wcs/templates/wcs/backoffice/block-inspect.html
 create mode 100644 wcs/templates/wcs/backoffice/includes/inspect-field.html

diff --git a/tests/admin_pages/test_block.py b/tests/admin_pages/test_block.py
index ec5f83ddd..be0810360 100644
--- a/tests/admin_pages/test_block.py
+++ b/tests/admin_pages/test_block.py
@@ -441,3 +441,20 @@ def test_block_edit_field_warnings(pub):
     assert 'This block of fields contains 30 fields.' in resp.text
     assert '<div id="new-field"><h3>New Field</h3>' not in resp.text
     assert '>Duplicate<' not in resp.text
+
+
+def test_block_inspect(pub):
+    create_superuser(pub)
+    BlockDef.wipe()
+    block = BlockDef()
+    block.name = 'foobar'
+    block.fields = [
+        fields.StringField(id='123', required=True, label='Test', type='string'),
+        fields.StringField(id='124', required=True, label='Test2', type='string'),
+    ]
+    block.store()
+
+    app = login(get_app(pub))
+    resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
+    resp = resp.click('Inspector')
+    assert resp.pyquery('#inspect-fields .inspect-field').length == 2
diff --git a/tests/admin_pages/test_form.py b/tests/admin_pages/test_form.py
index 923ce6d2b..70c2b4127 100644
--- a/tests/admin_pages/test_form.py
+++ b/tests/admin_pages/test_form.py
@@ -10,6 +10,7 @@ import pytest
 from webtest import Upload
 
 from wcs import fields
+from wcs.blocks import BlockDef
 from wcs.carddef import CardDef
 from wcs.categories import Category, DataSourceCategory, WorkflowCategory
 from wcs.data_sources import NamedDataSource
@@ -3476,6 +3477,15 @@ def test_admin_form_inspect(pub):
     ]
     workflow.store()
 
+    BlockDef.wipe()
+    block = BlockDef()
+    block.name = 'foobar'
+    block.fields = [
+        fields.StringField(id='123', required=True, label='Test', type='string'),
+        fields.StringField(id='234', required=True, label='Test2', type='string'),
+    ]
+    block.store()
+
     FormDef.wipe()
     formdef = FormDef()
     formdef.name = 'form title'
@@ -3520,6 +3530,7 @@ def test_admin_form_inspect(pub):
         fields.FileField(
             id='12', label='file', automatic_image_resize=True, display_locations=['validation']
         ),
+        fields.BlockField(id='13', label='Block field', type='block:foobar'),
     ]
     formdef.workflow_options = {'test': 'plop'}
     formdef.store()
@@ -3566,3 +3577,6 @@ def test_admin_form_inspect(pub):
         resp.pyquery('[data-field-id="12"] .parameter-display_locations').text()
         == 'Display Locations: Validation Page'
     )
+    assert resp.pyquery('[data-field-id="13"] h4 .inspect-field-type a').attr.href.endswith(
+        block.get_admin_url() + 'inspect'
+    )
diff --git a/wcs/admin/blocks.py b/wcs/admin/blocks.py
index bcd28a15a..724715414 100644
--- a/wcs/admin/blocks.py
+++ b/wcs/admin/blocks.py
@@ -44,6 +44,7 @@ class BlockDirectory(FieldsDirectory):
         'delete',
         'export',
         'settings',
+        'inspect',
         ('history', 'snapshots_dir'),
     ]
     field_def_page_class = BlockFieldDefPage
@@ -103,6 +104,7 @@ class BlockDirectory(FieldsDirectory):
         if get_publisher().snapshot_class:
             r += htmltext('<li><a rel="popup" href="history/save">%s</a></li>') % _('Save snapshot')
             r += htmltext('<li><a href="history/">%s</a></li>') % _('History')
+        r += htmltext('<li><a href="inspect">%s</a></li>') % _('Inspector')
         r += htmltext('<li><a href="settings" rel="popup">%s</a></li>') % _('Settings')
         r += htmltext('</ul>')
         r += super().get_new_field_form(page_id=page_id)
@@ -206,6 +208,14 @@ class BlockDirectory(FieldsDirectory):
         r += form.render()
         return r.getvalue()
 
+    def inspect(self):
+        self.html_top(self.objectdef.name)
+        get_response().breadcrumb.append(('inspect', _('Inspector')))
+        context = {'blockdef': self.objectdef, 'view': self}
+        return template.QommonTemplateResponse(
+            templates=['wcs/backoffice/block-inspect.html'], context=context
+        )
+
 
 class BlocksDirectory(Directory):
     _q_exports = ['', 'new', 'categories', ('import', 'p_import')]
diff --git a/wcs/templates/wcs/backoffice/block-inspect.html b/wcs/templates/wcs/backoffice/block-inspect.html
new file mode 100644
index 000000000..33f5bf930
--- /dev/null
+++ b/wcs/templates/wcs/backoffice/block-inspect.html
@@ -0,0 +1,31 @@
+{% extends "wcs/backoffice/base.html" %}
+{% load i18n %}
+
+{% block appbar %}{% endblock %}
+
+{% block content %}
+
+<div class="pk-tabs inspect-tabs inspect-form-tabs">
+ <div class="pk-tabs--tab-list" role="tablist">
+  <button role="tab" aria-selected="true" aria-controls="inspect-infos" id="tab-infos" tabindex="0">{% trans "Information" %}</button>
+  <button role="tab" aria-selected="false" aria-controls="inspect-fields" id="tab-fields" tabindex="-1">{% trans "Fields" %}</button>
+ </div>
+ <div class="pk-tabs--container">
+
+ <div id="inspect-infos" role="tabpanel" tabindex="0" aria-labelledby="tab-info">
+<ul>
+<li><span class="parameter">{% trans "Title" %}{% trans ":" %}</span> {{ blockdef.name|default:"-" }}</li>
+<li><span class="parameter">{% trans "Category" %}{% trans ":" %}</span> {% if blockdef.category %}<a href="{{ blockdef.category.get_admin_url }}">{{ blockdef.category.name }}</a>{% else %}-{% endif %}</li>
+<li><span class="parameter">{% trans "Digest Template" %}{% trans ":" %}</span> {{ blockdef.digest_template|default:"-" }}</li>
+</ul>
+</div>
+
+<div id="inspect-fields" role="tabpanel" tabindex="0" aria-labelledby="tab-fields" hidden>
+{% for field in blockdef.fields %}
+{% include "wcs/backoffice/includes/inspect-field.html" %}
+{% endfor %}
+</div>
+</div>
+
+</div>
+{% endblock %}
diff --git a/wcs/templates/wcs/backoffice/formdef-inspect.html b/wcs/templates/wcs/backoffice/formdef-inspect.html
index b8e18b7fd..9450caa27 100644
--- a/wcs/templates/wcs/backoffice/formdef-inspect.html
+++ b/wcs/templates/wcs/backoffice/formdef-inspect.html
@@ -78,10 +78,7 @@
 {% blocktrans count fields_count=formdef.fields|count %}{{ fields_count }} field{% plural %}{{ fields_count }} fields.{% endblocktrans %}
 </p></div>
 {% for field in formdef.fields %}
-<div class="inspect-field inspect-field--{{ field.key }} {% if forloop.first %}inspect-field--first{% endif %}" data-field-id="{{ field.id }}">
-<h4><a href="fields/{{ field.id }}/">{{ field.ellipsized_label }}</a> <span class="inspect-field-type">- {{ field.get_type_label }}</span></h4>
-{{ field.get_parameters_view|safe }}
-</div>
+{% include "wcs/backoffice/includes/inspect-field.html" %}
 {% endfor %}
 </div>
 </div>
diff --git a/wcs/templates/wcs/backoffice/includes/inspect-field.html b/wcs/templates/wcs/backoffice/includes/inspect-field.html
new file mode 100644
index 000000000..b67780b7f
--- /dev/null
+++ b/wcs/templates/wcs/backoffice/includes/inspect-field.html
@@ -0,0 +1,11 @@
+<div class="inspect-field inspect-field--{{ field.key }} {% if forloop.first %}inspect-field--first{% endif %}"
+     data-field-id="{{ field.id }}">
+<h4><a href="{{ path|default:"fields/" }}{{ field.id }}/">{{ field.ellipsized_label }}</a>
+     <span class="inspect-field-type">-
+             {% if field.key == 'block' %}<a href="{{ field.block.get_admin_url }}inspect">{% endif %}
+             {{ field.get_type_label }}
+             {% if field.key == 'block' %}</a>{% endif %}
+     </span>
+</h4>
+{{ field.get_parameters_view|safe }}
+</div>
diff --git a/wcs/templates/wcs/backoffice/workflow-inspect.html b/wcs/templates/wcs/backoffice/workflow-inspect.html
index 523921e61..bc1d27be4 100644
--- a/wcs/templates/wcs/backoffice/workflow-inspect.html
+++ b/wcs/templates/wcs/backoffice/workflow-inspect.html
@@ -34,19 +34,13 @@
 
 <div id="inspect-variables" role="tabpanel" tabindex="0" aria-labelledby="tab-variables" hidden>
 {% for field in workflow.variables_formdef.fields %}
-<div class="inspect-field inspect-field--{{ field.key }} {% if forloop.first %}inspect-field--first{% endif %}" data-field-id="{{ field.id }}">
-<h4><a href="variables/fields/{{ field.id }}/">{{ field.ellipsized_label }}</a> <span class="inspect-field-type">- {{ field.get_type_label }}</span></h4>
-{{ field.get_parameters_view|safe }}
-</div>
+{% include "wcs/backoffice/includes/inspect-field.html" with path="variables/fields/" %}
 {% endfor %}
 </div>
 
 <div id="inspect-fields" role="tabpanel" tabindex="0" aria-labelledby="tab-fields" hidden>
 {% for field in workflow.backoffice_fields_formdef.fields %}
-<div class="inspect-field inspect-field--{{ field.key }} {% if forloop.first %}inspect-field--first{% endif %}" data-field-id="{{ field.id }}">
-<h4><a href="backoffice-fields/fields/{{ field.id }}/">{{ field.ellipsized_label }}</a> <span class="inspect-field-type">- {{ field.get_type_label }}</span></h4>
-{{ field.get_parameters_view|safe }}
-</div>
+{% include "wcs/backoffice/includes/inspect-field.html" with path="backoffice-fields/fields/" %}
 {% endfor %}
 </div>
 
-- 
2.36.1

