From 4a296305ad3de44bd0381685f43c49796f530116 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sun, 3 Apr 2022 08:50:21 +0200
Subject: [PATCH 1/2] backoffice: use a template to render formdata inspect
 page (#59897)

---
 wcs/backoffice/management.py                  | 226 ++++++++----------
 .../wcs/backoffice/formdata-inspect.html      |  68 ++++++
 2 files changed, 170 insertions(+), 124 deletions(-)
 create mode 100644 wcs/templates/wcs/backoffice/formdata-inspect.html

diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py
index 36fdf707a..e363fcf9c 100644
--- a/wcs/backoffice/management.py
+++ b/wcs/backoffice/management.py
@@ -45,7 +45,7 @@ from wcs.roles import logged_users_role
 from wcs.variables import LazyFieldVar
 from wcs.workflows import ActionsTracingEvolutionPart, WorkflowStatusItem, item_classes, template_on_formdata
 
-from ..qommon import _, errors, ezt, force_str, get_cfg, misc, ngettext, ods
+from ..qommon import _, errors, ezt, force_str, get_cfg, misc, ngettext, ods, template
 from ..qommon.afterjobs import AfterJob
 from ..qommon.backoffice.listing import pagination_links
 from ..qommon.backoffice.menu import html_top
@@ -778,6 +778,7 @@ class ManagementDirectory(Directory):
 
 
 class FormPage(Directory):
+    do_not_call_in_templates = True
     _q_exports = [
         '',
         'live',
@@ -3493,43 +3494,42 @@ class FormBackOfficeStatusPage(FormStatusPage):
             raise errors.AccessForbiddenError()
         if self.filled.is_draft():
             raise errors.AccessForbiddenError()
-        charset = get_publisher().site_charset
         get_response().breadcrumb.append(('inspect', _('Data Inspector')))
         self.html_top(self.formdef.name)
-        r = TemplateIO(html=True)
-        r += htmltext('<div id="appbar">')
-        r += htmltext('<h2>%s</h2>') % _('Data Inspector')
-        r += htmltext('<span class="actions">')
+
+        context = {}
+
+        context['actions'] = actions = []
+
         if self.formdef._names == 'formdefs':
             if get_publisher().get_backoffice_root().is_accessible('forms'):
-                r += htmltext(' <a href="%s">%s</a>') % (self.formdef.get_admin_url(), _('View Form'))
+                actions.append({'url': self.formdef.get_admin_url(), 'label': _('View Form')})
         elif self.formdef._names == 'carddefs':
             if get_publisher().get_backoffice_root().is_accessible('cards'):
-                r += htmltext(' <a href="%s">%s</a>') % (self.formdef.get_admin_url(), _('View Card'))
+                actions.append({'url': self.formdef.get_admin_url(), 'label': _('View Card')})
         if get_publisher().get_backoffice_root().is_accessible('workflows'):
-            r += htmltext(' <a href="%s">%s</a>') % (
-                self.formdef.workflow.get_admin_url(),
-                _('View Workflow'),
-            )
-        r += htmltext('</span>')
-        r += htmltext('</div>')
+            actions.append({'url': self.formdef.workflow.get_admin_url(), 'label': _('View Workflow')})
 
-        r += get_session().display_message()
+        context['html_form'] = self.test_tools_form()
+        context['view'] = self
 
-        r += htmltext('<div id="inspect-test-tools" class="section">')
-        r += htmltext('<h2>%s</h2>') % _('Test tools')
-        r += htmltext('<div>')
-        form = self.test_tools_form()
-        r += form.render()
-        r += htmltext('<div id="test-tool-result">')
-        r += self.test_tool_result()
-        r += htmltext('</div>')
-        r += htmltext('</div></div>')
+        context['has_tracing'] = False
+        for evolution in self.filled.evolution or []:
+            if evolution.parts and any(isinstance(x, ActionsTracingEvolutionPart) for x in evolution.parts):
+                context['has_tracing'] = True
+                break
+
+        context['has_markers_stack'] = bool('_markers_stack' in (self.filled.workflow_data or {}))
+        self.relations = list(self.filled.iter_target_datas())
+        context['has_relations'] = bool(self.relations)
 
-        r += htmltext('<div id="inspect-variables" class="section">')
-        r += htmltext('<h2>%s</h2>') % _('Variables')
-        r += htmltext('<ul class="form-inspector biglist">')
+        return template.QommonTemplateResponse(
+            templates=['wcs/backoffice/formdata-inspect.html'], context=context
+        )
 
+    def inspect_variables(self):
+        r = TemplateIO(html=True)
+        charset = get_publisher().site_charset
         substvars = CompatibilityNamesDict()
         substvars.update(self.filled.get_substitution_variables())
 
@@ -3620,14 +3620,13 @@ class FormBackOfficeStatusPage(FormStatusPage):
                 if not isinstance(v, str):
                     r += htmltext(' <span class="type">(%s)</span>') % get_type_name(v)
             r += htmltext('</div></li>')
-        r += htmltext('</div>')
+        return r.getvalue()
 
+    def inspect_functions(self):
+        r = TemplateIO(html=True)
         # assigned functions
         if self.formdef.workflow.roles:
             workflow = self.formdef.workflow
-            r += htmltext('<div id="inspect-functions" class="section">')
-            r += htmltext('<h2>%s</h2></li>\n') % _('Functions')
-            r += htmltext('<ul class="form-inspector biglist">')
             for key, label in (workflow.roles or {}).items():
                 r += htmltext('<li><span class="label">%s</span>') % label
                 r += htmltext('<div class="value">')
@@ -3649,107 +3648,86 @@ class FormBackOfficeStatusPage(FormStatusPage):
                     r += htmltext('<span class="unset">%s</span>') % _('unset')
                 r += htmltext('</div>')
                 r += htmltext('</li>\n')
-            r += htmltext('</ul>')
-            r += htmltext('</div>')
-
-        has_tracing = False
-        for evolution in self.filled.evolution or []:
-            if evolution.parts and any(isinstance(x, ActionsTracingEvolutionPart) for x in evolution.parts):
-                has_tracing = True
-                break
+        return r.getvalue()
 
-        if has_tracing:
-            action_classes = {x.key: x.description for x in item_classes}
-            r += htmltext('<div id="inspect-timeline" class="section">')
-            r += htmltext('<h2>%s</h2></li>\n') % _('Actions Tracing')
-            r += htmltext('<ul class="form-inspector biglist">')
-            wf_status = None
-            status_admin_base_url = '#'
-            last_event_line = None
-            for evolution in self.filled.evolution:
-                if evolution.status and evolution.status != wf_status:
-                    for part in evolution.parts or []:
-                        if isinstance(part, ActionsTracingEvolutionPart):
-                            if part.actions:
-                                r += (
-                                    htmltext('<li><span class="event">%s</span></li>')
-                                    % part.get_event_label()
-                                )
-                                last_event_line = part
-                                break
-                    try:
-                        status = self.filled.formdef.workflow.get_status(evolution.status)
-                        status_label = status.name
-                        status_admin_base_url = status.get_admin_url()
-                    except KeyError:
-                        status_label = _('Unavailable status (%s)') % evolution.status
-                        status_admin_base_url = '#missing'
-                    r += htmltext(
-                        '<li><span class="datetime">%s</span> '
-                        '<a class="tracing-link" href="%s"><strong>%s</strong></a></li>'
-                    ) % (
-                        time.strftime('%Y-%m-%d %H:%M:%S', evolution.time) if evolution.time else '-',
-                        status_admin_base_url,
-                        status_label,
-                    )
-                if evolution.status:
-                    wf_status = evolution.status
+    def inspect_tracing(self):
+        r = TemplateIO(html=True)
+        action_classes = {x.key: x.description for x in item_classes}
+        wf_status = None
+        status_admin_base_url = '#'
+        last_event_line = None
+        for evolution in self.filled.evolution:
+            if evolution.status and evolution.status != wf_status:
                 for part in evolution.parts or []:
                     if isinstance(part, ActionsTracingEvolutionPart):
-                        if part.actions and part != last_event_line:
-                            last_event_line = part
+                        if part.actions:
                             r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label()
-                        for action_ts, action_key, action_id in part.actions:
-                            action_label = action_classes.get(action_key, action_key)
-                            try:
-                                url = '%sitems/%s/' % (
-                                    part.get_base_url(self.filled.formdef.workflow, wf_status),
-                                    action_id,
-                                )
-                            except KeyError:
-                                url = '#missing-%s' % action_id
-                            r += htmltext(
-                                '<li><span class="datetime">%s</span> '
-                                '<a class="tracing-link" href="%s">%s</a></li>'
-                            ) % (
-                                action_ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
-                                url,
-                                action_label,
+                            last_event_line = part
+                            break
+                try:
+                    status = self.filled.formdef.workflow.get_status(evolution.status)
+                    status_label = status.name
+                    status_admin_base_url = status.get_admin_url()
+                except KeyError:
+                    status_label = _('Unavailable status (%s)') % evolution.status
+                    status_admin_base_url = '#missing'
+                r += htmltext(
+                    '<li><span class="datetime">%s</span> '
+                    '<a class="tracing-link" href="%s"><strong>%s</strong></a></li>'
+                ) % (
+                    time.strftime('%Y-%m-%d %H:%M:%S', evolution.time) if evolution.time else '-',
+                    status_admin_base_url,
+                    status_label,
+                )
+            if evolution.status:
+                wf_status = evolution.status
+            for part in evolution.parts or []:
+                if isinstance(part, ActionsTracingEvolutionPart):
+                    if part.actions and part != last_event_line:
+                        last_event_line = part
+                        r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label()
+                    for action_ts, action_key, action_id in part.actions:
+                        action_label = action_classes.get(action_key, action_key)
+                        try:
+                            url = '%sitems/%s/' % (
+                                part.get_base_url(self.filled.formdef.workflow, wf_status),
+                                action_id,
                             )
+                        except KeyError:
+                            url = '#missing-%s' % action_id
+                        r += htmltext(
+                            '<li><span class="datetime">%s</span> '
+                            '<a class="tracing-link" href="%s">%s</a></li>'
+                        ) % (
+                            action_ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
+                            url,
+                            action_label,
+                        )
+        return r.getvalue()
 
-            r += htmltext('</ul>')
-            r += htmltext('</div>')
+    def inspect_markers_stack(self):
+        r = TemplateIO(html=True)
+        for marker in reversed(self.filled.workflow_data['_markers_stack']):
+            status = self.filled.get_status(marker['status_id'])
+            if status:
+                r += htmltext('<li><span class="status">%s</span></li>') % status.name
+            else:
+                r += htmltext('<li><span class="status">%s</span></li>') % _('Unknown')
+        return r.getvalue()
 
-        # markers stack
-        if '_markers_stack' in (self.filled.workflow_data or {}):
-            r += htmltext('<div id="inspect-markers" class="section">')
-            r += htmltext('<h2>%s</h2>') % _('Markers Stack')
-            r += htmltext('<ul class="form-inspector biglist">')
-            for marker in reversed(self.filled.workflow_data['_markers_stack']):
-                status = self.filled.get_status(marker['status_id'])
-                if status:
-                    r += htmltext('<li><span class="status">%s</span></li>') % status.name
-                else:
-                    r += htmltext('<li><span class="status">%s</span></li>') % _('Unknown')
-            r += htmltext('</ul>')
-            r += htmltext('</div>')
+    def inspect_relations(self):
+        r = TemplateIO(html=True)
+        children = self.relations
 
-        children = list(self.filled.iter_target_datas())
-        if children:
-            r += htmltext('<div id="inspect-related" class="section">')
-            r += htmltext('<h2>%s</h2>') % _('Related Forms/Cards')
-            r += htmltext('<ul class="form-inspector biglist">')
-            for child, origin in children:
-                if isinstance(child, str):
-                    r += htmltext('<li><a href="">%s (%s)</a></li>') % (child, origin)
-                else:
-                    r += htmltext('<li><a href="%s">%s (%s)</a></li>') % (
-                        child.get_url(backoffice=True),
-                        child.get_display_name(),
-                        origin,
-                    )
-            r += htmltext('</ul>')
-            r += htmltext('</div>')
+        for child, origin in children:
+            if isinstance(child, str):
+                r += htmltext('<li><a href="">%s (%s)</a></li>') % (child, origin)
+            else:
+                r += htmltext('<li><a href="%s">%s (%s)</a></li>') % (
+                    child.get_url(backoffice=True),
+                    child.get_display_name(),
+                    origin,
+                )
 
         return r.getvalue()
 
diff --git a/wcs/templates/wcs/backoffice/formdata-inspect.html b/wcs/templates/wcs/backoffice/formdata-inspect.html
new file mode 100644
index 000000000..ee48ad8b0
--- /dev/null
+++ b/wcs/templates/wcs/backoffice/formdata-inspect.html
@@ -0,0 +1,68 @@
+{% extends "wcs/backoffice/base.html" %}
+{% load i18n %}
+
+{% block appbar-title %}{% trans "Data Inspector" %}{% endblock %}
+
+{% block appbar-actions %}
+{% for action in actions %}
+<a href="{{ action.url }}">{{ action.label }}</a>
+{% endfor %}
+{% endblock %}
+
+{% block content %}
+{{ block.super }}
+
+<div id="inspect-test-tools" class="section">
+<h2>{% trans "Test tools" %}</h2>
+<div>
+{{ html_form.render|safe }}
+<div id="test-tool-result">
+{{ view.test_tool_result|safe }}
+</div>
+</div>
+</div>
+
+<div id="inspect-variables" class="section">
+<h2>{% trans "Variables "%}</h2>
+<ul class="form-inspector biglist">
+{{ view.inspect_variables|safe }}
+</ul>
+</div>
+
+{% if view.formdef.workflow.roles %}
+<div id="inspect-functions" class="section">
+<h2>{% trans "Functions" %}</h2>
+<ul class="form-inspector biglist">
+{{ view.inspect_functions|safe }}
+</ul>
+</div>
+{% endif %}
+
+{% if has_tracing %}
+<div id="inspect-timeline" class="section">
+<h2>{% trans "Actions Tracing" %}</h2>
+<ul class="form-inspector biglist">
+{{ view.inspect_tracing|safe }}
+</ul>
+</div>
+{% endif %}
+
+{% if has_markers_stack %}
+<div id="inspect-markers" class="section">
+<h2>{% trans "Markers Stack" %}</h2>
+<ul class="form-inspector biglist">
+{{ view.inspect_markers_stack|safe }}
+</ul>
+</div>
+{% endif %}
+
+{% if has_relations %}
+<div id="inspect-related" class="section">
+<h2>{% trans "Related Forms/Cards" %}</h2>
+<ul class="form-inspector biglist">
+{{ view.inspect_relations|safe }}
+</ul>
+</div>
+{% endif %}
+
+{% endblock %}
-- 
2.35.1

