diff --git a/debian/control b/debian/control
index 1be2da0a6..0ea9d2a1d 100644
--- a/debian/control
+++ b/debian/control
@@ -24,6 +24,7 @@ Depends: graphviz,
python3-dnspython,
python3-hobo,
python3-lasso,
+ python3-lxml,
python3-pil,
python3-psycopg2,
python3-pyproj,
diff --git a/setup.py b/setup.py
index 23a2a2f85..e10e0259a 100644
--- a/setup.py
+++ b/setup.py
@@ -178,7 +178,9 @@ setup(
'XStatic-Leaflet-GestureHandling',
'XStatic-Select2',
'pyproj',
+ 'pyquery',
'unidecode',
+ 'lxml',
],
package_dir={'wcs': 'wcs'},
packages=find_packages(),
diff --git a/tests/test_snapshots.py b/tests/test_snapshots.py
index 3dcde6c7e..9a8c1ce48 100644
--- a/tests/test_snapshots.py
+++ b/tests/test_snapshots.py
@@ -149,94 +149,6 @@ def test_snapshot_basics(pub):
assert [int(f.id) for f in snapshot6.instance.fields] == list(range(0, 12))
-def test_snapshot_diff(pub):
- create_superuser(pub)
- create_role(pub)
-
- formdef = FormDef()
- formdef.name = 'testform'
- formdef.fields = []
- formdef.store()
- assert pub.snapshot_class.count() == 1
- snapshot1 = pub.snapshot_class.get_latest('formdef', formdef.id)
-
- formdef.fields = [StringField(id=1, label='Test', type='string')]
- formdef.store()
- assert pub.snapshot_class.count() == 2
- snapshot2 = pub.snapshot_class.get_latest('formdef', formdef.id)
-
- formdef.fields += [StringField(id=2, label='Test bis', type='string')]
- formdef.store()
- assert pub.snapshot_class.count() == 3
- snapshot3 = pub.snapshot_class.get_latest('formdef', formdef.id)
-
- app = login(get_app(pub))
- resp = app.get('/backoffice/forms/%s/history/' % formdef.id)
- assert 'name="version1" value="%s"' % snapshot3.id in resp
- assert 'name="version2" value="%s"' % snapshot3.id not in resp
- assert 'name="version1" value="%s"' % snapshot2.id in resp
- assert 'name="version2" value="%s"' % snapshot2.id in resp
- assert 'name="version1" value="%s"' % snapshot1.id not in resp
- assert 'name="version2" value="%s"' % snapshot1.id in resp
-
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
- % (formdef.id, snapshot1.id, snapshot3.id)
- )
- assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
- assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
- assert resp.text.count('diff_sub') == 1
- assert resp.text.count('diff_add') == 24
-
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
- % (formdef.id, snapshot3.id, snapshot1.id)
- )
- assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
- assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
- assert resp.text.count('diff_sub') == 1
- assert resp.text.count('diff_add') == 24
-
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
- % (formdef.id, snapshot2.id, snapshot3.id)
- )
- assert 'Snapshot %s' % (snapshot2.id, snapshot2.id) in resp
- assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
- assert resp.text.count('diff_sub') == 0
- assert resp.text.count('diff_add') == 11
-
- formdef.fields = [StringField(id=1, label='Test', type='string')]
- formdef.store()
- assert pub.snapshot_class.count() == 4
- snapshot4 = pub.snapshot_class.get_latest('formdef', formdef.id)
-
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
- % (formdef.id, snapshot3.id, snapshot4.id)
- )
- assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
- assert 'Snapshot %s' % (snapshot4.id, snapshot4.id) in resp
- assert resp.text.count('diff_sub') == 11
- assert resp.text.count('diff_add') == 0
-
- resp = app.get('/backoffice/forms/%s/history/compare' % (formdef.id), status=404)
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s' % (formdef.id, snapshot4.id), status=404
- )
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version2=%s' % (formdef.id, snapshot4.id), status=404
- )
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s' % (formdef.id, snapshot3.id, 0),
- status=404,
- )
- resp = app.get(
- '/backoffice/forms/%s/history/compare?version1=%s&version2=%s' % (formdef.id, 0, snapshot4.id),
- status=404,
- )
-
-
def test_snapshot_instance(pub):
formdef = FormDef()
formdef.name = 'testform'
@@ -296,6 +208,100 @@ def test_snapshot_user(pub):
assert str(snapshot.user) == 'unknown user'
+def test_form_snapshot_diff(pub):
+ create_superuser(pub)
+ create_role(pub)
+
+ formdef = FormDef()
+ formdef.name = 'testform'
+ formdef.fields = []
+ formdef.store()
+ assert pub.snapshot_class.count() == 1
+ snapshot1 = pub.snapshot_class.get_latest('formdef', formdef.id)
+
+ formdef.fields = [StringField(id=1, label='Test', type='string')]
+ formdef.store()
+ assert pub.snapshot_class.count() == 2
+ snapshot2 = pub.snapshot_class.get_latest('formdef', formdef.id)
+
+ formdef.fields += [StringField(id=2, label='Test bis', type='string')]
+ formdef.store()
+ assert pub.snapshot_class.count() == 3
+ snapshot3 = pub.snapshot_class.get_latest('formdef', formdef.id)
+
+ app = login(get_app(pub))
+ resp = app.get('/backoffice/forms/%s/history/' % formdef.id)
+ assert 'name="version1" value="%s"' % snapshot3.id in resp
+ assert 'name="version2" value="%s"' % snapshot3.id not in resp
+ assert 'name="version1" value="%s"' % snapshot2.id in resp
+ assert 'name="version2" value="%s"' % snapshot2.id in resp
+ assert 'name="version1" value="%s"' % snapshot1.id not in resp
+ assert 'name="version2" value="%s"' % snapshot1.id in resp
+
+ resp = app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
+ % (formdef.id, snapshot1.id, snapshot3.id)
+ )
+ assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert resp.text.count('diff_sub') == 1
+ assert resp.text.count('diff_add') == 24
+ resp = resp.click('Compare inspect')
+ assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert 'http://example.net/backoffice/forms/%s/fields/1/' % formdef.id in resp
+ assert 'http://example.net/backoffice/forms/%s/fields/2/' % formdef.id in resp
+
+ resp = app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
+ % (formdef.id, snapshot3.id, snapshot1.id)
+ )
+ assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert resp.text.count('diff_sub') == 1
+ assert resp.text.count('diff_add') == 24
+
+ resp = app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
+ % (formdef.id, snapshot2.id, snapshot3.id)
+ )
+ assert 'Snapshot %s' % (snapshot2.id, snapshot2.id) in resp
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert resp.text.count('diff_sub') == 0
+ assert resp.text.count('diff_add') == 11
+
+ formdef.fields = [StringField(id=1, label='Test', type='string')]
+ formdef.store()
+ assert pub.snapshot_class.count() == 4
+ snapshot4 = pub.snapshot_class.get_latest('formdef', formdef.id)
+
+ resp = app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s'
+ % (formdef.id, snapshot3.id, snapshot4.id)
+ )
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert 'Snapshot %s' % (snapshot4.id, snapshot4.id) in resp
+ assert resp.text.count('diff_sub') == 11
+ assert resp.text.count('diff_add') == 0
+
+ app.get('/backoffice/forms/%s/history/compare' % (formdef.id), status=404)
+ app.get('/backoffice/forms/%s/history/compare?version1=%s' % (formdef.id, snapshot4.id), status=404)
+ app.get('/backoffice/forms/%s/history/compare?version2=%s' % (formdef.id, snapshot4.id), status=404)
+ app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s' % (formdef.id, snapshot3.id, 0),
+ status=404,
+ )
+ app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s' % (formdef.id, 0, snapshot4.id),
+ status=404,
+ )
+ app.get(
+ '/backoffice/forms/%s/history/compare?version1=%s&version2=%s&mode=foobar'
+ % (formdef.id, snapshot1.id, snapshot3.id),
+ status=404,
+ )
+
+
def test_form_snapshot_comments(pub):
create_superuser(pub)
create_role(pub)
@@ -587,6 +593,70 @@ def test_form_snapshot_browse_with_import_error(pub):
assert 'Can not display snapshot (Unknown referenced objects [Unknown field types: foobar])' in resp
+def test_workflow_snapshot_diff(pub):
+ create_superuser(pub)
+ create_role(pub)
+
+ Workflow.wipe()
+ workflow = Workflow(name='test')
+ workflow.store()
+ assert pub.snapshot_class.count() == 1
+ snapshot1 = pub.snapshot_class.get_latest('workflow', workflow.id)
+
+ workflow.add_status('Status1', 'st1')
+ workflow.store()
+ assert pub.snapshot_class.count() == 2
+ snapshot2 = pub.snapshot_class.get_latest('workflow', workflow.id)
+
+ ac1 = workflow.add_global_action('Action', 'ac1')
+ trigger = ac1.triggers[0]
+ assert trigger.key == 'manual'
+ trigger.roles = ['foobar']
+ workflow.store()
+ assert pub.snapshot_class.count() == 3
+ snapshot3 = pub.snapshot_class.get_latest('workflow', workflow.id)
+
+ workflow.global_actions = []
+ workflow.store()
+ assert pub.snapshot_class.count() == 4
+ snapshot4 = pub.snapshot_class.get_latest('workflow', workflow.id)
+
+ app = login(get_app(pub))
+ resp = app.get(
+ '/backoffice/workflows/%s/history/compare?version1=%s&version2=%s&mode=inspect'
+ % (workflow.id, snapshot1.id, snapshot2.id)
+ )
+ assert 'Snapshot %s' % (snapshot1.id, snapshot1.id) in resp
+ assert 'Snapshot %s' % (snapshot2.id, snapshot2.id) in resp
+ assert 'id="tab-statuses"' in resp
+ assert 'id="tab-global-actions"' not in resp
+
+ resp = app.get(
+ '/backoffice/workflows/%s/history/compare?version1=%s&version2=%s&mode=inspect'
+ % (workflow.id, snapshot2.id, snapshot3.id)
+ )
+ assert 'Snapshot %s' % (snapshot2.id, snapshot2.id) in resp
+ assert 'Snapshot %s' % (snapshot3.id, snapshot3.id) in resp
+ assert 'http://example.net/backoffice/workflows/%s/global-actions/ac1/' % (workflow.id) in resp
+ assert 'http://example.net/backoffice/workflows/%s/status/st1/' % workflow.id in resp
+ assert 'id="tab-statuses"' in resp
+ assert 'id="tab-global-actions"' in resp
+
+ resp = app.get(
+ '/backoffice/workflows/%s/history/compare?version1=%s&version2=%s&mode=inspect'
+ % (workflow.id, snapshot3.id, snapshot4.id)
+ )
+ assert 'id="tab-statuses"' in resp
+ assert 'id="tab-global-actions"' in resp
+
+ resp = app.get(
+ '/backoffice/workflows/%s/history/compare?version1=%s&version2=%s&mode=inspect'
+ % (workflow.id, snapshot1.id, snapshot4.id)
+ )
+ assert 'id="tab-statuses"' in resp
+ assert 'id="tab-global-actions"' not in resp
+
+
def test_workflow_snapshot_browse(pub):
create_superuser(pub)
create_role(pub)
@@ -1003,6 +1073,24 @@ def test_mail_template_snapshot_restore(pub):
mail_template2 = MailTemplate.get(resp.location.split('/')[-2])
assert mail_template2.id == mail_template.id
+ snapshot1 = pub.snapshot_class.select_object_history(mail_template)[0]
+ snapshot2 = pub.snapshot_class.select_object_history(mail_template)[1]
+ app.get(
+ '/backoffice/workflows/mail-templates/%s/history/compare?version1=%s&version2=%s&mode=xml'
+ % (mail_template.id, snapshot1.id, snapshot2.id),
+ status=200,
+ )
+ app.get(
+ '/backoffice/workflows/mail-templates/%s/history/compare?version1=%s&version2=%s&mode=inspect'
+ % (mail_template.id, snapshot1.id, snapshot2.id),
+ status=404,
+ )
+ app.get(
+ '/backoffice/workflows/mail-templates/%s/history/compare?version1=%s&version2=%s&mode=foobar'
+ % (mail_template.id, snapshot1.id, snapshot2.id),
+ status=404,
+ )
+
def test_mail_template_snapshot_browse(pub):
create_superuser(pub)
diff --git a/wcs/admin/blocks.py b/wcs/admin/blocks.py
index b8e9ba625..6ca116287 100644
--- a/wcs/admin/blocks.py
+++ b/wcs/admin/blocks.py
@@ -58,7 +58,8 @@ class BlockDirectory(FieldsDirectory):
fields_count_total_hard_limit = 60
def __init__(self, section='forms', *args, **kwargs):
- if kwargs.pop('component', None): # snapshot
+ kwargs.pop('component', None) # snapshot
+ if 'instance' in kwargs:
kwargs['objectdef'] = kwargs.pop('instance')
self.section = section
super().__init__(*args, **kwargs)
@@ -211,6 +212,9 @@ class BlockDirectory(FieldsDirectory):
def inspect(self):
self.html_top(self.objectdef.name)
get_response().breadcrumb.append(('inspect', _('Inspector')))
+ return self.render_inspect()
+
+ def render_inspect(self):
context = {'blockdef': self.objectdef, 'view': self}
return template.QommonTemplateResponse(
templates=['wcs/backoffice/block-inspect.html'], context=context
diff --git a/wcs/admin/forms.py b/wcs/admin/forms.py
index b29d4cc98..9cb91aaef 100644
--- a/wcs/admin/forms.py
+++ b/wcs/admin/forms.py
@@ -647,7 +647,8 @@ class FormDefPage(Directory):
except KeyError:
raise TraversalError()
self.formdefui = self.formdef_ui_class(self.formdef)
- get_response().breadcrumb.append((component + '/', self.formdef.name))
+ if component:
+ get_response().breadcrumb.append((component + '/', self.formdef.name))
self.fields = self.fields_directory_class(self.formdef)
self.fields.html_top = self.html_top
self.role = WorkflowRoleDirectory(self.formdef)
@@ -1647,6 +1648,9 @@ class FormDefPage(Directory):
def inspect(self):
self.html_top(self.formdef.name)
get_response().breadcrumb.append(('inspect', _('Inspector')))
+ return self.render_inspect()
+
+ def render_inspect(self):
context = {'formdef': self.formdef, 'view': self}
if self.formdef.workflow.variables_formdef:
context['workflow_options'] = {}
diff --git a/wcs/admin/workflows.py b/wcs/admin/workflows.py
index 8e69a312e..39cb7cc00 100644
--- a/wcs/admin/workflows.py
+++ b/wcs/admin/workflows.py
@@ -1602,7 +1602,8 @@ class WorkflowPage(Directory):
self.criticality_levels_dir = CriticalityLevelsDirectory(self.workflow)
self.logged_errors_dir = LoggedErrorsDirectory(parent_dir=self, workflow_id=self.workflow.id)
self.snapshots_dir = SnapshotsDirectory(self.workflow)
- get_response().breadcrumb.append((component + '/', self.workflow.name))
+ if component:
+ get_response().breadcrumb.append((component + '/', self.workflow.name))
def html_top(self, title):
return html_top('workflows', title)
@@ -1707,6 +1708,9 @@ class WorkflowPage(Directory):
def inspect(self):
self.html_top(self.workflow.name)
get_response().breadcrumb.append(('inspect', _('Inspector')))
+ return self.render_inspect()
+
+ def render_inspect(self):
context = {'workflow': self.workflow, 'view': self}
return template.QommonTemplateResponse(
templates=['wcs/backoffice/workflow-inspect.html'], context=context
diff --git a/wcs/backoffice/snapshots.py b/wcs/backoffice/snapshots.py
index d209ad675..24194cd8c 100644
--- a/wcs/backoffice/snapshots.py
+++ b/wcs/backoffice/snapshots.py
@@ -15,8 +15,11 @@
# along with this program; if not, see
{label_or_comment}
({user}{timestamp})'.format(
- name=_('Snapshot'),
- pk=snapshot.id,
- label_or_comment=label_or_comment,
- user='%s ' % snapshot.user if snapshot.user_id else '',
- timestamp=misc.strftime(misc.datetime_format(), snapshot.timestamp),
- )
+ klass = snapshot1.get_object_class()
+ backoffice_class = import_string(klass.backoffice_class)
+ has_inspect = hasattr(backoffice_class, 'render_inspect')
+ if mode == 'inspect' and not has_inspect:
+ raise errors.TraversalError()
+
+ context = getattr(self, 'get_compare_%s_context' % mode)(snapshot1, snapshot2)
+ context.update(
+ {
+ 'mode': mode,
+ 'has_inspect': has_inspect,
+ 'snapshot1': snapshot1,
+ 'snapshot2': snapshot2,
+ }
+ )
+ return template.QommonTemplateResponse(
+ templates=['wcs/backoffice/snapshots_compare.html'],
+ context=context,
+ )
+
+ def snapshot_desc(self, snapshot):
+ label_or_comment = ''
+ if snapshot.label:
+ label_or_comment = snapshot.label
+ elif snapshot.comment:
+ label_or_comment = snapshot.comment
+ return '{name} {pk} - {label_or_comment} ({user}{timestamp})'.format(
+ name=_('Snapshot'),
+ pk=snapshot.id,
+ label_or_comment=label_or_comment,
+ user='%s ' % snapshot.user if snapshot.user_id else '',
+ timestamp=misc.strftime(misc.datetime_format(), snapshot.timestamp),
+ )
+
+ def get_compare_xml_context(self, snapshot1, snapshot2):
serialization1 = snapshot1.get_serialization(indented=True)
serialization2 = snapshot2.get_serialization(indented=True)
diff_serialization = difflib.HtmlDiff(wrapcolumn=160).make_table(
fromlines=serialization1.splitlines(True),
tolines=serialization2.splitlines(True),
- fromdesc=snapshot_desc(snapshot1),
- todesc=snapshot_desc(snapshot2),
)
- return template.QommonTemplateResponse(
- templates=['wcs/backoffice/snapshots_compare.html'],
- context={
- 'snapshot1': snapshot1,
- 'snapshot2': snapshot2,
- 'diff_serialization': diff_serialization,
- },
- )
+ return {
+ 'fromdesc': self.snapshot_desc(snapshot1),
+ 'todesc': self.snapshot_desc(snapshot2),
+ 'diff_serialization': diff_serialization,
+ }
+
+ def get_compare_inspect_context(self, snapshot1, snapshot2):
+ klass = snapshot1.get_object_class()
+ backoffice_class = import_string(klass.backoffice_class)
+
+ def clean_panel(tab):
+ panel = pq(tab)
+ # remove quicknavs
+ panel.find('.inspect--quicknav').remove()
+ # remove page & field counters, for formdef
+ panel.find('.page-field-counters').remove()
+ # remove status colors
+ panel.find('.inspect-status--colour').remove()
+ return panel.html().strip('\n')
+
+ def fix_result(panel_diff):
+ if not panel_diff:
+ return panel_diff
+ panel = pq(panel_diff)
+ # remove "Link" added by htmldiff
+ for link in panel.find('a'):
+ d = pq(link)
+ text = d.html()
+ new_text = re.sub(r' Link: .*$', '', text)
+ d.html(new_text)
+ # remove empty ins and del tags
+ for elem in panel.find('ins, del'):
+ d = pq(elem)
+ if not d.html().strip():
+ d.remove()
+ # prevent auto-closing behaviour of pyquery .html() method
+ for elem in panel.find('span, ul, div'):
+ d = pq(elem)
+ if not d.html():
+ d.html(' ')
+ # sometimes status section are misplaced by htmldiff, fix it
+ for elem in panel.find('div.section.status'):
+ d = pq(elem)
+ parents = d.parents('div.section.status')
+ if parents:
+ pq(parents[0]).after(d.remove())
+ return panel.html()
+
+ inspect1 = backoffice_class(component=None, instance=snapshot1.instance).render_inspect()
+ inspect1 = template.render(inspect1.templates, inspect1.context)
+ d1 = pq(str(inspect1))
+ inspect2 = backoffice_class(component=None, instance=snapshot2.instance).render_inspect()
+ inspect2 = template.render(inspect2.templates, inspect2.context)
+ d2 = pq(str(inspect2))
+ panels_attrs = [tab.attrib for tab in d1('[role="tabpanel"]')]
+ panels1 = [clean_panel(tab) for tab in d1('[role="tabpanel"]')]
+ panels2 = [clean_panel(tab) for tab in d2('[role="tabpanel"]')]
+
+ # build tab list (merge version 1 and version2)
+ tabs1 = d1.find('[role="tab"]')
+ tabs2 = d2.find('[role="tab"]')
+ tabs_order = [t.get('id') for t in panels_attrs]
+ tabs = {}
+ for tab in tabs1 + tabs2:
+ tab_id = pq(tab).attr('aria-controls')
+ tabs[tab_id] = pq(tab).outer_html()
+ tabs = [tabs[k] for k in tabs_order if k in tabs]
+
+ # build diff of each panel
+ panels_diff = list(map(htmldiff, panels1, panels2))
+ panels_diff = [fix_result(t) for t in panels_diff]
+
+ return {
+ 'fromdesc': self.snapshot_desc(snapshot1),
+ 'todesc': self.snapshot_desc(snapshot2),
+ 'tabs': tabs,
+ 'panels': zip(panels_attrs, panels_diff),
+ 'tab_class_names': d1('.pk-tabs').attr('class'),
+ }
def snapshots(self):
current_date = None
diff --git a/wcs/qommon/static/css/dc2/admin.scss b/wcs/qommon/static/css/dc2/admin.scss
index 4c84bbaa5..871093dc8 100644
--- a/wcs/qommon/static/css/dc2/admin.scss
+++ b/wcs/qommon/static/css/dc2/admin.scss
@@ -969,7 +969,7 @@ div.full-screen-link {
text-align: right;
}
-p.last-modification {
+p.last-modification, p.snapshot-description {
font-size: 80%;
margin: 0;
}
@@ -2374,8 +2374,8 @@ div.timetable-widget {
min-width: 4em;
}
-.section.diff {
- background: transparent;
+div.diff {
+ margin: 1em 0;
}
table.diff {
@@ -2396,6 +2396,7 @@ table.diff {
*/
overflow: hidden;
text-overflow: ellipsis;
+ vertical-align: top;
}
.diff_header {
background: #f7f7f7;
@@ -2419,6 +2420,30 @@ table.diff {
}
}
+ins {
+ text-decoration: none;
+ background-color: #d4fcbc;
+}
+
+del {
+ text-decoration: line-through;
+ background-color: #fbb6c2;
+ color: #555;
+}
+
+.inspect-tabs h3 {
+ del, ins {
+ font-weight: bold;
+ background-color: transparent;
+ }
+ del, del a {
+ color: #fbb6c2 !important;
+ }
+ ins, ins a {
+ color: #d4fcbc !important;
+ }
+}
+
#sidebar .operator-and-value-widget {
.title-and-operator {
display: flex;
diff --git a/wcs/templates/wcs/backoffice/block-inspect.html b/wcs/templates/wcs/backoffice/block-inspect.html
index 33f5bf930..4e3a9fcb2 100644
--- a/wcs/templates/wcs/backoffice/block-inspect.html
+++ b/wcs/templates/wcs/backoffice/block-inspect.html
@@ -22,7 +22,7 @@
+
{% blocktrans count page_count=formdef.page_count %}{{ page_count }} page{% plural %}{{ page_count }} pages{% endblocktrans %}, {% blocktrans count fields_count=formdef.fields|count %}{{ fields_count }} field{% plural %}{{ fields_count }} fields.{% endblocktrans %}
{{ fromdesc|safe }} ➔ {{ todesc|safe }}
+