Add cosmetic improvements

* Adds label for each action page.
* Adds a colored state for opengnsys connected clients
* Fix nav active item
* Rename some actions
* Adds DISK to partition and format form
multi-ogserver
Jose M. Guisado 2021-03-24 14:32:16 +01:00
parent 9ee0565ac4
commit 2ad382b5ed
16 changed files with 104 additions and 16 deletions

View File

@ -24,6 +24,7 @@ class PartitionForm(FlaskForm):
fs = SelectField(label=_('Filesystem'),
choices=[('EXT4', 'EXT4'),
('NTFS', 'NTFS'),
('DISK', 'Disk'),
('EMPTY', 'Empty')])
size = IntegerField(label=_('Size (KB)'))
format_partition = BooleanField(label=_('Format'))

View File

@ -0,0 +1,3 @@
.state--opg {
background-color: rgb(252, 222, 66);
}

View File

@ -3,8 +3,11 @@
{% block content %}
<h1 class="m-5">{{_('Client details')}}</h1>
{{ wtf.quick_form(form,
method='post',
button_map={'create': 'primary'}) }}
button_map={'create': 'primary'},
extra_classes="mx-5") }}
{% endblock %}

View File

@ -3,6 +3,10 @@
{% block content %}
<h1 class="m-5">{{_('Hardware inventory')}}</h1>
<h2 class="mb-3 mx-5">Selected client: {{ form.ips.data }}</h1>
<table class="table table-striped">
<thead class="thead-dark">
<tr>

View File

@ -3,9 +3,20 @@
{% block content %}
<h1 class="m-5">{{_('Create a partition image')}}</h1>
<h2 class="mx-5">Selected client: {{ form.ip.data }}</h1>
<ul class="list-group mx-5 list-group-horizontal-sm">
{% for ip in ip_list %}
<li class="list-group-item flex-fill list-group-item-info">{{ ip }}</li>
{% endfor %}
</ul>
{{ wtf.quick_form(form,
action=url_for('action_image_create'),
method='post',
button_map={'create': 'primary'}) }}
button_map={'create': 'primary'},
extra_classes='mx-5') }}
{% endblock %}

View File

@ -3,6 +3,16 @@
{% block content %}
{% set ip_list = form.ips.data.split(' ') %}
{% set ip_count = ip_list | length %}
<h1 class="m-5">Restore partition image to {{ip_count}} {%if ip_count > 1%}computers{% else %}computer{% endif %}</h1>
<ul class="list-group mx-5 list-group-horizontal-sm">
{% for ip in ip_list %}
<li class="list-group-item flex-fill list-group-item-info">{{ ip }}</li>
{% endfor %}
</ul>
{{ wtf.quick_form(form,
action=url_for('action_image_restore'),
method='post',

View File

@ -3,6 +3,16 @@
{% block content %}
{% set ip_list = form.ips.data.split(' ') %}
{% set ip_count = ip_list | length %}
<h1 class="m-5">Changing boot mode of {{ip_count}} {%if ip_count > 1%}computers{% else %}computer{% endif %}</h1>
<ul class="list-group mx-5 list-group-horizontal-sm">
{% for ip in ip_list %}
<li class="list-group-item flex-fill list-group-item-info">{{ ip }}</li>
{% endfor %}
</ul>
{{ wtf.quick_form(form,
action=url_for('action_mode'),
method='post',

View File

@ -3,9 +3,12 @@
{% block content %}
<h1 class="m-5">{{_('Start session')}}</h1>
{{ wtf.quick_form(form,
action=url_for('action_session'),
method='post',
button_map={'run': 'primary'}) }}
button_map={'run': 'primary'},
extra_classes='mx-5') }}
{% endblock %}

View File

@ -3,12 +3,14 @@
{% block content %}
<h1 class="m-5">{{_('Partition and Format')}}</h1>
{% for form in forms %}
{{ wtf.quick_form(form,
method='post',
form_type='inline',
extra_classes='m-2 p-2',
form_type='inline',
extra_classes='mx-5 pb-3',
button_map={'modify': 'primary',
'delete': 'danger'}) }}

View File

@ -3,9 +3,12 @@
{% block content %}
<h1 class="m-5">{{_('Software Inventory')}}</h1>
{{ wtf.quick_form(form,
action=url_for('action_software'),
method='post',
button_map={'view': 'primary', 'update': 'primary'}) }}
button_map={'view': 'primary', 'update': 'primary'},
extra_classes="mx-5")}}
{% endblock %}

View File

@ -3,6 +3,16 @@
{% block content %}
{% set ip_list = form.ips.data.split(' ') %}
{% set ip_count = ip_list | length %}
<h1 class="m-5">Powering on {{ip_count}} {%if ip_count > 1%}computers{% else %}computer{% endif %}</h1>
<ul class="list-group mx-5 list-group-horizontal-sm">
{% for ip in ip_list %}
<li class="list-group-item flex-fill list-group-item-info">{{ ip }}</li>
{% endfor %}
</ul>
{{ wtf.quick_form(form,
action=url_for('action_wol'),
method='post',

View File

@ -4,6 +4,7 @@
{% block head %}
<script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/soleta.css') }}" />
<script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script>
<title>{% block title %}{% endblock %} - OpenGnsys</title>
{% endblock %}
@ -32,7 +33,7 @@
{% block footer %}
<footer class="footer navbar-inverse bg-dark" role="contentinfo">
<div class="text-center text-secondary my-2 p-3">
<div class="text-center text-secondary mt-1 p-3">
Powered by
<a class="text-light" href="https://opengnsys.soleta.eu/">Soleta Networks</a>
</div>

View File

@ -0,0 +1,12 @@
{% extends 'base.html' %}
{% block content %}
<div class="m-4 w-25 card text-center">
<div class="card-header">
Connected clients (ogClient)
</div>
<div class="card-body">
<p class="card-text">{{ clients['clients'] | length }}</p>
</div>
</div>
{% endblock %}

View File

@ -6,11 +6,11 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<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>
</li>
{% if current_user.is_authenticated %}
<li class="nav-item">
<li class="nav-item {% if request.endpoint == "scopes" %}active{% endif %}">
<a class="nav-link" href="{{ url_for('scopes') }}">{{ _('Scopes') }}</a>
</li>
{% endif %}

View File

@ -1,10 +1,11 @@
{% extends 'base.html' %}
{% block nav_scopes %}active{% endblock %}
{% macro print_scopes_tree(scopes) -%}
<ul class="list-group list-group-flush mx-5">
{% for scope in scopes %}
<li class="list-group-item">
<li class="list-group-item state--{{ scope['state'] | lower }}">
<input class="form-check-input" type="checkbox"
value="{{ " ".join(scope["ip"]) }}"
name="{{ scope["name"] }}_{{ scope["id"] }}">
@ -32,9 +33,9 @@
{{ _('Actions') }}
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<input class="dropdown-item" type="submit" value="{{ _('Run') }}"
<input class="dropdown-item" type="submit" value="{{ _('Power on (WoL)') }}"
formaction="{{ url_for('action_wol') }}" formmethod="get">
<input class="dropdown-item" type="submit" value="{{ _('Poweroff') }}"
<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">
@ -44,13 +45,13 @@
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="{{ _('Sessions') }}"
<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="{{ _('Setup') }}"
<input class="dropdown-item" type="submit" value="{{ _('Partition & Format') }}"
formaction="{{ url_for('action_setup_show') }}" formmethod="get">
<input class="dropdown-item" type="submit" value="{{ _('Details') }}"
<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">

View File

@ -75,8 +75,16 @@ def get_client_setup(ip):
partition['code'] = PART_TYPE_CODES[partition['code']]
partition['filesystem'] = FS_CODES[partition['filesystem']]
return db_partitions
def get_clients(state_filter=None):
r = g.server.get('/clients')
clients = r.json()
if state_filter:
return filter(clients.items(), lambda c: c.state == state_filter)
return clients
def parse_scopes_from_tree(tree, scope_type):
scopes = []
for scope in tree['scope']:
@ -106,6 +114,10 @@ def server_error(error):
@app.route('/')
def index():
clients = None
if current_user.is_authenticated:
clients = get_clients()
return render_template('dashboard.html', clients=clients)
return render_template('base.html')
@app.route('/login', methods=['GET', 'POST'])
@ -196,8 +208,10 @@ def action_setup_show():
form.disk.data = db_part['disk']
form.partition.data = db_part['partition']
# XXX: Should separate whole disk form from partition setup form
if db_part['code'] in PART_SCHEME_CODES.values():
if db_part['filesystem'] == "DISK":
form.part_type.choices = list(PART_SCHEME_CODES.values())
form.fs.render_kw = {'disabled': ''}
form.part_type.data = db_part['code']
form.fs.data = db_part['filesystem']
form.size.data = db_part['size']