mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-06 16:00:28 +01:00
New darkmode theme
This commit is contained in:
parent
a053504bb8
commit
13b9d15d8f
20
src/api.py
20
src/api.py
@ -2,10 +2,15 @@ import ipaddress, subprocess, datetime, os, util
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
from util import *
|
from util import *
|
||||||
|
import configparser
|
||||||
|
|
||||||
notEnoughParameter = {"status": False, "reason": "Please provide all required parameters."}
|
notEnoughParameter = {"status": False, "reason": "Please provide all required parameters."}
|
||||||
good = {"status": True, "reason": ""}
|
good = {"status": True, "reason": ""}
|
||||||
|
|
||||||
|
def ret(status=True, reason="", data=""):
|
||||||
|
return {"status": status, "reason": reason, "data": data}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def togglePeerAccess(data, g):
|
def togglePeerAccess(data, g):
|
||||||
checkUnlock = g.cur.execute(f"SELECT * FROM {data['config']} WHERE id='{data['peerID']}'").fetchone()
|
checkUnlock = g.cur.execute(f"SELECT * FROM {data['config']} WHERE id='{data['peerID']}'").fetchone()
|
||||||
@ -70,7 +75,7 @@ class managePeer:
|
|||||||
})
|
})
|
||||||
return {"status": True, "reason": "", "data": chartData}
|
return {"status": True, "reason": "", "data": chartData}
|
||||||
|
|
||||||
class addConfiguration:
|
class manageConfiguration:
|
||||||
def AddressCheck(self, data):
|
def AddressCheck(self, data):
|
||||||
address = data['address']
|
address = data['address']
|
||||||
address = address.replace(" ", "")
|
address = address.replace(" ", "")
|
||||||
@ -165,4 +170,15 @@ class addConfiguration:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"status": False, "reason": "Can't delete peer", "data": str(e)}
|
return {"status": False, "reason": "Can't delete peer", "data": str(e)}
|
||||||
|
|
||||||
return good
|
return good
|
||||||
|
|
||||||
|
def getConfigurationInfo(self, configName, WG_CONF_PATH):
|
||||||
|
conf = configparser.ConfigParser(strict=False)
|
||||||
|
try:
|
||||||
|
with open(f'{WG_CONF_PATH}/{configName}.conf', 'r'):
|
||||||
|
conf.read(f'{WG_CONF_PATH}/{configName}.conf')
|
||||||
|
if not conf.has_section("Interface"):
|
||||||
|
return ret(status=False, reason="No [Interface] in configuration file")
|
||||||
|
return ret(data=dict(conf['Interface']))
|
||||||
|
except FileNotFoundError as err:
|
||||||
|
return ret(status=False, reason=str(err))
|
@ -3,6 +3,7 @@
|
|||||||
Under Apache-2.0 License
|
Under Apache-2.0 License
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from crypt import methods
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import configparser
|
import configparser
|
||||||
import hashlib
|
import hashlib
|
||||||
@ -1599,7 +1600,7 @@ def addConfigurationAddressCheck():
|
|||||||
returnData = {"status": True, "reason": ""}
|
returnData = {"status": True, "reason": ""}
|
||||||
required = ['address']
|
required = ['address']
|
||||||
if checkJSONAllParameter(required, data):
|
if checkJSONAllParameter(required, data):
|
||||||
returnData = api.addConfiguration.AddressCheck(api.addConfiguration, data)
|
returnData = api.manageConfiguration.AddressCheck(api.manageConfiguration, data)
|
||||||
else:
|
else:
|
||||||
return jsonify(api.notEnoughParameter)
|
return jsonify(api.notEnoughParameter)
|
||||||
return jsonify(returnData)
|
return jsonify(returnData)
|
||||||
@ -1610,7 +1611,7 @@ def addConfigurationPortCheck():
|
|||||||
returnData = {"status": True, "reason": ""}
|
returnData = {"status": True, "reason": ""}
|
||||||
required = ['port']
|
required = ['port']
|
||||||
if checkJSONAllParameter(required, data):
|
if checkJSONAllParameter(required, data):
|
||||||
returnData = api.addConfiguration.PortCheck(api.addConfiguration, data, get_conf_list())
|
returnData = api.manageConfiguration.PortCheck(api.manageConfiguration, data, get_conf_list())
|
||||||
else:
|
else:
|
||||||
return jsonify(api.notEnoughParameter)
|
return jsonify(api.notEnoughParameter)
|
||||||
return jsonify(returnData)
|
return jsonify(returnData)
|
||||||
@ -1621,7 +1622,7 @@ def addConfigurationNameCheck():
|
|||||||
returnData = {"status": True, "reason": ""}
|
returnData = {"status": True, "reason": ""}
|
||||||
required = ['name']
|
required = ['name']
|
||||||
if checkJSONAllParameter(required, data):
|
if checkJSONAllParameter(required, data):
|
||||||
returnData = api.addConfiguration.NameCheck(api.addConfiguration, data, get_conf_list())
|
returnData = api.manageConfiguration.NameCheck(api.manageConfiguration, data, get_conf_list())
|
||||||
else:
|
else:
|
||||||
return jsonify(api.notEnoughParameter)
|
return jsonify(api.notEnoughParameter)
|
||||||
return jsonify(returnData)
|
return jsonify(returnData)
|
||||||
@ -1641,36 +1642,40 @@ def addConfiguration():
|
|||||||
if i not in data.keys():
|
if i not in data.keys():
|
||||||
return jsonify(api.notEnoughParameter)
|
return jsonify(api.notEnoughParameter)
|
||||||
config = get_conf_list()
|
config = get_conf_list()
|
||||||
nameCheck = api.addConfiguration.NameCheck(api.addConfiguration, {"name": data['addConfigurationName']}, config)
|
nameCheck = api.manageConfiguration.NameCheck(api.manageConfiguration, {"name": data['addConfigurationName']}, config)
|
||||||
if not nameCheck['status']:
|
if not nameCheck['status']:
|
||||||
return nameCheck
|
return nameCheck
|
||||||
|
|
||||||
portCheck = api.addConfiguration.PortCheck(api.addConfiguration, {"port": data['addConfigurationListenPort']}, config)
|
portCheck = api.manageConfiguration.PortCheck(api.manageConfiguration, {"port": data['addConfigurationListenPort']}, config)
|
||||||
if not portCheck['status']:
|
if not portCheck['status']:
|
||||||
return portCheck
|
return portCheck
|
||||||
|
|
||||||
addressCheck = api.addConfiguration.AddressCheck(api.addConfiguration, {"address": data['addConfigurationAddress']})
|
addressCheck = api.manageConfiguration.AddressCheck(api.manageConfiguration, {"address": data['addConfigurationAddress']})
|
||||||
if not addressCheck['status']:
|
if not addressCheck['status']:
|
||||||
return addressCheck
|
return addressCheck
|
||||||
|
|
||||||
returnData = api.addConfiguration.addConfiguration(api.addConfiguration, data, config, WG_CONF_PATH)
|
returnData = api.manageConfiguration.addConfiguration(api.manageConfiguration, data, config, WG_CONF_PATH)
|
||||||
return jsonify(returnData)
|
return jsonify(returnData)
|
||||||
|
|
||||||
@app.route('/api/deleteConfiguration', methods=['POST'])
|
@app.route('/api/deleteConfiguration', methods=['POST'])
|
||||||
def deleteConfiguration():
|
def deleteConfiguration():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
returnData = {"status": True, "reason": "", "data":""}
|
|
||||||
required = ['name']
|
required = ['name']
|
||||||
if not checkJSONAllParameter(required, data):
|
if not checkJSONAllParameter(required, data):
|
||||||
return jsonify(api.notEnoughParameter)
|
return jsonify(api.notEnoughParameter)
|
||||||
|
returnData = api.manageConfiguration.deleteConfiguration(api.manageConfiguration, data, get_conf_list(), g, WG_CONF_PATH)
|
||||||
returnData = api.addConfiguration.deleteConfiguration(api.addConfiguration, data, get_conf_list(), g, WG_CONF_PATH)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return returnData
|
return returnData
|
||||||
|
|
||||||
|
@app.route('/api/getConfigurationInfo', methods=['GET'])
|
||||||
|
def getConfigurationInfo():
|
||||||
|
data = request.args.to_dict()
|
||||||
|
required = ['configName']
|
||||||
|
if not checkJSONAllParameter(required, data):
|
||||||
|
return jsonify(api.notEnoughParameter)
|
||||||
|
else:
|
||||||
|
return api.manageConfiguration.getConfigurationInfo(api.manageConfiguration, data['configName'], WG_CONF_PATH)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dashboard Tools Related
|
Dashboard Tools Related
|
||||||
"""
|
"""
|
||||||
|
@ -173,6 +173,10 @@ body {
|
|||||||
margin: 0 1rem 0 0;
|
margin: 0 1rem 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-control:hover{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-control:active,
|
.btn-control:active,
|
||||||
.btn-control:focus {
|
.btn-control:focus {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
@ -914,4 +918,8 @@ pre.index-alert {
|
|||||||
|
|
||||||
.sb-update-url .dot-running{
|
.sb-update-url .dot-running{
|
||||||
transform: translateX(10px);
|
transform: translateX(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item{
|
||||||
|
transition: all 0.1s ease-in;
|
||||||
}
|
}
|
123
src/static/css/theme/dark.css
Normal file
123
src/static/css/theme/dark.css
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
:root{
|
||||||
|
--blue: #3f9eff;
|
||||||
|
--dark1: #1C1C1E;
|
||||||
|
--dark2: #232323;
|
||||||
|
--dark3: #3f3f3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
background-color: var(--dark1);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr{
|
||||||
|
border-top: 1px solid rgb(255 255 255 / 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Color */
|
||||||
|
|
||||||
|
.bg-dark{
|
||||||
|
background-color: #232323!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-primary{
|
||||||
|
color: var(--blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form Related */
|
||||||
|
|
||||||
|
.form-control{
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #232323;
|
||||||
|
border: 1px solid #686868;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #232323;
|
||||||
|
border-color: #686868;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.50);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:disabled, .form-control[readonly]{
|
||||||
|
background-color: #525252;
|
||||||
|
opacity: 1;
|
||||||
|
color: #a5a5a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-label::before{
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Side Bar */
|
||||||
|
|
||||||
|
.sidebar{
|
||||||
|
background-color: #232323 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-link, .bottomNavContainer .nav-link{
|
||||||
|
color: #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-link.active, .bottomNavContainer .nav-link.active{
|
||||||
|
color: var(--blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover{
|
||||||
|
background-color: #3f3f3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card{
|
||||||
|
background-color: #232323;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Button Related */
|
||||||
|
|
||||||
|
.btn-outline-primary{
|
||||||
|
color: var(--blue);
|
||||||
|
border-color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-primary:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: var(--blue);
|
||||||
|
border-color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active, .show>.btn-outline-primary.dropdown-toggle{
|
||||||
|
background-color: var(--blue);
|
||||||
|
border-color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Configuration Card (index.html) */
|
||||||
|
.conf_card:hover{
|
||||||
|
border-color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal */
|
||||||
|
.modal-content{
|
||||||
|
background-color: var(--dark1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header, .modal-footer{
|
||||||
|
border-color:rgb(255 255 255 / 10%);;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List Group Item */
|
||||||
|
.list-group-item{
|
||||||
|
background-color: var(--dark2);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item:hover{
|
||||||
|
color: white;
|
||||||
|
background-color: var(--dark3);
|
||||||
|
border-color: var(--dark3);
|
||||||
|
}
|
@ -8,7 +8,7 @@ let peers = [];
|
|||||||
/**
|
/**
|
||||||
* Definitions
|
* Definitions
|
||||||
*/
|
*/
|
||||||
$(".bottomNavConfigs").addClass("active")
|
$(".bottomNavConfigs").addClass("active");
|
||||||
let configuration_name;
|
let configuration_name;
|
||||||
let configuration_interval;
|
let configuration_interval;
|
||||||
let configuration_timeout = window.localStorage.getItem("configurationTimeout");
|
let configuration_timeout = window.localStorage.getItem("configurationTimeout");
|
||||||
@ -38,6 +38,7 @@ let peers = [];
|
|||||||
let settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), bootstrapModalConfig);
|
let settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), bootstrapModalConfig);
|
||||||
let deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), bootstrapModalConfig);
|
let deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), bootstrapModalConfig);
|
||||||
let configurationDeleteModal = new bootstrap.Modal(document.getElementById('configuration_delete_modal'), bootstrapModalConfig);
|
let configurationDeleteModal = new bootstrap.Modal(document.getElementById('configuration_delete_modal'), bootstrapModalConfig);
|
||||||
|
let configurationEditModal = new bootstrap.Modal(document.getElementById('editConfigurationModal'), bootstrapModalConfig);
|
||||||
let peerDataUsageModal = new bootstrap.Modal(document.getElementById('peerDataUsage'), bootstrapModalConfig);
|
let peerDataUsageModal = new bootstrap.Modal(document.getElementById('peerDataUsage'), bootstrapModalConfig);
|
||||||
$("[data-toggle='tooltip']").tooltip();
|
$("[data-toggle='tooltip']").tooltip();
|
||||||
$("[data-toggle='popover']").popover();
|
$("[data-toggle='popover']").popover();
|
||||||
@ -977,6 +978,13 @@ let peers = [];
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getConfigurationDetails() {
|
||||||
|
function done(res){
|
||||||
|
console.log(res);
|
||||||
|
}
|
||||||
|
ajaxGetJSON(`/api/getConfigurationInfo?configName=${configuration_name}`, done)
|
||||||
|
}
|
||||||
|
|
||||||
configurations = {
|
configurations = {
|
||||||
peerDataUsageChartObj: () => { return peerDataUsageChartObj },
|
peerDataUsageChartObj: () => { return peerDataUsageChartObj },
|
||||||
peerDataUsageModal: () => { return peerDataUsageModal },
|
peerDataUsageModal: () => { return peerDataUsageModal },
|
||||||
@ -987,6 +995,7 @@ let peers = [];
|
|||||||
ipModal: () => { return ipModal; },
|
ipModal: () => { return ipModal; },
|
||||||
qrcodeModal: () => { return qrcodeModal; },
|
qrcodeModal: () => { return qrcodeModal; },
|
||||||
settingModal: () => { return settingModal; },
|
settingModal: () => { return settingModal; },
|
||||||
|
configurationEditModal: () => { return configurationEditModal; },
|
||||||
configurationTimeout: () => { return configuration_timeout; },
|
configurationTimeout: () => { return configuration_timeout; },
|
||||||
updateDisplayMode: () => { display_mode = window.localStorage.getItem("displayMode"); },
|
updateDisplayMode: () => { display_mode = window.localStorage.getItem("displayMode"); },
|
||||||
removeConfigurationInterval: () => { removeConfigurationInterval(); },
|
removeConfigurationInterval: () => { removeConfigurationInterval(); },
|
||||||
@ -998,7 +1007,7 @@ let peers = [];
|
|||||||
parsePeers: (response) => { parsePeers(response); },
|
parsePeers: (response) => { parsePeers(response); },
|
||||||
toggleAccess: (peerID) => { toggleAccess(peerID); },
|
toggleAccess: (peerID) => { toggleAccess(peerID); },
|
||||||
|
|
||||||
|
getConfigurationDetails: () => { getConfigurationDetails() },
|
||||||
setConfigurationName: (confName) => { configuration_name = confName; },
|
setConfigurationName: (confName) => { configuration_name = confName; },
|
||||||
getConfigurationName: () => { return configuration_name; },
|
getConfigurationName: () => { return configuration_name; },
|
||||||
setActiveConfigurationName: () => { setActiveConfigurationName(); },
|
setActiveConfigurationName: () => { setActiveConfigurationName(); },
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
let $body = $("body");
|
let $body = $("body");
|
||||||
let available_ips = [];
|
let available_ips = [];
|
||||||
let $add_peer = document.getElementById("save_peer");
|
let $add_peer = document.getElementById("save_peer");
|
||||||
@ -89,11 +87,6 @@ $body.on("click", ".btn-data-usage-peer", function(){
|
|||||||
ajaxPostJSON("/api/getPeerDataUsage", {"config": configurations.getConfigurationName(), "peerID": configurations.peerDataUsageChartObj().data.peerID, "interval": window.localStorage.getItem("peerTimePeriod")}, loadPeerDataUsageChartDone);
|
ajaxPostJSON("/api/getPeerDataUsage", {"config": configurations.getConfigurationName(), "peerID": configurations.peerDataUsageChartObj().data.peerID, "interval": window.localStorage.getItem("peerTimePeriod")}, loadPeerDataUsageChartDone);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('#peerDataUsage').on('shown.bs.modal', function() {
|
$('#peerDataUsage').on('shown.bs.modal', function() {
|
||||||
configurations.peerDataUsageChartObj().resize();
|
configurations.peerDataUsageChartObj().resize();
|
||||||
}).on('hidden.bs.modal', function() {
|
}).on('hidden.bs.modal', function() {
|
||||||
@ -117,6 +110,17 @@ $(".switchTimePeriod").on("click", function(){
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit Configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
$editConfiguration = $("#edit_configuration");
|
||||||
|
$editConfiguration.on("click", function(){
|
||||||
|
configurations.getConfigurationDetails();
|
||||||
|
configurations.configurationEditModal().toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ==========
|
* ==========
|
||||||
* Add peers
|
* Add peers
|
||||||
|
@ -170,7 +170,7 @@
|
|||||||
data-url="/download_all/{{conf_data['name']}}"><i
|
data-url="/download_all/{{conf_data['name']}}"><i
|
||||||
class="bi bi-cloud-download-fill"></i> Download All Peers</a>
|
class="bi bi-cloud-download-fill"></i> Download All Peers</a>
|
||||||
<hr>
|
<hr>
|
||||||
<a class="text-primary" id="configuration_setting"><i class="bi bi-gear-fill"></i>
|
<a class="text-primary" id="edit_configuration"><i class="bi bi-gear-fill"></i>
|
||||||
Configration Settings</a>
|
Configration Settings</a>
|
||||||
<a class="text-danger" id="configuration_delete"><i class="bi bi-trash3-fill"></i>
|
<a class="text-danger" id="configuration_delete"><i class="bi bi-trash3-fill"></i>
|
||||||
Delete Configuration</a>
|
Delete Configuration</a>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
|
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
|
||||||
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/dashboard.css') }}">
|
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/dashboard.css') }}">
|
||||||
|
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/theme/dark.css') }}">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
|
||||||
|
@ -123,7 +123,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="addConfigurationPreUp">PreUp</label>
|
<label for="addConfigurationPreUp">PreUp</label>
|
||||||
|
@ -354,4 +354,109 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal fade" id="editConfigurationModal">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="staticBackdropLabel">Edit Configuration</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="addCconfigurationAlert" class="alert alert-danger alert-dismissible fade show d-none"
|
||||||
|
role="alert">
|
||||||
|
<div class="alert-body"></div>
|
||||||
|
</div>
|
||||||
|
<pre id="addCconfigurationAlertMessage" class="index-alert d-none"></pre>
|
||||||
|
<form id="add_configuration_form">
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<label for="editConfigurationPrivateKey">Private Key <code>*</code></label>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationPrivateKey"
|
||||||
|
name="editConfigurationPrivateKey" required>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-danger" id="reGeneratePrivateKey"
|
||||||
|
data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i
|
||||||
|
class="bi bi-arrow-repeat"></i></button>
|
||||||
|
</div>
|
||||||
|
<div id="editConfigurationPrivateKeyFeedback" class="input-feedback"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationName">Configuration Name <code>*</code></label>
|
||||||
|
<input type="text" class="form-control" id="editConfigurationName"
|
||||||
|
name="editConfigurationName" required>
|
||||||
|
<div id="editConfigurationNameFeedback" class="input-feedback"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationListenPort">Listen Port <code>*</code></label>
|
||||||
|
<input type="number" class="form-control codeFont" id="editConfigurationListenPort"
|
||||||
|
name="editConfigurationListenPort" required>
|
||||||
|
<div id="editConfigurationListenPortFeedback" class="input-feedback"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationAddress">Address <code>*</code>
|
||||||
|
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationAddress"
|
||||||
|
placeholder="Ex: 192.168.0.1/24" name="editConfigurationAddress" required>
|
||||||
|
<div id="editConfigurationAddressFeedback" class="input-feedback"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for=""># of available IPs</label>
|
||||||
|
<p class="editConfigurationAvailableIPs">N/A</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationPreUp">PreUp</label>
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationPreUp"
|
||||||
|
name="editConfigurationPreUp">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationPreDown">PreDown</label>
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationPreDown"
|
||||||
|
name="editConfigurationPreDown">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationPostUp">PostUp</label>
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationPostUp"
|
||||||
|
name="editConfigurationPostUp">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editConfigurationPostDown">PostDown</label>
|
||||||
|
<input type="text" class="form-control codeFont" id="editConfigurationPostDown"
|
||||||
|
name="editConfigurationPostDown">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="editConfigurationBtn">Add</button>
|
||||||
|
<div class="text-primary editConfigurationStatus editConfigurationAddStatus d-none">
|
||||||
|
<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
Editing Configuration
|
||||||
|
</div>
|
||||||
|
<div class="text-primary editConfigurationStatus editConfigurationToggleStatus d-none waiting">
|
||||||
|
<i class="bi bi-circle"></i> Toggle Configuration
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -62,7 +62,6 @@
|
|||||||
<ul class="nav flex-column">
|
<ul class="nav flex-column">
|
||||||
<li class="nav-item"><a href="https://github.com/donaldzou/WGDashboard/releases/tag/{{ session['dashboard_version'] }}"><small class="nav-link text-muted">{{ session['dashboard_version'] }}</small></a></li>
|
<li class="nav-item"><a href="https://github.com/donaldzou/WGDashboard/releases/tag/{{ session['dashboard_version'] }}"><small class="nav-link text-muted">{{ session['dashboard_version'] }}</small></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user