summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel GarcĂ­a Moreno <danigm@soleta.eu>2021-06-30 12:40:22 +0200
committerOpenGnSys Support Team <soporte-og@soleta.eu>2021-06-30 17:19:55 +0200
commit42dc44323e4cf0eaf0b563ba02f368942cf86e3d (patch)
tree807a055b475f7358317239017b38872294a39491
parent288654722d061591ac834ecf9fb2310280473323 (diff)
Add new partition button in setup action
This patch adds a way to add a new partition to the setup.html template. This button opens a modal dialog with a new form and calls a new endpoint to create the new partition (this endpoint does nothing, it's needed to be implemented in the future). I've followed the initial design for this template, with one form per each partition, so every button will call a function and reload the page. It's possible to do all actions at once, but that will require a rework of this, to do that we can just define an unique form in the whole html, remove all the "Modify" buttons and add just one "Apply" button at the end. But maybe that option is a lot complex in the backend because will require to validate all the changes at once. This patch also improves the setup.html form without using flask-bootstrap and rendering the form in the template directly with the bootstrap4 classes.
-rw-r--r--ogcp/forms/action_forms.py16
-rw-r--r--ogcp/templates/actions/setup.html81
-rw-r--r--ogcp/templates/base.html2
-rw-r--r--ogcp/views.py34
4 files changed, 119 insertions, 14 deletions
diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py
index 159c55a..0404e71 100644
--- a/ogcp/forms/action_forms.py
+++ b/ogcp/forms/action_forms.py
@@ -38,6 +38,22 @@ class PartitionForm(FlaskForm):
modify = SubmitField(label=_('Modify'))
delete = SubmitField(label=_('Delete'))
+
+class NewPartitionForm(FlaskForm):
+ ips = HiddenField()
+ part_type = SelectField(label=_('Type'),
+ choices=[('LINUX', 'Linux'),
+ ('NTFS', 'NTFS'),
+ ('EMPTY', 'Empty')])
+ fs = SelectField(label=_('Filesystem'),
+ choices=[('EXT4', 'EXT4'),
+ ('NTFS', 'NTFS'),
+ ('DISK', 'Disk'),
+ ('EMPTY', 'Empty')])
+ size = IntegerField(label=_('Size (KB)'))
+ create = SubmitField(label=_('Create'))
+
+
class HardwareForm(FlaskForm):
ips = HiddenField()
refresh = SubmitField(label=_('Refresh'))
diff --git a/ogcp/templates/actions/setup.html b/ogcp/templates/actions/setup.html
index 0dcd4c7..6856ed1 100644
--- a/ogcp/templates/actions/setup.html
+++ b/ogcp/templates/actions/setup.html
@@ -1,19 +1,82 @@
{% extends 'commands.html' %}
-{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<h1 class="m-5">{{_('Partition and Format')}}</h1>
-{% for form in forms %}
+<table class="table">
+ <thead class="text-center">
+ <tr>
+ <th>Type</th>
+ <th>Filesytem</th>
+ <th>Size (KB)</th>
+ <th>Format?</th>
+ <th colspan="2"></th>
+ </tr>
+ </thead>
-{{ wtf.quick_form(form,
- method='post',
- form_type='inline',
- extra_classes='mx-5 pb-3',
- button_map={'modify': 'primary',
- 'delete': 'danger'}) }}
+ <tbody>
+ {% for form in forms %}
+ <form class="form-inline" method="POST">
+ <tr>
+ {{ form.hidden_tag() }}
+ <td>{{ form.part_type(class_="form-control") }}</td>
+ <td>{{ form.fs(class_="form-control") }}</td>
+ <td>{{ form.size(class_="form-control") }}</td>
+ <td>{{ form.format_partition(class_="form-control") }}</td>
+ <td>{{ form.modify(class_="form-control btn-primary") }}</td>
+ <td>{{ form.delete(class_="form-control btn-danger") }}</td>
+ </tr>
+ </form>
+ {% endfor %}
+ </tbody>
+</table>
-{% endfor %}
+<button class="btn btn-primary" data-toggle="modal" data-target="#newPartitionModal">
+ {{ _('Add a new Partition') }}
+</button>
+
+<!-- Modal -->
+<div class="modal fade" id="newPartitionModal" tabindex="-1" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form class="form" method="POST">
+ <div class="modal-header">
+ <h5 class="modal-title" id="exampleModalLabel">{{ _('Create a new partition') }}</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ {{ new_partition_form.hidden_tag() }}
+
+ <div class="form-group">
+ <label for="{{ new_partition_form.part_type.id }}">{{ new_partition_form.part_type.label }}</label>
+ {{ new_partition_form.part_type(class_="form-control") }}
+ </div>
+ <div class="form-group">
+ <label for="{{ new_partition_form.fs.id }}">{{ new_partition_form.fs.label }}</label>
+ {{ new_partition_form.fs(class_="form-control") }}
+ </div>
+ <div class="form-group">
+ <label for="{{ new_partition_form.size.id }}">{{ new_partition_form.size.label }}</label>
+ {% if new_partition_form.size.errors %}
+ {{ new_partition_form.size(class_="form-control is-invalid") }}
+ {% else %}
+ {{ new_partition_form.size(class_="form-control") }}
+ {% endif %}
+ {% for error in new_partition_form.size.errors %}
+ <div class="invalid-feedback">{{ error }}</div>
+ {% endfor %}
+ </div>
+ </div>
+ <div class="modal-footer">
+ {{ new_partition_form.create(class_="btn btn-primary") }}
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
{% endblock %}
diff --git a/ogcp/templates/base.html b/ogcp/templates/base.html
index 022801f..68e2e64 100644
--- a/ogcp/templates/base.html
+++ b/ogcp/templates/base.html
@@ -56,6 +56,8 @@
<!-- ChartJS -->
<script src="{{ url_for('static', filename='AdminLTE/plugins/chart.js/Chart.min.js') }}"></script>
+ <script src="{{ url_for('static', filename='js/ogcp.js') }}"></script>
+
<script>
// error messages
{% for category, message in get_flashed_messages(with_categories=True) %}
diff --git a/ogcp/views.py b/ogcp/views.py
index c4b8afe..0505f66 100644
--- a/ogcp/views.py
+++ b/ogcp/views.py
@@ -9,9 +9,9 @@ from flask import (
g, render_template, url_for, flash, redirect, request, jsonify, make_response
)
from ogcp.forms.action_forms import (
- WOLForm, PartitionForm, ClientDetailsForm, HardwareForm, SessionForm,
- ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm, RoomForm,
- DeleteRoomForm
+ WOLForm, PartitionForm, NewPartitionForm, ClientDetailsForm, HardwareForm,
+ SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm,
+ RoomForm, DeleteRoomForm
)
from flask_login import (
current_user, LoginManager,
@@ -226,12 +226,19 @@ def action_wol():
@app.route('/action/setup', methods=['GET'])
@login_required
-def action_setup_show():
- ips = parse_ips(request.args.to_dict())
+def action_setup_show(ips=None, new_partition_form=None):
+ if not ips:
+ ips = parse_ips(request.args.to_dict())
+
db_partitions = get_client_setup(ips)
forms = [PartitionForm() for _ in db_partitions]
forms = list(forms)
+ if not new_partition_form:
+ new_partition_form = NewPartitionForm()
+ new_partition_form.ips.data = " ".join(ips)
+ new_partition_form.create.render_kw = {"formaction": url_for('action_setup_create')}
+
for form, db_part in zip(forms, db_partitions):
form.ips.data = " ".join(ips)
form.disk.data = db_part['disk']
@@ -249,8 +256,25 @@ def action_setup_show():
scopes, _clients = get_scopes(ips)
return render_template('actions/setup.html',
forms=forms,
+ new_partition_form=new_partition_form,
scopes=scopes)
+@app.route('/action/setup/create', methods=['POST'])
+@login_required
+def action_setup_create():
+ form = NewPartitionForm(request.form)
+ ips = form.ips.data.split(' ')
+
+ if form.validate():
+ # TODO: create the real partition
+ flash(_('Partition created successfully'), category='info')
+ return redirect(url_for('action_setup_show', ips=ips))
+
+ flash(_('Invalid partition configuration'), category='error')
+ # This return will maintain the new partition form state, but will break
+ # the F5 behavior in the browser
+ return action_setup_show(ips, form)
+
@app.route('/action/setup/modify', methods=['POST'])
@login_required
def action_setup_modify():