ProxmoxAAS-Dashboard/scripts/account.js
2023-08-31 19:01:58 +00:00

123 lines
3.4 KiB
JavaScript

import { requestAPI, goToPage, getCookie, setTitleAndHeader } from "./utils.js";
window.addEventListener("DOMContentLoaded", init);
const prefixes = {
1024: [
"",
"Ki",
"Mi",
"Gi",
"Ti"
],
1000: [
"",
"K",
"M",
"G",
"T"
]
};
async function init () {
setTitleAndHeader();
const cookie = document.cookie;
if (cookie === "") {
goToPage("login.html");
}
const resources = await requestAPI("/user/dynamic/resources");
const instances = await requestAPI("/user/config/cluster");
const nodes = await requestAPI("/user/config/nodes");
document.querySelector("#username").innerText = `Username: ${getCookie("username")}`;
document.querySelector("#pool").innerText = `Pool: ${instances.pool}`;
document.querySelector("#vmid").innerText = `VMID Range: ${instances.vmid.min} - ${instances.vmid.max}`;
document.querySelector("#nodes").innerText = `Nodes: ${nodes.toString()}`;
buildResourceTable("#resource-container", resources);
}
function buildResourceTable (containerID, resources) {
if (resources instanceof Object) {
const container = document.querySelector(containerID);
Object.keys(resources.resources).forEach((element) => {
if (resources.resources[element].display) {
if (resources.resources[element].type === "list") {
}
else {
const chart = createResourceUsageChart(resources.resources[element].title, resources.avail[element], resources.used[element], resources.max[element], resources.resources[element]);
container.append(chart);
}
}
});
}
}
function createResourceUsageChart (resourceName, resourceAvail, resourceUsed, resourceMax, resourceUnitData) {
const container = document.createElement("div");
// layout fits 6 resources per row on large screens
// max width = (100% [parent] - 50px [5 flexbox col gap]) / 6
container.style = "position: relative; min-width: 200px; width: 100%; max-width: calc((100% - 50px) / 6); aspect-ratio: 1;";
const canvas = document.createElement("canvas");
container.append(canvas);
const maxStr = parseNumber(resourceMax, resourceUnitData);
const usedStr = parseNumber(resourceUsed, resourceUnitData);
const usedRatio = resourceUsed / resourceMax;
const R = Math.min(usedRatio * 510, 255);
const G = Math.min((1 - usedRatio) * 510, 255);
const usedColor = `rgb(${R}, ${G}, 0)`;
new Chart(canvas, {
type: "pie",
data: {
labels: [
"Used",
"Available"
],
datasets: [{
label: resourceName,
data: [resourceUsed, resourceAvail],
backgroundColor: [
usedColor,
"rgb(140, 140, 140)"
],
borderWidth: 0,
hoverOffset: 4
}]
},
options: {
plugins: {
title: {
display: true,
position: "bottom",
text: [resourceName, `Used ${usedStr} of ${maxStr}`],
color: "white"
},
legend: {
display: false
}
}
}
});
canvas.role = "img";
canvas.ariaLabel = `${resourceName} used ${usedStr} of ${maxStr}`;
return container;
}
function parseNumber (value, unitData) {
const compact = unitData.compact;
const multiplier = unitData.multiplier;
const base = unitData.base;
const unit = unitData.unit;
value = multiplier * value;
if (value <= 0) {
return `0 ${unit}`;
}
else if (compact) {
const exponent = Math.floor(Math.log(value) / Math.log(base));
value = value / base ** exponent;
const unitPrefix = prefixes[base][exponent];
return `${value} ${unitPrefix}${unit}`;
}
else {
return `${value} ${unit}`;
}
}