Add ATC Team chat, soft identity, and update Present decks.

Ship team/DM chat with files, avatars, unread alerts, and a first-open identity gate (including Guest); fold Team into Ops desk; clarify Datacenter Engineer vs "Data Plumbers" FDE roles; refresh Present story/tech slides to match.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
root
2026-07-19 01:42:00 +02:00
parent 03e207b46d
commit b4714c70d1
11 changed files with 1953 additions and 139 deletions
+21 -10
View File
@@ -44,10 +44,11 @@
let gpuData = null;
let chatModelsLoaded = false;
let opsUsers = [
{ id: "jody", name: "Jody van Dongen", team: "admin", role: "ATC Datacenter Admin" },
{ id: "laurens", name: "Laurens Rammers", team: "admin", role: "ATC Datacenter Admin" },
{ id: "mo", name: "Mohamed El Kadi", team: "fde", role: "Data Forward Deployed Engineer" },
{ id: "bart", name: "Bart Sjerps", team: "fde", role: "Data Forward Deployed Engineer" },
{ id: "jody", name: "Jody van Dongen", team: "admin", role: "Datacenter Engineer" },
{ id: "laurens", name: "Laurens Rammers", team: "admin", role: "Datacenter Engineer" },
{ id: "mo", name: "Mohamed El Kadi", team: "fde", role: "Data Forward Deployed Engineer · \"Data Plumbers\" 😉" },
{ id: "bart", name: "Bart Sjerps", team: "fde", role: "Data Forward Deployed Engineer · \"Data Plumbers\" 😉" },
{ id: "guest", name: "Guest", team: "guest", role: "Visitor" },
];
function selectedChatModel() {
@@ -98,16 +99,19 @@
if (me === "laurens") return "jody";
if (me === "mo") return "bart";
if (me === "bart") return "mo";
if (me === "guest") return "jody";
return "jody";
}
function assigneeOptionsHtml(selected) {
const admins = opsUsers.filter((u) => u.team === "admin");
const fde = opsUsers.filter((u) => u.team === "fde");
const guests = opsUsers.filter((u) => u.team === "guest");
const opt = (u) =>
`<option value="${u.id}" ${u.id === selected ? "selected" : ""}>${escape(u.name)}</option>`;
return `<optgroup label="ATC Admins">${admins.map(opt).join("")}</optgroup>
<optgroup label="FDE team">${fde.map(opt).join("")}</optgroup>`;
return `<optgroup label="Datacenter Engineers">${admins.map(opt).join("")}</optgroup>
<optgroup label="FDE team">${fde.map(opt).join("")}</optgroup>
${guests.length ? `<optgroup label="Other">${guests.map(opt).join("")}</optgroup>` : ""}`;
}
async function loadOpsUsers() {
@@ -856,7 +860,7 @@
((node && node.ip) || (a && a.ip) || "no-ip") +
"): " +
it.message +
". Suggest next steps for ATC admins Jody and Laurens."
". Suggest next steps for Datacenter Engineers Jody and Laurens."
);
});
$("#triage-inspect")?.addEventListener("click", () => {
@@ -952,6 +956,9 @@
activeTicketId = null;
});
$("#btn-ops-close")?.addEventListener("click", closeDrawers);
$("#btn-ops-open-team")?.addEventListener("click", () => {
window.cockpitTeam?.open?.();
});
$("#btn-ops-refresh")?.addEventListener("click", () => loadTickets().catch((e) => alert(e.message)));
$("#ops-quick")?.addEventListener("click", (e) => {
@@ -962,10 +969,14 @@
openTicketModal();
return;
}
if (q === "team") {
window.cockpitTeam?.open?.();
return;
}
if (q === "to-admin") {
openTicketModal({
title: "Handoff to ATC admin",
body: "Context for Jody / Laurens:\n\n",
title: "Handoff to Datacenter Engineer",
body: "Context for Jody / Laurens (storage · servers · network · rack & stack · installs):\n\n",
assignee: "jody",
priority: "normal",
});
@@ -974,7 +985,7 @@
if (q === "to-fde") {
openTicketModal({
title: "Data FDE / AI cluster request",
body: "Request for Mohamed El Kadi / Bart Sjerps (Data Forward Deployed Engineers · AI workloads):\n\n",
body: "Request for Mohamed El Kadi / Bart Sjerps (Data FDEs · \"Data Plumbers\" 😉 · AI workloads):\n\n",
assignee: "mo",
priority: "normal",
});