update account page, instance creation form, and config page,
fix issue with instance delete confirm popup, fix issues with dialog exit handling without form element
This commit is contained in:
parent
6fe526be6e
commit
3521228366
@ -53,12 +53,12 @@ function populateResources (containerID, meta, resources) {
|
||||
Object.keys(meta).forEach((resourceType) => {
|
||||
if (meta[resourceType].display) {
|
||||
if (meta[resourceType].type === "list") {
|
||||
resources[resourceType].forEach((listResource) => {
|
||||
resources[resourceType].total.forEach((listResource) => {
|
||||
createResourceUsageChart(container, listResource.name, listResource.avail, listResource.used, listResource.max, null);
|
||||
});
|
||||
}
|
||||
else {
|
||||
createResourceUsageChart(container, meta[resourceType].name, resources[resourceType].avail, resources[resourceType].used, resources[resourceType].max, meta[resourceType]);
|
||||
createResourceUsageChart(container, meta[resourceType].name, resources[resourceType].total.avail, resources[resourceType].total.used, resources[resourceType].total.max, meta[resourceType]);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -125,28 +125,28 @@ function handlePasswordChangeForm () {
|
||||
const body = `
|
||||
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
|
||||
<label for="new-password">New Password</label>
|
||||
<input class="w3-input w3-border" type="password" id="new-password" name="new-password">
|
||||
<input class="w3-input w3-border" id="new-password" name="new-password" type="password"required>
|
||||
<label for="confirm-password">Confirm Password</label>
|
||||
<input class="w3-input w3-border" type="password" id="confirm-password" name="confirm-password">
|
||||
<input class="w3-input w3-border" id="confirm-password" name="confirm-password" type="password" required>
|
||||
</form>
|
||||
<p class="w3-large" id="error-message" style="text-align: center; color: var(--negative-color); margin-top: 0.5em; margin-bottom: 0;"></p>
|
||||
`;
|
||||
dialog("Change Password", body, async (result, form) => {
|
||||
const d = dialog("Change Password", body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
const result = await requestAPI("/auth/password", "POST", { password: form.get("new-password") });
|
||||
if (result.status !== 200) {
|
||||
alert(result.error);
|
||||
}
|
||||
}
|
||||
}, (dialog, form) => {
|
||||
const pass = form.get("new-password");
|
||||
const conf = form.get("confirm-password");
|
||||
if (pass !== conf) {
|
||||
dialog.querySelector("#error-message").innerText = "Passwords must match";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
var password = d.querySelector("#new-password")
|
||||
var confirm_password = d.querySelector("#confirm-password");
|
||||
|
||||
function validatePassword(){
|
||||
confirm_password.setCustomValidity( password.value !=
|
||||
confirm_password.value ? "Passwords Don't Match" : '');
|
||||
}
|
||||
|
||||
password.addEventListener("change", validatePassword);
|
||||
confirm_password.addEventListener("keyup", validatePassword);
|
||||
}
|
||||
|
@ -54,8 +54,10 @@ async function populateResources () {
|
||||
const global = await requestAPI("/global/config/resources");
|
||||
const user = await requestAPI("/user/config/resources");
|
||||
let options = [];
|
||||
if (global.cpu.whitelist) {
|
||||
user.cpu.forEach((userType) => {
|
||||
const globalCPU = global.cpu;
|
||||
const userCPU = node in user.cpu.nodes ? user.cpu.nodes[node] : user.cpu.global;
|
||||
if (globalCPU.whitelist) {
|
||||
userCPU.forEach((userType) => {
|
||||
options.push(userType.name);
|
||||
});
|
||||
options = options.sort((a, b) => {
|
||||
@ -65,7 +67,7 @@ async function populateResources () {
|
||||
else {
|
||||
const supported = await requestPVE(`/nodes/${node}/capabilities/qemu/cpu`);
|
||||
supported.data.forEach((supportedType) => {
|
||||
if (!user.cpu.some((userType) => supportedType.name === userType.name)) {
|
||||
if (!userCPU.some((userType) => supportedType.name === userType.name)) {
|
||||
options.push(supportedType.name);
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,4 @@
|
||||
export function dialog (header, body, onclose = async (result, form) => { }, validate = async (dialog, form) => {
|
||||
return true;
|
||||
}) {
|
||||
export function dialog (header, body, onclose = async (result, form) => { }) {
|
||||
const dialog = document.createElement("dialog");
|
||||
dialog.innerHTML = `
|
||||
<p class="w3-large" id="prompt" style="text-align: center;"></p>
|
||||
@ -15,29 +13,20 @@ export function dialog (header, body, onclose = async (result, form) => { }, val
|
||||
dialog.querySelector("#body").innerHTML = body;
|
||||
dialog.addEventListener("close", async () => {
|
||||
const formElem = dialog.querySelector("form");
|
||||
let formData = null;
|
||||
if (formElem) {
|
||||
formData = new FormData(formElem);
|
||||
}
|
||||
const formData = formElem ? new FormData(formElem) : null;
|
||||
await onclose(dialog.returnValue, formData);
|
||||
dialog.parentElement.removeChild(dialog);
|
||||
});
|
||||
if (!dialog.querySelector("form")) {
|
||||
dialog.querySelector("#confirm").addEventListener("click", async (e) => {
|
||||
e.preventDefault();
|
||||
let valid = true;
|
||||
const formElem = dialog.querySelector("form");
|
||||
if (formElem) {
|
||||
const form = new FormData(formElem);
|
||||
valid = await validate(dialog, form);
|
||||
}
|
||||
if (valid) {
|
||||
dialog.close(e.target.value);
|
||||
}
|
||||
});
|
||||
dialog.querySelector("#cancel").addEventListener("click", async (e) => {
|
||||
e.preventDefault();
|
||||
dialog.close(e.target.value);
|
||||
});
|
||||
}
|
||||
document.body.append(dialog);
|
||||
dialog.showModal();
|
||||
return dialog;
|
||||
|
@ -163,6 +163,9 @@ async function handleInstanceAdd () {
|
||||
const rootfsStorage = d.querySelector("#rootfs-storage");
|
||||
rootfsStorage.selectedIndex = -1;
|
||||
|
||||
const userResources = await requestAPI("/user/dynamic/resources", "GET");
|
||||
const userCluster = await requestAPI("/user/config/cluster", "GET");
|
||||
|
||||
const nodeSelect = d.querySelector("#node");
|
||||
const clusterNodes = await requestPVE("/nodes", "GET");
|
||||
const allowedNodes = await requestAPI("/user/config/nodes", "GET");
|
||||
@ -185,6 +188,23 @@ async function handleInstanceAdd () {
|
||||
});
|
||||
templateStorage.selectedIndex = -1;
|
||||
rootfsStorage.selectedIndex = -1;
|
||||
|
||||
if (node in userResources.cores.nodes) {
|
||||
d.querySelector("#cores").max = userResources.cores.nodes[node].avail;
|
||||
}
|
||||
else {
|
||||
d.querySelector("#cores").max = userResources.cores.global.avail;
|
||||
}
|
||||
|
||||
if (node in userResources.memory.nodes) {
|
||||
d.querySelector("#memory").max = userResources.memory.nodes[node].avail;
|
||||
}
|
||||
else {
|
||||
d.querySelector("#memory").max = userResources.memory.global.avail;
|
||||
}
|
||||
|
||||
d.querySelector("#vmid").min = userCluster.vmid.min;
|
||||
d.querySelector("#vmid").max = userCluster.vmid.max;
|
||||
});
|
||||
|
||||
const templateImage = d.querySelector("#template-image"); // populate templateImage depending on selected image storage
|
||||
@ -199,11 +219,4 @@ async function handleInstanceAdd () {
|
||||
});
|
||||
templateImage.selectedIndex = -1;
|
||||
});
|
||||
|
||||
const userResources = await requestAPI("/user/dynamic/resources", "GET");
|
||||
const userCluster = await requestAPI("/user/config/cluster", "GET");
|
||||
d.querySelector("#cores").max = userResources.cores.avail;
|
||||
d.querySelector("#memory").max = userResources.memory.avail;
|
||||
d.querySelector("#vmid").min = userCluster.vmid.min;
|
||||
d.querySelector("#vmid").max = userCluster.vmid.max;
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ class InstanceCard extends HTMLElement {
|
||||
handleDeleteButton () {
|
||||
if (!this.actionLock && this.status === "stopped") {
|
||||
const header = `Delete VM ${this.vmid}`;
|
||||
const body = `<p>Are you sure you want to <strong>delete</strong> VM </p><p>${this.vmid}</p>`;
|
||||
const body = `<p>Are you sure you want to <strong>delete</strong> VM ${this.vmid}</p>`;
|
||||
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
|
Loading…
Reference in New Issue
Block a user