snapshots: compare inspect (#87751)
This commit is contained in:
parent
bd06f2b82f
commit
1d00c5fce8
|
@ -585,7 +585,8 @@ class Agenda(WithSnapshotMixin, WithApplicationMixin, WithInspectMixin, models.M
|
|||
slug = data.pop('slug')
|
||||
qs_kwargs = {}
|
||||
if snapshot:
|
||||
qs_kwargs = {'snapshot': snapshot}
|
||||
qs_kwargs = {'snapshot': snapshot} # don't take slug from snapshot: it has to be unique !
|
||||
data['slug'] = str(uuid.uuid4()) # random slug
|
||||
else:
|
||||
qs_kwargs = {'slug': slug}
|
||||
agenda, created = cls.objects.update_or_create(defaults=data, **qs_kwargs)
|
||||
|
@ -3018,7 +3019,8 @@ class EventsType(WithSnapshotMixin, WithApplicationMixin, WithInspectMixin, mode
|
|||
slug = data.pop('slug')
|
||||
qs_kwargs = {}
|
||||
if snapshot:
|
||||
qs_kwargs = {'snapshot': snapshot}
|
||||
qs_kwargs = {'snapshot': snapshot} # don't take slug from snapshot: it has to be unique !
|
||||
data['slug'] = str(uuid.uuid4()) # random slug
|
||||
else:
|
||||
qs_kwargs = {'slug': slug}
|
||||
events_type, created = cls.objects.update_or_create(defaults=data, **qs_kwargs)
|
||||
|
@ -3648,7 +3650,8 @@ class Resource(WithSnapshotMixin, WithApplicationMixin, WithInspectMixin, models
|
|||
slug = data.pop('slug')
|
||||
qs_kwargs = {}
|
||||
if snapshot:
|
||||
qs_kwargs = {'snapshot': snapshot}
|
||||
qs_kwargs = {'snapshot': snapshot} # don't take slug from snapshot: it has to be unique !
|
||||
data['slug'] = str(uuid.uuid4()) # random slug
|
||||
else:
|
||||
qs_kwargs = {'slug': slug}
|
||||
resource, created = cls.objects.update_or_create(defaults=data, **qs_kwargs)
|
||||
|
@ -3708,7 +3711,8 @@ class Category(WithSnapshotMixin, WithApplicationMixin, WithInspectMixin, models
|
|||
slug = data.pop('slug')
|
||||
qs_kwargs = {}
|
||||
if snapshot:
|
||||
qs_kwargs = {'snapshot': snapshot}
|
||||
qs_kwargs = {'snapshot': snapshot} # don't take slug from snapshot: it has to be unique !
|
||||
data['slug'] = str(uuid.uuid4()) # random slug
|
||||
else:
|
||||
qs_kwargs = {'slug': slug}
|
||||
category, created = cls.objects.update_or_create(defaults=data, **qs_kwargs)
|
||||
|
@ -4106,7 +4110,8 @@ class UnavailabilityCalendar(WithSnapshotMixin, WithApplicationMixin, WithInspec
|
|||
slug = data.pop('slug')
|
||||
qs_kwargs = {}
|
||||
if snapshot:
|
||||
qs_kwargs = {'snapshot': snapshot}
|
||||
qs_kwargs = {'snapshot': snapshot} # don't take slug from snapshot: it has to be unique !
|
||||
data['slug'] = str(uuid.uuid4()) # random slug
|
||||
else:
|
||||
qs_kwargs = {'slug': slug}
|
||||
unavailability_calendar, created = cls.objects.update_or_create(defaults=data, **qs_kwargs)
|
||||
|
|
|
@ -79,9 +79,11 @@ class AbstractSnapshot(models.Model):
|
|||
def get_instance(self):
|
||||
try:
|
||||
# try reusing existing instance
|
||||
return self.get_instance_model().snapshots.get(snapshot=self)
|
||||
instance = self.get_instance_model().snapshots.get(snapshot=self)
|
||||
except self.get_instance_model().DoesNotExist:
|
||||
return self.load_instance(self.serialization, snapshot=self)
|
||||
instance = self.load_instance(self.serialization, snapshot=self)
|
||||
instance.slug = self.serialization['slug'] # restore slug
|
||||
return instance
|
||||
|
||||
def load_instance(self, json_instance, snapshot=None):
|
||||
return self.get_instance_model().import_json(json_instance, snapshot=snapshot)[1]
|
||||
|
|
|
@ -16,13 +16,17 @@
|
|||
|
||||
import difflib
|
||||
import json
|
||||
import re
|
||||
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.template import loader
|
||||
from django.urls import reverse
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
from lxml.html.diff import htmldiff
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
from chrono.utils.timezone import localtime
|
||||
|
||||
|
@ -65,7 +69,7 @@ class InstanceWithSnapshotHistoryCompareView(DetailView):
|
|||
kwargs[self.instance_context_key] = self.object
|
||||
|
||||
mode = self.request.GET.get('mode') or 'json'
|
||||
if mode not in ['json']:
|
||||
if mode not in ['json', 'inspect']:
|
||||
raise Http404
|
||||
|
||||
snapshot1, snapshot2 = self.get_snapshots()
|
||||
|
@ -90,6 +94,65 @@ class InstanceWithSnapshotHistoryCompareView(DetailView):
|
|||
return context
|
||||
return self.render_to_response(context)
|
||||
|
||||
def get_compare_inspect_context(self, snapshot1, snapshot2):
|
||||
instance1 = snapshot1.get_instance()
|
||||
instance2 = snapshot2.get_instance()
|
||||
|
||||
def get_context(instance):
|
||||
return {
|
||||
'object': instance,
|
||||
}
|
||||
|
||||
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() or '').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(' ')
|
||||
return panel.html()
|
||||
|
||||
inspect1 = loader.render_to_string(self.inspect_template_name, get_context(instance1), self.request)
|
||||
d1 = pq(str(inspect1))
|
||||
inspect2 = loader.render_to_string(self.inspect_template_name, get_context(instance2), self.request)
|
||||
d2 = pq(str(inspect2))
|
||||
panels_attrs = [tab.attrib for tab in d1('[role="tabpanel"]')]
|
||||
panels1 = list(d1('[role="tabpanel"]'))
|
||||
panels2 = list(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 {
|
||||
'tabs': tabs,
|
||||
'panels': zip(panels_attrs, panels_diff),
|
||||
'tab_class_names': d1('.pk-tabs').attr('class'),
|
||||
}
|
||||
|
||||
def get_compare_json_context(self, snapshot1, snapshot2):
|
||||
s1 = json.dumps(snapshot1.serialization, sort_keys=True, indent=2)
|
||||
s2 = json.dumps(snapshot2.serialization, sort_keys=True, indent=2)
|
||||
|
|
|
@ -966,6 +966,33 @@ p.snapshot-description {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
div.diff {
|
||||
margin: 1em 0;
|
||||
h3 {
|
||||
del, ins {
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
}
|
||||
del {
|
||||
color: #fbb6c2 !important;
|
||||
}
|
||||
ins {
|
||||
color: #d4fcbc !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ins {
|
||||
text-decoration: none;
|
||||
background-color: #d4fcbc;
|
||||
}
|
||||
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
background-color: #fbb6c2;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
table.diff {
|
||||
background: white;
|
||||
border: 1px solid #f3f3f3;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Compare snapshots' %} ({% if mode == 'json' %}{% trans "JSON" %}{% else %}{% trans "Inspect" %}{% endif %})</h2>
|
||||
<span class="actions">
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=inspect">{% trans "Compare inspect" %}</a>
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=json">{% trans "Compare JSON" %}</a>
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
|
|
|
@ -12,314 +12,7 @@
|
|||
|
||||
|
||||
{% block content %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-settings" aria-selected="false" id="tab-settings" role="tab" tabindex="-1">{% trans "Settings" %}</button>
|
||||
<button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
|
||||
{% if object.kind == 'events' %}
|
||||
<button aria-controls="panel-events" aria-selected="false" id="tab-events" role="tab" tabindex="-1">{% trans "Events" %}</button>
|
||||
<button aria-controls="panel-exceptions" aria-selected="false" id="tab-exceptions" role="tab" tabindex="-1">{% trans "Recurrence exceptions" %}</button>
|
||||
{% elif object.kind == 'meetings' %}
|
||||
<button aria-controls="panel-meeting-types" aria-selected="false" id="tab-meeting-types" role="tab" tabindex="-1">{% trans "Meeting Types" %}</button>
|
||||
<button aria-controls="panel-desks" aria-selected="false" id="tab-desks" role="tab" tabindex="-1">{% trans "Desks" %}</button>
|
||||
<button aria-controls="panel-resources" aria-selected="false" id="tab-resources" role="tab" tabindex="-1">{% trans "Resources" %}</button>
|
||||
{% elif object.kind == 'virtual' %}
|
||||
<button aria-controls="panel-agendas" aria-selected="false" id="tab-agendas" role="tab" tabindex="-1">{% trans "Included Agendas" %}</button>
|
||||
<button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Exception Periods" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-settings" hidden id="panel-settings" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
|
||||
{% if object.kind != 'virtual' %}
|
||||
<h4>{% trans "Display options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_display_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
<h4>{% trans "Booking check options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_booking_check_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
{% if agenda.partial_bookings %}
|
||||
<h4>{% trans "Invoicing options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_invoicing_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<h4>{% trans "Management notifications" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_notifications_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind != 'virtual' and not object.partial_bookings %}
|
||||
<h4>{% trans "Booking reminders" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_reminder_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h4>{% trans "Booking Delays" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_booking_delays_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-permissions" hidden id="panel-permissions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_permissions_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
|
||||
<div aria-labelledby="tab-events" hidden id="panel-events" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for event in object.event_set.all %}
|
||||
<h4>{{ event }}</h4>
|
||||
<ul>
|
||||
{% for label, value in event.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-exceptions" hidden id="panel-exceptions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for desk in object.desk_set.all %}{% if desk.slug == '_exceptions_holder' %}
|
||||
<h4>{% trans "Unavailability calendars" %}</h4>
|
||||
<ul>
|
||||
{% for unavailability_calendar in desk.unavailability_calendars.all %}
|
||||
<li class="parameter-unavailability-calendar }}">
|
||||
{{ unavailability_calendar }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>{% trans "Exception sources" %}</h4>
|
||||
{% for source in desk.timeperiodexceptionsource_set.all %}
|
||||
<h5>{{ source }}</h5>
|
||||
<ul>
|
||||
{% for label, value in source.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h4>{% trans "Exceptions" %}</h4>
|
||||
{% for exception in desk.timeperiodexception_set.all %}
|
||||
<h5>{{ exception }}</h5>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
{% endif %}{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% elif object.kind == 'meetings' %}
|
||||
|
||||
<div aria-labelledby="tab-meeting-types" hidden id="panel-meeting-types" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for meeting_type in object.meetingtype_set.all %}
|
||||
<h4>{{ meeting_type }}</h4>
|
||||
<ul>
|
||||
{% for label, value in meeting_type.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-desks" hidden id="panel-desks" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for desk in object.desk_set.all %}
|
||||
<h4>{{ desk }}</h4>
|
||||
<ul>
|
||||
{% for label, value in desk.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h5>{% trans "Opening hours" %}</h5>
|
||||
{% for time_period in desk.timeperiod_set.all %}
|
||||
<h6>{{ time_period }}</h6>
|
||||
<ul>
|
||||
{% for label, value in time_period.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h5>{% trans "Unavailability calendars" %}</h5>
|
||||
<ul>
|
||||
{% for unavailability_calendar in desk.unavailability_calendars.all %}
|
||||
<li class="parameter-unavailability-calendar }}">
|
||||
{{ unavailability_calendar }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h5>{% trans "Exception sources" %}</h5>
|
||||
{% for source in desk.timeperiodexceptionsource_set.all %}
|
||||
<h6>{{ source }}</h6>
|
||||
<ul>
|
||||
{% for label, value in source.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h5>{% trans "Exceptions" %}</h5>
|
||||
{% for exception in desk.timeperiodexception_set.all %}
|
||||
<h6>{{ exception }}</h6>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-resources" hidden id="panel-resources" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for resource in object.resources.all %}
|
||||
<li class="parameter-resource }}">
|
||||
{{ resource }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% elif object.kind == "virtual" %}
|
||||
|
||||
<div aria-labelledby="tab-agendas" hidden id="panel-agendas" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for agenda in object.real_agendas.all %}
|
||||
<li class="parameter-agenda }}">
|
||||
{{ agenda }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-time-periods" hidden id="panel-time-periods" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for time_period in object.excluded_timeperiods.all %}
|
||||
<h4>{{ time_period }}</h4>
|
||||
<ul>
|
||||
{% for label, value in time_period.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include 'chrono/manager_agenda_inspect_fragment.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
{% load i18n %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-settings" aria-selected="false" id="tab-settings" role="tab" tabindex="-1">{% trans "Settings" %}</button>
|
||||
<button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
|
||||
{% if object.kind == 'events' %}
|
||||
<button aria-controls="panel-events" aria-selected="false" id="tab-events" role="tab" tabindex="-1">{% trans "Events" %}</button>
|
||||
<button aria-controls="panel-exceptions" aria-selected="false" id="tab-exceptions" role="tab" tabindex="-1">{% trans "Recurrence exceptions" %}</button>
|
||||
{% elif object.kind == 'meetings' %}
|
||||
<button aria-controls="panel-meeting-types" aria-selected="false" id="tab-meeting-types" role="tab" tabindex="-1">{% trans "Meeting Types" %}</button>
|
||||
<button aria-controls="panel-desks" aria-selected="false" id="tab-desks" role="tab" tabindex="-1">{% trans "Desks" %}</button>
|
||||
<button aria-controls="panel-resources" aria-selected="false" id="tab-resources" role="tab" tabindex="-1">{% trans "Resources" %}</button>
|
||||
{% elif object.kind == 'virtual' %}
|
||||
<button aria-controls="panel-agendas" aria-selected="false" id="tab-agendas" role="tab" tabindex="-1">{% trans "Included Agendas" %}</button>
|
||||
<button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Exception Periods" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-settings" hidden id="panel-settings" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
|
||||
{% if object.kind != 'virtual' %}
|
||||
<h4>{% trans "Display options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_display_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
<h4>{% trans "Booking check options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_booking_check_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
{% if agenda.partial_bookings %}
|
||||
<h4>{% trans "Invoicing options" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_invoicing_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<h4>{% trans "Management notifications" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_notifications_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if object.kind != 'virtual' and not object.partial_bookings %}
|
||||
<h4>{% trans "Booking reminders" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_reminder_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h4>{% trans "Booking Delays" %}</h4>
|
||||
<ul>
|
||||
{% for label, value in object.get_booking_delays_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-permissions" hidden id="panel-permissions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_permissions_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if object.kind == 'events' %}
|
||||
|
||||
<div aria-labelledby="tab-events" hidden id="panel-events" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for event in object.event_set.all %}
|
||||
<h4>{{ event }}</h4>
|
||||
<ul>
|
||||
{% for label, value in event.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-exceptions" hidden id="panel-exceptions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for desk in object.desk_set.all %}{% if desk.slug == '_exceptions_holder' %}
|
||||
<h4>{% trans "Unavailability calendars" %}</h4>
|
||||
<ul>
|
||||
{% for unavailability_calendar in desk.unavailability_calendars.all %}
|
||||
<li class="parameter-unavailability-calendar }}">
|
||||
{{ unavailability_calendar }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>{% trans "Exception sources" %}</h4>
|
||||
{% for source in desk.timeperiodexceptionsource_set.all %}
|
||||
<h5>{{ source }}</h5>
|
||||
<ul>
|
||||
{% for label, value in source.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h4>{% trans "Exceptions" %}</h4>
|
||||
{% for exception in desk.timeperiodexception_set.all %}
|
||||
<h5>{{ exception }}</h5>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
{% endif %}{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% elif object.kind == 'meetings' %}
|
||||
|
||||
<div aria-labelledby="tab-meeting-types" hidden id="panel-meeting-types" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for meeting_type in object.meetingtype_set.all %}
|
||||
<h4>{{ meeting_type }}</h4>
|
||||
<ul>
|
||||
{% for label, value in meeting_type.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-desks" hidden id="panel-desks" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for desk in object.desk_set.all %}
|
||||
<h4>{{ desk }}</h4>
|
||||
<ul>
|
||||
{% for label, value in desk.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h5>{% trans "Opening hours" %}</h5>
|
||||
{% for time_period in desk.timeperiod_set.all %}
|
||||
<h6>{{ time_period }}</h6>
|
||||
<ul>
|
||||
{% for label, value in time_period.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h5>{% trans "Unavailability calendars" %}</h5>
|
||||
<ul>
|
||||
{% for unavailability_calendar in desk.unavailability_calendars.all %}
|
||||
<li class="parameter-unavailability-calendar }}">
|
||||
{{ unavailability_calendar }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h5>{% trans "Exception sources" %}</h5>
|
||||
{% for source in desk.timeperiodexceptionsource_set.all %}
|
||||
<h6>{{ source }}</h6>
|
||||
<ul>
|
||||
{% for label, value in source.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
<h5>{% trans "Exceptions" %}</h5>
|
||||
{% for exception in desk.timeperiodexception_set.all %}
|
||||
<h6>{{ exception }}</h6>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-resources" hidden id="panel-resources" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for resource in object.resources.all %}
|
||||
<li class="parameter-resource }}">
|
||||
{{ resource }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% elif object.kind == "virtual" %}
|
||||
|
||||
<div aria-labelledby="tab-agendas" hidden id="panel-agendas" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for agenda in object.real_agendas.all %}
|
||||
<li class="parameter-agenda }}">
|
||||
{{ agenda }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-time-periods" hidden id="panel-time-periods" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for time_period in object.excluded_timeperiods.all %}
|
||||
<h4>{{ time_period }}</h4>
|
||||
<ul>
|
||||
{% for label, value in time_period.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Compare snapshots' %} ({% if mode == 'json' %}{% trans "JSON" %}{% else %}{% trans "Inspect" %}{% endif %})</h2>
|
||||
<span class="actions">
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=inspect">{% trans "Compare inspect" %}</a>
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=json">{% trans "Compare JSON" %}</a>
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
|
|
|
@ -11,26 +11,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'chrono/manager_category_inspect_fragment.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{% load i18n %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Compare snapshots' %} ({% if mode == 'json' %}{% trans "JSON" %}{% else %}{% trans "Inspect" %}{% endif %})</h2>
|
||||
<span class="actions">
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=inspect">{% trans "Compare inspect" %}</a>
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=json">{% trans "Compare JSON" %}</a>
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
|
|
|
@ -11,52 +11,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-custom-fields" aria-selected="false" id="tab-custom-fields" role="tab" tabindex="-1">{% trans "Custom fields" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-custom-fields" hidden id="panel-custom-fields" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for value in object.get_custom_fields %}
|
||||
<h4>{{ value.label }}</h4>
|
||||
<ul>
|
||||
<li class="parameter-varname">
|
||||
<span class="parameter">{% trans "Field slug:" %}</span>
|
||||
{{ value.varname }}
|
||||
</li>
|
||||
<li class="parameter-label">
|
||||
<span class="parameter">{% trans "Field label:" %}</span>
|
||||
{{ value.label }}
|
||||
</li>
|
||||
<li class="parameter-field-type">
|
||||
<span class="parameter">{% trans "Field type:" %}</span>
|
||||
{% if value.field_type == 'text' %}{% trans "Text" %}{% endif %}
|
||||
{% if value.field_type == 'textarea' %}{% trans "Textarea" %}{% endif %}
|
||||
{% if value.field_type == 'textbool' %}{% trans "Boolean" %}{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include 'chrono/manager_events_type_inspect_fragment.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
{% load i18n %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-custom-fields" aria-selected="false" id="tab-custom-fields" role="tab" tabindex="-1">{% trans "Custom fields" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-custom-fields" hidden id="panel-custom-fields" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for value in object.get_custom_fields %}
|
||||
<h4>{{ value.label }}</h4>
|
||||
<ul>
|
||||
<li class="parameter-varname">
|
||||
<span class="parameter">{% trans "Field slug:" %}</span>
|
||||
{{ value.varname }}
|
||||
</li>
|
||||
<li class="parameter-label">
|
||||
<span class="parameter">{% trans "Field label:" %}</span>
|
||||
{{ value.label }}
|
||||
</li>
|
||||
<li class="parameter-field-type">
|
||||
<span class="parameter">{% trans "Field type:" %}</span>
|
||||
{% if value.field_type == 'text' %}{% trans "Text" %}{% endif %}
|
||||
{% if value.field_type == 'textarea' %}{% trans "Textarea" %}{% endif %}
|
||||
{% if value.field_type == 'textbool' %}{% trans "Boolean" %}{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Compare snapshots' %} ({% if mode == 'json' %}{% trans "JSON" %}{% else %}{% trans "Inspect" %}{% endif %})</h2>
|
||||
<span class="actions">
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=inspect">{% trans "Compare inspect" %}</a>
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=json">{% trans "Compare JSON" %}</a>
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
|
|
|
@ -11,27 +11,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include 'chrono/manager_resource_inspect_fragment.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{% load i18n %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Compare snapshots' %} ({% if mode == 'json' %}{% trans "JSON" %}{% else %}{% trans "Inspect" %}{% endif %})</h2>
|
||||
<span class="actions">
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=inspect">{% trans "Compare inspect" %}</a>
|
||||
<a href="?version1={{ snapshot1.pk }}&version2={{ snapshot2.pk }}&mode=json">{% trans "Compare JSON" %}</a>
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
|
|
|
@ -11,58 +11,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
|
||||
<button aria-controls="panel-exceptions" aria-selected="false" id="tab-exceptions" role="tab" tabindex="-1">{% trans "Exceptions" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-permissions" hidden id="panel-permissions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_permissions_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-exceptions" hidden id="panel-exceptions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for exception in object.timeperiodexception_set.all %}
|
||||
<h4>{{ exception }}</h4>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include 'chrono/manager_unavailability_calendar_inspect_fragment.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
{% load i18n %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-information" aria-selected="true" id="tab-information" role="tab" tabindex="0">{% trans "Information" %}</button>
|
||||
<button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
|
||||
<button aria-controls="panel-exceptions" aria-selected="false" id="tab-exceptions" role="tab" tabindex="-1">{% trans "Exceptions" %}</button>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-information" id="panel-information" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-permissions" hidden id="panel-permissions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
<ul>
|
||||
{% for label, value in object.get_permissions_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-exceptions" hidden id="panel-exceptions" role="tabpanel" tabindex="0">
|
||||
<div class="section">
|
||||
{% for exception in object.timeperiodexception_set.all %}
|
||||
<h4>{{ exception }}</h4>
|
||||
<ul>
|
||||
{% for label, value in exception.get_inspect_fields %}
|
||||
<li class="parameter-{{ label|slugify }}">
|
||||
<span class="parameter">{% blocktrans %}{{ label }}:{% endblocktrans %}</span>
|
||||
{{ value }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -829,6 +829,7 @@ resource_history = ResourceHistoryView.as_view()
|
|||
|
||||
class ResourceHistoryCompareView(InstanceWithSnapshotHistoryCompareView):
|
||||
template_name = 'chrono/manager_resource_history_compare.html'
|
||||
inspect_template_name = 'chrono/manager_resource_inspect_fragment.html'
|
||||
model = Resource
|
||||
instance_context_key = 'resource'
|
||||
history_view = 'chrono-manager-resource-history'
|
||||
|
@ -960,6 +961,7 @@ category_history = CategoryHistoryView.as_view()
|
|||
|
||||
class CategoryHistoryCompareView(InstanceWithSnapshotHistoryCompareView):
|
||||
template_name = 'chrono/manager_category_history_compare.html'
|
||||
inspect_template_name = 'chrono/manager_category_inspect_fragment.html'
|
||||
model = Category
|
||||
instance_context_key = 'category'
|
||||
history_view = 'chrono-manager-category-history'
|
||||
|
@ -1148,6 +1150,7 @@ events_type_history = EventsTypeHistoryView.as_view()
|
|||
|
||||
class EventsTypeHistoryCompareView(InstanceWithSnapshotHistoryCompareView):
|
||||
template_name = 'chrono/manager_events_type_history_compare.html'
|
||||
inspect_template_name = 'chrono/manager_events_type_inspect_fragment.html'
|
||||
model = EventsType
|
||||
instance_context_key = 'events_type'
|
||||
history_view = 'chrono-manager-events-type-history'
|
||||
|
@ -4209,9 +4212,12 @@ class AgendaInspectView(ManagedAgendaMixin, DetailView):
|
|||
'desk_set',
|
||||
queryset=Desk.objects.prefetch_related(
|
||||
'timeperiod_set',
|
||||
'timeperiodexception_set',
|
||||
'timeperiodexceptionsource_set',
|
||||
'unavailability_calendars',
|
||||
Prefetch(
|
||||
'timeperiodexception_set',
|
||||
queryset=TimePeriodException.objects.filter(source__isnull=True),
|
||||
),
|
||||
),
|
||||
),
|
||||
Prefetch('event_set', queryset=Event.objects.filter(primary_event__isnull=True)),
|
||||
|
@ -4237,6 +4243,7 @@ agenda_history = AgendaHistoryView.as_view()
|
|||
|
||||
class AgendaHistoryCompareView(ManagedAgendaMixin, InstanceWithSnapshotHistoryCompareView):
|
||||
template_name = 'chrono/manager_agenda_history_compare.html'
|
||||
inspect_template_name = 'chrono/manager_agenda_inspect_fragment.html'
|
||||
model = Agenda
|
||||
instance_context_key = 'agenda'
|
||||
history_view = 'chrono-manager-agenda-history'
|
||||
|
@ -4893,6 +4900,7 @@ class UnavailabilityCalendarHistoryCompareView(
|
|||
ManagedUnavailabilityCalendarMixin, InstanceWithSnapshotHistoryCompareView
|
||||
):
|
||||
template_name = 'chrono/manager_unavailability_calendar_history_compare.html'
|
||||
inspect_template_name = 'chrono/manager_unavailability_calendar_inspect_fragment.html'
|
||||
model = UnavailabilityCalendar
|
||||
instance_context_key = 'unavailability_calendar'
|
||||
history_view = 'chrono-manager-unavailability-calendar-history'
|
||||
|
|
|
@ -14,6 +14,7 @@ Package: python3-chrono
|
|||
Architecture: all
|
||||
Depends: python3-django (>= 2:3.2),
|
||||
python3-gadjo,
|
||||
python3-lxml,
|
||||
python3-publik-django-templatetags,
|
||||
python3-requests,
|
||||
python3-uwsgidecorators,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[MASTER]
|
||||
persistent=yes
|
||||
ignore=vendor,Bouncers,ezt.py
|
||||
extension-pkg-allow-list=lxml
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
disable=
|
||||
|
|
1
setup.py
1
setup.py
|
@ -169,6 +169,7 @@ setup(
|
|||
'workalendar',
|
||||
'weasyprint',
|
||||
'sorl-thumbnail',
|
||||
'lxml',
|
||||
],
|
||||
zip_safe=False,
|
||||
cmdclass={
|
||||
|
|
|
@ -1026,7 +1026,7 @@ def test_import_events(app, admin_user):
|
|||
)
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
resp = resp.form.submit(status=302)
|
||||
assert len(ctx.captured_queries) == 32
|
||||
assert len(ctx.captured_queries) == 31
|
||||
assert Event.objects.count() == 5
|
||||
assert set(Event.objects.values_list('slug', flat=True)) == {
|
||||
'labelb',
|
||||
|
|
|
@ -44,15 +44,20 @@ def test_agenda_history(settings, app, admin_user):
|
|||
]
|
||||
assert '(Version 42.0)' in resp.pyquery('tr:nth-child(1)').text()
|
||||
|
||||
resp = app.get(
|
||||
'/manage/agendas/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (agenda.pk, snapshot1.pk, snapshot2.pk)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
assert resp.text.count('diff_sub') == 1
|
||||
assert resp.text.count('diff_add') == 16
|
||||
assert resp.text.count('diff_chg') == 0
|
||||
for mode in ['json', 'inspect', '']:
|
||||
resp = app.get(
|
||||
'/manage/agendas/%s/history/compare/?version1=%s&version2=%s&mode=%s'
|
||||
% (agenda.pk, snapshot1.pk, snapshot2.pk, mode)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
if mode == 'inspect':
|
||||
assert resp.text.count('<ins>') == 6
|
||||
assert resp.text.count('<del>') == 0
|
||||
else:
|
||||
assert resp.text.count('diff_sub') == 1
|
||||
assert resp.text.count('diff_add') == 16
|
||||
assert resp.text.count('diff_chg') == 0
|
||||
resp = app.get(
|
||||
'/manage/agendas/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (agenda.pk, snapshot2.pk, snapshot1.pk)
|
||||
|
@ -112,15 +117,20 @@ def test_category_history(settings, app, admin_user):
|
|||
]
|
||||
assert '(Version 42.0)' in resp.pyquery('tr:nth-child(1)').text()
|
||||
|
||||
resp = app.get(
|
||||
'/manage/category/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (category.pk, snapshot1.pk, snapshot2.pk)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
for mode in ['json', 'inspect', '']:
|
||||
resp = app.get(
|
||||
'/manage/category/%s/history/compare/?version1=%s&version2=%s&mode=%s'
|
||||
% (category.pk, snapshot1.pk, snapshot2.pk, mode)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
if mode == 'inspect':
|
||||
assert resp.text.count('<ins>') == 1
|
||||
assert resp.text.count('<del>') == 1
|
||||
else:
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
resp = app.get(
|
||||
'/manage/category/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (category.pk, snapshot2.pk, snapshot1.pk)
|
||||
|
@ -154,15 +164,20 @@ def test_events_type_history(settings, app, admin_user):
|
|||
]
|
||||
assert '(Version 42.0)' in resp.pyquery('tr:nth-child(1)').text()
|
||||
|
||||
resp = app.get(
|
||||
'/manage/events-type/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (events_type.pk, snapshot1.pk, snapshot2.pk)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
for mode in ['json', 'inspect', '']:
|
||||
resp = app.get(
|
||||
'/manage/events-type/%s/history/compare/?version1=%s&version2=%s&mode=%s'
|
||||
% (events_type.pk, snapshot1.pk, snapshot2.pk, mode)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
if mode == 'inspect':
|
||||
assert resp.text.count('<ins>') == 1
|
||||
assert resp.text.count('<del>') == 1
|
||||
else:
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
resp = app.get(
|
||||
'/manage/events-type/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (events_type.pk, snapshot2.pk, snapshot1.pk)
|
||||
|
@ -196,15 +211,20 @@ def test_resource_history(settings, app, admin_user):
|
|||
]
|
||||
assert '(Version 42.0)' in resp.pyquery('tr:nth-child(1)').text()
|
||||
|
||||
resp = app.get(
|
||||
'/manage/resource/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (resource.pk, snapshot1.pk, snapshot2.pk)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
for mode in ['json', 'inspect', '']:
|
||||
resp = app.get(
|
||||
'/manage/resource/%s/history/compare/?version1=%s&version2=%s&mode=%s'
|
||||
% (resource.pk, snapshot1.pk, snapshot2.pk, mode)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
if mode == 'inspect':
|
||||
assert resp.text.count('<ins>') == 1
|
||||
assert resp.text.count('<del>') == 1
|
||||
else:
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
resp = app.get(
|
||||
'/manage/resource/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (resource.pk, snapshot2.pk, snapshot1.pk)
|
||||
|
@ -238,15 +258,20 @@ def test_unavailability_calendar_history(settings, app, admin_user):
|
|||
]
|
||||
assert '(Version 42.0)' in resp.pyquery('tr:nth-child(1)').text()
|
||||
|
||||
resp = app.get(
|
||||
'/manage/unavailability-calendar/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (unavailability_calendar.pk, snapshot1.pk, snapshot2.pk)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
for mode in ['json', 'inspect', '']:
|
||||
resp = app.get(
|
||||
'/manage/unavailability-calendar/%s/history/compare/?version1=%s&version2=%s&mode=%s'
|
||||
% (unavailability_calendar.pk, snapshot1.pk, snapshot2.pk, mode)
|
||||
)
|
||||
assert 'Snapshot (%s)' % (snapshot1.pk) in resp
|
||||
assert 'Snapshot (%s) - (Version 42.0)' % (snapshot2.pk) in resp
|
||||
if mode == 'inspect':
|
||||
assert resp.text.count('<ins>') == 1
|
||||
assert resp.text.count('<del>') == 1
|
||||
else:
|
||||
assert resp.text.count('diff_sub') == 0
|
||||
assert resp.text.count('diff_add') == 0
|
||||
assert resp.text.count('diff_chg') == 2
|
||||
resp = app.get(
|
||||
'/manage/unavailability-calendar/%s/history/compare/?version1=%s&version2=%s'
|
||||
% (unavailability_calendar.pk, snapshot2.pk, snapshot1.pk)
|
||||
|
|
Loading…
Reference in New Issue