Files
wireguard-ui-multi/custom/js/helper.js
T
sysopsandClaude Sonnet 5 867dc7740a Replace from-scratch rewrite with real ngoduykhanh/wireguard-ui fork
The from-scratch Go rewrite had unresolved bugs (missing go.sum, UI
404s, path issues) from being built without a working local Go
toolchain to verify against. Switching strategy: use the actual
upstream wireguard-ui codebase (proven, battle-tested single-server
manager) as the base, and extend it for multi-server support instead
of re-deriving everything from zero.

Kept our own installers (bootstrap.sh, update.sh, scripts/install.sh,
scripts/proxmox-install.sh) - these still apply, just need updating
to build/install the upstream module layout instead of the old
cmd/wireguard-ui-multi structure.

Module path intentionally left as upstream's own
(github.com/ngoduykhanh/wireguard-ui) for now to avoid touching every
internal import; revisit if this needs to be fully rebranded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 18:34:44 +02:00

146 lines
8.6 KiB
JavaScript

function renderClientList(data) {
$.each(data, function(index, obj) {
// render telegram button
let telegramButton = ''
if (obj.Client.telegram_userid) {
telegramButton = `<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_telegram_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Telegram</button>
</div>`
}
let telegramHtml = "";
if (obj.Client.telegram_userid && obj.Client.telegram_userid.length > 0) {
telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${obj.Client.telegram_userid}</span>`
}
// render client status css tag style
let clientStatusHtml = '>'
if (obj.Client.enabled) {
clientStatusHtml = `style="visibility: hidden;">`
}
// render client allocated ip addresses
let allocatedIpsHtml = "";
$.each(obj.Client.allocated_ips, function(index, obj) {
allocatedIpsHtml += `<small class="badge badge-secondary">${obj}</small>&nbsp;`;
})
// render client allowed ip addresses
let allowedIpsHtml = "";
$.each(obj.Client.allowed_ips, function(index, obj) {
allowedIpsHtml += `<small class="badge badge-secondary">${obj}</small>&nbsp;`;
})
let subnetRangesString = "";
if (obj.Client.subnet_ranges && obj.Client.subnet_ranges.length > 0) {
subnetRangesString = obj.Client.subnet_ranges.join(',')
}
let additionalNotesHtml = "";
if (obj.Client.additional_notes && obj.Client.additional_notes.length > 0) {
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${obj.Client.additional_notes.toUpperCase()}</span>`
}
// render client html content
let html = `<div class="col-sm-6 col-md-6 col-lg-4" id="client_${obj.Client.id}">
<div class="info-box">
<div class="overlay" id="paused_${obj.Client.id}"` + clientStatusHtml
+ `<i class="paused-client fas fa-3x fa-play" onclick="resumeClient('${obj.Client.id}')"></i>
</div>
<div class="info-box-content" style="overflow: hidden">
<div class="btn-group">
<a href="download?clientid=${obj.Client.id}" class="btn btn-outline-primary btn-sm">Download</a>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_email_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Email</button>
</div>
${telegramButton}
<div class="btn-group">
<button type="button" class="btn btn-outline-danger btn-sm">More</button>
<button type="button" class="btn btn-outline-danger btn-sm dropdown-toggle dropdown-icon"
data-toggle="dropdown">
</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_edit_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Edit</a>
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_pause_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Disable</a>
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_remove_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Delete</a>
</div>
</div>
<hr>
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.Client.name}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${obj.Client.public_key}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${subnetRangesString}</span>
${telegramHtml}
${additionalNotesHtml}
<span class="info-box-text"><i class="fas fa-envelope"></i> ${obj.Client.email}</span>
<span class="info-box-text"><i class="fas fa-clock"></i>
${prettyDateTime(obj.Client.created_at)}</span>
<span class="info-box-text"><i class="fas fa-history"></i>
${prettyDateTime(obj.Client.updated_at)}</span>
<span class="info-box-text"><i class="fas fa-server" style="${obj.Client.use_server_dns ? "opacity: 1.0" : "opacity: 0.5"}"></i>
${obj.Client.use_server_dns ? 'DNS enabled' : 'DNS disabled'}</span>
<span class="info-box-text"><i class="fas fa-file"></i>
${obj.Client.additional_notes}</span>
<span class="info-box-text"><strong>IP Allocation</strong></span>`
+ allocatedIpsHtml
+ `<span class="info-box-text"><strong>Allowed IPs</strong></span>`
+ allowedIpsHtml
+`</div>
</div>
</div>`
// add the client html elements to the list
$('#client-list').append(html);
});
}
function renderUserList(data) {
$.each(data, function(index, obj) {
let clientStatusHtml = '>'
// render user html content
let html = `<div class="col-sm-6 col-md-6 col-lg-4" id="user_${obj.username}">
<div class="info-box">
<div class="info-box-content">
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#modal_edit_user" data-username="${obj.username}">Edit</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
data-target="#modal_remove_user" data-username="${obj.username}">Delete</button>
</div>
<hr>
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.username}</span>
<span class="info-box-text"><i class="fas fa-terminal"></i> ${obj.admin? 'Administrator':'Manager'}</span>
</div>
</div>
</div>`
// add the user html elements to the list
$('#users-list').append(html);
});
}
function prettyDateTime(timeStr) {
const dt = new Date(timeStr);
const offsetMs = dt.getTimezoneOffset() * 60 * 1000;
const dateLocal = new Date(dt.getTime() - offsetMs);
return dateLocal.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ");
}