use GODEBUG=embedfollowsymlinks=1 to support symlinked web src files
tronnet/workflows: Code Style -- Web Components / style-web (push) Failing after 18s
tronnet/workflows: Static Analysis -- Golang / static-go (push) Failing after 22s

This commit is contained in:
alu committed 2026-10-22 20:54:23 +00:00
1 parent 98790dbe3b
commit 5c658db34e
94 files changed
+11 -14

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/account.js" type="module"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<link rel="modulepreload" href="websrc/scripts/dialog.js">
<style>
@media screen and (width >= 1264px){
.resource-container {
display: grid;
grid-template-columns: repeat(auto-fill, calc(100% / 6));
grid-gap: 0;
justify-content: space-between;
}
}
@media screen and (width <= 1264px) and (width >= 680px) {
.resource-container {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
grid-gap: 0;
justify-content: space-between;
}
}
@media screen and (width <= 680px) {
.resource-container {
display: flex;
flex-direction: column;
gap: 0;
flex-wrap: nowrap;
justify-content: center;
}
}
</style>
</head>
<body>
{{template "header" .}}
<main>
<h2>Account</h2>
<section class="w3-card w3-padding">
<h3>Account Details</h3>
<p id="username">Username: {{.user.Username.UserID}}@{{.user.Username.Realm}}</p>
<p id="email">Email: {{.user.Mail}}</p>
<p>Password: <button class="w3-button" id="change-password" type="button" style="padding: 0em; height: 1.5em; line-height: 1.5em;">Change Password</button></p>
</section>
{{range $poolname, $pool := .pools}}
{{template "pool-resources" $pool}}
{{end}}
</main>
<template id="change-password-dialog">
<link rel="stylesheet" href="websrc/modules/w3.css">
<link rel="stylesheet" href="websrc/css/style.css">
<link rel="stylesheet" href="websrc/css/form.css">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Change Password
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="new-password">New Password</label>
<input class="w3-input w3-border" id="new-password" name="new-password" type="password" autocomplete="new-password" required>
<label for="confirm-password">Confirm Password</label>
<input class="w3-input w3-border" id="confirm-password" name="confirm-password" type="password" autocomplete="new-password" required>
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" type="submit" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" type="submit" value="confirm" form="form" class="w3-button w3-margin">CONFIRM</button>
</div>
</dialog>
</template>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
{{range $i, $x := .backups}}
{{template "backup-card" $x}}
{{end}}
+36
View File
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/backups.js" type="module"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<link rel="modulepreload" href="websrc/scripts/dialog.js">
<style>
</style>
</head>
<body>
{{template "header" .}}
<main>
<h2><a href="index">Instances</a> / {{.config.Name}} / Backups</h2>
<section class="w3-card w3-padding">
<div class="w3-row" style="border-bottom: 1px solid;">
<p class="w3-col l2 m4 s8">Time</p>
<p class="w3-col l6 m6 hide-small">Notes</p>
<p class="w3-col l2 hide-medium">Size</p>
<p class="w3-col l2 m2 s4">Actions</p>
</div>
<div id="backups-container">
{{range $i, $x := .backups}}
{{template "backup-card" $x}}
{{end}}
</div>
<div class="w3-container w3-center">
{{template "backups-add-backup" .}}
</div>
</section>
<div class="w3-container w3-center">
<a class="w3-button w3-margin" id="exit" href="index">EXIT</a>
</div>
</main>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
{{template "boot" .config.Boot}}
+1
View File
@@ -0,0 +1 @@
{{template "devices" .config.Devices}}
+1
View File
@@ -0,0 +1 @@
{{template "nets" .config.Nets}}
+1
View File
@@ -0,0 +1 @@
{{template "volumes" Map "Volumes" .config.Volumes "InstanceType" .config.Type}}
+89
View File
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/config.js" type="module"></script>
<script src="websrc/scripts/draggable.js" type="module"></script>
<script src="websrc/modules/Sortable.min.js"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<link rel="modulepreload" href="websrc/scripts/dialog.js">
<style>
.input-grid p, .input-grid div {
margin-top: 0;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
overflow: hidden;
white-space: nowrap;
}
</style>
</head>
<body>
{{template "header" .}}
<main>
<section>
<h2><a href="index">Instances</a>/{{.config.Name}}/Config</h2>
<form id="config-form">
<fieldset class="w3-card w3-padding">
<legend>Resources</legend>
<div class="input-grid" id="resources" style="grid-template-columns: auto auto auto 1fr;">
{{if eq .config.Type "VM"}}
{{template "proctype-input" .config.ProctypeSelect}}
{{end}}
{{template "cores-input" .config.Cores}}
{{template "memory-input" .config.Memory}}
{{if eq .config.Type "CT"}}
{{template "swap-input" .config.Swap}}
{{end}}
</div>
</fieldset>
<fieldset class="w3-card w3-padding">
<legend>Volumes</legend>
<div class="input-grid" id="volumes" style="grid-template-columns: auto auto 1fr auto;">
{{template "volumes" Map "Volumes" .config.Volumes "InstanceType" .config.Type}}
</div>
<div class="w3-container w3-center">
<!--Add Disk Button & Dialog Template-->
{{template "volumes-add-disk" .}}
<!--Add CD Button & Dialog Template-->
{{if eq .config.Type "VM"}}
{{template "volumes-add-cd"}}
{{end}}
</div>
</fieldset>
<fieldset class="w3-card w3-padding">
<legend>Network Interfaces</legend>
<div class="input-grid" id="networks" style="grid-template-columns: auto auto 1fr auto;">
{{template "nets" .config.Nets}}
</div>
<div class="w3-container w3-center">
<!--Add Net Button & Dialog Template-->
{{template "nets-add-net"}}
</div>
</fieldset>
{{if eq .config.Type "VM"}}
<fieldset class="w3-card w3-padding">
<legend>PCIe Devices</legend>
<div class="input-grid" id="devices" style="grid-template-columns: auto auto 1fr auto;">
{{template "devices" .config.Devices}}
</div>
<div class="w3-container w3-center">
<!--Add Device Button & Dialog Template-->
{{template "devices-add-device"}}
</div>
</fieldset>
<fieldset class="w3-card w3-padding">
<legend>Boot Order</legend>
<div id="boot-order">
{{template "boot" .config.Boot}}
</div>
</fieldset>
{{end}}
<div class="w3-container w3-center" id="form-actions">
<button class="w3-button w3-margin" id="exit" type="submit">EXIT</button>
</div>
</form>
</section>
</main>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
{{range .instances}}
{{template "instance-card" .}}
{{end}}
+150
View File
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/index.js" type="module"></script>
<script src="websrc/modules/wfa.js" type="module"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<link rel="modulepreload" href="websrc/scripts/dialog.js">
<link rel="modulepreload" href="websrc/scripts/clientsync.js">
<style>
@media screen and (width >= 440px) {
#vm-search {
max-width: calc(100% - 10px - 152px);
}
}
@media screen and (width <= 440px) {
#vm-search {
max-width: calc(100% - 10px - 47px);
}
}
@media screen and (width >= 993px) {
#instance-table {
display: grid;
grid-template-columns: repeat(7, auto);
grid-column-gap: 1em;
grid-row-gap: 0.25em;
}
#instance-table-header, #instance-container, #instance-table instance-card {
display: contents;
}
}
@media screen and (width <= 993px) and (width >= 601px){
#instance-table {
display: grid;
grid-template-columns: repeat(5, auto);
grid-column-gap: 1em;
grid-row-gap: 0.25em;
}
#instance-table-header, #instance-container, #instance-table instance-card {
display: contents;
}
}
@media screen and (width <= 601px) and (width >= 440px){
#instance-table {
display: grid;
grid-template-columns: repeat(4, auto);
grid-column-gap: 1em;
grid-row-gap: 0.25em;
}
#instance-table-header, #instance-container, #instance-table instance-card {
display: contents;
}
}
@media screen and (width <= 440px) {
#instance-table {
display: grid;
grid-template-columns: repeat(3, auto);
grid-column-gap: 1em;
grid-row-gap: 0.25em;
}
#instance-table-header, #instance-container, #instance-table instance-card {
display: contents;
}
}
</style>
</head>
<body>
{{template "header" .}}
<main>
<section>
<h2>Instances</h2>
<div class="w3-card w3-padding">
<div class="flex row nowrap" style="margin-top: 1em; justify-content: space-between;">
<form id="vm-search" role="search" class="flex row nowrap" tabindex="0">
<button type="submit" id="submit" class="w3-button" style="padding: 0; width: 1em; height: 1em; line-height: 1em;"><img alt="Search Instances" aria-label="Search Instances" src="websrc/images/common/search.svg#symb"></button>
<input type="search" id="search" class="w3-input w3-border" style="height: 1lh; max-width: fit-content;" aria-label="search instances by name">
</form>
<!--Add Instance Button & Dialog Template-->
<button type="button" id="instance-add" class="w3-button" aria-label="create new instance">
<span class="large" style="margin: 0;">Create Instance</span>
<img class="small" style="height: 1lh; width: 1lh;" alt="Create Instance" aria-label="Create Instance" src="websrc/images/actions/instance/add.svg#symb">
</button>
<template id="create-instance-dialog">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Create New Instance
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="type">Instance Type</label>
<select class="w3-select w3-border" name="type" id="type" selected-index="-1" required>
<option value="lxc">Container</option>
<option value="qemu">Virtual Machine</option>
</select>
<label for="pool">Pool</label>
<select class="w3-select w3-border" name="pool" id="pool" required></select>
<label for="node">Node</label>
<select class="w3-select w3-border" name="node" id="node" required></select>
<label for="name">Name</label>
<input class="w3-input w3-border" name="name" id="name" type="text" required>
<label for="vmid">ID</label>
<input class="w3-input w3-border" name="vmid" id="vmid" type="number" required>
<label for="cores">Cores (Threads)</label>
<input class="w3-input w3-border" name="cores" id="cores" type="number" min="1" max="8192" required>
<label for="memory">Memory (MiB)</label>
<input class="w3-input w3-border" name="memory" id="memory" type="number" min="16" step="1" required>
<p class="container-specific none" style="grid-column: 1 / span 2; text-align: center;">Container Options</p>
<label class="container-specific none" for="swap">Swap (MiB)</label>
<input class="w3-input w3-border container-specific none" name="swap" id="swap" type="number" min="0" step="1" required disabled>
<label class="container-specific none" for="template-image">Template Image</label>
<select class="w3-select w3-border container-specific none" name="template-image" id="template-image" required disabled></select>
<label class="container-specific none" for="rootfs-storage">ROOTFS Storage</label>
<select class="w3-select w3-border container-specific none" name="rootfs-storage" id="rootfs-storage" required disabled></select>
<label class="container-specific none" for="rootfs-size">ROOTFS Size (GiB)</label>
<input class="w3-input w3-border container-specific none" name="rootfs-size" id="rootfs-size" type="number" min="0" max="131072" required disabled>
<label class="container-specific none" for="password">Password</label>
<input class="w3-input w3-border container-specific none" name="password" id="password" type="password" autocomplete="new-password" required disabled>
<label class="container-specific none" for="confirm-password">Confirm Password</label>
<input class="w3-input w3-border container-specific none" name="confirm-password" id="confirm-password" type="password" autocomplete="new-password" required disabled>
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" type="submit" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" type="submit" value="confirm" form="form" class="w3-button w3-margin" >CONFIRM</button>
</div>
</dialog>
</template>
</div>
<div id="instance-table">
<div id="instance-table-header">
<p>ID</p>
<p>Name</p>
<p class="hide-tiny">Type</p>
<p class="hide-small">Status</p>
<p class="hide-medium">Host Name</p>
<p class="hide-medium">Host Status</p>
<p>Actions</p>
</div>
<hr style="grid-column: 1 / -1; padding: 0; margin: 0;">
<div id="instance-container">
{{range .instances}}
{{template "instance-card" .}}
{{end}}
</div>
</div>
</div>
</section>
</main>
</body>
</html>
+28
View File
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/login.js" type="module"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<link rel="modulepreload" href="websrc/scripts/dialog.js">
</head>
<body>
{{template "header" .}}
<main class="flex" style="justify-content: center; align-items: center;">
<div class="w3-container w3-card w3-margin w3-padding" style="height: fit-content;">
<h2 class="w3-center">{{.global.Organization}} Login</h2>
<form>
<label for="username"><b>Username</b></label>
<input class="w3-input w3-border" id="username" name="username" type="text" autocomplete="username">
<label for="password"><b>Password</b></label>
<input class="w3-input w3-border" id="password" name="password" type="password" autocomplete="current-password">
<label for="realm">Realm</label>
{{template "select" .realms}}
<div class="w3-center">
<button class="w3-button w3-margin" id="submit" type="submit">LOGIN</button>
</div>
</form>
</div>
</main>
</body>
</html>
+84
View File
@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template "head" .}}
<script src="websrc/scripts/settings.js" type="module"></script>
<link rel="modulepreload" href="websrc/scripts/utils.js">
<style>
label {
display: flex;
height: fit-content;
width: 100%;
align-items: center;
justify-content: left;
column-gap: 0.5em;
}
label + p {
margin-top: 0.5em;
margin-bottom: 1em;
}
p:last-child {
margin-bottom: 0;
}
#save.disabled {
display: none;
}
#save.enabled {
display: unset;
}
</style>
</head>
<body>
{{template "header" .}}
<main>
<h2>Settings</h2>
<form id="settings">
<section class="w3-card w3-padding">
<h3>Synchronization Settings</h3>
<fieldset>
<legend>App Sync Method</legend>
<label><input class="w3-radio" type="radio" id="sync-always" name="sync-scheme" value="always" required>Always Sync</label>
<p>App will always periodically synchronize with Proxmox. High resource usage.</p>
<label><input class="w3-radio" type="radio" id="sync-hash" name="sync-scheme" value="hash" required>Check For Sync</label>
<p>App will periodically check for updates and synchronize only if needed. Medium resource usage.</p>
<label><input class="w3-radio" type="radio" id="sync-interrupt" name="sync-scheme" value="interrupt" required>Sync When Needed</label>
<p>App will react to changes and synchronize when changes are made. Low resource usage.</p>
<label><input class="w3-radio" type="radio" id="sync-never" name="sync-scheme" value="never" required>Never Sync</label>
<p>App will never automatically sync. Reload the page to sync the latest cluster state.</p>
</fieldset>
<fieldset>
<legend>App Sync Frequency</legend>
<div class="input-grid" style="grid-template-columns: auto auto 1fr;">
<p>Sync every</p><input aria-label="sync rate in seconds" class="w3-input w3-border" type="number" id="sync-rate" name="sync-rate" min="1" required><p>Second(s)</p>
</div>
</fieldset>
</section>
<section class="w3-card w3-padding">
<h3>Search Settings</h3>
<fieldset>
<legend>Instance Search Criteria</legend>
<label><input class="w3-radio" type="radio" id="search-exact" name="search-criteria" value="exact" required>Exact Match</label>
<p>Sorts by exact query match in instance name.</p>
<label><input class="w3-radio" type="radio" id="search-fuzzy" name="search-criteria" value="fuzzy" required>Fuzzy Match</label>
<p>Sorts by best matching to worst matching.</p>
</fieldset>
</section>
<section class="w3-card w3-padding">
<h3>Appearance</h3>
<fieldset>
<legend>Default Theme</legend>
<label>Theme<select class="w3-select w3-border" id="appearance-theme" name="appearance-theme" style="width: fit-content; padding-right: 24px;">
<option value="auto">Auto</option>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
</label>
</fieldset>
</section>
<div class="w3-container w3-center" id="form-actions">
<button class="w3-button w3-margin disabled" id="save" type="submit">SAVE</button>
</div>
</form>
</main>
</body>
</html>