fix formatting

This commit is contained in:
Arthur Lu 2023-05-17 21:40:37 +00:00
parent 2bb73ce828
commit 7141c0d23c
5 changed files with 96 additions and 96 deletions

View File

@ -1,5 +1,5 @@
import {requestPVE, requestAPI, goToPage, getURIData, resources_config, setTitleAndHeader} from "./utils.js";
import {alert, dialog} from "./dialog.js";
import { requestPVE, requestAPI, goToPage, getURIData, resources_config, setTitleAndHeader } from "./utils.js";
import { alert, dialog } from "./dialog.js";
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
@ -11,13 +11,13 @@ let type;
let vmid;
let config;
async function init () {
async function init() {
setTitleAndHeader();
let cookie = document.cookie;
if (cookie === "") {
goToPage("login.html");
}
let uriData = getURIData();
node = uriData.node;
type = uriData.type;
@ -32,27 +32,27 @@ async function init () {
document.querySelector("#exit").addEventListener("click", handleFormExit);
}
function getOrdered(keys){
let ordered_keys = Object.keys(keys).sort((a,b) => {parseInt(a) - parseInt(b)}); // ordered integer list
function getOrdered(keys) {
let ordered_keys = Object.keys(keys).sort((a, b) => { parseInt(a) - parseInt(b) }); // ordered integer list
return ordered_keys;
}
async function getConfig () {
async function getConfig() {
config = await requestPVE(`/nodes/${node}/${type}/${vmid}/config`, "GET");
}
function populateResources () {
function populateResources() {
let name = type === "qemu" ? "name" : "hostname";
document.querySelector("#name").innerHTML = document.querySelector("#name").innerHTML.replace("%{vmname}", config.data[name]);
addResourceLine("resources", "images/resources/cpu.svg", "Cores", {type: "number", value: config.data.cores, min: 1, max: 8192}, "Threads");
addResourceLine("resources", "images/resources/ram.svg", "Memory", {type: "number", value: config.data.memory, min: 16, step: 1}, "MiB");
addResourceLine("resources", "images/resources/cpu.svg", "Cores", { type: "number", value: config.data.cores, min: 1, max: 8192 }, "Threads");
addResourceLine("resources", "images/resources/ram.svg", "Memory", { type: "number", value: config.data.memory, min: 16, step: 1 }, "MiB");
if (type === "lxc") {
addResourceLine("resources", "images/resources/swap.svg", "Swap", {type: "number", value: config.data.swap, min: 0, step: 1}, "MiB");
addResourceLine("resources", "images/resources/swap.svg", "Swap", { type: "number", value: config.data.swap, min: 0, step: 1 }, "MiB");
}
}
function addResourceLine (fieldset, iconHref, labelText, inputAttr, unitText=null) {
function addResourceLine(fieldset, iconHref, labelText, inputAttr, unitText = null) {
let field = document.querySelector(`#${fieldset}`);
let icon = document.createElement("img");
@ -83,9 +83,9 @@ function addResourceLine (fieldset, iconHref, labelText, inputAttr, unitText=nul
}
}
function populateDisk () {
function populateDisk() {
document.querySelector("#disks").innerHTML = "";
for(let i = 0; i < diskMetaData[type].prefixOrder.length; i++){
for (let i = 0; i < diskMetaData[type].prefixOrder.length; i++) {
let prefix = diskMetaData[type].prefixOrder[i];
let busName = diskMetaData[type][prefix].name;
let disks = {};
@ -108,12 +108,12 @@ function populateDisk () {
}
}
function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
function addDiskLine(fieldset, busPrefix, busName, device, diskDetails) {
let field = document.querySelector(`#${fieldset}`);
let diskName = `${busName} ${device}`;
let diskID = `${busPrefix}${device}`;
// Set the disk icon, either drive.svg or disk.svg
let icon = document.createElement("img");
icon.src = diskMetaData[type][busPrefix].icon;
@ -138,12 +138,12 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
diskMetaData.actionBarOrder.forEach((element) => {
let action = document.createElement("img");
action.classList.add("clickable");
if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("attach")){ // attach
if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("attach")) { // attach
action.src = "images/actions/disk/attach.svg";
action.title = "Attach Disk";
action.addEventListener("click", handleDiskAttach);
}
else if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("detach")){ // detach
else if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("detach")) { // detach
action.src = "images/actions/disk/detach.svg";
action.title = "Detach Disk";
action.addEventListener("click", handleDiskDetach);
@ -154,7 +154,7 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
action.title = "Delete Disk";
if (active === "active") {
action.addEventListener("click", handleDiskDelete);
}
}
}
else {
let active = diskMetaData[type][busPrefix].actions.includes(element) ? "active" : "inactive"; // resize
@ -176,7 +176,7 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
field.append(actionDiv);
}
async function handleDiskDetach () {
async function handleDiskDetach() {
let header = `Detach ${this.dataset.disk}`;
let body = `<p>Are you sure you want to detach disk</p><p>${this.dataset.disk}</p>`;
dialog(header, body, async (result, form) => {
@ -202,7 +202,7 @@ async function handleDiskDetach () {
});
}
async function handleDiskAttach () {
async function handleDiskAttach() {
let diskImage = config.data[this.dataset.disk];
let header = `Attach ${diskImage}`;
@ -211,7 +211,7 @@ async function handleDiskAttach () {
dialog(header, body, async (result, form) => {
if (result === "confirm") {
let device = form.get("device");
document.querySelector(`img[data-disk="${this.dataset.disk}"]`).src = "images/status/loading.svg";
document.querySelector(`img[data-disk="${this.dataset.disk}"]`).src = "images/status/loading.svg";
let body = {
node: node,
type: type,
@ -233,8 +233,8 @@ async function handleDiskAttach () {
});
}
async function handleDiskResize () {
let header = `Resize ${this.dataset.disk}`;
async function handleDiskResize() {
let header = `Resize ${this.dataset.disk}`;
let body = `<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"></input>`;
dialog(header, body, async (result, form) => {
@ -252,7 +252,7 @@ async function handleDiskResize () {
await getConfig();
populateDisk();
}
else{
else {
alert(result.error);
await getConfig();
populateDisk();
@ -261,7 +261,7 @@ async function handleDiskResize () {
});
}
async function handleDiskMove () {
async function handleDiskMove() {
let content = type === "qemu" ? "images" : "rootdir";
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
@ -269,7 +269,7 @@ async function handleDiskMove () {
let options = "";
storage.data.forEach((element) => {
if (element.content.includes(content)){
if (element.content.includes(content)) {
options += `<option value="${element.storage}">${element.storage}</option>"`;
}
});
@ -289,7 +289,7 @@ async function handleDiskMove () {
vmid: vmid,
disk: this.dataset.disk,
storage: form.get("storage-select"),
delete: form.get("delete-check") === "on" ? "1": "0"
delete: form.get("delete-check") === "on" ? "1" : "0"
}
let result = await requestAPI("/instance/disk/move", "POST", body);
if (result.status === 200) {
@ -305,7 +305,7 @@ async function handleDiskMove () {
});
}
async function handleDiskDelete () {
async function handleDiskDelete() {
let header = `Delete ${this.dataset.disk}`;
let body = `<p>Are you sure you want to <strong>delete</strong> disk</p><p>${this.dataset.disk}</p>`;
@ -332,15 +332,15 @@ async function handleDiskDelete () {
});
}
async function handleDiskAdd () {
async function handleDiskAdd() {
let content = type === "qemu" ? "images" : "rootdir";
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
let header = "Create New Disk";
let options = "";
storage.data.forEach((element) => {
if (element.content.includes(content)){
if (element.content.includes(content)) {
options += `<option value="${element.storage}">${element.storage}</option>"`;
}
});
@ -376,15 +376,15 @@ async function handleDiskAdd () {
});
}
async function handleCDAdd () {
async function handleCDAdd() {
let content = "iso";
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
let header = `Add a CDROM`;
let storageOptions = "";
storage.data.forEach((element) => {
if (element.content.includes(content)){
if (element.content.includes(content)) {
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
}
});
@ -422,7 +422,7 @@ async function handleCDAdd () {
let storage = document.querySelector("#storage-select").value;
let ISOSelect = document.querySelector("#iso-select");
ISOSelect.innerHTML = `<option hidden disabled selected value></option>`;
let isos = await requestPVE(`/nodes/${node}/storage/${storage}/content`, "GET", {content: content});
let isos = await requestPVE(`/nodes/${node}/storage/${storage}/content`, "GET", { content: content });
isos.data.forEach((element) => {
if (element.content.includes(content)) {
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
@ -431,7 +431,7 @@ async function handleCDAdd () {
});
}
function populateNetworks () {
function populateNetworks() {
document.querySelector("#networks").innerHTML = "";
let networks = {};
let prefix = networkMetaData.prefix;
@ -446,7 +446,7 @@ function populateNetworks () {
});
}
function addNetworkLine (fieldset, prefix, netID, netDetails) {
function addNetworkLine(fieldset, prefix, netID, netDetails) {
let field = document.querySelector(`#${fieldset}`);
let icon = document.createElement("img");
@ -481,12 +481,12 @@ function addNetworkLine (fieldset, prefix, netID, netDetails) {
field.append(actionDiv);
}
async function handleNetworkConfig () {
async function handleNetworkConfig() {
let netID = this.dataset.network;
let netDetails = this.dataset.netvals;
let header = `Edit ${netID}`;
let body = `<label for="rate">Rate Limit (MB/s)</label><input type="number" id="rate" name="rate" class="w3-input w3-border">`;
let d = dialog(header, body, async (result, form) => {
if (result === "confirm") {
document.querySelector(`img[data-network="${netID}"]`).src = "images/status/loading.svg";
@ -502,7 +502,7 @@ async function handleNetworkConfig () {
await getConfig();
populateNetworks();
}
else{
else {
alert(result.error);
await getConfig();
populateNetworks();
@ -513,7 +513,7 @@ async function handleNetworkConfig () {
d.querySelector("#rate").value = netDetails.split("rate=")[1].split(",")[0];
}
async function handleFormExit () {
async function handleFormExit() {
let body = {
node: node,
type: type,

View File

@ -1,4 +1,4 @@
export function dialog (header, body, callback = async (result, form) => {}) {
export function dialog(header, body, callback = async (result, form) => { }) {
let dialog = document.createElement("dialog");
dialog.innerHTML = `
<p class="w3-large" id="prompt" style="text-align: center;"></p>
@ -23,7 +23,7 @@ export function dialog (header, body, callback = async (result, form) => {}) {
return dialog;
}
export function alert (message) {
export function alert(message) {
let dialog = document.createElement("dialog");
dialog.innerHTML = `
<form method="dialog">

View File

@ -1,23 +1,23 @@
import {requestPVE, requestAPI, goToPage, goToURL, instances_config, nodes_config, setTitleAndHeader} from "./utils.js";
import {alert, dialog} from "./dialog.js";
import {PVE} from "../vars.js"
import { requestPVE, requestAPI, goToPage, goToURL, instances_config, nodes_config, setTitleAndHeader } from "./utils.js";
import { alert, dialog } from "./dialog.js";
import { PVE } from "../vars.js"
window.addEventListener("DOMContentLoaded", init);
async function init () {
async function init() {
setTitleAndHeader();
let cookie = document.cookie;
if (cookie === "") {
goToPage("login.html");
}
await populateInstances();
let addInstanceBtn = document.querySelector("#instance-add");
addInstanceBtn.addEventListener("click", handleInstanceAdd);
}
async function populateInstances () {
async function populateInstances() {
let resources = await requestPVE("/cluster/resources", "GET");
let instanceContainer = document.getElementById("instance-container");
let instances = [];
@ -26,7 +26,7 @@ async function populateInstances () {
if (element.type === "lxc" || element.type === "qemu") {
let nodeName = element.node;
let nodeStatus = resources.data.find(item => item.node === nodeName && item.type === "node").status;
element.node = {name: nodeName, status: nodeStatus};
element.node = { name: nodeName, status: nodeStatus };
instances.push(element);
}
});
@ -58,14 +58,14 @@ async function populateInstances () {
</div>
</div>
`;
for(let i = 0; i < instances.length; i++) {
for (let i = 0; i < instances.length; i++) {
let newInstance = new Instance();
newInstance.data = instances[i];
instanceContainer.append(newInstance.shadowElement);
}
}
async function handleInstanceAdd () {
async function handleInstanceAdd() {
let header = "Create New Instance";
let body = `
@ -130,7 +130,7 @@ async function handleInstanceAdd () {
let typeSelect = d.querySelector("#type");
typeSelect.selectedIndex = -1;
typeSelect.addEventListener("change", () => {
if(typeSelect.value === "qemu") {
if (typeSelect.value === "qemu") {
d.querySelectorAll(".container-specific").forEach((element) => {
element.classList.add("none");
element.disabled = true;
@ -198,7 +198,7 @@ async function handleInstanceAdd () {
}
export class Instance {
constructor () {
constructor() {
let shadowRoot = document.createElement("div");
shadowRoot.classList.add("w3-row");
@ -235,7 +235,7 @@ export class Instance {
this.actionLock = false;
}
set data (data) {
set data(data) {
if (data.status === "unknown") {
data.status = "stopped";
}
@ -247,7 +247,7 @@ export class Instance {
this.update();
}
update () {
update() {
let vmidParagraph = this.shadowElement.querySelector("#instance-id");
vmidParagraph.innerText = this.vmid;
@ -306,9 +306,9 @@ export class Instance {
}
}
async handlePowerButton () {
async handlePowerButton() {
if(!this.actionLock) {
if (!this.actionLock) {
let header = `${this.status === "running" ? "Stop" : "Start"} VM ${this.vmid}`;
let body = `<p>Are you sure you want to ${this.status === "running" ? "stop" : "start"} VM</p><p>${this.vmid}</p>`
@ -322,13 +322,13 @@ export class Instance {
this.update();
let result = await requestPVE(`/nodes/${this.node.name}/${this.type}/${this.vmid}/status/${targetAction}`, "POST", {node: this.node.name, vmid: this.vmid});
let result = await requestPVE(`/nodes/${this.node.name}/${this.type}/${this.vmid}/status/${targetAction}`, "POST", { node: this.node.name, vmid: this.vmid });
const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay));
while (true) {
let taskStatus = await requestPVE(`/nodes/${this.node.name}/tasks/${result.data}/status`, "GET");
if(taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
if (taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
this.status = targetStatus;
this.update();
this.actionLock = false;
@ -341,7 +341,7 @@ export class Instance {
this.actionLock = false;
break;
}
else{ // task has not stopped
else { // task has not stopped
await waitFor(1000);
}
}
@ -350,21 +350,21 @@ export class Instance {
}
}
handleConfigButton () {
handleConfigButton() {
if (!this.actionLock && this.status === "stopped") { // if the action lock is false, and the node is stopped, then navigate to the conig page with the node infor in the search query
goToPage("config.html", {node: this.node.name, type: this.type, vmid: this.vmid});
goToPage("config.html", { node: this.node.name, type: this.type, vmid: this.vmid });
}
}
handleConsoleButton () {
handleConsoleButton() {
if (!this.actionLock && this.status === "running") {
let data = {console: `${this.type === "qemu" ? "kvm" : "lxc"}`, vmid: this.vmid, vmname: this.name, node: this.node.name, resize: "off", cmd: ""};
let data = { console: `${this.type === "qemu" ? "kvm" : "lxc"}`, vmid: this.vmid, vmname: this.name, node: this.node.name, resize: "off", cmd: "" };
data[`${this.type === "qemu" ? "novnc" : "xtermjs"}`] = 1;
goToURL(PVE, data, true);
}
}
handleDeleteButton () {
handleDeleteButton() {
if (!this.actionLock && this.status === "stopped") {
let header = `Delete VM ${this.vmid}`;

View File

@ -1,9 +1,9 @@
import {requestTicket, goToPage, deleteAllCookies, requestPVE, setTitleAndHeader} from "./utils.js";
import {alert} from "./dialog.js";
import { requestTicket, goToPage, deleteAllCookies, requestPVE, setTitleAndHeader } from "./utils.js";
import { alert } from "./dialog.js";
window.addEventListener("DOMContentLoaded", init);
async function init (){
async function init() {
setTitleAndHeader();
await deleteAllCookies();
let formSubmitButton = document.querySelector("#submit");
@ -11,7 +11,7 @@ async function init (){
let realmSelect = document.querySelector("#realm");
realms.data.forEach((element) => {
realmSelect.add(new Option(element.comment, element.realm));
if("default" in element && element.default === 1){
if ("default" in element && element.default === 1) {
realmSelect.value = element.realm;
}
});
@ -23,7 +23,7 @@ async function init (){
formSubmitButton.innerText = "Authenticating...";
let ticket = await requestTicket(formData.get("username"), formData.get("password"), formData.get("realm"));
if (ticket.status === 200) {
formSubmitButton.innerText = "LOGIN";
formSubmitButton.innerText = "LOGIN";
goToPage("index.html");
}
else if (ticket.status === 401) {

View File

@ -1,19 +1,19 @@
import {API, organization} from "/vars.js";
import { API, organization } from "/vars.js";
export const resources_config = {
disk: {
actionBarOrder: ["move", "resize", "detach_attach", "delete"],
lxc: {
prefixOrder: ["rootfs", "mp", "unused"],
rootfs: {name: "ROOTFS", icon: "images/resources/drive.svg", actions: ["move", "resize"]},
mp: {name: "MP", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"]},
unused: {name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"]}
rootfs: { name: "ROOTFS", icon: "images/resources/drive.svg", actions: ["move", "resize"] },
mp: { name: "MP", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"] },
unused: { name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"] }
},
qemu: {
prefixOrder: ["ide", "sata", "unused"],
ide: {name: "IDE", icon: "images/resources/disk.svg", actions: ["delete"]},
sata: {name: "SATA", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"]},
unused: {name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"]}
ide: { name: "IDE", icon: "images/resources/disk.svg", actions: ["delete"] },
sata: { name: "SATA", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"] },
unused: { name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"] }
}
},
network: {
@ -79,7 +79,7 @@ export function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(";");
for(let i = 0; i < ca.length; i++) {
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
@ -91,12 +91,12 @@ export function getCookie(cname) {
return "";
}
export async function requestTicket (username, password, realm) {
let response = await requestAPI("/ticket", "POST", {username: `${username}@${realm}`, password: password}, false);
export async function requestTicket(username, password, realm) {
let response = await requestAPI("/ticket", "POST", { username: `${username}@${realm}`, password: password }, false);
return response;
}
export async function requestPVE (path, method, body = null) {
export async function requestPVE(path, method, body = null) {
let prms = new URLSearchParams(body);
let content = {
method: method,
@ -106,7 +106,7 @@ export async function requestPVE (path, method, body = null) {
"Content-Type": "application/x-www-form-urlencoded"
}
}
if(method === "POST") {
if (method === "POST") {
content.body = prms.toString();
content.headers.CSRFPreventionToken = getCookie("CSRFPreventionToken");
}
@ -115,7 +115,7 @@ export async function requestPVE (path, method, body = null) {
return response;
}
export async function requestAPI (path, method, body = null) {
export async function requestAPI(path, method, body = null) {
let prms = new URLSearchParams(body);
let content = {
method: method,
@ -136,7 +136,7 @@ export async function requestAPI (path, method, body = null) {
return response;
}
async function request (url, content) {
async function request(url, content) {
let response = await fetch(url, content);
let data = null;
@ -148,8 +148,8 @@ async function request (url, content) {
data = null;
}
if(!response.ok){
return {status: response.status, error: data ? data.error : response.status};
if (!response.ok) {
return { status: response.status, error: data ? data.error : response.status };
}
else {
data.status = response.status;
@ -157,9 +157,9 @@ async function request (url, content) {
}
}
export function goToPage (page, data={}, newwindow = false) {
export function goToPage(page, data = {}, newwindow = false) {
let url = new URL(`https://${window.location.host}/${page}`);
for(let k in data) {
for (let k in data) {
url.searchParams.append(k, data[k]);
}
@ -171,9 +171,9 @@ export function goToPage (page, data={}, newwindow = false) {
}
}
export function goToURL (href, data={}, newwindow = false) {
export function goToURL(href, data = {}, newwindow = false) {
let url = new URL(href);
for(let k in data) {
for (let k in data) {
url.searchParams.append(k, data[k]);
}
@ -185,16 +185,16 @@ export function goToURL (href, data={}, newwindow = false) {
}
}
export function getURIData () {
export function getURIData() {
let url = new URL(window.location.href);
return Object.fromEntries(url.searchParams);
}
export async function deleteAllCookies () {
export async function deleteAllCookies() {
await requestAPI("/ticket", "DELETE");
}
export function setTitleAndHeader () {
export function setTitleAndHeader() {
document.title = `${organization} - client`;
document.querySelector("h1").innerText = organization;
}