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

+121
View File
@@ -0,0 +1,121 @@
{{define "backup-card"}}
<backup-card data-volid="{{.Volid}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/modules/w3.css">
<link rel="stylesheet" href="websrc/css/style.css">
<style>
* {
margin: 0;
}
a {
height: 1em;
width: 1em;
margin: 0;
padding: 0;
}
</style>
<div class="w3-row" style="margin-top: 1em; margin-bottom: 1em;">
<p class="w3-col l2 m4 s8">{{.TimeFormatted}}</p>
<p class="w3-col l6 m6 hide-small">{{.Notes}}</p>
<p class="w3-col l2 hide-medium">{{.SizeFormatted}}</p>
<div class="w3-col l2 m2 s4 flex row nowrap" style="height: 1lh;">
<img id="edit-btn" class="clickable" alt="change notes" src="websrc/images/actions/backups/config.svg#symb">
<img id="delete-btn" class="clickable" alt="delete backup" role="button" tabindex=0 src="websrc/images/actions/backups/delete-active.svg#symb">
<img id="restore-btn" class="clickable" alt="restore from backup" role="button" tabindex=0 src="websrc/images/actions/backups/restore.svg#symb">
</div>
</div>
<template id="edit-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">
Edit Backup
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto;" id="form">
<label for="rate">Notes</label>
<textarea id="notes" name="notes" class="w3-input w3-border">{{.Notes}}</textarea>
</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>
<template id="delete-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">
Delete Backup
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>
Are you sure you want to <strong>delete</strong> the backup made at {{.TimeFormatted}}?
</p>
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" value="confirm" form="form" class="w3-button w3-margin" >CONFIRM</button>
</div>
</dialog>
</template>
<template id="restore-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">
Restore From Backup?
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>
Are you sure you want to <strong>restore</strong> from the backup made at {{.TimeFormatted}}?
<br>
<br>
<strong>WARNING: Restoring from a backup will WIPE disks NOT contained in the backup!!!</strong>
</p>
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" value="confirm" form="form" class="w3-button w3-margin" >CONFIRM</button>
</div>
</dialog>
</template>
</template>
</backup-card>
{{end}}
{{define "backups-add-backup"}}
<button type="button" id="backup-add" class="w3-button" aria-label="Create Backup">
<span class="large" style="margin: 0;">Create Backup</span>
<img class="small" role="img" style="height: 1lh; width: 1lh;" alt="Create Backup" src="websrc/images/actions/network/add.svg#symb">
</button>
<template id="create-backup-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">
Create Backup
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto;" id="form">
<label for="rate">Notes</label>
<textarea id="notes" name="notes" class="w3-input w3-border">{{.Notes}}</textarea>
</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>
{{end}}
+35
View File
@@ -0,0 +1,35 @@
{{/* <head> common across all pages */}}
{{define "head"}}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.global.Organization}} - dashboard</title>
<link rel="icon" href="websrc/images/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="websrc/modules/w3.css">
<script>
window.PVE = "{{.global.PVE}}";
window.API = "{{.global.API}}";
window.DASH = "{{.global.DASH}}";
</script>
<link rel="stylesheet" href="websrc/css/style.css">
<link rel="stylesheet" href="websrc/css/nav.css">
<link rel="stylesheet" href="websrc/css/form.css">
{{end}}
{{/* <header> common across all pages */}}
{{define "header"}}
<header>
<h1>{{.global.Organization}}</h1>
<label for="navtoggle">&#9776;</label>
<input type="checkbox" id="navtoggle">
<nav id="navigation">
{{if eq .page "login"}}
<a href="login" aria-current="page">Login</a>
{{else}}
<a href="index" {{if eq .page "index"}} aria-current="page" {{end}}>Instances</a>
<a href="account" {{if eq .page "account"}} aria-current="page" {{end}}>Account</a>
<a href="settings" {{if eq .page "settings"}} aria-current="page" {{end}}>Settings</a>
<a href="login">Logout</a>
{{end}}
</nav>
</header>
{{end}}
+561
View File
@@ -0,0 +1,561 @@
{{define "proctype-input"}}
<img alt="CPU Type" src="websrc/images/resources/cpu.svg#symb">
<label for="proctype">CPU Type</label>
{{template "select" .}}
<div></div>
{{end}}
{{define "cores-input"}}
<img alt="CPU Amount" src="websrc/images/resources/cpu.svg#symb">
<label for="cores">CPU Amount</label>
<input id="cores" name="cores" class="w3-input w3-border" type="number" required value="{{.}}">
<p>Cores</p>
{{end}}
{{define "memory-input"}}
<img alt="Memory Amount" src="websrc/images/resources/ram.svg#symb">
<label for="ram">Memory</label>
<input id="ram" name="ram" class="w3-input w3-border" type="number" required value="{{.}}">
<p>MiB</p>
{{end}}
{{define "swap-input"}}
<img alt="Swap Amount" src="websrc/images/resources/swap.svg#symb">
<label for="swap">Swap</label>
<input id="swap" name="swap" class="w3-input w3-border" type="number" required value="{{.}}">
<p>MiB</p>
{{end}}
{{define "volumes"}}
{{range $k,$v := .Volumes}}
{{if eq $v.Type "rootfs"}}
{{ template "volume-rootfs" Map "Name" $k "Volume" $v "InstanceType" $.InstanceType}}
{{else if eq $v.Type "mp"}}
{{ template "volume-mp" Map "Name" $k "Volume" $v "InstanceType" $.InstanceType}}
{{else if eq $v.Type "ide"}}
{{ template "volume-ide" Map "Name" $k "Volume" $v "InstanceType" $.InstanceType}}
{{else if or (eq $v.Type "scsi") (eq $v.Type "sata")}}
{{ template "volume-scsi" Map "Name" $k "Volume" $v "InstanceType" $.InstanceType}}
{{else if eq $v.Type "unused"}}
{{ template "volume-unused" Map "Name" $k "Volume" $v "InstanceType" $.InstanceType}}
{{else}}
{{end}}
{{end}}
{{end}}
{{define "volumes-add-disk"}}
<button type="button" id="disk-add" class="w3-button" aria-label="Add New Disk">
<span class="large" style="margin: 0;">Add Disk</span>
<img class="small" style="height: 1lh; width: 1lh;" alt="Add New Disk" src="websrc/images/actions/disk/add-disk.svg#symb">
</button>
<template id="add-disk-dialog">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Create New Disk
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
{{if eq .config.Type "VM"}}
<label for="device">SCSI</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="30" value="0" required>
{{else}}
<label for="device">MP</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="255" value="0" required>
{{end}}
<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required></select>
<label for="size">Size (GiB)</label><input class="w3-input w3-border" name="size" id="size" type="number" min="0" max="131072" 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>
{{end}}
{{define "volumes-add-cd"}}
<button type="button" id="cd-add" class="w3-button" aria-label="Add New CD">
<span class="large" style="margin: 0;">Mount CD</span>
<img class="small" style="height: 1lh; width: 1lh;" alt="Add New CDROM" src="websrc/images/actions/disk/add-cd.svg#symb">
</button>
<template id="add-cd-dialog">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Mount a CDROM
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="device">IDE</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="3" required>
<label for="iso-select">Image</label><select class="w3-select w3-border" name="iso-select" id="iso-select" required></select>
</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>
{{end}}
{{define "volume-rootfs"}}
<img data-volume={{.Name}} alt="Drive" src="websrc/images/resources/drive.svg#symb">
<p>{{.Name}}</p>
<p>{{.Volume.File}}</p>
<div>
{{template "volume-action-move" .}}
{{template "volume-action-resize" .}}
{{template "volume-action-none" .}}
{{template "volume-action-none" .}}
</div>
{{end}}
{{define "volume-mp"}}
<img data-volume={{.Name}} alt="Drive" src="websrc/images/resources/drive.svg#symb">
<p>{{.Name}}</p>
<p>{{.Volume.File}}</p>
<div>
{{template "volume-action-move" .}}
{{template "volume-action-resize" .}}
{{template "volume-action-detach" .}}
{{template "volume-action-delete-inactive" .}}
</div>
{{end}}
{{define "volume-ide"}}
<img data-volume={{.Name}} alt="Drive" src="websrc/images/resources/drive.svg#symb">
<p>{{.Name}}</p>
<p>{{.Volume.File}}</p>
<div>
{{template "volume-action-none" .}}
{{template "volume-action-none" .}}
{{template "volume-action-none" .}}
{{template "volume-action-delete" .}}
</div>
{{end}}
{{define "volume-scsi"}}
<img data-volume={{.Name}} alt="Drive" src="websrc/images/resources/drive.svg#symb">
<p>{{.Name}}</p>
<p>{{.Volume.File}}</p>
<div>
{{template "volume-action-move" .}}
{{template "volume-action-resize" .}}
{{template "volume-action-detach" .}}
{{template "volume-action-delete-inactive" .}}
</div>
{{end}}
{{define "volume-unused"}}
<img data-volume={{.Name}} alt="Drive" src="websrc/images/resources/drive.svg#symb">
<p>{{.Name}}</p>
<p>{{.Volume.File}}</p>
<div>
{{template "volume-action-move-inactive" .}}
{{template "volume-action-resize-inactive" .}}
{{template "volume-action-attach" .}}
{{template "volume-action-delete" .}}
</div>
{{end}}
{{define "volume-action-move"}}
<volume-action data-type="move" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Move {{.Name}}" src="websrc/images/actions/disk/move-active.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Move {{.Name}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select"></select>
<label for="delete-check">Delete Source</label><input class="w3-input w3-border" name="delete-check" id="delete-check" type="checkbox" checked 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>
</template>
</volume-action>
{{end}}
{{define "volume-action-move-inactive"}}
<volume-action data-type="none" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img alt="" src="websrc/images/actions/disk/move-inactive.svg#symb">
</template>
</volume-action>
{{end}}
{{define "volume-action-resize"}}
<volume-action data-type="resize" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Resize {{.Name}}" src="websrc/images/actions/disk/resize-active.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Resize {{.Name}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="size-increment">Size Increment (GiB)</label>
<input class="w3-input w3-border" name="size-increment" id="size-increment" type="number" min="0" max="131072">
</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>
</template>
</volume-action>
{{end}}
{{define "volume-action-resize-inactive"}}
<volume-action data-type="none" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img alt="" src="websrc/images/actions/disk/resize-inactive.svg#symb">
</template>
</volume-action>
{{end}}
{{define "volume-action-delete"}}
<volume-action data-type="delete" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Delete {{.Name}}" src="websrc/images/actions/disk/delete-active.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Delete {{.Name}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>Are you sure you want to <strong>delete</strong> disk {{.Name}}?</p>
</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>
</template>
</volume-action>
{{end}}
{{define "volume-action-delete-inactive"}}
<volume-action data-type="none" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img alt="" src="websrc/images/actions/disk/delete-inactive.svg#symb">
</template>
</volume-action>
{{end}}
{{define "volume-action-attach"}}
<volume-action data-type="attach" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Attach {{.Name}}" src="websrc/images/actions/disk/attach.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Attach {{.Name}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
{{if eq .InstanceType "VM"}}
<label for="device">SCSI</label>
<input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="30" required>
{{else}}
<label for="device">MP</label>
<input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="255" required>
<label for="device">Path</label>
<input class="w3-input w3-border" name="mp" id="mp" required>
{{end}}
</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>
</template>
</volume-action>
{{end}}
{{define "volume-action-detach"}}
<volume-action data-type="detach" data-volume="{{.Name}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Detach {{.Name}}" src="websrc/images/actions/disk/detach.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Detach {{.Name}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>Are you sure you want to detach disk {{.Name}}?</p>
</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>
</template>
</volume-action>
{{end}}
{{define "volume-action-none"}}
<volume-action data-type="none">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img alt="" src="websrc/images/common/blank.svg">
</template>
</volume-action>
{{end}}
{{define "nets"}}
{{range $k,$v := .}}
{{template "net" $v}}
{{end}}
{{end}}
{{define "nets-add-net"}}
<button type="button" id="network-add" class="w3-button" aria-label="Add New Network Interface">
<span class="large" style="margin: 0;">Add Network</span>
<img class="small" style="height: 1lh; width: 1lh;" alt="Add New Network Interface" src="websrc/images/actions/network/add.svg#symb">
</button>
<template id="add-net-dialog">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Create Network Interface
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="netid">Interface ID</label><input type="number" id="netid" name="netid" class="w3-input w3-border">
<label for="rate">Rate Limit (MB/s)</label><input type="number" id="rate" name="rate" class="w3-input w3-border">
{{if eq .config.Type "CT"}}
<label for="name">Interface Name</label><input type="text" id="name" name="name" class="w3-input w3-border">
{{end}}
</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>
{{end}}
{{define "net"}}
<img data-network="{{.Net_ID}}" alt="Net {{.Net_ID}}" src="websrc/images/resources/network.svg#symb">
<p>{{.Net_ID}}</p>
<p>{{.Value}}</p>
<div>
<network-action data-type="config" data-network="{{.Net_ID}}" data-value="{{.Value}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Configure Net {{.Net_ID}}" src="websrc/images/actions/network/config.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Edit {{.Net_ID}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="rate">Rate Limit (MB/s)</label><input type="number" id="rate" name="rate" class="w3-input w3-border">
</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>
</template>
</network-action>
<network-action data-type="delete" data-network="{{.Net_ID}}" data-value="{{.Value}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Delete Net {{.Net_ID}}" src="websrc/images/actions/network/delete-active.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Delete {{.Net_ID}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>Are you sure you want to <strong>delete</strong> {{.Net_ID}}?</p>
</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>
</template>
</network-action>
</div>
{{end}}
{{define "devices"}}
{{range $k,$v := .}}
{{template "device" $v}}
{{end}}
{{end}}
{{define "devices-add-device"}}
<button type="button" id="device-add" class="w3-button" aria-label="Add New PCIe Device">
<span class="large" style="margin: 0;">Add Device</span>
<img class="small" style="height: 1lh; width: 1lh;" alt="Add New PCIe Device" src="websrc/images/actions/device/add.svg#symb">
</button>
<template id="add-device-dialog">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Add Expansion Card
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="hostpci">Device Bus</label><input type="number" id="hostpci" name="hostpci" class="w3-input w3-border">
<label for="device">Device</label><select id="device" name="device" required></select>
<label for="pcie">PCI-Express</label><input type="checkbox" id="pcie" name="pcie" class="w3-input w3-border">
</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>
{{end}}
{{define "device"}}
<img data-device="{{.Device_ID}}" alt="Device {{.Device_ID}}" src="websrc/images/resources/device.svg#symb">
<p>{{.Device_ID}}</p>
<p>{{.Device_Name}}</p>
<div>
<device-action data-type="config" data-device="{{.Device_ID}}" data-value="{{.Device_ID}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Configure Device {{.Device_ID}}" src="websrc/images/actions/device/config.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
Edit Expansion Card {{.Device_ID}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="device">Device</label><select id="device" name="device" required></select><label for="pcie">PCI-Express</label><input type="checkbox" id="pcie" name="pcie" class="w3-input w3-border">
</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>
</template>
</device-action>
<device-action data-type="delete" data-device="{{.Device_ID}}" data-value="{{.Device_ID}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/css/style.css">
<img class="clickable" alt="Delete Device {{.Device_ID}}" src="websrc/images/actions/device/delete-active.svg#symb">
<template id="dialog-template">
<dialog class="w3-container w3-card w3-border-0">
<p class="w3-large" id="prompt">
remove Expansion Card {{.Device_ID}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>Are you sure you want to <strong>remove</strong> {{.Device_ID}}?</p>
</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>
</template>
</device-action>
</div>
{{end}}
{{define "boot"}}
{{template "boot-container" Map "ID" "enabled" "Name" "Enabled" "Targets" .Enabled}}
<hr style="padding: 0; margin: 0;">
{{template "boot-container" Map "ID" "disabled" "Name" "Disabled" "Targets" .Disabled}}
{{end}}
{{define "boot-container"}}
<draggable-container id="{{.ID}}" data-group="boot">
<template shadowrootmode="open">
<style>
* {
box-sizing: border-box;
}
div.draggable-item.ghost {
border: 1px dashed var(--main-text-color);
border-radius: 5px;
margin: -1px;
}
div.draggable-item {
cursor: grab;
}
div.draggable-item img {
height: 1em;
width: 1em;
}
div.draggable-item p {
margin: 0;
}
div.draggable-item p.volume-file {
overflow: hidden;
white-space: nowrap;
}
#wrapper {
padding-bottom: 1em;
}
</style>
<label>{{.Name}}</label>
<div id="wrapper">
{{range .Targets}}
{{template "boot-target" .}}
{{end}}
</div>
</template>
</draggable-container>
{{end}}
{{define "boot-target"}}
{{if .volume_id}}
<div class="draggable-item" data-value="{{.volume_id}}" style="display: grid; grid-template-columns: auto auto 8ch 1fr; column-gap: 0.5em; align-items: center;">
<img alt="Drag" src="websrc/images/actions/drag.svg#symb">
<img alt="Volume" src="websrc/images/resources/drive.svg#symb">
<p class="volume-id">{{.volume_id}}</p>
<p class="volume-file">{{.file}}</p>
</div>
{{else if .net_id}}
<div class="draggable-item" data-value="{{.net_id}}" style="display: grid; grid-template-columns: auto auto 8ch 1fr; column-gap: 0.5em; align-items: center;">
<img alt="Drag" src="websrc/images/actions/drag.svg#symb">
<img alt="Net" src="websrc/images/resources/network.svg#symb">
<p class="volume-id">{{.net_id}}</p>
<p class="volume-file">{{.value}}</p>
</div>
{{else}}
{{end}}
{{end}}
+163
View File
@@ -0,0 +1,163 @@
{{define "instance-card"}}
<instance-card data-type="{{.Type}}" data-status="{{.Status}}" data-vmid="{{.VMID}}" data-name="{{.Name}}" data-node="{{.Node}}" data-nodestatus="{{.NodeStatus}}">
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/modules/w3.css">
<link rel="stylesheet" href="websrc/css/style.css">
<style>
* {
margin: 0;
padding: 0;
width: fit-content;
}
a, svg, img {
line-height: 1em;
height: 1em;
width: 1em;
margin: 0;
padding: 0;
}
a img {
vertical-align: unset;
}
#instance-name {
overflow-x: hidden;
min-width: 0;
width: auto;
white-space: nowrap;
}
.flex { /* needed for some reason to avoid a flickering issue on chrome ONLY */
display: flex;
}
.row { /* needed for some reason to avoid a flickering issue on chrome ONLY */
flex-direction: row;
column-gap: 0.5em;
align-items: center;
}
.nowrap { /* needed for some reason to avoid a flickering issue on chrome ONLY */
flex-wrap: nowrap;
}
@media screen and (width >=993px) {
.hide-large {display: none !important;}
}
@media screen and (width <=993px) and (width >=601px){
.hide-large {display: none !important;}
.hide-medium {display:none !important}
}
@media screen and (width <=601px) and (width >=440px){
.hide-large {display: none !important;}
.hide-medium {display:none !important}
.hide-small {display:none !important}
}
@media screen and (width <= 440px) {
.hide-large {display: none !important;}
.hide-medium {display:none !important}
.hide-small {display:none !important}
.hide-tiny { display: none !important;}
}
</style>
<p>{{.VMID}}</p>
<p id="instance-name">{{.Name}}</p>
<p class="hide-small">{{.Type}}</p>
<div class="flex row nowrap hide-tiny">
{{if eq .Status "running"}}
<img id="status" alt="instance is running" src="websrc/images/status/active.svg#symb">
{{else if eq .Status "stopped"}}
<img id="status" alt="instance is stopped" src="websrc/images/status/inactive.svg#symb">
{{else if eq .Status "loading"}}
<img id="status" alt="instance is loading" src="websrc/images/status/loading.svg#symb">
{{else}}
<img id="status" alt="instance is loading" src="websrc/images/status/loading.svg#symb">
{{end}}
<p>{{.Status}}</p>
</div>
<p class="hide-medium">{{.Node}}</p>
<div class="flex row nowrap hide-medium">
{{if eq .NodeStatus "online"}}
<img alt="node is online" src="websrc/images/status/active.svg#symb">
{{else if eq .NodeStatus "offline"}}
<img alt="node is offline" src="websrc/images/status/inactive.svg#symb">
{{else if eq .NodeStatus "unknown"}}
<img alt="node is offline" src="websrc/images/status/inactive.svg#symb">
{{else}}
{{end}}
<p>{{.NodeStatus}}</p>
</div>
<div class="flex row nowrap">
{{if and (eq .NodeStatus "online") (eq .Status "running")}}
<img id="power-btn" class="clickable" alt="shutdown instance" role="button" tabindex=0 src="websrc/images/actions/instance/stop.svg#symb">
<img id="configure-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/config-inactive.svg#symb">
<img id="backup-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/backup-inactive.svg#symb">
<a href="{{.ConsolePath}}" target="_blank">
<img id="console-btn" class="clickable" alt="open console" src="websrc/images/actions/instance/console-active.svg#symb">
</a>
<img id="delete-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/delete-inactive.svg#symb">
{{else if and (eq .NodeStatus "online") (eq .Status "stopped")}}
<img id="power-btn" class="clickable" alt="start instance" role="button" tabindex=0 src="websrc/images/actions/instance/start.svg#symb">
<a href="{{.ConfigPath}}">
<img id="configure-btn" class="clickable" alt="change configuration" src="websrc/images/actions/instance/config-active.svg#symb">
</a>
<a href="{{.BackupsPath}}">
<img id="backup-btn" class="clickable" alt="manage backups" src="websrc/images/actions/instance/backup-active.svg#symb">
</a>
<img id="console-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/console-inactive.svg#symb">
<img id="delete-btn" class="clickable" alt="delete instance" role="button" tabindex=0 src="websrc/images/actions/instance/delete-active.svg#symb">
{{else if and (eq .NodeStatus "online") (eq .Status "loading")}}
<img id="power-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/loading.svg#symb">
<img id="configure-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/config-inactive.svg#symb">
<img id="backup-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/backup-inactive.svg#symb">
<img id="console-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/console-inactive.svg#symb">
<img id="delete-btn" alt="" aria-disabled="true" role="none" src="websrc/images/actions/instance/delete-inactive.svg#symb">
{{else}}
{{end}}
</div>
<template id="power-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">
{{if eq .Status "running"}}
Stop {{.VMID}}
{{else if eq .Status "stopped"}}
Start {{.VMID}}
{{else}}
{{end}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
{{if eq .Status "running"}}
<p>Are you sure you want to <strong>stop</strong> {{.VMID}}?</p>
{{else if eq .Status "stopped"}}
<p>Are you sure you want to <strong>start</strong> {{.VMID}}?</p>
{{else}}
{{end}}
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" value="confirm" form="form" class="w3-button w3-margin" >CONFIRM</button>
</div>
</dialog>
</template>
<template id="delete-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">
Delete {{.VMID}}
</p>
<div id="body">
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<p>Are you sure you want to <strong>delete</strong> {{.VMID}}?</p>
</form>
</div>
<div id="controls" class="w3-center w3-container">
<button id="cancel" value="cancel" form="form" class="w3-button w3-margin" formnovalidate>CANCEL</button>
<button id="confirm" value="confirm" form="form" class="w3-button w3-margin">CONFIRM</button>
</div>
</dialog>
</template>
</template>
</instance-card>
{{end}}
+34
View File
@@ -0,0 +1,34 @@
{{define "pool-resources"}}
<section class="w3-card w3-padding">
<h3>Pool: {{.PoolID}}</h3>
<p id="vmid">VMID Range: {{.AllowedVMIDRange.Min}} - {{.AllowedVMIDRange.Max}}</p>
<p id="nodes">Nodes: {{MapKeys .AllowedNodes ", "}}</p>
<p id="backups">Max Backups Per Instance: {{.AllowedBackups.MaxPerInstance}} Max Backups Total: {{.AllowedBackups.MaxTotal}}</p>
<div>
{{range $category, $v := .ResourceCharts}}
{{if eq $category ""}}
<h4>Generic</h4>
{{else}}
<h4>{{$category}}</h4>
{{end}}
<div class="resource-container">
{{range $v}}
{{if .Display}}
{{if eq .Type "numeric"}}
{{template "resource-chart" .}}
{{end}}
{{if eq .Type "storage"}}
{{template "resource-chart" .}}
{{end}}
{{if eq .Type "list"}}
{{range .Resources}}
{{template "resource-chart" .}}
{{end}}
{{end}}
{{end}}
{{end}}
</div>
{{end}}
</div>
</section>
{{end}}
+44
View File
@@ -0,0 +1,44 @@
{{define "resource-chart"}}
<resource-chart>
<template shadowrootmode="open">
<link rel="stylesheet" href="websrc/modules/w3.css">
<link rel="stylesheet" href="websrc/css/style.css">
<style>
#container{
margin: 0;
width: 100%;
height: fit-content;
padding: 0.5em;
}
progress {
width: 100%;
border: 0;
height: 1em;
appearance: none;
}
#caption {
text-align: center;
margin-top: 0.5em;
display: flex;
flex-direction: column;
}
progress::-moz-progress-bar {
background: #{{.ColorHex}};
}
progress::-webkit-progress-bar {
background: var(--main-text-color);
}
progress::-webkit-progress-value {
background: #{{.ColorHex}};
}
</style>
<div id="container">
<progress value="{{.Used}}" max="{{.Max}}" id="resource"></progress>
<label id="caption" for="resource">
<span>{{.Name}}</span>
<span>{{.Avail}} {{.Prefix}}{{.Unit}} Avaliable</span>
</label>
</div>
</template>
</resource-chart>
{{end}}
+27
View File
@@ -0,0 +1,27 @@
{{/*
Select: generic data driven <select> element template
.ID = (string) select element id & name attribute
.Required = (bool) select element required attribute
.Options = ([]Options) array of Options
*/}}
{{define "select"}}
<select class="w3-select w3-border" id="{{.ID}}" name="{{.ID}}" {{if .Required}}required{{end}}>
{{range .Options}}
{{template "option" .}}
{{end}}
</select>
{{end}}
{{/*
Options: generic data driven <option> element template
.Selected = (bool) option element selected attribute
.Value = (string) option element value attribute
.Display = (string) option element innerText
*/}}
{{define "option"}}
{{if .Selected}}
<option value="{{.Value}}" selected>{{.Display}}</option>
{{else}}
<option value="{{.Value}}">{{.Display}}</option>
{{end}}
{{end}}