manager: support for saving a page snapshot with a label (#56519)

This commit is contained in:
Agate 2022-07-06 15:04:14 +02:00
parent 346000f67f
commit 4ed8ebcf21
9 changed files with 115 additions and 12 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.26 on 2022-07-06 12:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('data', '0056_display_condition'),
]
operations = [
migrations.AddField(
model_name='pagesnapshot',
name='label',
field=models.CharField(blank=True, max_length=150, verbose_name='Label'),
),
]

View File

@ -717,13 +717,14 @@ class PageSnapshot(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
comment = models.TextField(blank=True, null=True)
serialization = JSONField(blank=True, default=dict)
label = models.CharField(_('Label'), max_length=150, blank=True)
class Meta:
ordering = ('-timestamp',)
@classmethod
def take(cls, page, request=None, comment=None, deletion=False):
snapshot = cls(page=page, comment=comment)
def take(cls, page, request=None, comment=None, deletion=False, label=None):
snapshot = cls(page=page, comment=comment, label=label or '')
if request and not request.user.is_anonymous:
snapshot.user = request.user
if not deletion:

View File

@ -408,3 +408,7 @@ class PlaceholderOptionsForm(forms.Form):
('fx-grid--t3', _('3 columns')),
],
)
class PageSnapshotSaveForm(forms.Form):
label = forms.CharField(label=_('Label'), max_length=150, required=True)

View File

@ -16,16 +16,36 @@
{% block content %}
<div>
<ul class="objects-list">
{% for snapshot in object_list %}
<li>{{ snapshot.timestamp }}, {{ snapshot.comment }}
{% if snapshot.user %} ({{ snapshot.user.get_full_name }}){% endif %}
<a href="{% url 'combo-snapshot-view' pk=snapshot.id %}">{% trans "view" %}</a>
<a href="{% url 'combo-manager-snapshot-export' page_pk=view.page.id pk=snapshot.id %}">{% trans "export" %}</a>
<a href="{% url 'combo-manager-snapshot-restore' page_pk=view.page.id pk=snapshot.id %}" rel="popup">{% trans "restore" %}</a>
</li>
{% endfor %}
</ul>
<table class="main">
<thead>
<th>{% trans 'Date' %}</th>
<th>{% trans 'Description' %}</th>
<th>{% trans 'User' %}</th>
<th>{% trans 'Actions' %}</th>
</thead>
<tbody>
{% for snapshot in object_list %}
<tr>
<td>
{{ snapshot.timestamp }}
</td>
<td>
{% if snapshot.label %}
<strong>{{ snapshot.label }}</strong>
{% elif snapshot.comment %}
{{ snapshot.comment }}
{% endif %}
</td>
<td>{% if snapshot.user %} {{ snapshot.user.get_full_name }}{% endif %}</td>
<td>
<a href="{% url 'combo-snapshot-view' pk=snapshot.id %}">{% trans "view" %}</a>
<a href="{% url 'combo-manager-snapshot-export' page_pk=view.page.id pk=snapshot.id %}">{% trans "export" %}</a>
<a href="{% url 'combo-manager-snapshot-restore' page_pk=view.page.id pk=snapshot.id %}" rel="popup">{% trans "restore" %}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "gadjo/pagination.html" %}

View File

@ -16,6 +16,7 @@
<li><a class="action-add-child" rel="popup" href="{% url 'combo-manager-page-add-child' pk=object.id %}">{% trans 'Add a child page' %}</a></li>
<li><a class="action-edit-roles" rel="popup" href="{% url 'combo-manager-page-edit-roles' pk=object.id %}">{% trans 'Manage edit roles' %}</a></li>
<li><a rel="popup" class="action-duplicate" href="{% url 'combo-manager-page-duplicate' pk=object.id %}">{% trans 'Duplicate' %}</a></li>
<li><a rel="popup" class="action-save" href="{% url 'combo-manager-page-save' pk=object.id %}">{% trans 'Save snapshot' %}</a></li>
<li><a class="action-delete" rel="popup" href="{% url 'combo-manager-page-delete' pk=object.id %}">{% trans 'Delete' %}</a></li>
{% endif %}
</ul>

View File

@ -0,0 +1,24 @@
{% extends "combo/manager_base.html" %}
{% load i18n %}
{% load cells %}
{% load thumbnail %}
{% block appbar %}
<h2>{% trans 'Save Page' %} - {{ page.title }}</h2>
{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'combo-manager-page-view' pk=page.id %}">{% trans 'Page' %} - {{page.title }}</a>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans 'Save' %}</button>
<a class="cancel" href="{% url 'combo-manager-page-view' pk=page.id %}">{% trans 'Cancel' %}</a>
</div>
</form>
{% endblock %}

View File

@ -85,6 +85,11 @@ urlpatterns = [
pages_admin_required(views.page_duplicate),
name='combo-manager-page-duplicate',
),
url(
r'^pages/(?P<pk>\d+)/save',
pages_admin_required(views.snapshot_save),
name='combo-manager-page-save',
),
url(
r'^pages/(?P<pk>\d+)/edit-roles/$',
pages_admin_required(views.page_edit_roles),

View File

@ -83,6 +83,7 @@ from .forms import (
PageExportForm,
PageRestrictedAddForm,
PageSelectTemplateForm,
PageSnapshotSaveForm,
PageVisibilityForm,
PlaceholderOptionsForm,
SiteExportForm,
@ -644,6 +645,27 @@ def snapshot_export(request, *args, **kwargs):
return response
class SnapshotSaveView(ManagedPageMixin, FormView):
form_class = PageSnapshotSaveForm
template_name = 'combo/snapshot_save.html'
def get_success_url(self):
return reverse('combo-manager-page-view', kwargs={'pk': self.page.pk})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['page'] = self.page
return context
def form_valid(self, form):
PageSnapshot.take(self.page, request=self.request, label=form.cleaned_data['label'])
messages.info(self.request, _('Snapshot "%s" has been saved.') % form.cleaned_data['label'])
return super().form_valid(form)
snapshot_save = SnapshotSaveView.as_view()
class PageRedirectToEditView(RedirectView):
permanent = False

View File

@ -2513,6 +2513,14 @@ def test_page_versionning(app, admin_user):
resp2 = resp.click('See online')
assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')
# save snapshot with a label
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id, status=200)
resp = resp.click('Save snapshot')
resp.form['label'] = 'CGUv1'
resp = resp.form.submit().follow()
assert page.pagesnapshot_set.latest('pk').label == 'CGUv1'
# clean it up
Page.snapshots.all().delete()
assert Page.objects.count() == 1