A module that sees something a tech must act on now (a timer overrun, a meter past its limit, timecode gone) raises an alert on a channel, 1–6, and every dashboard listening to that channel flashes: the menu bar — brought out for the duration if it was hidden — and a frame round the screen alternate between the level's two colours, with the alert's text bold across the bar. Low fades slowly, medium faster, critical snaps with no fade and floods the board behind the tiles too, in a muted cut that shows faintly through the tile panels without costing their content any contrast. Server: the hub. One alert per channel (a new one replaces the last), timed out server-side (1–600 s, 15 by default, 0 = held until cleared), broadcast over the shell stream as `alert` / `alert-clear`; GET /api/alerts for a dashboard that opens or reconnects mid-alert; POST /api/alerts and DELETE /api/alerts/<n>, open like a layout save. Modules raise from their server entry with shell.alert() / shell.clearAlert() or from a tile with moduleApi.alert() / moduleApi.clearAlert(); a module's alerts end when it stops. Colours live as alerts.colors in the data directory's proddash.json. Dashboard: the Layouts menu gains a folded Alerts row with six numbered toggles; the channel list saves with the layout, local and named (the server keeps it in a saved layout). Admin: a folded Alerts section with two colour pickers per level, a swatch running each level's cadence, and a Test row. Docs: docs/ALERTS.md (the feature), a "Raising alerts" section in the module guide, README. Tools: tools/alert.js raises/clears/lists from the command line; tools/alerts.test.js drives it all end to end. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
85 lines
5.1 KiB
HTML
85 lines
5.1 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>ProdDash</title>
|
|
<meta name="theme-color" content="#0b0e12">
|
|
<link rel="manifest" href="/manifest.webmanifest">
|
|
<link rel="icon" href="/icons/icon-192.png">
|
|
<link rel="apple-touch-icon" href="/icons/icon-180.png">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
<meta name="apple-mobile-web-app-title" content="ProdDash">
|
|
<link rel="stylesheet" href="/style.css">
|
|
</head>
|
|
<body>
|
|
<header id="topbar">
|
|
<span id="brand">Prod<span class="accent">Dash</span></span>
|
|
|
|
<!-- An alert this dashboard listens to: its text, bold, centred in the bar (shell.js fills it). -->
|
|
<div id="alert-banner" role="status" aria-live="assertive" hidden>
|
|
<span class="alert-channel" aria-hidden="true"></span>
|
|
<span class="alert-text"></span>
|
|
<span class="alert-more"></span>
|
|
</div>
|
|
|
|
<span class="spacer"></span>
|
|
|
|
<button class="tb-btn icon" id="autohide-btn" title="Auto-hide bars" aria-label="Auto-hide tile title bars" aria-pressed="false">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<path d="M9 6l3-3 3 3"/>
|
|
<rect x="4" y="10" width="16" height="10" rx="1.5"/>
|
|
<path d="M4 14h16"/>
|
|
</svg>
|
|
</button>
|
|
|
|
<button class="tb-btn icon" id="fs-btn" title="Fullscreen" aria-label="Fullscreen">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<path d="M4 9V5a1 1 0 0 1 1-1h4"/><path d="M20 9V5a1 1 0 0 0-1-1h-4"/>
|
|
<path d="M4 15v4a1 1 0 0 0 1 1h4"/><path d="M20 15v4a1 1 0 0 1-1 1h-4"/>
|
|
</svg>
|
|
</button>
|
|
|
|
<div class="dropdown" id="add-dd">
|
|
<button class="tb-btn icon" id="add-btn" title="Add tile" aria-label="Add tile">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
|
|
</button>
|
|
<div class="menu" id="add-menu" hidden></div>
|
|
</div>
|
|
|
|
<div class="dropdown" id="layout-dd">
|
|
<button class="tb-btn icon" id="layout-btn" title="Layouts" aria-label="Layouts">
|
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
<rect x="3" y="3" width="8" height="8" rx="1.5"/>
|
|
<rect x="3" y="13" width="8" height="8" rx="1.5"/>
|
|
<rect x="13" y="3" width="8" height="18" rx="1.5"/>
|
|
</svg>
|
|
</button>
|
|
<div class="menu" id="layout-menu" hidden></div>
|
|
</div>
|
|
|
|
<a class="tb-btn icon" id="admin-link" href="/admin/" title="Admin" aria-label="Admin">
|
|
<svg width="14" height="14" viewBox="0 0 90 90" fill="currentColor" aria-hidden="true"><path d="M 82.94 32.538 c -2.685 0 -5.093 -1.545 -6.327 -3.929 c -0.245 -0.476 -0.504 -0.948 -0.774 -1.416 c -0.27 -0.468 -0.55 -0.928 -0.84 -1.378 c -1.448 -2.26 -1.582 -5.117 -0.239 -7.443 c 1.951 -3.378 0.792 -7.696 -2.584 -9.645 l -9.352 -5.4 c -3.378 -1.951 -7.696 -0.792 -9.645 2.584 l -0.002 0.003 c -1.322 2.291 -3.815 3.641 -6.456 3.512 c -1.149 -0.056 -2.301 -0.057 -3.455 0 c -2.638 0.128 -5.124 -1.226 -6.444 -3.513 l -0.002 -0.002 c -1.951 -3.378 -6.269 -4.535 -9.645 -2.584 l -9.352 5.4 c -3.378 1.951 -4.535 6.269 -2.584 9.645 l 0.002 0.002 c 1.321 2.286 1.25 5.117 -0.18 7.336 c -0.625 0.972 -1.201 1.97 -1.726 2.993 c -1.209 2.353 -3.625 3.836 -6.269 3.836 H 7.063 c -3.9 0 -7.061 3.162 -7.061 7.061 v 10.801 c 0 3.9 3.162 7.061 7.061 7.061 l 0 0 c 2.685 0 5.093 1.545 6.327 3.929 c 0.245 0.475 0.504 0.948 0.774 1.416 c 0.27 0.468 0.55 0.928 0.84 1.378 c 1.448 2.26 1.582 5.117 0.239 7.443 c -1.951 3.378 -0.792 7.696 2.584 9.645 l 9.352 5.4 c 3.378 1.951 7.696 0.792 9.645 -2.584 l 0.002 -0.003 c 1.322 -2.291 3.815 -3.641 6.456 -3.512 c 1.149 0.056 2.301 0.057 3.455 0 c 2.638 -0.128 5.124 1.226 6.444 3.513 l 0.002 0.002 c 1.951 3.378 6.268 4.535 9.645 2.584 l 9.352 -5.4 c 3.378 -1.949 4.535 -6.268 2.584 -9.645 l -0.002 -0.002 c -1.321 -2.286 -1.25 -5.117 0.18 -7.336 c 0.625 -0.972 1.201 -1.97 1.726 -2.993 c 1.209 -2.353 3.625 -3.836 6.269 -3.836 h 0.003 c 3.9 0 7.061 -3.162 7.061 -7.061 V 39.599 C 90.001 35.7 86.84 32.538 82.94 32.538 z M 54.998 62.318 c -9.565 5.523 -21.796 2.245 -27.317 -7.32 c -5.523 -9.565 -2.245 -21.796 7.32 -27.317 s 21.796 -2.245 27.317 7.32 C 67.841 44.566 64.563 56.797 54.998 62.318 z"/></svg>
|
|
</a>
|
|
</header>
|
|
|
|
<button id="topbar-notch" title="Hide / show the menu bar" aria-label="Hide or show the menu bar"></button>
|
|
|
|
<main id="gridwrap">
|
|
<div id="grid">
|
|
<div id="empty-state">No tiles yet — use “+ Add tile” to build this dashboard.<br>
|
|
Every browser keeps its own layout.</div>
|
|
</div>
|
|
</main>
|
|
|
|
<div id="modal-backdrop" hidden>
|
|
<div id="modal" role="dialog" aria-modal="true"></div>
|
|
</div>
|
|
|
|
<div id="toast" hidden></div>
|
|
|
|
<script type="module" src="/shell.js"></script>
|
|
</body>
|
|
</html>
|