code cleanup on custom dialogs
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
This commit is contained in:
parent
a0fe199ccb
commit
822c89adda
@ -8,6 +8,7 @@
|
|||||||
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
<link rel="stylesheet" href="css/nav.css">
|
<link rel="stylesheet" href="css/nav.css">
|
||||||
|
<link rel="stylesheet" href="css/form.css">
|
||||||
<script src="scripts/index.js" type="module"></script>
|
<script src="scripts/index.js" type="module"></script>
|
||||||
<script src="scripts/instance.js" type="module"></script>
|
<script src="scripts/instance.js" type="module"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {requestPVE, requestAPI, goToPage, getURIData, resources} from "./utils.js";
|
import {requestPVE, requestAPI, goToPage, getURIData, resources} from "./utils.js";
|
||||||
import {Dialog} from "./dialog.js";
|
import {dialog} from "./dialog.js";
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
|
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
|
||||||
|
|
||||||
@ -174,13 +174,9 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskDetach () {
|
async function handleDiskDetach () {
|
||||||
let dialog = document.createElement("dialog-form");
|
let header = `Detach ${this.dataset.disk}`;
|
||||||
document.body.append(dialog);
|
let body = `<p>Are you sure you want to detach disk</p><p>${this.dataset.disk}</p>`;
|
||||||
|
dialog(header, body, async (result, form) => {
|
||||||
dialog.header = `Detach ${this.dataset.disk}`;
|
|
||||||
dialog.formBody = `<p>Are you sure you want to detach disk</p><p>${this.dataset.disk}</p>`;
|
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
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 = {
|
let body = {
|
||||||
@ -200,21 +196,16 @@ async function handleDiskDetach () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskAttach () {
|
async function handleDiskAttach () {
|
||||||
let dialog = document.createElement("dialog-form");
|
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
let diskImage = config.data[this.dataset.disk];
|
let diskImage = config.data[this.dataset.disk];
|
||||||
|
|
||||||
dialog.header = `Attach ${diskImage}`;
|
let header = `Attach ${diskImage}`;
|
||||||
dialog.formBody = `<label for="device">${type === "qemu" ? "SATA" : "MP"}</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="${type === "qemu" ? "5" : "255"}" required></input>`;
|
let body = `<label for="device">${type === "qemu" ? "SATA" : "MP"}</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="${type === "qemu" ? "5" : "255"}" required></input>`;
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
dialog(header, body, async (result, form) => {
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
let device = form.get("device");
|
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";
|
||||||
@ -236,19 +227,14 @@ async function handleDiskAttach () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskResize () {
|
async function handleDiskResize () {
|
||||||
let dialog = document.createElement("dialog-form");
|
let header = `Resize ${this.dataset.disk}`;
|
||||||
document.body.append(dialog);
|
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 = `Resize ${this.dataset.disk}`;
|
dialog(header, body, async (result, form) => {
|
||||||
dialog.formBody = `<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.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
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 = {
|
let body = {
|
||||||
@ -269,18 +255,14 @@ async function handleDiskResize () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskMove () {
|
async function handleDiskMove () {
|
||||||
let content = type === "qemu" ? "images" : "rootdir";
|
let content = type === "qemu" ? "images" : "rootdir";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
||||||
let dialog = document.createElement("dialog-form");
|
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = `Move ${this.dataset.disk}`;
|
let header = `Move ${this.dataset.disk}`;
|
||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
@ -288,16 +270,14 @@ async function handleDiskMove () {
|
|||||||
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let select = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select">${options}</select>`;
|
let select = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select"><option hidden disabled selected value></option>${options}</select>`;
|
||||||
|
|
||||||
dialog.formBody = `
|
let body = `
|
||||||
${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>
|
<label for="delete-check">Delete Source</label><input class="w3-input w3-border" name="delete-check" id="delete-check" type="checkbox" checked required>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
dialog.shadowRoot.querySelector("#storage-select").selectedIndex = -1;
|
dialog(header, body, async (result, form) => {
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
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 = {
|
let body = {
|
||||||
@ -319,19 +299,14 @@ async function handleDiskMove () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskDelete () {
|
async function handleDiskDelete () {
|
||||||
let dialog = document.createElement("dialog-form");
|
let header = `Delete ${this.dataset.disk}`;
|
||||||
document.body.append(dialog);
|
let body = `<p>Are you sure you want to <strong>delete</strong> disk</p><p>${this.dataset.disk}</p>`;
|
||||||
|
|
||||||
dialog.header = `Delete ${this.dataset.disk}`;
|
dialog(header, body, async (result, form) => {
|
||||||
dialog.formBody = `<p>Are you sure you want to <strong>delete</strong> disk</p><p>${this.dataset.disk}</p>`;
|
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
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 = {
|
let body = {
|
||||||
@ -351,18 +326,14 @@ async function handleDiskDelete () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskAdd () {
|
async function handleDiskAdd () {
|
||||||
let content = type === "qemu" ? "images" : "rootdir";
|
let content = type === "qemu" ? "images" : "rootdir";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
||||||
let dialog = document.createElement("dialog-form");
|
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = "Create New Disk";
|
let header = "Create New Disk";
|
||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
@ -370,17 +341,15 @@ async function handleDiskAdd () {
|
|||||||
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let select = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required>${options}</select>`;
|
let select = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required><option hidden disabled selected value></option>${options}</select>`;
|
||||||
|
|
||||||
dialog.formBody = `
|
let body = `
|
||||||
<label for="device">${type === "qemu" ? "SATA" : "MP"}</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="${type === "qemu" ? "5" : "255"}" value="0" required></input>
|
<label for="device">${type === "qemu" ? "SATA" : "MP"}</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="${type === "qemu" ? "5" : "255"}" value="0" required></input>
|
||||||
${select}
|
${select}
|
||||||
<label for="size">Size (GiB)</label><input class="w3-input w3-border" name="size" id="size" type="number" min="0" max="131072" required></input>
|
<label for="size">Size (GiB)</label><input class="w3-input w3-border" name="size" id="size" type="number" min="0" max="131072" required></input>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
dialog.shadowRoot.querySelector("#storage-select").selectedIndex = -1;
|
dialog(header, body, async (result, form) => {
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
let body = {
|
let body = {
|
||||||
node: node,
|
node: node,
|
||||||
@ -401,18 +370,14 @@ async function handleDiskAdd () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleCDAdd () {
|
async function handleCDAdd () {
|
||||||
let content = "iso";
|
let content = "iso";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET", null);
|
||||||
let dialog = document.createElement("dialog-form");
|
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = `Add a CDROM`;
|
let header = `Add a CDROM`;
|
||||||
|
|
||||||
let storageOptions = "";
|
let storageOptions = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
@ -420,29 +385,15 @@ async function handleCDAdd () {
|
|||||||
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
|
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let storageSelect = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required>${storageOptions}</select>`;
|
let storageSelect = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required><option hidden disabled selected value></option>${storageOptions}</select>`;
|
||||||
|
|
||||||
dialog.formBody = `
|
let body = `
|
||||||
<label for="device">IDE</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="3" required></input>
|
<label for="device">IDE</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="3" required></input>
|
||||||
${storageSelect}
|
${storageSelect}
|
||||||
<label for="iso-select">Image</label><select class="w3-select w3-border" name="iso-select" id="iso-select" required></select>
|
<label for="iso-select">Image</label><select class="w3-select w3-border" name="iso-select" id="iso-select" required></select>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
dialog.shadowRoot.querySelector("#storage-select").selectedIndex = -1;
|
let d = dialog(header, body, async (result, form) => {
|
||||||
|
|
||||||
dialog.shadowRoot.querySelector("#storage-select").addEventListener("change", async () => {
|
|
||||||
let storage = dialog.shadowRoot.querySelector("#storage-select").value;
|
|
||||||
let ISOSelect = dialog.shadowRoot.querySelector("#iso-select");
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ISOSelect.selectedIndex = -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
let body = {
|
let body = {
|
||||||
node: node,
|
node: node,
|
||||||
@ -462,9 +413,19 @@ async function handleCDAdd () {
|
|||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
dialog.show();
|
d.querySelector("#storage-select").addEventListener("change", async () => {
|
||||||
|
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});
|
||||||
|
isos.data.forEach((element) => {
|
||||||
|
if (element.content.includes(content)) {
|
||||||
|
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleFormExit () {
|
async function handleFormExit () {
|
||||||
|
@ -1,60 +1,39 @@
|
|||||||
export class Dialog extends HTMLElement {
|
export function dialog (header, body, callback = async (result, form) => {}) {
|
||||||
constructor () {
|
let dialog = document.createElement("dialog");
|
||||||
super();
|
dialog.innerHTML = `
|
||||||
let shadowRoot = this.attachShadow({mode: "open"});
|
<p class="w3-large" id="prompt" style="text-align: center;"></p>
|
||||||
|
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form"></form>
|
||||||
|
<div class="w3-center w3-container">
|
||||||
|
<button value="cancel" form="form" class="w3-button w3-margin" style="background-color: #f00;" formnovalidate>CANCEL</button>
|
||||||
|
<button value="confirm" form="form" class="w3-button w3-margin" style="background-color: #0f0;">CONFIRM</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
dialog.className = "w3-container w3-card w3-border-0";
|
||||||
|
dialog.querySelector("#prompt").innerText = header;
|
||||||
|
dialog.querySelector("form").innerHTML = body;
|
||||||
|
|
||||||
shadowRoot.innerHTML = `
|
document.body.append(dialog);
|
||||||
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
dialog.showModal();
|
||||||
<link rel="stylesheet" href="css/style.css" type="text/css">
|
|
||||||
<link rel="stylesheet" href="css/form.css" type="text/css">
|
|
||||||
<dialog class="w3-container w3-card-4 w3-border-0">
|
|
||||||
<p class="w3-large" id="prompt" style="text-align: center;"></p>
|
|
||||||
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form"></form>
|
|
||||||
<div class="w3-center w3-container">
|
|
||||||
<button value="cancel" form="form" class="w3-button w3-margin" style="background-color: #f00;" formnovalidate>CANCEL</button>
|
|
||||||
<button value="confirm" form="form" class="w3-button w3-margin" style="background-color: #0f0;">CONFIRM</button>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.shadowElement = shadowRoot;
|
dialog.addEventListener("close", async () => {
|
||||||
this.dialog = shadowRoot.querySelector("dialog");
|
await callback(dialog.returnValue, new FormData(dialog.querySelector("form")));
|
||||||
this.form = shadowRoot.querySelector("form");
|
dialog.parentElement.removeChild(dialog);
|
||||||
}
|
});
|
||||||
|
|
||||||
set header (header) {
|
return dialog;
|
||||||
this.shadowElement.querySelector("#prompt").innerText = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
set formBody (formBody) {
|
|
||||||
this.form.innerHTML = formBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
set callback (callback) {
|
|
||||||
this.dialog.addEventListener("close", async () => {
|
|
||||||
await callback(this.dialog.returnValue, new FormData(this.form));
|
|
||||||
document.querySelector("dialog-form").remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
show () {
|
|
||||||
this.dialog.showModal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function alert (message) {
|
export function alert (message) {
|
||||||
let form = document.createElement("form");
|
|
||||||
form.method = "dialog";
|
|
||||||
form.innerHTML = `
|
|
||||||
<p class="w3-center" style="margin-bottom: 0px;">${message}</p>
|
|
||||||
<div class="w3-center">
|
|
||||||
<button class="w3-button w3-margin" id="submit">OK</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
let dialog = document.createElement("dialog");
|
let dialog = document.createElement("dialog");
|
||||||
dialog.classList.add("w3-card");
|
dialog.innerHTML = `
|
||||||
dialog.classList.add("w3-container");
|
<form method="dialog">
|
||||||
dialog.append(form);
|
<p class="w3-center" style="margin-bottom: 0px;">${message}</p>
|
||||||
|
<div class="w3-center">
|
||||||
|
<button class="w3-button w3-margin" id="submit">OK</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
`;
|
||||||
|
dialog.className = "w3-container w3-card w3-border-0";
|
||||||
|
|
||||||
document.body.append(dialog);
|
document.body.append(dialog);
|
||||||
dialog.showModal();
|
dialog.showModal();
|
||||||
@ -62,6 +41,6 @@ export function alert (message) {
|
|||||||
dialog.addEventListener("close", () => {
|
dialog.addEventListener("close", () => {
|
||||||
dialog.parentElement.removeChild(dialog);
|
dialog.parentElement.removeChild(dialog);
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("dialog-form", Dialog);
|
return dialog;
|
||||||
|
}
|
134
scripts/index.js
134
scripts/index.js
@ -1,5 +1,5 @@
|
|||||||
import {requestPVE, requestAPI, goToPage} from "./utils.js";
|
import {requestPVE, requestAPI, goToPage} from "./utils.js";
|
||||||
import {Dialog} from "./dialog.js";
|
import {dialog} from "./dialog.js";
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", init);
|
window.addEventListener("DOMContentLoaded", init);
|
||||||
|
|
||||||
@ -64,12 +64,9 @@ async function populateInstances () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleInstanceAdd () {
|
async function handleInstanceAdd () {
|
||||||
let dialog = document.createElement("dialog-form");
|
let header = "Create New Instance";
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = "Create New Instance";
|
|
||||||
|
|
||||||
dialog.formBody = `
|
let body = `
|
||||||
<label for="type">Instance Type</label>
|
<label for="type">Instance Type</label>
|
||||||
<select class="w3-select w3-border" name="type" id="type" required>
|
<select class="w3-select w3-border" name="type" id="type" required>
|
||||||
<option value="lxc">Container</option>
|
<option value="lxc">Container</option>
|
||||||
@ -100,67 +97,7 @@ async function handleInstanceAdd () {
|
|||||||
<input class="w3-input w3-border container-specific none" name="password" id="password" type="password" required disabled></input>
|
<input class="w3-input w3-border container-specific none" name="password" id="password" type="password" required disabled></input>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
let typeSelect = dialog.shadowRoot.querySelector("#type");
|
let d = dialog(header, body, async (result, form) => {
|
||||||
typeSelect.selectedIndex = -1;
|
|
||||||
typeSelect.addEventListener("change", () => {
|
|
||||||
if(typeSelect.value === "qemu") {
|
|
||||||
dialog.shadowRoot.querySelectorAll(".container-specific").forEach((element) => {
|
|
||||||
element.classList.add("none");
|
|
||||||
element.disabled = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dialog.shadowRoot.querySelectorAll(".container-specific").forEach((element) => {
|
|
||||||
element.classList.remove("none");
|
|
||||||
element.disabled = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let templateContent = "iso";
|
|
||||||
let templateStorage = dialog.shadowRoot.querySelector("#template-storage");
|
|
||||||
templateStorage.selectedIndex = -1;
|
|
||||||
|
|
||||||
let rootfsContent = "rootdir";
|
|
||||||
let rootfsStorage = dialog.shadowRoot.querySelector("#rootfs-storage");
|
|
||||||
rootfsStorage.selectedIndex = -1;
|
|
||||||
|
|
||||||
let nodeSelect = dialog.shadowRoot.querySelector("#node");
|
|
||||||
let nodes = await requestPVE("/nodes", "GET");
|
|
||||||
nodes.data.forEach((element) => {
|
|
||||||
if (element.status === "online") {
|
|
||||||
nodeSelect.add(new Option(element.node));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
nodeSelect.selectedIndex = -1;
|
|
||||||
nodeSelect.addEventListener("change", async () => { // change template and rootfs storage based on node
|
|
||||||
let node = nodeSelect.value;
|
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
|
||||||
storage.data.forEach((element) => {
|
|
||||||
if (element.content.includes(templateContent)) {
|
|
||||||
templateStorage.add(new Option(element.storage));
|
|
||||||
}
|
|
||||||
if (element.content.includes(rootfsContent)) {
|
|
||||||
rootfsStorage.add(new Option(element.storage));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
templateStorage.selectedIndex = -1;
|
|
||||||
rootfsStorage.selectedIndex = -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
let templateImage = dialog.shadowRoot.querySelector("#template-image"); // populate templateImage by
|
|
||||||
templateStorage.addEventListener("change", async () => {
|
|
||||||
let content = "vztmpl";
|
|
||||||
let images = await requestPVE(`/nodes/${nodeSelect.value}/storage/${templateStorage.value}/content`, "GET");
|
|
||||||
images.data.forEach((element) => {
|
|
||||||
if (element.content.includes(content)) {
|
|
||||||
templateImage.append(new Option(element.volid.replace(`${templateStorage.value}:${content}/`, ""), element.volid));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
templateImage.selectedIndex = -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
let body = {
|
let body = {
|
||||||
node: form.get("node"),
|
node: form.get("node"),
|
||||||
@ -186,7 +123,66 @@ async function handleInstanceAdd () {
|
|||||||
populateInstances();
|
populateInstances();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
dialog.show();
|
let typeSelect = d.querySelector("#type");
|
||||||
|
typeSelect.selectedIndex = -1;
|
||||||
|
typeSelect.addEventListener("change", () => {
|
||||||
|
if(typeSelect.value === "qemu") {
|
||||||
|
d.querySelectorAll(".container-specific").forEach((element) => {
|
||||||
|
element.classList.add("none");
|
||||||
|
element.disabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d.querySelectorAll(".container-specific").forEach((element) => {
|
||||||
|
element.classList.remove("none");
|
||||||
|
element.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let templateContent = "iso";
|
||||||
|
let templateStorage = d.querySelector("#template-storage");
|
||||||
|
templateStorage.selectedIndex = -1;
|
||||||
|
|
||||||
|
let rootfsContent = "rootdir";
|
||||||
|
let rootfsStorage = d.querySelector("#rootfs-storage");
|
||||||
|
rootfsStorage.selectedIndex = -1;
|
||||||
|
|
||||||
|
let nodeSelect = d.querySelector("#node");
|
||||||
|
let nodes = await requestPVE("/nodes", "GET");
|
||||||
|
nodes.data.forEach((element) => {
|
||||||
|
if (element.status === "online") {
|
||||||
|
nodeSelect.add(new Option(element.node));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nodeSelect.selectedIndex = -1;
|
||||||
|
nodeSelect.addEventListener("change", async () => { // change template and rootfs storage based on node
|
||||||
|
let node = nodeSelect.value;
|
||||||
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
||||||
|
storage.data.forEach((element) => {
|
||||||
|
if (element.content.includes(templateContent)) {
|
||||||
|
templateStorage.add(new Option(element.storage));
|
||||||
|
}
|
||||||
|
if (element.content.includes(rootfsContent)) {
|
||||||
|
rootfsStorage.add(new Option(element.storage));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
templateStorage.selectedIndex = -1;
|
||||||
|
rootfsStorage.selectedIndex = -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
let templateImage = d.querySelector("#template-image"); // populate templateImage depending on selected image storage
|
||||||
|
templateStorage.addEventListener("change", async () => {
|
||||||
|
templateImage.innerHTML = ``;
|
||||||
|
let content = "vztmpl";
|
||||||
|
let images = await requestPVE(`/nodes/${nodeSelect.value}/storage/${templateStorage.value}/content`, "GET");
|
||||||
|
images.data.forEach((element) => {
|
||||||
|
if (element.content.includes(content)) {
|
||||||
|
templateImage.append(new Option(element.volid.replace(`${templateStorage.value}:${content}/`, ""), element.volid));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
templateImage.selectedIndex = -1;
|
||||||
|
});
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import {requestPVE, requestAPI, goToPage, goToURL, instances, nodes} from "./utils.js";
|
import {requestPVE, requestAPI, goToPage, goToURL, instances, nodes} from "./utils.js";
|
||||||
import {Dialog} from "./dialog.js";
|
import {dialog} from "./dialog.js";
|
||||||
|
|
||||||
export class Instance extends HTMLElement {
|
export class Instance extends HTMLElement {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -117,14 +117,10 @@ export class Instance extends HTMLElement {
|
|||||||
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>`
|
||||||
|
|
||||||
let dialog = document.createElement("dialog-form");
|
dialog(header, body, async (result, form) => {
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = `${this.status === "running" ? "Stop" : "Start"} VM ${this.vmid}`;
|
|
||||||
dialog.formBody = `<p>Are you sure you want to ${this.status === "running" ? "stop" : "start"} VM</p><p>${this.vmid}</p>`
|
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
this.actionLock = true;
|
this.actionLock = true;
|
||||||
let targetAction = this.status === "running" ? "stop" : "start";
|
let targetAction = this.status === "running" ? "stop" : "start";
|
||||||
@ -158,9 +154,7 @@ export class Instance extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,13 +174,11 @@ export class Instance extends HTMLElement {
|
|||||||
|
|
||||||
handleDeleteButton () {
|
handleDeleteButton () {
|
||||||
if (!this.actionLock && this.status === "stopped") {
|
if (!this.actionLock && this.status === "stopped") {
|
||||||
let dialog = document.createElement("dialog-form");
|
|
||||||
document.body.append(dialog);
|
|
||||||
|
|
||||||
dialog.header = `Delete VM ${this.vmid}`;
|
let header = `Delete VM ${this.vmid}`;
|
||||||
dialog.formBody = `<p>Are you sure you want to <strong>delete</strong> VM </p><p>${this.vmid}</p>`
|
let body = `<p>Are you sure you want to <strong>delete</strong> VM </p><p>${this.vmid}</p>`
|
||||||
|
|
||||||
dialog.callback = async (result, form) => {
|
dialog(header, body, async (result, form) => {
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
this.actionLock = true;
|
this.actionLock = true;
|
||||||
let prevStatus = this.status;
|
let prevStatus = this.status;
|
||||||
@ -215,9 +207,7 @@ export class Instance extends HTMLElement {
|
|||||||
this.actionLock = false;
|
this.actionLock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,8 +206,4 @@ export function getURIData () {
|
|||||||
|
|
||||||
export function deleteAllCookies () {
|
export function deleteAllCookies () {
|
||||||
document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/;domain=.tronnet.net;"); });
|
document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/;domain=.tronnet.net;"); });
|
||||||
}
|
|
||||||
|
|
||||||
export function reload () {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user