feat: add Fleet operations view

This commit is contained in:
lussierj committed 2026-08-11 17:37:36 +00:00
1 parent c6d01df31c
commit 786a1ab910
12 files changed
+1062 -148

No files matched your search

-103
View File
@@ -239,110 +239,7 @@
}
}
function locationText(miner) {
if (miner.room_id) return "Room " + miner.room_id;
if (miner.site_id) return "Site " + miner.site_id;
return "Not assigned";
}
async function loadMiners(query) {
const rows = document.getElementById("minerRows");
if (!rows) return;
showState("loading");
const params = new URLSearchParams({ limit: "100", offset: "0" });
if (query) params.set("query", query);
try {
const envelope = await api(
"/api/inventory/miners?" + params.toString()
);
if (!envelope || !Array.isArray(envelope.data)) {
throw new Error(
"MinerOps returned an invalid inventory response."
);
}
const miners = envelope.data;
if (!miners.every(function (miner) {
return miner &&
typeof miner === "object" &&
typeof miner.id === "string" &&
miner.id.trim() !== "";
})) {
throw new Error(
"MinerOps returned an incomplete inventory response."
);
}
rows.replaceChildren();
if (!miners.length) {
showState(
"empty",
query
? "No authorized miners match this search."
: "No miners have been added or discovered yet."
);
return;
}
for (const miner of miners) {
const row = create("tr");
const identity = create("div");
const link = create("a", {
className: "object-link",
text: text(miner.asset_id, "No Asset ID"),
href: "/miners/" +
encodeURIComponent(miner.id) +
"/detail"
});
identity.appendChild(link);
identity.appendChild(create("span", {
className: "secondary",
text: miner.id
}));
addCell(row, "Asset ID", identity);
addCell(
row,
"Current MAC",
miner.current_mac || "Not observed"
);
addCell(row, "Model", miner.model);
addCell(row, "Lifecycle", status(miner.lifecycle_status));
addCell(row, "Runtime", status(miner.runtime_status));
addCell(row, "Location", locationText(miner));
rows.appendChild(row);
}
showState("ready");
} catch (error) {
showState(
error.permissionDenied ? "denied" : "error",
error.message
);
}
}
function setupMiners() {
const form = document.getElementById("minerSearchForm");
const input = document.getElementById("minerSearchInput");
if (!form || !input) return;
const initial =
new URLSearchParams(window.location.search).get("query") || "";
input.value = initial;
form.addEventListener("submit", function (event) {
event.preventDefault();
const query = input.value.trim();
const url = query
? "/assets/miners?query=" + encodeURIComponent(query)
: "/assets/miners";
window.history.pushState({ query: query }, "", url);
loadMiners(query);
});
window.addEventListener("popstate", function () {
const query =
new URLSearchParams(window.location.search).get("query") || "";
input.value = query;
loadMiners(query);
});
loadMiners(initial);
}
setupShell();
if (view === "repairs") loadRepairs();
if (view === "miners") setupMiners();
})();