summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose M. Guisado <jguisado@soleta.eu>2022-01-27 16:51:35 +0100
committerJose M. Guisado <jguisado@soleta.eu>2022-01-27 16:51:35 +0100
commit31b1e920772ce6dd56f3f56b5a882c2f71333c13 (patch)
treeacd9cab08f7a7fb5691828be7394d3fbf0c76855
parentb566528012aabfc435f82525d84471ab7bbcff74 (diff)
Add confirmation page when deleting image
User can confirm when deleting an image by double checking the information displayed on this page. Adds a new optional field in GenericForm: 'ids'. Used when dealing with ids instead of ips.
-rw-r--r--ogcp/forms/action_forms.py1
-rw-r--r--ogcp/templates/actions/delete_image.html20
-rw-r--r--ogcp/templates/images.html2
-rw-r--r--ogcp/translations/es/LC_MESSAGES/messages.po110
-rw-r--r--ogcp/views.py36
5 files changed, 106 insertions, 63 deletions
diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py
index 09197d5..a2cac37 100644
--- a/ogcp/forms/action_forms.py
+++ b/ogcp/forms/action_forms.py
@@ -17,6 +17,7 @@ from flask_babel import _
class GenericForm(FlaskForm):
ips = HiddenField()
+ ids = HiddenField()
submit = SubmitField(label=_l('Submit'))
diff --git a/ogcp/templates/actions/delete_image.html b/ogcp/templates/actions/delete_image.html
new file mode 100644
index 0000000..608375f
--- /dev/null
+++ b/ogcp/templates/actions/delete_image.html
@@ -0,0 +1,20 @@
+{% extends 'images.html' %}
+{% import "bootstrap/wtf.html" as wtf %}
+
+{% block content %}
+
+{{ args }}
+
+<h1 class="m-5">
+ {{ _('Delete image %(image_name)s', image_name=image_name) }}
+</h1>
+
+{{ wtf.quick_form(form,
+ action=url_for('action_image_delete'),
+ method='post',
+ button_map={'submit': 'primary'},
+ extra_classes="mx-5") }}
+
+{% endblock %}
+
+
diff --git a/ogcp/templates/images.html b/ogcp/templates/images.html
index e198e6c..2a67e58 100644
--- a/ogcp/templates/images.html
+++ b/ogcp/templates/images.html
@@ -28,6 +28,6 @@
<input class="btn btn-light" type="submit" value="{{ _('Image details') }}"
form="imagesForm" formaction="{{ url_for('action_image_info') }}" formmethod="get">
<input class="btn btn-light" type="submit" value="{{ _('Delete image') }}"
- form="imagesForm" formaction="{{ url_for('action_image_delete') }}" formmethod="post">
+ form="imagesForm" formaction="{{ url_for('action_image_delete') }}" formmethod="get">
{% endblock %}
diff --git a/ogcp/translations/es/LC_MESSAGES/messages.po b/ogcp/translations/es/LC_MESSAGES/messages.po
index 4918bdc..33f0e97 100644
--- a/ogcp/translations/es/LC_MESSAGES/messages.po
+++ b/ogcp/translations/es/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0.0\n"
"Report-Msgid-Bugs-To: opengnsys@soleta.eu\n"
-"POT-Creation-Date: 2022-01-20 13:33+0100\n"
+"POT-Creation-Date: 2022-01-27 15:17+0100\n"
"PO-Revision-Date: 2021-12-23 16:47+0100\n"
"Last-Translator: Soleta Networks <opengnsys@soleta.eu>\n"
"Language: es\n"
@@ -102,7 +102,7 @@ msgstr "ogServer: error al reiniciar cliente"
msgid "Client rebooted successfully"
msgstr "Cliente reiniciado con éxito"
-#: views.py:835 views.py:967
+#: views.py:835 views.py:968
msgid "OgServer replied with a non ok status code"
msgstr "OgServer respondió con un código de estado de error"
@@ -142,182 +142,186 @@ msgstr "El servidor respondió con el código de error al eliminar la sala."
msgid "Room deleted successfully"
msgstr "Sala eliminada con éxito"
-#: views.py:969
-msgid "Delete client request processed successfully"
-msgstr "Solicitud de eliminar cliente procesada con éxito"
+#: views.py:970
+msgid "Image deletion request sent successfully"
+msgstr "La imagen ha sido borrada"
-#: forms/action_forms.py:20 forms/action_forms.py:28 forms/action_forms.py:137
-#: forms/action_forms.py:142 forms/action_forms.py:151
-#: forms/action_forms.py:156
+#: views.py:977
+msgid "Please select one image to delete"
+msgstr "Solo puede seleccionar una imagen para borrar"
+
+#: forms/action_forms.py:21 forms/action_forms.py:29 forms/action_forms.py:138
+#: forms/action_forms.py:143 forms/action_forms.py:152
+#: forms/action_forms.py:157
msgid "Submit"
msgstr "Enviar"
-#: forms/action_forms.py:25 forms/action_forms.py:33 forms/action_forms.py:63
+#: forms/action_forms.py:26 forms/action_forms.py:34 forms/action_forms.py:64
#: templates/actions/hardware.html:14
msgid "Type"
msgstr "Tipo"
-#: forms/action_forms.py:31 forms/action_forms.py:76 forms/action_forms.py:87
+#: forms/action_forms.py:32 forms/action_forms.py:77 forms/action_forms.py:88
msgid "Partition"
msgstr "Partición"
-#: forms/action_forms.py:49
+#: forms/action_forms.py:50
msgid "Filesystem"
msgstr "Sistema de ficheros"
-#: forms/action_forms.py:57
+#: forms/action_forms.py:58
msgid "Size (KB)"
msgstr "Tamaño (KB)"
-#: forms/action_forms.py:58
+#: forms/action_forms.py:59
msgid "Format"
msgstr "Formatear"
-#: forms/action_forms.py:72 templates/commands.html:25
+#: forms/action_forms.py:73 templates/commands.html:25
msgid "Refresh"
msgstr "Actualizar"
-#: forms/action_forms.py:77
+#: forms/action_forms.py:78
msgid "View"
msgstr "Vista"
-#: forms/action_forms.py:78
+#: forms/action_forms.py:79
msgid "Update"
msgstr "Actualizar"
-#: forms/action_forms.py:82
+#: forms/action_forms.py:83
msgid "Session"
msgstr "Sesión"
-#: forms/action_forms.py:83
+#: forms/action_forms.py:84
msgid "Run"
msgstr "Lanzar"
-#: forms/action_forms.py:88
+#: forms/action_forms.py:89
msgid "Image"
msgstr "Imagen"
-#: forms/action_forms.py:89
+#: forms/action_forms.py:90
msgid "Method"
msgstr "Método"
-#: forms/action_forms.py:91
+#: forms/action_forms.py:92
msgid "Restore"
msgstr "Restaurar"
-#: forms/action_forms.py:94 forms/action_forms.py:160
+#: forms/action_forms.py:95 forms/action_forms.py:161
msgid "Name"
msgstr "Nombre"
-#: forms/action_forms.py:95
+#: forms/action_forms.py:96
msgid "IP"
msgstr "IP"
-#: forms/action_forms.py:96
+#: forms/action_forms.py:97
msgid "MAC"
msgstr "MAC"
-#: forms/action_forms.py:97
+#: forms/action_forms.py:98
msgid "Serial Number"
msgstr "Número de serie"
-#: forms/action_forms.py:98 forms/action_forms.py:149
+#: forms/action_forms.py:99 forms/action_forms.py:150
msgid "Netmask"
msgstr "Máscara de red"
-#: forms/action_forms.py:99 forms/action_forms.py:122
+#: forms/action_forms.py:100 forms/action_forms.py:123
msgid "ogLive"
msgstr "ogLive"
-#: forms/action_forms.py:101
+#: forms/action_forms.py:102
msgid "Remote"
msgstr "Remoto"
-#: forms/action_forms.py:102
+#: forms/action_forms.py:103
msgid "Maintenance"
msgstr "Mantenimiento"
-#: forms/action_forms.py:103
+#: forms/action_forms.py:104
msgid "Interface"
msgstr "Interfaz"
-#: forms/action_forms.py:107
+#: forms/action_forms.py:108
msgid "Driver"
msgstr "Controlador"
-#: forms/action_forms.py:109
+#: forms/action_forms.py:110
msgid "Repository"
msgstr "Repositorio"
-#: forms/action_forms.py:111 forms/action_forms.py:154
+#: forms/action_forms.py:112 forms/action_forms.py:155
msgid "Room"
msgstr "Sala"
-#: forms/action_forms.py:112
+#: forms/action_forms.py:113
msgid "Boot Mode"
msgstr "Modo de arranque"
-#: forms/action_forms.py:113 forms/action_forms.py:131
+#: forms/action_forms.py:114 forms/action_forms.py:132
msgid "Create"
msgstr "Crear"
-#: forms/action_forms.py:117
+#: forms/action_forms.py:118
msgid "Boot mode"
msgstr "Modo de arranque"
-#: forms/action_forms.py:118 forms/action_forms.py:123
+#: forms/action_forms.py:119 forms/action_forms.py:124
msgid "Ok"
msgstr "OK"
-#: forms/action_forms.py:127
+#: forms/action_forms.py:128
msgid "OS"
msgstr "SO"
-#: forms/action_forms.py:128
+#: forms/action_forms.py:129
msgid "Image name"
msgstr "Nombre de la imagen"
-#: forms/action_forms.py:130
+#: forms/action_forms.py:131
msgid "Description"
msgstr "Descripción"
-#: forms/action_forms.py:134
+#: forms/action_forms.py:135
msgid "Center name"
msgstr "Nombre del centro"
-#: forms/action_forms.py:136
+#: forms/action_forms.py:137
msgid "Comment"
msgstr "Comentario"
-#: forms/action_forms.py:140 forms/action_forms.py:145
+#: forms/action_forms.py:141 forms/action_forms.py:146
msgid "Center"
msgstr "Centro"
-#: forms/action_forms.py:147
+#: forms/action_forms.py:148
msgid "Room name"
msgstr "Nombre de la sala"
-#: forms/action_forms.py:159
+#: forms/action_forms.py:160
msgid "Id"
msgstr "Id"
-#: forms/action_forms.py:161
+#: forms/action_forms.py:162
msgid "Size (GiB)"
msgstr "Tamaño (GiB)"
-#: forms/action_forms.py:162
+#: forms/action_forms.py:163
msgid "Datasize (GiB)"
msgstr "Tamaño de los datos (GiB)"
-#: forms/action_forms.py:163
+#: forms/action_forms.py:164
msgid "Modified"
msgstr "Modificado"
-#: forms/action_forms.py:164
+#: forms/action_forms.py:165
msgid "Permissions"
msgstr "Permisos"
-#: forms/action_forms.py:165
+#: forms/action_forms.py:166
msgid "Software id"
msgstr "ID de software"
@@ -506,6 +510,11 @@ msgstr "Formulario para eliminar un centro"
msgid "Delete %(ip_count)d client(s)"
msgstr "Elimina %(ip_count)d cliente(s)"
+#: templates/actions/delete_image.html:9
+#, python-format
+msgid "Delete image %(image_name)s"
+msgstr "Borrar imagen %(image_name)s"
+
#: templates/actions/delete_room.html:6
msgid "Delete room form"
msgstr "Formulario para eliminar una sala"
@@ -559,4 +568,3 @@ msgstr "Inventario de software"
#: templates/actions/legacy/log.html:6
msgid "Client log"
msgstr "Registro de clientes"
-
diff --git a/ogcp/views.py b/ogcp/views.py
index 3c587d2..a5e9573 100644
--- a/ogcp/views.py
+++ b/ogcp/views.py
@@ -953,21 +953,35 @@ def action_image_info():
return render_template('actions/image_details.html', form=form)
-@app.route('/action/image/delete', methods=['POST'])
+@app.route('/action/image/delete', methods=['GET', 'POST'])
@login_required
def action_image_delete():
- ids = parse_elements(request.form.to_dict())
- if not validate_elements(ids, max_len=1):
+ form = GenericForm(request.form)
+ if request.method == 'POST':
+ ids = form.ids.data.split(' ')
+ if not validate_elements(ids, max_len=1):
+ return redirect(url_for('images'))
+ id = ids.pop()
+ payload = {'image': id}
+ r = g.server.post('/image/delete', payload)
+ if r.status_code != requests.codes.ok:
+ flash(_('OgServer replied with a non ok status code'), category='error')
+ else:
+ flash(_('Image deletion request sent successfully'), category='info')
return redirect(url_for('images'))
-
- id = ids.pop()
- payload = {'image': id}
- r = g.server.post('/image/delete', payload)
- if r.status_code != requests.codes.ok:
- flash(_('OgServer replied with a non ok status code'), category='error')
else:
- flash(_('Delete client request processed successfully'), category='info')
- return redirect(url_for('images'))
+ images = [(name, imgid) for name, imgid in request.args.to_dict().items() if name != "csrf_token"]
+ if not validate_elements(images, max_len=1):
+ return redirect(url_for('images'))
+ image_name, image_id = images[0]
+ r = g.server.get('/images')
+ form.ids.data = image_id
+ if not validate_elements(images, max_len=1):
+ flash(_('Please select one image to delete'), category='error')
+ return redirect(url_for('images'))
+ return render_template('actions/delete_image.html', form=form,
+ image_name=image_name.split('_', 1)[0], image_id=image_id,
+ images=r.json()['images'])
@app.route('/action/log', methods=['GET'])
@login_required