add delete button to insances,

add confirm message on start/stop,
change power action from shutdown to stop,
improve action button alt texts

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
This commit is contained in:
Arthur Lu 2023-02-21 19:57:47 +00:00
parent 7539ff731b
commit 26e46a9c6b
2 changed files with 64 additions and 33 deletions

View File

@ -1,4 +1,5 @@
import {requestPVE, goToPage, goToURL, instances} from "./utils.js";
import { Dialog } from "./dialog.js";
export class Instance extends HTMLElement {
constructor () {
@ -23,8 +24,9 @@ export class Instance extends HTMLElement {
<hr>
<div class="btn-group">
<img id="power-btn">
<img id="configure-btn" alt="change instance configuration">
<img id="console-btn" alt="connect to instance console or display">
<img id="console-btn">
<img id="configure-btn">
<img id="delete-btn">
</div>
</article>
`;
@ -80,46 +82,67 @@ export class Instance extends HTMLElement {
consoleButton.title = instances[this.status].consoleButtonAlt;
consoleButton.addEventListener("click", this.handleConsoleButton.bind(this));
let deleteButton = this.shadowElement.querySelector("#delete-btn");
deleteButton.src = instances[this.status].deleteButtonSrc;
deleteButton.alt = instances[this.status].deleteButtonAlt;
deleteButton.title = instances[this.status].deleteButtonAlt;
deleteButton.addEventListener("click", this.handleDeleteButton.bind(this));
if (this.node.status !== "online") {
powerButton.classList.add("hidden");
configButton.classList.add("hidden");
consoleButton.classList.add("hidden");
deleteButton.classList.add("hidden");
}
}
async handlePowerButton () {
if(!this.actionLock) {
this.actionLock = true;
let targetAction = this.status === "running" ? "shutdown" : "start";
let targetStatus = this.status === "running" ? "stopped" : "running";
let prevStatus = this.status;
this.status = "loading";
this.update();
let dialog = document.createElement("dialog-form");
document.body.append(dialog);
let result = await requestPVE(`/nodes/${this.node.name}/${this.type}/${this.vmid}/status/${targetAction}`, "POST", {node: this.node.name, vmid: this.vmid});
dialog.header = `${this.status === "running" ? "Stop" : "Start"} VM ${this.vmid}`;
dialog.formBody = `<p>Are you sure you want to ${this.status === "running" ? "stop" : "start"}</p><p>VM ${this.vmid}</p>`
const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay));
dialog.callback = async (result, form) => {
if (result === "confirm") {
this.actionLock = true;
let targetAction = this.status === "running" ? "stop" : "start";
let targetStatus = this.status === "running" ? "stopped" : "running";
let prevStatus = this.status;
this.status = "loading";
while (true) {
let taskStatus = await requestPVE(`/nodes/${this.node.name}/tasks/${result.data}/status`);
if(taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
this.status = targetStatus;
this.update();
this.actionLock = false;
break;
}
else if (taskStatus.data.status === "stopped") { // task stopped but was not successful
this.status = prevStatus;
console.error(`attempted to ${targetAction} ${this.vmid} but process returned stopped:${result.data.exitstatus}`);
this.update();
this.actionLock = false;
break;
}
else{ // task has not stopped
await waitFor(1000);
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`);
if(taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
this.status = targetStatus;
this.update();
this.actionLock = false;
break;
}
else if (taskStatus.data.status === "stopped") { // task stopped but was not successful
this.status = prevStatus;
console.error(`attempted to ${targetAction} ${this.vmid} but process returned stopped:${result.data.exitstatus}`);
this.update();
this.actionLock = false;
break;
}
else{ // task has not stopped
await waitFor(1000);
}
}
}
}
dialog.show();
}
}
@ -136,6 +159,8 @@ export class Instance extends HTMLElement {
goToURL("https://pve.tronnet.net", data, true);
}
}
handleDeleteButton () {}
}
customElements.define("instance-article", Instance);

View File

@ -37,25 +37,31 @@ export const instances = {
powerButtonSrc: "images/actions/stop.svg",
powerButtonAlt: "Shutdown Instance",
configButtonSrc: "images/actions/config-inactive.svg",
configButtonAlt: "Configuration Disabled",
configButtonAlt: "Change Configuration (Inactive)",
consoleButtonSrc: "images/actions/console-active.svg",
consoleButtonAlt: "Open Console"
consoleButtonAlt: "Open Console",
deleteButtonSrc: "images/actions/delete-inactive.svg",
deleteButtonAlt: "Delete Instance (Inactive)"
},
stopped: {
powerButtonSrc: "images/actions/start.svg",
powerButtonAlt: "Start Instance",
configButtonSrc: "images/actions/config-active.svg",
configButtonAlt: "Configure Instance",
configButtonAlt: "Change Configuration",
consoleButtonSrc: "images/actions/console-inactive.svg",
consoleButtonAlt: "Console Inactive"
consoleButtonAlt: "Open Console (Inactive)",
deleteButtonSrc: "images/actions/delete-active.svg",
deleteButtonAlt: "Delete Instance"
},
loading: {
powerButtonSrc: "images/actions/loading.svg",
powerButtonAlt: "Loading Instance",
configButtonSrc: "images/actions/config-inactive.svg",
configButtonAlt: "Configuration Disabled",
configButtonAlt: "Change Configuration (Inactive)",
consoleButtonSrc: "images/actions/console-inactive.svg",
consoleButtonAlt: "Console Inactive"
consoleButtonAlt: "Open Console (Inactive)",
deleteButtonSrc: "images/actions/delete-inactive.svg",
deleteButtonAlt: "Delete Instance (Inactive)"
}
}