mirror of
https://github.com/house-of-vanity/OutFleet.git
synced 2025-07-07 01:24:06 +00:00
WIP: reworking UI
This commit is contained in:
@ -1,93 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<title>{% block title %}Dashboard{% endblock %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='layout.css') }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}Dashboard{% endblock %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='layout.css') }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
.border {
|
||||
border: 0px solid black;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10px;
|
||||
}
|
||||
.form-field {
|
||||
margin: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<!-- Script to make the Menu link work -->
|
||||
<!-- Just stripped down version of the js/ui.js script for the side-menu layout -->
|
||||
<script>
|
||||
function getElements() {
|
||||
return {
|
||||
menu: document.getElementById('nav'),
|
||||
menuLink: document.getElementById('menuLink')
|
||||
};
|
||||
}
|
||||
|
||||
function toggleClass(element, className) {
|
||||
var classes = element.className.split(/\s+/);
|
||||
var length = classes.length;
|
||||
var i = 0;
|
||||
|
||||
for (; i < length; i++) {
|
||||
if (classes[i] === className) {
|
||||
classes.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The className is not found
|
||||
if (length === classes.length) {
|
||||
classes.push(className);
|
||||
}
|
||||
|
||||
element.className = classes.join(' ');
|
||||
}
|
||||
|
||||
function toggleMenu() {
|
||||
var active = 'active';
|
||||
var elements = getElements();
|
||||
|
||||
toggleClass(elements.menu, active);
|
||||
}
|
||||
|
||||
function handleEvent(e) {
|
||||
var elements = getElements();
|
||||
|
||||
if (e.target.id === elements.menuLink.id) {
|
||||
toggleMenu();
|
||||
e.preventDefault();
|
||||
} else if (elements.menu.className.indexOf('active') !== -1) {
|
||||
toggleMenu();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.addEventListener('click', handleEvent);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="layout" class="content pure-g">
|
||||
<div id="nav" class="pure-u-1-3">
|
||||
<a href="#" id="menuLink" class="nav-menu-button">Menu</a>
|
||||
|
||||
<div class="nav-inner">
|
||||
<button onclick="location.href='/';" style="cursor:pointer;" class="primary-button pure-button">OutFleet v.{{ VERSION }}</button>
|
||||
|
||||
<div class="pure-menu custom-restricted-width">
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-item"><a href="/" class="pure-menu-link">Servers</a></li>
|
||||
<li class="pure-menu-item"><a href="/clients" class="pure-menu-link">Clients</a></li>
|
||||
<li class="pure-menu-item"><a href="/sync" class="pure-menu-link">Sync status</a></li>
|
||||
</ul>
|
||||
{{ VERSION }}
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-2-24 border">
|
||||
<div class="content">
|
||||
<div class="nav-inner">
|
||||
<button onclick="location.href='/';" style="cursor:pointer;" class="pure-button">OutFleet {{ VERSION
|
||||
}}</button>
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-item"><a href="/" class="pure-menu-link">Servers</a></li>
|
||||
<li class="pure-menu-item"><a href="/clients" class="pure-menu-link">Clients</a></li>
|
||||
<li class="pure-menu-item"><a href="/sync" class="pure-menu-link">Sync status</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-22-24 border">
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<!-- Script to make the Menu link work -->
|
||||
<!-- Just stripped down version of the js/ui.js script for the side-menu layout -->
|
||||
<script>
|
||||
function getElements() {
|
||||
return {
|
||||
menu: document.getElementById('nav'),
|
||||
menuLink: document.getElementById('menuLink')
|
||||
};
|
||||
}
|
||||
|
||||
function toggleClass(element, className) {
|
||||
var classes = element.className.split(/\s+/);
|
||||
var length = classes.length;
|
||||
var i = 0;
|
||||
|
||||
for (; i < length; i++) {
|
||||
if (classes[i] === className) {
|
||||
classes.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The className is not found
|
||||
if (length === classes.length) {
|
||||
classes.push(className);
|
||||
}
|
||||
|
||||
element.className = classes.join(' ');
|
||||
}
|
||||
|
||||
function toggleMenu() {
|
||||
var active = 'active';
|
||||
var elements = getElements();
|
||||
|
||||
toggleClass(elements.menu, active);
|
||||
}
|
||||
|
||||
function handleEvent(e) {
|
||||
var elements = getElements();
|
||||
|
||||
if (e.target.id === elements.menuLink.id) {
|
||||
toggleMenu();
|
||||
e.preventDefault();
|
||||
} else if (elements.menu.className.indexOf('active') !== -1) {
|
||||
toggleMenu();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.addEventListener('click', handleEvent);
|
||||
});
|
||||
</script>
|
||||
{% if nt %}
|
||||
<label>
|
||||
<input type="checkbox" class="alertCheckbox" autocomplete="off" />
|
||||
<div class="alert {% if nl == 'error' %}error{% else %}success{% endif %}">
|
||||
<span class="alertText">{{nt}}
|
||||
<br class="clear"/></span>
|
||||
</div>
|
||||
</label>
|
||||
{% endif %}
|
||||
{% if nt %}
|
||||
<label>
|
||||
<input type="checkbox" class="alertCheckbox" autocomplete="off" />
|
||||
<div class="alert {% if nl == 'error' %}error{% else %}success{% endif %}">
|
||||
<span class="alertText">{{nt}}
|
||||
<br class="clear" /></span>
|
||||
</div>
|
||||
</label>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
@ -2,173 +2,190 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="list" class="pure-u-1-3" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
|
||||
<div class="server-item pure-g">
|
||||
<div class="pure-u-3-24">
|
||||
<div class="server-item">
|
||||
<h1 class="server-content-title">Clients</h1>
|
||||
</div>
|
||||
<div onclick="location.href='/clients?add_client=True';" class="server-item server-add ">
|
||||
<div class="">
|
||||
+
|
||||
</div>
|
||||
</div>
|
||||
{% for client, values in CLIENTS.items() %}
|
||||
<div class="server-item server-item-{% if client == selected_client %}unread{% else %}selected{% endif %} pure-g">
|
||||
<div class="pure-u-3-4" onclick="location.href='/clients?selected_client={{ client }}';">
|
||||
<div onclick="location.href='/clients?selected_client={{ client }}';"
|
||||
class="server-item server-item-{% if client == selected_client %}unread{% else %}selected{% endif %} ">
|
||||
<div class="">
|
||||
<h5 class="server-name">{{ values["name"] }}</h5>
|
||||
<h4 class="server-info">Allowed {{ values["servers"]|length }} server{% if values["servers"]|length >1 %}s{%endif%}</h4>
|
||||
<h4 class="server-info">Allowed {{ values["servers"]|length }} server{% if values["servers"]|length >1
|
||||
%}s{%endif%}</h4>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div onclick="location.href='/clients?add_client=True';" class="server-item server-add pure-g">
|
||||
<div class="pure-u-1">
|
||||
+
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="pure-u-20-24">
|
||||
{% if add_client %}
|
||||
|
||||
{% if add_client %}
|
||||
<div class="pure-u-1-3">
|
||||
<div class="server-content-header pure-g">
|
||||
<div class="pure-u-1-2">
|
||||
<h1 class="server-content-title">Add new client</h1>
|
||||
</div>
|
||||
<div class="server-content-header">
|
||||
<div class="">
|
||||
<h1 class="server-content-title">Add new client</h1>
|
||||
</div>
|
||||
<div class="server-content-body">
|
||||
</div>
|
||||
<div class="server-content-body">
|
||||
<form action="/add_client" class="pure-form pure-form-stacked" method="POST">
|
||||
<fieldset>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-23-24" name="name" required placeholder="Name"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-23-24" name="comment" placeholder="Comment"/>
|
||||
</div>
|
||||
<div class="pure-checkbox">
|
||||
{% for server in SERVERS %}
|
||||
<label class="pure-checkbox" for="option{{loop.index0}}">{{server.info()["name"]}}
|
||||
<input type="checkbox" id="option{{loop.index0}}" name="servers" value="{{server.info()['local_server_id']}}"></label>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Add</button>
|
||||
<input type="text" class="form-field pure-u-8-24" name="name" required placeholder="Name" />
|
||||
<input type="text" class="form-field pure-u-8-24" name="comment" placeholder="Comment" />
|
||||
{% for server in SERVERS %}
|
||||
<label class="pure-checkbox" for="option{{loop.index0}}">
|
||||
<input type="checkbox" id="option{{loop.index0}}" name="servers"
|
||||
value="{{server.info()['local_server_id']}}">{{server.info()["name"]}}</label>
|
||||
{% endfor %}
|
||||
<button type="submit" class="pure-button pure-button-primary button">Add client</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if selected_client and not add_client %}
|
||||
{% if selected_client and not add_client %}
|
||||
{% set client = CLIENTS[selected_client] %}
|
||||
|
||||
<div class="pure-u-1-2">
|
||||
<div class="server-content-header pure-g">
|
||||
<div class="pure-u-1-2">
|
||||
<h1 class="server-content-title">{{client['name']}}</h1>
|
||||
<h4 class="server-info">{{ client['comment'] }}</h4>
|
||||
<h4 class="server-info">id {{ selected_client }}</h4>
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1">
|
||||
<div class="server-content-header">
|
||||
<div class="">
|
||||
<h1 class="server-content-title">{{client['name']}}</h1>
|
||||
<h4 class="server-info">{{ selected_client }}</h4>
|
||||
{% if client['comment'] != "" %}<h4 class="server-info">{{ client['comment'] }}</h4>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="server-content-body">
|
||||
<form action="/add_client" class="pure-form pure-form-stacked" method="POST">
|
||||
<fieldset>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-1" name="name" required value="{{client['name']}}"/>
|
||||
<input type="hidden" class="pure-u-1" name="old_name" required value="{{client['name']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-1" name="comment" value="{{client['comment']}}"/>
|
||||
</div>
|
||||
<input type="hidden" class="pure-u-1" name="user_id" value="{{selected_client}}"/>
|
||||
</div>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-6-24">
|
||||
|
||||
<div class="pure-checkbox">
|
||||
<p>Allow access to:</p>
|
||||
{% for server in SERVERS %}
|
||||
<label class="pure-checkbox" for="option{{loop.index0}}">{{server.info()["name"]}}{% if server.info()['local_server_id'] in client['servers'] %} ( Used {% for key in server.data["keys"] %}{% if key.name == client['name'] %}{{ (key.used_bytes if key.used_bytes else 0) | filesizeformat }}{% endif %}{% endfor %}){%endif%}
|
||||
<input
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}checked{%endif%}
|
||||
type="checkbox" id="option{{loop.index0}}" name="servers" value="{{server.info()['local_server_id']}}"></label>
|
||||
<div class="server-content-body">
|
||||
<form action="/add_client" class="pure-form pure-form-aligned" method="POST">
|
||||
<fieldset>
|
||||
|
||||
{% endfor %}
|
||||
<div class="">
|
||||
<input type="text" class="form-field" name="name" required value="{{client['name']}}" />
|
||||
<input type="hidden" class="form-field" name="old_name" required
|
||||
value="{{client['name']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<input type="text" class="form-field" name="comment" value="{{client['comment']}}" />
|
||||
</div>
|
||||
<input type="hidden" class="form-field" name="user_id" value="{{selected_client}}" />
|
||||
|
||||
</div>
|
||||
<div class="pure-checkbox">
|
||||
<p>Allow access to:</p>
|
||||
{% for server in SERVERS %}
|
||||
<label class="pure-checkbox" for="option{{loop.index0}}">
|
||||
<input {% if server.info()['local_server_id'] in client['servers'] %}checked{%endif%}
|
||||
type="checkbox" id="option{{loop.index0}}" name="servers"
|
||||
value="{{server.info()['local_server_id']}}">{{server.info()["name"]}}
|
||||
{% if server.info()['local_server_id'] in client['servers'] %} ( Used {% for key in
|
||||
server.data["keys"] %}{% if key.name == client['name'] %}{{ (key.used_bytes if
|
||||
key.used_bytes else 0) | filesizeformat }}{% endif %}{% endfor %}){%endif%}</label>
|
||||
|
||||
</div>
|
||||
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Save and apply</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endfor %}
|
||||
|
||||
<div>
|
||||
<h3>Invite text</h3><hr>
|
||||
<textarea style="width: 100%; rows=10">
|
||||
</div>
|
||||
<button type="submit" class="pure-button pure-button-primary button">Save and Apply</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form action="/del_client" class="pure-form pure-form-stacked" method="POST">
|
||||
<input type="hidden" name="name" required value="{{client['name']}}" />
|
||||
<input type="hidden" name="user_id" value="{{selected_client}}" />
|
||||
|
||||
<label for="really" class="pure-radio">
|
||||
<button type="submit" id="really"
|
||||
class="pure-button pure-button-primary delete-button button">Delete Client 🔒<input
|
||||
type="checkbox" id="agree" name="agree" required></button></label>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div style="" class="pure-u-18-24">
|
||||
<div class="pure-u-9-24">
|
||||
<div>
|
||||
<h3>Invite text</h3>
|
||||
|
||||
<textarea style="width: 96%; height: 360px; resize:none" disabled>
|
||||
Install OutLine VPN. Copy and paste below keys to OutLine client.
|
||||
Same keys will work simultaneously on many devices.
|
||||
{% for server in SERVERS -%}
|
||||
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}
|
||||
{{server.info()['name']}}
|
||||
```{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ dynamic_hostname }}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{% endfor %}```
|
||||
{% endif %}
|
||||
{%- endfor -%}</textarea>
|
||||
</div>
|
||||
<hr>
|
||||
<div style="padding-top: 15px; padding-bottom: 15px">
|
||||
<div class="pure-u-1">
|
||||
<h3>Dynamic Access Keys</h3>
|
||||
<table class="pure-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server</th>
|
||||
<th>Dynamic</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for server in SERVERS %}
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}
|
||||
<tr>
|
||||
<td>{{ server.info()['name'] }}</td>
|
||||
<td>
|
||||
<p style="font-size: 10pt">{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ dynamic_hostname }}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{% endfor %}</p>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1">
|
||||
<h3>SS Links</h3>
|
||||
<table class="pure-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server</th>
|
||||
<th>SSlink</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for server in SERVERS %}
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}
|
||||
<tr>
|
||||
<td>{{ server.info()['name'] }}</td>
|
||||
<td>
|
||||
<pre style="font-size: 10pt">{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}{{ key.access_url }}{% endif %}{% endfor %}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<form action="/del_client" class="pure-form pure-form-stacked" method="POST">
|
||||
<input type="hidden" class="pure-u-1" name="name" required value="{{client['name']}}"/>
|
||||
<input type="hidden" class="pure-u-1" name="user_id" value="{{selected_client}}"/>
|
||||
<button type="submit" class="pure-button button-error pure-input-1 ">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
```{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{
|
||||
dynamic_hostname
|
||||
}}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{%
|
||||
endfor %}```
|
||||
{% endif %}
|
||||
{%- endfor -%}
|
||||
</textarea>
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-14-24">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 content">
|
||||
<h3>Dynamic Access Keys</h3>
|
||||
<table class="pure-table" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server</th>
|
||||
<th>Dynamic</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for server in SERVERS %}
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}
|
||||
<tr>
|
||||
<td>{{ server.info()['name'] }}</td>
|
||||
<td style="font-size: 10pt">
|
||||
{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{
|
||||
dynamic_hostname
|
||||
}}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{%
|
||||
endif %}{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pure-u-1 content">
|
||||
<h3>SS Links</h3>
|
||||
<table class="pure-table" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server</th>
|
||||
<th>SSlink</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for server in SERVERS %}
|
||||
{% if server.info()['local_server_id'] in client['servers'] %}
|
||||
<tr>
|
||||
<td>{{ server.info()['name'] }}</td>
|
||||
<td style="font-size: 10pt">
|
||||
{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}{{
|
||||
key.access_url }}{% endif %}{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,150 +1,167 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="list" class="pure-u-1-3" xmlns="http://www.w3.org/1999/html">
|
||||
<div class="server-item pure-g">
|
||||
<h1 class="server-content-title">Servers</h1>
|
||||
</div>
|
||||
{% for server in SERVERS %}
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-4-24">
|
||||
<div class="server-item ">
|
||||
<h1 class="server-content-title">Servers</h1>
|
||||
</div>
|
||||
{% for server in SERVERS %}
|
||||
{% set list_ns = namespace(total_bytes=0) %}
|
||||
{% for key in server.data["keys"] %}
|
||||
{% if key.used_bytes %}
|
||||
{% set list_ns.total_bytes = list_ns.total_bytes + key.used_bytes %}
|
||||
{% endif %}
|
||||
{% if key.used_bytes %}
|
||||
{% set list_ns.total_bytes = list_ns.total_bytes + key.used_bytes %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div class="server-item server-item-{% if loop.index0 == selected_server|int %}unread{% else %}selected{% endif %} pure-g">
|
||||
<div class="pure-u-3-4" onclick="location.href='/?selected_server={{loop.index0}}';">
|
||||
<h5 class="server-name">{{ server.info()["name"] }}</h5>
|
||||
<h4 class="server-info">{{ '/'.join(server.info()["url"].split('/')[0:-1]) }}</h4>
|
||||
<h4 class="server-info">Port {{ server.info()["port_for_new_access_keys"] }}</h4>
|
||||
<h4 class="server-info">Hostname {{ server.info()["hostname_for_access_keys"] }}</h4>
|
||||
<h4 class="server-info">Traffic: {{ list_ns.total_bytes | filesizeformat }}</h4>
|
||||
<h4 class="server-info">v.{{ server.info()["version"] }}</h4>
|
||||
<p class="server-comment">
|
||||
{{ server.info()["comment"] }}
|
||||
</p>
|
||||
<div
|
||||
class="server-item server-item-{% if loop.index0 == selected_server|int %}unread{% else %}selected{% endif %} ">
|
||||
<div onclick="location.href='/?selected_server={{loop.index0}}';">
|
||||
<h5 class="server-name">{{ server.info()["name"] }}</h5>
|
||||
<h4 class="server-info">API {{ '/'.join(server.info()["url"].split('/')[0:-1]).split("://")[1] }}</h4>
|
||||
<h4 class="server-info">Client Port: {{ server.info()["port_for_new_access_keys"] }}</h4>
|
||||
<h4 class="server-info">Hostname: {{ server.info()["hostname_for_access_keys"] }}</h4>
|
||||
<h4 class="server-info">Traffic: {{ list_ns.total_bytes | filesizeformat }}</h4>
|
||||
<h4 class="server-info">Version: {{ server.info()["version"] }}</h4>
|
||||
<p class="server-comment">
|
||||
{{ server.info()["comment"] }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div onclick="location.href='/?add_server=True';" class="server-item server-add pure-g">
|
||||
<div class="pure-u-1">
|
||||
{% endfor %}
|
||||
<div onclick="location.href='/?add_server=True';" class="server-item server-add ">
|
||||
<div class="">
|
||||
+
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% if add_server %}
|
||||
<div class="pure-u-1-3">
|
||||
<div class="server-content-header pure-g">
|
||||
<div class="pure-u-1-2">
|
||||
<div class="pure-u-19-24">
|
||||
{% if add_server %}
|
||||
<div class="server-content-header">
|
||||
<div class="">
|
||||
<h1 class="server-content-title">Add new server</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="server-content-body">
|
||||
<form action="/add_server" class="pure-form pure-form-stacked" method="POST">
|
||||
<fieldset>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-23-24" name="url" placeholder="Server management URL"/>
|
||||
<form action="/add_server" class="pure-form pure-form-stacked" method="POST">
|
||||
<fieldset>
|
||||
<div class="">
|
||||
<div class="form-field">
|
||||
<input type="text" class="form-field" name="url" placeholder="Server management URL" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<input type="text" class="form-field" name="cert" placeholder="Certificate" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<input type="text" class="form-field" name="comment" placeholder="Comment" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text"class="pure-u-23-24" name="cert" placeholder="Certificate"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<input type="text" class="pure-u-23-24" name="comment" placeholder="Comment"/>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Add</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<button type="submit" class="pure-button pure-button-primary button">Add server</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if SERVERS|length != 0 and not add_server %}
|
||||
{% if SERVERS|length != 0 and not add_server %}
|
||||
|
||||
{% if selected_server is none %}
|
||||
{% set server = SERVERS[0] %}
|
||||
{% set server = SERVERS[0] %}
|
||||
{% else %}
|
||||
{% set server = SERVERS[selected_server|int] %}
|
||||
{% set server = SERVERS[selected_server|int] %}
|
||||
{% endif %}
|
||||
<div id="main" class="pure-u-1">
|
||||
<div class="server-content">
|
||||
<div class="server-content-header pure-g">
|
||||
<div class="pure-u-1-2">
|
||||
<h1 class="server-content-title">{{server.info()["name"]}}</h1>
|
||||
<p class="server-content-subtitle">
|
||||
<span>v.{{server.info()["version"]}} {{server.info()["local_server_id"]}}</span>
|
||||
</p>
|
||||
<div class="pure-u-19-24">
|
||||
<div class="">
|
||||
<div class="server-content">
|
||||
<div class="server-content-header ">
|
||||
<div class="">
|
||||
<h1 class="server-content-title">{{server.info()["name"]}}</h1>
|
||||
<p class="server-content-subtitle">
|
||||
<span>v.{{server.info()["version"]}} {{server.info()["local_server_id"]}}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% set ns = namespace(total_bytes=0) %}
|
||||
{% for key in SERVERS[selected_server|int].data["keys"] %}
|
||||
{% set ns = namespace(total_bytes=0) %}
|
||||
{% for key in SERVERS[selected_server|int].data["keys"] %}
|
||||
{% if key.used_bytes %}
|
||||
{% set ns.total_bytes = ns.total_bytes + key.used_bytes %}
|
||||
{% set ns.total_bytes = ns.total_bytes + key.used_bytes %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div class="server-content-body">
|
||||
<h3>Clients: {{ server.info()['keys']|length }}</h3>
|
||||
<h3>Total traffic: {{ ns.total_bytes | filesizeformat }}</h3>
|
||||
<form class="pure-form pure-form-stacked" method="POST">
|
||||
<fieldset>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="name">Server Name</br> Note that this will not be reflected on the devices of the users that you invited to connect to it.</label>
|
||||
<input type="text" id="name" class="pure-u-23-24" name="name" value="{{server.info()['name']}}"/>
|
||||
{% endfor %}
|
||||
<div class="server-content-body">
|
||||
<h3>Clients: {{ server.info()['keys']|length }}</h3>
|
||||
<h3>Total traffic: {{ ns.total_bytes | filesizeformat }}</h3>
|
||||
<form class="pure-form pure-form-aligned" method="POST">
|
||||
<fieldset>
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="name">Server Name</br>Must be unique. Used for Dynamic Link
|
||||
generation.</label>
|
||||
<input class="form-field" type="text" id="name" class="" name="name"
|
||||
value="{{server.info()['name']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<label for="comment">Comment</br>Will be used as "Server name" in client
|
||||
app.</label>
|
||||
<input class="form-field" type="text" id="comment" class="" name="comment"
|
||||
value="{{server.info()['comment']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<label for="port_for_new_access_keys">Port For New Access Keys</label>
|
||||
<input class="form-field" type="text" id="port_for_new_access_keys" class=""
|
||||
name="port_for_new_access_keys"
|
||||
value="{{server.info()['port_for_new_access_keys']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<label for="hostname_for_access_keys">Hostname For Access Keys</label>
|
||||
<input class="form-field" type="text" id="hostname_for_access_keys" class=""
|
||||
name="hostname_for_access_keys"
|
||||
value="{{server.info()['hostname_for_access_keys']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<label for="url">Server URL</label>
|
||||
<input class="form-field" type="text" readonly id="url" class="" name="url"
|
||||
value="{{server.info()['url']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
<label for="cert">Server Access Certificate</label>
|
||||
<input class="form-field" type="text" readonly id="cert" class="" name="cert"
|
||||
value="{{server.info()['cert']}}" />
|
||||
</div>
|
||||
<div class="">
|
||||
Created {{format_timestamp(server.info()['created_timestamp_ms']) }}
|
||||
</div>
|
||||
<input class="form-field" type="hidden" readonly id="server_id" class="" name="server_id"
|
||||
value="{{server.info()['local_server_id']}}" />
|
||||
</div>
|
||||
<p>Share anonymous metrics</p>
|
||||
<label for="metrics_enabled" class="pure-radio">
|
||||
<input type="radio" id="metrics_enabled" name="metrics" value="True" {% if
|
||||
server.info()['metrics_enabled']==True %}checked{% endif %} /> Enable
|
||||
</label>
|
||||
<label for="metrics_disabled" class="pure-radio">
|
||||
<input type="radio" id="metrics_disabled" name="metrics" value="False" {% if
|
||||
server.info()['metrics_enabled']==False %}checked{% endif %} /> Disable
|
||||
</label>
|
||||
<button type="submit" class="pure-button pure-button-primary button">Save and apply</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form action="/del_server" method="post">
|
||||
|
||||
<input type="hidden" id="really" value="{{ server.info()[" local_server_id"] }}">
|
||||
<label for="really" class="pure-radio">
|
||||
<button type="submit" class="pure-button pure-button-primary delete-button button">Delete
|
||||
Server 🔒<input type="checkbox" id="agree" name="agree" required></button></label>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="comment">Comment</br>This value will be used as "Server name" in client app.</label>
|
||||
<input type="text" id="comment" class="pure-u-23-24" name="comment" value="{{server.info()['comment']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="port_for_new_access_keys">Port For New Access Keys</label>
|
||||
<input type="text" id="port_for_new_access_keys" class="pure-u-23-24" name="port_for_new_access_keys" value="{{server.info()['port_for_new_access_keys']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="hostname_for_access_keys">Hostname For Access Keys</label>
|
||||
<input type="text" id="hostname_for_access_keys" class="pure-u-23-24" name="hostname_for_access_keys" value="{{server.info()['hostname_for_access_keys']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="url">Server URL</label>
|
||||
<input type="text" readonly id="url" class="pure-u-23-24" name="url" value="{{server.info()['url']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="cert">Server Access Certificate</label>
|
||||
<input type="text" readonly id="cert" class="pure-u-23-24" name="cert" value="{{server.info()['cert']}}"/>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-u-md-1-3">
|
||||
<label for="created_timestamp_ms">Created</label>
|
||||
<input type="text" readonly id="created_timestamp_ms" class="pure-u-23-24" name="created_timestamp_ms" value="{{format_timestamp(server.info()['created_timestamp_ms']) }}"/>
|
||||
</div>
|
||||
<input type="hidden" readonly id="server_id" class="pure-u-23-24" name="server_id" value="{{server.info()['local_server_id']}}"/>
|
||||
</div>
|
||||
<p>Share anonymous metrics</p>
|
||||
<label for="metrics_enabled" class="pure-radio">
|
||||
<input type="radio" id="metrics_enabled" name="metrics" value="True" {% if server.info()['metrics_enabled'] == True %}checked{% endif %} /> Enable
|
||||
</label>
|
||||
<label for="metrics_disabled" class="pure-radio">
|
||||
<input type="radio" id="metrics_disabled" name="metrics" value="False" {% if server.info()['metrics_enabled'] == False %}checked{% endif %} /> Disable
|
||||
</label>
|
||||
<button type="submit" class="pure-button pure-button-primary button">Save and apply</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form action="/del_server" method="post">
|
||||
<input type="hidden" name="local_server_id" value="{{ server.info()["local_server_id"] }}">
|
||||
<button type="submit" class="pure-button pure-button-primary delete-button button">Delete Server</button>
|
||||
<input type="checkbox" id="agree" name="agree" required>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,17 +1,32 @@
|
||||
<h1>Last sync log</h1>
|
||||
<form action="/sync" class="pure-form pure-form-stacked" method="POST">
|
||||
<p>Wipe ALL keys on ALL servers?</p>
|
||||
<label for="no_wipe" class="pure-radio">
|
||||
<input type="radio" id="no_wipe" name="wipe" value="no_wipe" checked /> No
|
||||
</label>
|
||||
<label for="do_wipe" class="pure-radio">
|
||||
<input type="radio" id="do_wipe" name="wipe" value="all" /> Yes
|
||||
</label>
|
||||
<button type="submit" class="pure-button button-error pure-input-1 ">Sync now</button>
|
||||
</form>
|
||||
{% extends "base.html" %}
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
|
||||
<!-- and it's easy to individually load additional languages -->
|
||||
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script> -->
|
||||
|
||||
<script>hljs.highlightAll();</script>
|
||||
|
||||
|
||||
<h1>Last logs</h1>
|
||||
<form action="/sync" class="pure-form pure-form-stacked" method="POST">
|
||||
<button type="submit" class="pure-button pure-button-primary button">Sync now</button>
|
||||
<p>Also wipe ALL keys on ALL servers? Use in case of inconsistency.</p>
|
||||
<label for="no_wipe" class="pure-radio">
|
||||
<input type="radio" id="no_wipe" name="wipe" value="no_wipe" checked /> No
|
||||
</label>
|
||||
<label for="do_wipe" class="pure-radio">
|
||||
<input type="radio" id="do_wipe" name="wipe" value="all" /> Yes
|
||||
</label>
|
||||
|
||||
</form>
|
||||
|
||||
<pre style="height: 600px; overflow: scroll;">
|
||||
<code class="language-c">
|
||||
{% for line in lines %}{{ line }}{% endfor %}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
{% endblock %}
|
Reference in New Issue
Block a user