summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ogcp/static/css/soleta.css8
-rw-r--r--ogcp/templates/actions/mode.html3
-rw-r--r--ogcp/templates/base.html56
-rw-r--r--ogcp/templates/nav.html16
-rw-r--r--ogcp/templates/scopes.html88
-rw-r--r--ogcp/views.py48
6 files changed, 131 insertions, 88 deletions
diff --git a/ogcp/static/css/soleta.css b/ogcp/static/css/soleta.css
index d748f5b..ca49897 100644
--- a/ogcp/static/css/soleta.css
+++ b/ogcp/static/css/soleta.css
@@ -6,3 +6,11 @@ html, body {
width: 100%;
height: 100% !important;
}
+
+#sidebar .list-group-item {
+ background-color: transparent;
+}
+
+.toast {
+ margin: 10px;
+}
diff --git a/ogcp/templates/actions/mode.html b/ogcp/templates/actions/mode.html
index 0fd3266..3adce8f 100644
--- a/ogcp/templates/actions/mode.html
+++ b/ogcp/templates/actions/mode.html
@@ -1,4 +1,4 @@
-{% extends 'base.html' %}
+{% extends 'scopes.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
@@ -20,4 +20,3 @@
extra_classes="m-5") }}
{% endblock %}
-
diff --git a/ogcp/templates/base.html b/ogcp/templates/base.html
index 5fda82a..dca6205 100644
--- a/ogcp/templates/base.html
+++ b/ogcp/templates/base.html
@@ -17,24 +17,25 @@
<div class="main d-flex flex-column align-items-stretch h-100">
{% include 'nav.html' %}
{% block nav %}{% endblock %}
- {% block flash %}
- {% for category, message in get_flashed_messages(with_categories=True) %}
- {% if category == 'info' %}
- <div class="alert alert-info alert-dismissible fade show m-1" role="alert">
- {% elif category == 'error' %}
- <div class="alert alert-danger alert-dismissible fade show m-1" role="alert">
- {% else %}
- <div class="alert alert-warning alert-dismissible fade show m-1" role="alert">
- {% endif %}
- {{ message }}
- <button type="button" class="close" data-dismiss="alert" aria-label="{{ _('Close') }}">
- <span aria-hidden="true">&times;</span>
- </button>
+ <div class="container-fluid flex-grow-1">
+ {% block container %}
+ <div class="row h-100">
+ {# The sidebar is not visible on index #}
+ {% if request.endpoint != "index" %}
+ <div id="sidebar" class="bg-light col-md-3 col-lg-2">
+ {% block sidebar %}{% endblock %}
+ </div>
+ {% else %}
+ {% endif %}
+ <div id="content" class="col">
+ <div id="commands" class="py-2">{% block commands %}{% endblock %}</div>
+ <div class="container">
+ {% block content %}{% endblock %}
+ </div>
+ </div>
</div>
- {% endfor %}
- {% endblock %}
-
- <div id="content" class="container-fluid flex-grow-1">{% block content %}{% endblock %}</div>
+ {% endblock %}
+ </div>
{% block footer %}
<footer class="footer navbar-inverse bg-dark flex-shrink-0" role="contentinfo">
@@ -52,5 +53,26 @@
<script src="{{ url_for('static', filename='AdminLTE/plugins/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<!-- AdminLTE App -->
<script src="{{ url_for('static', filename='AdminLTE/dist/js/adminlte.min.js') }}"></script>
+
+ <script>
+ // error messages
+ {% for category, message in get_flashed_messages(with_categories=True) %}
+ let bgclass = 'bg-success';
+ {% if category == 'info' %}
+ bgclass = 'bg-info';
+ {% elif category == 'error' %}
+ bgclass = 'bg-danger';
+ {% else %}
+ bgclass = 'bg-warning';
+ {% endif %}
+ $(document).Toasts('create', {
+ class: bgclass,
+ position: 'topLeft',
+ autohide: true,
+ delay: 5000,
+ title: '{{ message }}',
+ })
+ {% endfor %}
+ </script>
</body>
</html>
diff --git a/ogcp/templates/nav.html b/ogcp/templates/nav.html
index 39b0ac2..f2ca3b5 100644
--- a/ogcp/templates/nav.html
+++ b/ogcp/templates/nav.html
@@ -6,13 +6,25 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
+ {% if current_user.is_authenticated %}
<li class="nav-item {% if request.endpoint == "index" %}active{% endif %}">
- <a class="nav-link" href="{{ url_for('index') }}">{{ _('Home') }}<span class="sr-only">(current)</span></a>
+ <a class="nav-link" href="{{ url_for('index') }}">{{ _('Dashboard') }}<span class="sr-only">(current)</span></a>
</li>
- {% if current_user.is_authenticated %}
<li class="nav-item {% if request.endpoint == "scopes" %}active{% endif %}">
<a class="nav-link" href="{{ url_for('scopes') }}">{{ _('Scopes') }}</a>
</li>
+ <li class="nav-item {% if request.endpoint == "commands" %}active{% endif %}">
+ <a class="nav-link" href="#">{{ _('Commands') }}</a>
+ </li>
+ <li class="nav-item {% if request.endpoint == "images" %}active{% endif %}">
+ <a class="nav-link" href="#">{{ _('Images') }}</a>
+ </li>
+ <li class="nav-item {% if request.endpoint == "tasks" %}active{% endif %}">
+ <a class="nav-link" href="#">{{ _('Tasks') }}</a>
+ </li>
+ <li class="nav-item {% if request.endpoint == "schedule" %}active{% endif %}">
+ <a class="nav-link" href="#">{{ _('Schedule') }}</a>
+ </li>
{% endif %}
</ul>
diff --git a/ogcp/templates/scopes.html b/ogcp/templates/scopes.html
index 3cb84fd..00f6883 100644
--- a/ogcp/templates/scopes.html
+++ b/ogcp/templates/scopes.html
@@ -3,10 +3,10 @@
{% macro print_scopes_tree(scopes) -%}
- <ul class="list-group list-group-flush mx-5">
+ <ul class="list-group list-group-flush">
{% for scope in scopes %}
<li class="list-group-item state--{{ scope['state'] | lower }}">
- <input class="form-check-input" type="checkbox"
+ <input class="form-check-input" type="checkbox" form="scopesForm"
value="{{ " ".join(scope["ip"]) }}"
name="{{ scope["name"] }}_{{ scope["id"] }}">
{{ scope["name"] }}
@@ -20,51 +20,47 @@
{% endmacro %}
-{% block content %}
+{% block container %}
+ <form id="scopesForm">
+ <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
+ </form>
+ {{ super() }}
+</form>
+{% endblock %}
-<form>
- <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
+{% block sidebar %}
{{ print_scopes_tree(scopes["scope"]) }}
+{% endblock %}
- <div class="dropdown mt-2">
- <button class="btn btn-primary dropdown-toggle" type="button"
- id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true"
- aria-expanded="false">
- {{ _('Actions') }}
- </button>
- <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
- <input class="dropdown-item" type="submit" value="{{ _('Power on (WoL)') }}"
- formaction="{{ url_for('action_wol') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Power off') }}"
- formaction="{{ url_for('action_poweroff') }}" formmethod="post">
- <input class="dropdown-item" type="submit" value="{{ _('Reboot') }}"
- formaction="{{ url_for('action_reboot') }}" formmethod="post">
- <input class="dropdown-item" type="submit" value="{{ _('Refresh') }}"
- formaction="{{ url_for('action_refresh') }}" formmethod="post">
- <input class="dropdown-item" type="submit" value="{{ _('Hardware') }}"
- formaction="{{ url_for('action_hardware') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Software') }}"
- formaction="{{ url_for('action_software') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Start session') }}"
- formaction="{{ url_for('action_session') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Restore Image') }}"
- formaction="{{ url_for('action_image_restore') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Partition & Format') }}"
- formaction="{{ url_for('action_setup_show') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Client details') }}"
- formaction="{{ url_for('action_client_info') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Add client') }}"
- formaction="{{ url_for('action_client_add') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Create image') }}"
- formaction="{{ url_for('action_image_create') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Set boot mode') }}"
- formaction="{{ url_for('action_mode') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Add room') }}"
- formaction="{{ url_for('action_room_add') }}" formmethod="get">
- <input class="dropdown-item" type="submit" value="{{ _('Delete room') }}"
- formaction="{{ url_for('action_room_delete') }}" formmethod="get">
- </div>
- </div>
-</form>
-
+{% block commands %}
+ <input class="btn btn-light" type="submit" value="{{ _('Power on (WoL)') }}"
+ form="scopesForm" formaction="{{ url_for('action_wol') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Power off') }}"
+ form="scopesForm" formaction="{{ url_for('action_poweroff') }}" formmethod="post">
+ <input class="btn btn-light" type="submit" value="{{ _('Reboot') }}"
+ form="scopesForm" formaction="{{ url_for('action_reboot') }}" formmethod="post">
+ <input class="btn btn-light" type="submit" value="{{ _('Refresh') }}"
+ form="scopesForm" formaction="{{ url_for('action_refresh') }}" formmethod="post">
+ <input class="btn btn-light" type="submit" value="{{ _('Hardware') }}"
+ form="scopesForm" formaction="{{ url_for('action_hardware') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Software') }}"
+ form="scopesForm" formaction="{{ url_for('action_software') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Start session') }}"
+ form="scopesForm" formaction="{{ url_for('action_session') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Restore Image') }}"
+ form="scopesForm" formaction="{{ url_for('action_image_restore') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Partition & Format') }}"
+ form="scopesForm" formaction="{{ url_for('action_setup_show') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Client details') }}"
+ form="scopesForm" formaction="{{ url_for('action_client_info') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Add client') }}"
+ form="scopesForm" formaction="{{ url_for('action_client_add') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Create image') }}"
+ form="scopesForm" formaction="{{ url_for('action_image_create') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Set boot mode') }}"
+ form="scopesForm" formaction="{{ url_for('action_mode') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Add room') }}"
+ form="scopesForm" formaction="{{ url_for('action_room_add') }}" formmethod="get">
+ <input class="btn btn-light" type="submit" value="{{ _('Delete room') }}"
+ form="scopesForm" formaction="{{ url_for('action_room_delete') }}" formmethod="get">
{% endblock %}
diff --git a/ogcp/views.py b/ogcp/views.py
index 9865e0f..5496daf 100644
--- a/ogcp/views.py
+++ b/ogcp/views.py
@@ -105,6 +105,30 @@ def parse_scopes_from_tree(tree, scope_type):
scopes += parse_scopes_from_tree(scope, scope_type)
return scopes
+def add_state_and_ips(scope, clients):
+ if 'ip' in scope:
+ filtered_client = filter(lambda x: x['addr']==scope['ip'], clients)
+ client = next(filtered_client, False)
+ if client:
+ scope['state'] = client['state']
+ else:
+ scope['state'] = 'OFF'
+ scope['ip'] = [scope['ip']]
+ else:
+ scope['ip'] = []
+ for child in scope['scope']:
+ scope['ip'] += add_state_and_ips(child, clients)
+ return scope['ip']
+
+def get_scopes():
+ r = g.server.get('/scopes')
+ scopes = r.json()
+ r = g.server.get('/clients')
+ clients = r.json()
+ add_state_and_ips(scopes, clients['clients'])
+
+ return scopes, clients
+
@login_manager.user_loader
def load_user(user_id):
if user_id == 1:
@@ -167,26 +191,7 @@ def logout():
@app.route('/scopes/')
@login_required
def scopes():
- def add_state_and_ips(scope, clients):
- if 'ip' in scope:
- filtered_client = filter(lambda x: x['addr']==scope['ip'], clients)
- client = next(filtered_client, False)
- if client:
- scope['state'] = client['state']
- else:
- scope['state'] = 'OFF'
- scope['ip'] = [scope['ip']]
- else:
- scope['ip'] = []
- for child in scope['scope']:
- scope['ip'] += add_state_and_ips(child, clients)
- return scope['ip']
-
- r = g.server.get('/scopes')
- scopes = r.json()
- r = g.server.get('/clients')
- clients = r.json()
- add_state_and_ips(scopes, clients['clients'])
+ scopes, clients = get_scopes()
return render_template('scopes.html', scopes=scopes, clients=clients)
@app.route('/action/poweroff', methods=['POST'])
@@ -585,7 +590,8 @@ def action_mode():
return redirect(url_for("scopes"))
form.ok.render_kw = { 'formaction': url_for('action_mode') }
- return render_template('actions/mode.html', form=form)
+ scopes, clients = get_scopes()
+ return render_template('actions/mode.html', form=form, scopes=scopes, clients=clients)
@app.route('/action/image/create', methods=['GET', 'POST'])