Files
ome-cockpit/ui/index.html
T
mo b73ff9465c Initial import of Dell OpenManage Cockpit for ATC.
Interactive OME fleet UI with topology, KPI popups, in-browser SSH, chat, tickets, and full inventory landscape.
2026-07-17 04:00:38 +02:00

451 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dell OpenManage Cockpit — ATC</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/styles.css?v=kpi1" />
<link rel="icon" href="/dell.png" type="image/png" />
<link rel="stylesheet" href="/vendor/xterm/xterm.css?v=home1" />
</head>
<body>
<div id="notify-stack" aria-live="polite" aria-atomic="false"></div>
<div id="app">
<header class="topbar">
<a class="brand" href="/" title="OpenManage Cockpit home">
<img class="dell-logo" src="/dell.png" alt="Dell" width="44" height="44" />
<div class="brand-text">
<h1>OpenManage <span>Cockpit</span></h1>
<p id="ome-meta">OME · connecting…</p>
</div>
</a>
<div class="kpi-strip" id="kpi-strip" aria-label="Fleet KPIs"></div>
<div class="top-actions">
<button type="button" class="btn ghost" id="btn-reset-view" title="Fit fleet in view">Reset view</button>
<button type="button" class="btn ghost" id="btn-ome-console" title="Open OME console">OME console</button>
<button type="button" class="btn ghost" id="btn-ops" title="ATC admin tickets">Ops desk</button>
<button type="button" class="btn primary" id="btn-chat">Cockpit chat</button>
</div>
</header>
<aside class="rail left" id="left-rail">
<section class="rail-block open" data-module="viz">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>Visualization</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Interactive topology layout</p>
<div class="viz-grid" id="layout-modes">
<button type="button" class="viz-card active" data-layout="orbit"><span class="viz-ico"></span><span class="viz-t">Orbit</span><span class="viz-s">Hub &amp; rings</span></button>
<button type="button" class="viz-card" data-layout="galaxy"><span class="viz-ico"></span><span class="viz-t">Galaxy</span><span class="viz-s">Spiral arms</span></button>
<button type="button" class="viz-card" data-layout="clusters"><span class="viz-ico"></span><span class="viz-t">Clusters</span><span class="viz-s">Subnet islands</span></button>
<button type="button" class="viz-card" data-layout="lanes"><span class="viz-ico"></span><span class="viz-t">Lanes</span><span class="viz-s">Fiber highways</span></button>
<button type="button" class="viz-card" data-layout="helix"><span class="viz-ico"></span><span class="viz-t">Helix</span><span class="viz-s">3D depth coil</span></button>
</div>
</div>
</section>
<section class="rail-block open" data-module="filters">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>Filters</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Servers / iDRACs = include types. Both off = empty map.</p>
<div class="filters" id="filters">
<label class="toggle"><input type="checkbox" id="f-servers" checked /> Servers</label>
<label class="toggle"><input type="checkbox" id="f-idrac" /> iDRACs</label>
<label class="toggle"><input type="checkbox" id="f-connected" /> Connected only</label>
<label class="toggle"><input type="checkbox" id="f-powered" /> Powered on</label>
<label class="toggle"><input type="checkbox" id="f-has-power" /> Has power reading</label>
<label class="toggle"><input type="checkbox" id="f-ghost-links" /> Ghost offline links</label>
<label class="toggle"><input type="checkbox" id="f-pulse-links" checked /> Animate link pulse</label>
<label class="range">
<span>Min watts <em id="min-w-label">0</em></span>
<input type="range" id="f-min-watts" min="0" max="800" step="10" value="0" />
</label>
</div>
<div class="filter-actions">
<button type="button" class="btn ghost compact" id="btn-clear-filters" title="Reset filters to defaults">Reset filters</button>
</div>
<input type="search" id="search" class="search" placeholder="Search name, tag, IP, model…" autocomplete="off" />
</div>
</section>
<section class="rail-block open" data-module="view">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>Color mode</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Node colors by status, power, model…</p>
<div class="chip-grid" id="view-modes">
<button type="button" class="chip active" data-mode="status">Status</button>
<button type="button" class="chip" data-mode="power">Power (W)</button>
<button type="button" class="chip" data-mode="connection">Connection</button>
<button type="button" class="chip" data-mode="model">Model</button>
<button type="button" class="chip" data-mode="subnet">Subnet</button>
</div>
</div>
</section>
<section class="rail-block open" data-module="gpu">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>V100 GPU matrix</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Live atc-gpu-prod · llama3-70b-gptq</p>
<div id="gpu-summary" class="gpu-summary">Waiting for GPU telemetry…</div>
<div id="gpu-matrix" class="gpu-matrix"></div>
</div>
</section>
<section class="rail-block open" data-module="live">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>Realtime context</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Live OME alerts + fleet deltas — click to focus</p>
<div class="ctx-stats" id="ctx-stats"></div>
<div class="list" id="alert-list"></div>
</div>
</section>
<section class="rail-block open" data-module="networks">
<button type="button" class="rail-toggle" aria-expanded="true">
<span>Networks</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Management subnets — click to focus</p>
<div class="list" id="subnet-list"></div>
</div>
</section>
<section class="rail-block" data-module="models">
<button type="button" class="rail-toggle" aria-expanded="false">
<span>Models</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<p class="hint">Server platforms in inventory</p>
<div class="list" id="model-list"></div>
</div>
</section>
<section class="rail-block" data-module="groups">
<button type="button" class="rail-toggle" aria-expanded="false">
<span>Groups</span>
<span class="chev" aria-hidden="true"></span>
</button>
<div class="rail-panel">
<div class="list" id="group-list"></div>
</div>
</section>
</aside>
<main class="stage">
<div class="ctx-bar" id="ctx-bar">
<div class="ctx-live">
<span class="pulse-dot" aria-hidden="true"></span>
<span id="ctx-live-text">Realtime context · waiting for OME…</span>
</div>
<div class="ctx-focus" id="ctx-focus">Focus: all networks</div>
</div>
<canvas id="topo"></canvas>
<div class="stage-hud">
<div class="legend" id="legend"></div>
<div class="hint-bar">Scroll = zoom · drag = pan · hover tip · double-click = Quick Connect</div>
</div>
<aside class="ctx-feed" id="ctx-feed" aria-label="Realtime feed">
<header class="ctx-feed-head" id="ctx-feed-drag">
<strong>Live feed</strong>
<span id="ctx-feed-meta"></span>
<span class="feed-docks">
<button type="button" class="feed-dock" id="btn-feed-collapse" title="Minimize feed"></button>
<button type="button" class="feed-dock hidden" id="btn-feed-expand" title="Expand feed"></button>
</span>
</header>
<div class="ctx-feed-body" id="ctx-feed-body"></div>
</aside>
</main>
<aside class="rail right" id="inspector">
<div class="inspector-empty" id="inspector-empty">
<img src="/dell.png" alt="" class="ghost-logo" />
<h2>Inspector</h2>
<p>Select a node, KPI, or subnet for live details. Everything is clickable.</p>
</div>
<div class="inspector-body hidden" id="inspector-body"></div>
</aside>
<footer class="ticker" id="ticker"></footer>
</div>
<!-- Cockpit chat -->
<div class="drawer" id="chat-drawer" aria-hidden="true">
<div class="drawer-head">
<div class="drawer-brand">
<img src="/dell.png" alt="Dell" height="22" />
<span>Cockpit chat</span>
</div>
<button type="button" class="btn ghost" id="btn-chat-close">Close</button>
</div>
<div class="chat-context" id="chat-context">
<label class="chat-model-wrap" title="Select model">
<span class="chat-model-label">Model</span>
<select id="chat-model" class="chat-model-select" aria-label="Chat model">
<option value="llama3-70b-gptq">llama3-70b-gptq</option>
</select>
</label>
<span class="chat-ctx-pill" id="chat-ctx-fleet">fleet …</span>
<span class="chat-ctx-pill" id="chat-ctx-focus">focus: none</span>
</div>
<div class="chat-quick" id="chat-quick">
<button type="button" data-q="What is the current fleet health? Name critical systems.">Fleet health</button>
<button type="button" data-q="List all critical alerts with system name and IP.">Critical alerts</button>
<button type="button" data-q="Which connected nodes use the most power right now?">Top power</button>
<button type="button" data-q="Summarize V100 GPU utilization on atc-gpu-prod.">GPU status</button>
</div>
<div class="chat-body" id="chat-body"></div>
<form class="chat-form" id="chat-form">
<input type="text" id="chat-input" placeholder="Ask about live OME fleet, alerts, power, iDRACs, GPUs…" autocomplete="off" />
<button type="submit" class="btn primary">Send</button>
</form>
</div>
<!-- Ops desk / tickets -->
<div class="drawer wide" id="ops-drawer" aria-hidden="true">
<div class="drawer-head">
<div class="drawer-brand">
<img src="/dell.png" alt="Dell" height="22" />
<span>ATC Ops desk</span>
</div>
<button type="button" class="btn ghost" id="btn-ops-close">Close</button>
</div>
<div class="ops-layout">
<div class="ops-side">
<label class="ops-identity">Acting as
<select id="ops-actor">
<option value="jody">Jody van Dongen</option>
<option value="laurens">Laurens Rammers</option>
</select>
</label>
<button type="button" class="btn primary" id="btn-new-ticket">New ticket</button>
<div class="ops-filters">
<select id="ops-filter">
<option value="openish">Active</option>
<option value="all">All</option>
<option value="open">Open</option>
<option value="accepted">Accepted</option>
<option value="in_progress">In progress</option>
<option value="resolved">Resolved</option>
<option value="closed">Closed</option>
<option value="mine">Assigned to me</option>
</select>
</div>
<div class="list" id="ticket-list"></div>
</div>
<div class="ops-main" id="ops-main">
<div class="ops-empty" id="ops-empty">
<h3>Admin collaboration</h3>
<p>Jody van Dongen and Laurens Rammers can exchange notes and tickets for ATC datacenter operations.</p>
</div>
<div class="ops-thread hidden" id="ops-thread"></div>
</div>
</div>
</div>
<div class="drawer" id="ai-drawer" aria-hidden="true">
<div class="drawer-head">
<div class="drawer-brand">
<img src="/dell.png" alt="Dell" height="22" />
<span>OpenManage AI</span>
</div>
<button type="button" class="btn ghost" id="btn-ai-close">Close</button>
</div>
<iframe id="ai-frame" title="OpenManage AI" src="about:blank"></iframe>
</div>
<div class="scrim" id="scrim"></div>
<div class="node-tip hidden" id="node-tip" role="tooltip"></div>
<div class="modal hidden" id="ticket-modal" aria-hidden="true" role="dialog" aria-labelledby="ticket-modal-title">
<div class="modal-card ticket-card">
<button type="button" class="modal-close" id="btn-ticket-modal-close" aria-label="Close">×</button>
<div class="modal-brand">
<img src="/dell.png" alt="Dell" width="36" height="36" />
<div>
<p class="modal-kicker">ATC Ops desk</p>
<h2 id="ticket-modal-title">Create ticket</h2>
<p class="modal-sub">Professional handoff between Jody van Dongen and Laurens Rammers</p>
</div>
</div>
<form id="ticket-form" class="ticket-form">
<label>Title
<input type="text" id="ticket-title" required maxlength="180" placeholder="Short operational title" />
</label>
<div class="ticket-form-row">
<label>Priority
<select id="ticket-priority">
<option value="low">Low</option>
<option value="normal" selected>Normal</option>
<option value="high">High</option>
<option value="critical">Critical</option>
</select>
</label>
<label>Assign to
<select id="ticket-assignee">
<option value="laurens">Laurens Rammers</option>
<option value="jody">Jody van Dongen</option>
</select>
</label>
</div>
<label>Details / note
<textarea id="ticket-body" rows="7" required placeholder="Context, system, IP, observed impact, requested action…"></textarea>
</label>
<div class="ticket-form-actions">
<button type="button" class="btn ghost" id="btn-ticket-cancel">Cancel</button>
<button type="submit" class="btn primary">Create ticket</button>
</div>
</form>
</div>
</div>
<div class="modal hidden" id="kpi-modal" aria-hidden="true" role="dialog" aria-labelledby="kpi-title">
<div class="modal-card kpi-card">
<button type="button" class="modal-close" id="btn-kpi-close" aria-label="Close">×</button>
<div class="modal-brand">
<img src="/dell.png" alt="Dell" width="36" height="36" />
<div>
<p class="modal-kicker">Fleet context</p>
<h2 id="kpi-title">KPI</h2>
<p class="modal-sub" id="kpi-sub">Interactive breakdown — click a system for actions</p>
</div>
</div>
<div class="kpi-summary" id="kpi-summary"></div>
<div class="kpi-toolbar">
<input type="search" id="kpi-search" class="search" placeholder="Search name, IP, model, tag, subnet…" autocomplete="off" />
<select id="kpi-sort" aria-label="Sort">
<option value="name">Sort: name</option>
<option value="watts">Sort: power</option>
<option value="status">Sort: status</option>
<option value="subnet">Sort: subnet</option>
</select>
<button type="button" class="btn" id="btn-kpi-apply">Apply as map filter</button>
<button type="button" class="btn ghost" id="btn-kpi-clear">Clear map filter</button>
</div>
<div class="kpi-layout">
<div class="kpi-list" id="kpi-list"></div>
<div class="kpi-detail" id="kpi-detail">
<p class="hint">Select a system on the left for live context and actions.</p>
</div>
</div>
</div>
</div>
<div class="modal hidden" id="triage-modal" aria-hidden="true" role="dialog" aria-labelledby="triage-title">
<div class="modal-card triage-card">
<button type="button" class="modal-close" id="btn-triage-close" aria-label="Close">×</button>
<div class="modal-brand">
<img src="/dell.png" alt="Dell" width="36" height="36" />
<div>
<p class="modal-kicker">Realtime triage</p>
<h2 id="triage-title">Critical alerts</h2>
<p class="modal-sub" id="triage-sub">Click a system to inspect · create ATC ticket instantly</p>
</div>
</div>
<div class="triage-toolbar">
<div class="chip-grid" id="triage-tabs">
<button type="button" class="chip active" data-triage="critical">Critical</button>
<button type="button" class="chip" data-triage="warning">Warning</button>
<button type="button" class="chip" data-triage="events">Fleet deltas</button>
<button type="button" class="chip" data-triage="hottest">Live power</button>
<button type="button" class="chip" data-triage="all">All feed</button>
</div>
<input type="search" id="triage-search" class="search" placeholder="Filter by system, IP, message, tag…" />
</div>
<div class="triage-layout">
<div class="triage-list" id="triage-list"></div>
<div class="triage-detail" id="triage-detail">
<p class="hint">Select an alert or system on the left.</p>
</div>
</div>
</div>
</div>
<div class="modal hidden" id="connect-modal" aria-hidden="true" role="dialog" aria-labelledby="connect-title">
<div class="modal-card">
<button type="button" class="modal-close" id="btn-connect-close" aria-label="Close">×</button>
<div class="modal-brand">
<img src="/dell.png" alt="Dell" width="36" height="36" />
<div>
<p class="modal-kicker">Quick Connect</p>
<h2 id="connect-title">Device</h2>
<p class="modal-sub" id="connect-sub"></p>
</div>
</div>
<div class="modal-badges" id="connect-badges"></div>
<div class="modal-context" id="connect-context"></div>
<div class="connect-grid" id="connect-grid"></div>
<p class="modal-foot">iDRAC opens in a new tab · SSH opens an in-browser terminal — enter your own username</p>
</div>
</div>
<div class="modal hidden" id="ssh-modal" aria-hidden="true" role="dialog" aria-labelledby="ssh-device">
<div class="modal-card ssh-card">
<button type="button" class="modal-close" id="btn-ssh-close" aria-label="Close">×</button>
<div class="modal-brand">
<img src="/dell.png" alt="Dell" width="36" height="36" />
<div>
<p class="modal-kicker">SSH terminal</p>
<h2 id="ssh-device">SSH session</h2>
<p class="modal-sub" id="ssh-sub"></p>
</div>
</div>
<p class="ssh-status" id="ssh-status">Enter username and password, then Connect.</p>
<form class="ssh-login" id="ssh-login" autocomplete="on">
<div class="ssh-grid">
<label>Host
<input type="text" id="ssh-host" name="host" autocomplete="off" spellcheck="false" />
</label>
<label>Port
<input type="number" id="ssh-port" name="port" value="22" min="1" max="65535" />
</label>
<label>Username
<input type="text" id="ssh-user" name="username" autocomplete="username" spellcheck="false" placeholder="your account (not root)" />
</label>
<label>Password
<input type="password" id="ssh-pass" name="password" autocomplete="current-password" placeholder="••••••••" />
</label>
</div>
<div class="ssh-actions">
<button type="submit" class="btn primary" id="ssh-connect-btn">Connect</button>
<button type="button" class="btn ghost" id="btn-ssh-disconnect">Disconnect</button>
</div>
</form>
<div class="ssh-term-wrap hidden" id="ssh-term-wrap">
<div id="ssh-term" class="ssh-term"></div>
</div>
</div>
</div>
<script src="/vendor/xterm/xterm.min.js?v=home1"></script>
<script src="/vendor/xterm/xterm-addon-fit.min.js?v=home1"></script>
<script src="/app.js?v=kpi1"></script>
<script src="/ops.js?v=kpi1"></script>
<script src="/ssh.js?v=kpi1"></script>
</body>
</html>