mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-07 00:10:13 +01:00
527 lines
33 KiB
HTML
527 lines
33 KiB
HTML
<html lang="en">
|
|
{% with title=title%}
|
|
{% include "header.html"%}
|
|
{% endwith %}
|
|
<body>
|
|
{% include "navbar.html" %}
|
|
<div class="container-fluid">
|
|
{% include "sidebar.html" %}
|
|
<div class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
|
|
<div class="form-group">
|
|
<input type="text" class="form-control" id="search_peer_textbox" placeholder="Search Peer..." value="">
|
|
</div>
|
|
</div>
|
|
<div id="config_body">
|
|
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
|
|
<div class="info mt-4">
|
|
<div id="config_info_alert"></div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<small class="text-muted"><strong>CONFIGURATION</strong></small>
|
|
<h1 class="mb-3"><samp id="conf_name">{{ title }}</samp></h1>
|
|
</div>
|
|
<div class="col">
|
|
<small class="text-muted"><strong>SWITCH</strong></small><br>
|
|
<div id="conf_status_btn" class="info_loading"></div>
|
|
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
</div>
|
|
<div class="w-100"></div>
|
|
<div class="col">
|
|
<small class="text-muted"><strong>STATUS</strong></small>
|
|
<h6 style="text-transform: uppercase;" id="conf_status" class="info_loading"></h6>
|
|
</div>
|
|
<div class="col">
|
|
<small class="text-muted"><strong>CONNECTED PEERS</strong></small>
|
|
<h6 style="text-transform: uppercase;" id="conf_connected_peers" class="info_loading"></h6>
|
|
</div>
|
|
<div class="col-sm">
|
|
<small class="text-muted"><strong>TOTAL DATA USAGE</strong></small>
|
|
<h6 style="text-transform: uppercase;" id="conf_total_data_usage" class="info_loading"></h6>
|
|
</div>
|
|
<div class="col-sm">
|
|
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
|
|
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading"></h6>
|
|
</div>
|
|
<div class="col-sm">
|
|
<small class="text-muted"><strong>TOTAL SENT</strong></small>
|
|
<h6 style="text-transform: uppercase;" id="conf_total_data_sent" class="info_loading"></h6>
|
|
</div>
|
|
<div class="w-100"></div>
|
|
<div class="col-sm">
|
|
<small class="text-muted">
|
|
<strong>PUBLIC KEY</strong>
|
|
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong>
|
|
</small>
|
|
<h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6>
|
|
</div>
|
|
<div class="col-sm">
|
|
<small class="text-muted"><strong>LISTEN PORT</strong></small>
|
|
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_listen_port"></samp></h6>
|
|
</div>
|
|
<div class="col-sm">
|
|
<small class="text-muted"><strong>ADDRESS</strong></small>
|
|
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp></h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="button-div mb-3">
|
|
<div class="row">
|
|
<div class="col-sm">
|
|
<div class="form-group">
|
|
<label for="sort_by_dropdown"><small class="text-muted">Sort Peers By</small></label>
|
|
<select class="form-control" id="sort_by_dropdown">
|
|
<option value="status">Status</option>
|
|
<option value="name">Name</option>
|
|
<option value="allowed_ip">Allowed IP</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm">
|
|
<div class="form-group">
|
|
<label><small class="text-muted">Refresh Interval</small></label><br>
|
|
<div class="btn-group interval-btn-group" role="group" style="width: 100%">
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip" data-placement="bottom" title="Refresh Peers"><i class="bi bi-arrow-repeat"></i></button>
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="5000">5s</button>
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="10000">10s</button>
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="30000">30s</button>
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="60000">1m</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm">
|
|
<div class="form-group">
|
|
<label><small class="text-muted">Display Mode</small></label><br>
|
|
<div class="btn-group display-btn-group" role="group" style="width: 100%">
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="grid"><i class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
|
|
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="list"><i class="bi bi-list" style="font-size: 1.5rem;"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="btn-manage-group">
|
|
<button type="button" class="btn btn-primary add_btn"><i class="bi bi-plus-circle-fill" style=""></i></button>
|
|
<button type="button" class="btn btn-secondary setting_btn"><i class="bi bi-three-dots"></i></button>
|
|
<div class="setting_btn_menu">
|
|
<a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i> Delete Peers</a>
|
|
<a class="text-info"><i class="bi bi-cloud-download-fill"></i> Download All Peers</a>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="row peer_list"></div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="add_modal" data-backdrop="static" data-keyboard="false" tabindex="-1"
|
|
aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="staticBackdropLabel">Add New Peer</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div>
|
|
<div class="custom-control custom-switch" style="margin-bottom: 1rem">
|
|
<input class="custom-control-input" type="checkbox" id="bulk_add">
|
|
<label class="custom-control-label" for="bulk_add"><strong>Add Peers by bulk</strong></label>
|
|
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body" data-toggle="popover" data-placement="right" data-trigger="click" data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i>
|
|
</div>
|
|
<div class="form-group" style="margin: 0">
|
|
{# <label for="new_add_amount">Amount</label>#}
|
|
<input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount" disabled>
|
|
</div>
|
|
|
|
</div>
|
|
<hr>
|
|
<div id="add_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form id="add_peer_form">
|
|
<div class="form-group non-bulk">
|
|
<div>
|
|
<label for="private_key">Private Key</label>
|
|
</div>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="private_key" aria-describedby="private_key">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-danger" id="re_generate_key" data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i class="bi bi-arrow-repeat"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group non-bulk">
|
|
<label for="public_key">Public Key <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="public_key" aria-describedby="public_key" disabled>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-6 non-bulk">
|
|
<div class="form-group">
|
|
<label for="new_add_name">Name</label>
|
|
<input type="text" class="form-control" id="new_add_name">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 non-bulk">
|
|
<div class="form-group">
|
|
<label for="allowed_ips">Allowed IPs <code>(Required)</code></label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="allowed_ips">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-primary" id="search_available_ip" data-toggle="tooltip" data-placement="top" title="Search Available IPs">
|
|
<i class="bi bi-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<p style="position: absolute; top: 4px; right: 1rem;" class="text-success" id="allowed_ips_indicator"></p>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="form-group">
|
|
<label for="new_add_DNS">DNS <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="new_add_DNS" value="{{ DNS }}">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="form-group">
|
|
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip" value="{{ endpoint_allowed_ip }}">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="form-group">
|
|
<label for="new_add_MTU">MTU</label>
|
|
<input type="text" class="form-control" id="new_add_MTU" value="{{ mtu }}">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="form-group">
|
|
<label for="new_add_keep_alive">Persistent keepalive</label>
|
|
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="enable_preshare_key" name="enable_preshare_key" value="enable_psk">
|
|
<label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label>
|
|
</div>
|
|
</div>
|
|
</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="save_peer" conf_id={{conf_data['name']}}>Add</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="delete_modal" data-backdrop="static" data-keyboard="false" tabindex="-1"
|
|
aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="staticBackdropLabel">Are you sure to delete this peer?</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="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<h6>This action is not reversible.</h6>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
|
|
<button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}} peer_id="">Yes</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="setting_modal" data-backdrop="static" data-keyboard="false" tabindex="-1"
|
|
aria-labelledby="staticBackdropLabel" aria-hidden="true" conf_id={{conf_data['name']}} peer_id="">
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="peer_name"></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="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="peer_private_key_textbox" class="form-label">Private Key <code>(Required for QR Code and download)</code></label>
|
|
<input type="password" class="form-control" id="peer_private_key_textbox" style="padding-right: 40px">
|
|
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
|
|
</div>
|
|
<div>
|
|
<label for="peer_preshared_key_textbox" class="form-label">Pre-Shared Key</label>
|
|
<input type="text" class="form-control" id="peer_preshared_key_textbox">
|
|
</div>
|
|
<hr>
|
|
|
|
<div class="row">
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_name_textbox" class="form-label">Name</label>
|
|
<input type="text" class="form-control" id="peer_name_textbox" placeholder="">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="peer_allowed_ip_textbox">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_DNS_textbox" class="form-label">DNS <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="peer_DNS_textbox">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs <code>(Required)</code></label>
|
|
<input type="text" class="form-control" id="peer_endpoint_allowed_ips">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_mtu" class="form-label">MTU</label>
|
|
<input type="text" class="form-control" id="peer_mtu">
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="mb-3">
|
|
<label for="peer_keep_alive" class="form-label">Persistent Keepalive</label>
|
|
<input type="text" class="form-control" id="peer_keep_alive">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</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="save_peer_setting" conf_id={{conf_data['name']}} peer_id="">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="available_ip_modal" data-backdrop="static" data-keyboard="false">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="staticBackdropLabel">Select available IP</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="selected_ip" style="padding: 1rem; border-bottom: 1px solid #dee2e6;">
|
|
<small class="text-muted"><strong>SELECTED IP (CLICK TO REMOVE)</strong></small>
|
|
<div id="selected_ip_list">
|
|
|
|
</div>
|
|
</div>
|
|
<div class="modal-body" style="max-height: 400px; overflow-y: scroll;">
|
|
<div class="list-group"></div>
|
|
</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="confirm_ip">Confirm</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="delete_bulk_modal" data-backdrop="static" data-keyboard="false">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="staticBackdropLabel">Select Peers to Delete</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="selected_peers" style="padding: 1rem; border-bottom: 1px solid #dee2e6;">
|
|
<small class="text-muted"><strong>SELECTED PEERS (CLICK TO REMOVE)</strong></small>
|
|
<div id="selected_peer_list"></div>
|
|
</div>
|
|
<div class="modal-body" style="max-height: 400px; overflow-y: scroll;">
|
|
<div class="list-group"></div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<a class="text-danger" id="select_all_delete_bulk_peers" style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a>
|
|
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled data-conf="{{conf_data['name']}}">Delete</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="qrcode_modal" data-backdrop="static" data-keyboard="false" tabindex="-1"
|
|
aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="peer_name">QR Code</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<img id="qrcode_img" style="width: 100%">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="position-fixed top-0 right-0 p-3" style="z-index: 5; right: 0; top: 50px;">
|
|
<div id="alertToast" class="toast hide" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
|
|
<div class="toast-header">
|
|
<strong class="mr-auto">WGDashboard</strong>
|
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="toast-body">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% include "tools.html" %}
|
|
</body>
|
|
{% include "footer.html" %}
|
|
<script src="{{ url_for('static',filename='js/wireguard.min.js') }}"></script>
|
|
<script src="{{ url_for('static',filename='js/configuration.min.js') }}"></script>
|
|
|
|
<script>
|
|
let load_timeout;
|
|
let load_interval = 0;
|
|
let conf_name = "{{ conf_data['name'] }}"
|
|
let peers = [];
|
|
$(".sb-"+conf_name+"-url").addClass("active");
|
|
function load_data(search){
|
|
startProgressBar()
|
|
let result = '';
|
|
$.ajax({
|
|
method: "GET",
|
|
url: "/get_config/"+conf_name+"?search="+encodeURIComponent(search),
|
|
headers:{
|
|
"Content-Type": "application/json"
|
|
},
|
|
success: function (response){
|
|
peers = response["peer_data"];
|
|
{# Check all status #}
|
|
if (response["listen_port"] === "" && response["status"] === "stopped"){
|
|
$("config_info_alert").append('<div class="alert alert-warning" role="alert">Peer QR Code and configuration file download required a specified <strong>Listen Port</strong>.</div>')
|
|
}
|
|
if (response["conf_address"] === "N/A"){
|
|
$("config_info_alert").append('<div class="alert alert-warning" role="alert">Configuration <strong>Address</strong> need to be specified to have peers connect to it.</div>')
|
|
}
|
|
{# Status Button #}
|
|
if (response["checked"] === "checked"){
|
|
$("#conf_status_btn").html('<a href="#" id="'+response["name"]+'" '+response["checked"]+' class="switch text-primary"><i class="bi bi-toggle2-on"></i> ON</a>');
|
|
}else{
|
|
$("#conf_status_btn").html('<a href="#" id="'+response["name"]+'" '+response["checked"]+' class="switch text-primary"><i class="bi bi-toggle2-off"></i> OFF</a>');
|
|
}
|
|
$("#sort_by_dropdown option").removeAttr("selected");
|
|
$("#sort_by_dropdown option[value="+response["sort_tag"]+"]").attr("selected", "selected");
|
|
$(".interval-btn-group button").removeClass("active");
|
|
$("button[data-refresh-interval="+response["dashboard_refresh_interval"]+"]").addClass("active");
|
|
$(".display-btn-group button").removeClass("active");
|
|
$("button[data-display-mode="+response["peer_display_mode"]+"]").addClass("active");
|
|
|
|
|
|
|
|
$("#conf_status").html(response["status"]+'<span class="dot dot-'+response["status"]+'"></span>');
|
|
$("#conf_connected_peers").html(response["running_peer"]);
|
|
$("#conf_total_data_usage").html(response["total_data_usage"][0] +" GB");
|
|
$("#conf_total_data_received").html(response["total_data_usage"][2] +" GB");
|
|
$("#conf_total_data_sent").html(response["total_data_usage"][1]+" GB");
|
|
$("#conf_public_key").html(response["public_key"]);
|
|
$("#conf_listen_port").html(response["listen_port"] === "" ? "N/A":response["listen_port"]);
|
|
$("#conf_address").html(response["conf_address"]);
|
|
$(".info h6").removeClass("info_loading");
|
|
$("#conf_status_btn").removeClass("info_loading")
|
|
|
|
|
|
|
|
if (response["peer_data"].length === 0){
|
|
$(".peer_list").html('<div class="col-12" style="text-align: center; margin-top: 1.5rem"><h3 class="text-muted">Oops! No peers found ‘︿’</h3></div>');
|
|
}else{
|
|
let display_mode = response["peer_display_mode"] === "list" ? "col-12" : "col-sm-6 col-lg-4";
|
|
response["peer_data"].forEach(function(peer){
|
|
let total_r = 0;
|
|
let total_s = 0;
|
|
total_r += peer["cumu_receive"];
|
|
total_s += peer["cumu_sent"];
|
|
let spliter = '<div class="w-100"></div>';
|
|
let peer_name =
|
|
'<div class="col-sm display" style="display: flex; align-items: center; margin-bottom: 0.2rem">' +
|
|
'<h5 style="margin: 0;">'+ (peer["name"] === "" ? "Untitled" : peer["name"]) +'</h5>' +
|
|
'<h6 style="text-transform: uppercase; margin: 0; margin-left: auto !important;"><span class="dot dot-'+peer["status"]+'" style="margin-left: auto !important;" data-toggle="tooltip" data-placement="left" title="Peer Running"></span></h6>' +
|
|
'</div>';
|
|
let peer_transfer = '<div class="col-12 peer_data_group" style="text-align: right; display: flex; margin-bottom: 0.5rem"><p class="text-primary" style="text-transform: uppercase; margin-bottom: 0; margin-right: 1rem"><small><i class="bi bi-arrow-down-right"></i> '+ roundN(peer["total_receive"] + total_r, 4) +' GB</small></p> <p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> '+ roundN(peer["total_sent"] + total_s, 4) +' GB</small></p> </div>'
|
|
let peer_key = '<div class="col-sm"><small class="text-muted" style="display: flex"><strong>PEER</strong><strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small> <h6><samp class="ml-auto key">'+peer["id"]+'</samp></h6></div>';
|
|
let peer_allowed_ip = '<div class="col-sm"><small class="text-muted"><strong>ALLOWED IP</strong></small><h6 style="text-transform: uppercase;">'+peer["allowed_ip"]+'</h6></div>';
|
|
let peer_latest_handshake = '<div class="col-sm"> <small class="text-muted"><strong>LATEST HANDSHAKE</strong></small> <h6 style="text-transform: uppercase;">'+peer['latest_handshake']+'</h6> </div>';
|
|
let peer_endpoint = '<div class="col-sm"><small class="text-muted"><strong>END POINT</strong></small><h6 style="text-transform: uppercase;">'+peer["endpoint"]+'</h6></div>';
|
|
let peer_control = '<div class="col-sm"><hr><div class="button-group" style="display:flex"><button type="button" class="btn btn-outline-primary btn-setting-peer btn-control" id="'+peer["id"]+'" data-toggle="modal"><i class="bi bi-gear-fill" data-toggle="tooltip" data-placement="bottom" title="Peer Settings"></i></button> <button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="'+peer["id"]+'" data-toggle="modal"><i class="bi bi-x-circle-fill" data-toggle="tooltip" data-placement="bottom" title="Delete Peer"></i></button>';
|
|
if (peer["private_key"] !== ""){
|
|
peer_control += '<div class="share_peer_btn_group" style="margin-left: auto !important; display: inline"><button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="/qrcode/'+response['name']+'?id='+encodeURIComponent(peer["id"])+'"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg></button><a href="/download/'+response["name"]+'?id='+encodeURIComponent(peer["id"])+'" class="btn btn-outline-info btn-download-peer btn-control"><i class="bi bi-download"></i></a></div>';
|
|
}
|
|
peer_control += '</div>';
|
|
let html = '<div class="'+display_mode+'" data-id="'+peer["id"]+'">' +
|
|
'<div class="card mb-3 card-'+peer["status"]+'">' +
|
|
'<div class="card-body">' +
|
|
'<div class="row">'
|
|
+ peer_name
|
|
+ spliter
|
|
+ peer_transfer
|
|
+ peer_key
|
|
+ peer_allowed_ip
|
|
+ peer_latest_handshake
|
|
+ spliter
|
|
+ peer_endpoint
|
|
+ spliter
|
|
+ peer_control
|
|
+ '</div>' +
|
|
'</div></div>' +
|
|
'</div></div>';
|
|
result += html;
|
|
})
|
|
$(".peer_list").html(result);
|
|
if (response["dashboard_refresh_interval"] !== load_interval){
|
|
load_interval = response["dashboard_refresh_interval"];
|
|
clearInterval(load_timeout);
|
|
load_timeout = setInterval(function (){
|
|
load_data($('#search_peer_textbox').val());
|
|
},response["dashboard_refresh_interval"])
|
|
}
|
|
}
|
|
$(".dot.dot-running").attr("title","Peer Running").tooltip();
|
|
$(".dot.dot-stopped").attr("title","Peer Stopped").tooltip();
|
|
$("i[data-toggle='tooltip']").tooltip();
|
|
endProgressBar()
|
|
}
|
|
})
|
|
}
|
|
$(function(){
|
|
load_data($('#search_peer_textbox').val());
|
|
});
|
|
</script>
|
|
|
|
</html> |