snapshots: Add submenu section in UI

Signed-off-by: Shubham Agarwal <shubhama@thoughtworks.com>
Reviewed-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
This commit is contained in:
Shubham Agarwal 2018-03-08 23:46:45 +05:30 committed by Joseph Nuthalapati
parent fe8536df8a
commit 7ff2196d04
No known key found for this signature in database
GPG Key ID: 5398F00A2FA43C35
5 changed files with 145 additions and 98 deletions

View File

@ -29,25 +29,25 @@ class SnapshotForm(forms.Form):
'(hourly, daily, monthly and yearly).')) '(hourly, daily, monthly and yearly).'))
hourly_limit = forms.IntegerField( hourly_limit = forms.IntegerField(
label=_('Hourly Snapshots Limit'), min_value=0, label=_('Hourly Snapshots Limit'), min_value=0, help_text=_(
help_text=('Snapper will only keep this number of hourly snapshots.')) 'Keep a maximum of this many hourly snapshots.'))
daily_limit = forms.IntegerField( daily_limit = forms.IntegerField(
label=_('Daily Snapshots Limit'), min_value=0, label=_('Daily Snapshots Limit'), min_value=0, help_text=_(
help_text=('Snapper will only keep this number of daily snapshots.')) 'Keep a maximum of this many daily snapshots.'))
weekly_limit = forms.IntegerField( weekly_limit = forms.IntegerField(
label=_('Weekly Snapshots Limit'), min_value=0, label=_('Weekly Snapshots Limit'), min_value=0, help_text=_(
help_text=('Snapper will only keep this number of weekly snapshots.')) 'Keep a maximum of this many weekly snapshots.'))
monthly_limit = forms.IntegerField( monthly_limit = forms.IntegerField(
label=_('Monthly Snapshots Limit'), min_value=0, label=_('Monthly Snapshots Limit'), min_value=0, help_text=_(
help_text=('Snapper will only keep this number of monthly snapshots.')) 'Keep a maximum of this many monthly snapshots.'))
yearly_limit = forms.IntegerField( yearly_limit = forms.IntegerField(
label=_('Yearly Snapshots Limit'), min_value=0, label=_('Yearly Snapshots Limit'), min_value=0, help_text=_(
help_text=('Snapper will only keep this number of yearly snapshots. ' 'Keep a maximum of this many yearly snapshots. '
'The default is 0 (disabled).')) 'The default is 0 (disabled).'))
number_min_age = forms.IntegerField( number_min_age = forms.IntegerField(
label=_('Delete Software Snapshots older than (days)'), min_value=0, label=_('Delete Software Snapshots older than (days)'), min_value=0,

View File

@ -23,85 +23,12 @@
{% block configuration %} {% block configuration %}
<p> <p>
<form class="form" method="post"> <form class="form-horizontal" method="post">
{% csrf_token %} {% csrf_token %}
<h3>{% trans "Configuration" %}</h3> <h3>{% trans "Configuration" %}</h3>
{{ form|bootstrap }} {{ form|bootstrap_horizontal:'col-sm-4' }}
<input type="submit" class="btn btn-primary" name="update" <input type="submit" class="btn btn-primary" name="update"
value="{% trans "Update setup" %}"/> value="{% trans "Update setup" %}"/>
<hr> </form>
<div class="row">
<div class="col-xs-6 text-left">
<input type="submit" class="btn btn-primary" name="create"
value="{% trans 'Create Snapshot' %}"/>
</div>
</form>
<div class="col-xs-6 text-right">
<a title="{% trans 'Delete all the snapshots' %}"
role="button" class="btn btn-danger"
{% if not has_deletable_snapshots %}
disabled="disabled"
{% else %}
href="{% url 'snapshot:delete-all' %}"
{% endif %}>
{% trans 'Delete All' %}
</a>
</div>
</div>
</p>
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered table-condensed table-striped">
<thead>
<th>{% trans "Number" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Rollback" %}</th>
<th>{% trans "Delete" %}</th>
</thead>
<tbody>
{% for snapshot in snapshots %}
{% if snapshot.description != "current" %}
<tr>
<td>
{{ snapshot.number }}
{% if snapshot.is_default %}
<span class="label label-primary">
{% trans "active" %}
</span>
{% endif %}
</td>
<td>{{ snapshot.date }}</td>
<td>{{ snapshot.description }}</td>
<td>
<a href="{% url 'snapshot:rollback' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Rollback to snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-repeat"
aria-hidden="true"></span>
</a>
</td>
<td>
{% if not snapshot.is_default %}
<a href="{% url 'snapshot:delete' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Delete snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-trash"
aria-hidden="true"></span>
</a>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,103 @@
{% extends "simple_service.html" %}
{% comment %}
#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
{% endcomment %}
{% load bootstrap %}
{% load i18n %}
{% block configuration %}
<p>
<div class="row">
<form class="form" method="post">
{% csrf_token %}
<div class="col-xs-6 text-left">
<input type="submit" class="btn btn-primary" name="create"
value="{% trans 'Create Snapshot' %}"/>
</div>
</form>
<div class="col-xs-6 text-right">
<a title="{% trans 'Delete all the snapshots' %}"
role="button" class="btn btn-danger"
{% if not has_deletable_snapshots %}
disabled="disabled"
{% else %}
href="{% url 'snapshot:delete-all' %}"
{% endif %}>
{% trans 'Delete All' %}
</a>
</div>
</div>
</p>
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered table-condensed table-striped">
<thead>
<th>{% trans "Number" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Rollback" %}</th>
<th>{% trans "Delete" %}</th>
</thead>
<tbody>
{% for snapshot in snapshots %}
{% if snapshot.description != "current" %}
<tr>
<td>
{{ snapshot.number }}
{% if snapshot.is_default %}
<span class="label label-primary">
{% trans "active" %}
</span>
{% endif %}
</td>
<td>{{ snapshot.date }}</td>
<td>{{ snapshot.description }}</td>
<td>
<a href="{% url 'snapshot:rollback' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Rollback to snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-repeat"
aria-hidden="true"></span>
</a>
</td>
<td>
{% if not snapshot.is_default %}
<a href="{% url 'snapshot:delete' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Delete snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-trash"
aria-hidden="true"></span>
</a>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

View File

@ -24,6 +24,7 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^sys/snapshot/$', views.index, name='index'), url(r'^sys/snapshot/$', views.index, name='index'),
url(r'^sys/snapshot/manage/$', views.manage, name='manage'),
url(r'^sys/snapshot/(?P<number>\d+)/delete$', views.delete, name='delete'), url(r'^sys/snapshot/(?P<number>\d+)/delete$', views.delete, name='delete'),
url(r'^sys/snapshot/all/delete$', views.delete_all, name='delete-all'), url(r'^sys/snapshot/all/delete$', views.delete_all, name='delete-all'),
url(r'^sys/snapshot/(?P<number>\d+)/rollback$', views.rollback, url(r'^sys/snapshot/(?P<number>\d+)/rollback$', views.rollback,

View File

@ -23,26 +23,28 @@ import json
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.urls import reverse from django.urls import reverse, reverse_lazy
from django.utils.translation import ugettext as _
from plinth import actions from plinth import actions
from plinth.errors import ActionError from plinth.errors import ActionError
from plinth.modules import snapshot as snapshot_module from plinth.modules import snapshot as snapshot_module
from plinth.utils import yes_or_no from plinth.utils import yes_or_no
from django.utils.translation import ugettext as _, ugettext_lazy
from . import get_configuration from . import get_configuration
from .forms import SnapshotForm from .forms import SnapshotForm
subsubmenu = [{'url': reverse_lazy('snapshot:index'),
'text': ugettext_lazy('Configure')},
{'url': reverse_lazy('snapshot:manage'),
'text': ugettext_lazy('Manage Snapshots')}]
def index(request): def index(request):
"""Show snapshot list.""" """Show snapshot list."""
status = get_configuration() status = get_configuration()
if request.method == 'POST': if request.method == 'POST':
form = SnapshotForm(request.POST) form = SnapshotForm(request.POST)
if 'create' in request.POST:
actions.superuser_run('snapshot', ['create'])
messages.success(request, _('Created snapshot.'))
if 'update' in request.POST and form.is_valid(): if 'update' in request.POST and form.is_valid():
update_configuration(request, status, form.cleaned_data) update_configuration(request, status, form.cleaned_data)
status = get_configuration() status = get_configuration()
@ -50,18 +52,32 @@ def index(request):
else: else:
form = SnapshotForm(initial=status) form = SnapshotForm(initial=status)
return TemplateResponse(
request, 'snapshot.html', {
'title': snapshot_module.name,
'description': snapshot_module.description,
'subsubmenu': subsubmenu,
'form': form
})
def manage(request):
"""Show snapshot list."""
if request.method == 'POST':
if 'create' in request.POST:
actions.superuser_run('snapshot', ['create'])
messages.success(request, _('Created snapshot.'))
output = actions.superuser_run('snapshot', ['list']) output = actions.superuser_run('snapshot', ['list'])
snapshots = json.loads(output) snapshots = json.loads(output)
has_deletable_snapshots = any( has_deletable_snapshots = any(
[snapshot for snapshot in snapshots[1:] if not snapshot['is_default']]) [snapshot for snapshot in snapshots[1:] if not snapshot['is_default']])
return TemplateResponse( return TemplateResponse(
request, 'snapshot.html', { request, 'snapshot_manage.html', {
'title': snapshot_module.name,
'description': snapshot_module.description,
'snapshots': snapshots, 'snapshots': snapshots,
'has_deletable_snapshots': has_deletable_snapshots, 'has_deletable_snapshots': has_deletable_snapshots,
'form': form 'subsubmenu': subsubmenu,
}) })
@ -108,7 +124,7 @@ def delete(request, number):
messages.success( messages.success(
request, request,
_('Deleted snapshot #{number}.').format(number=number)) _('Deleted snapshot #{number}.').format(number=number))
return redirect(reverse('snapshot:index')) return redirect(reverse('snapshot:manage'))
output = actions.superuser_run('snapshot', ['list']) output = actions.superuser_run('snapshot', ['list'])
snapshots = json.loads(output) snapshots = json.loads(output)
@ -125,7 +141,7 @@ def delete_all(request):
if request.method == 'POST': if request.method == 'POST':
actions.superuser_run('snapshot', ['delete-all']) actions.superuser_run('snapshot', ['delete-all'])
messages.success(request, _('Deleted all snapshots.')) messages.success(request, _('Deleted all snapshots.'))
return redirect(reverse('snapshot:index')) return redirect(reverse('snapshot:manage'))
output = actions.superuser_run('snapshot', ['list']) output = actions.superuser_run('snapshot', ['list'])
snapshots = json.loads(output) snapshots = json.loads(output)