Die API v1 ist als Produktgrenze geschärft in [dto.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/dto.rs>) und [server.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/server.rs>): getrennte Modelle für `state`, `preview`, `snapshot`, `command response`, `event stream` und stabile Fehlerobjekte mit echten Codes statt generischem Fallback. Dazu kamen `GET /api/v1/state` und `GET /api/v1/preview`, neue persistenzbezogene Commands wie `save_preset`, `save_creative_snapshot`, `recall_creative_snapshot`, `set_transition_style` und `upsert_group`, plus serverseitige Durchreichung der echten Fehlercodes. Die kreative Web-UI in [index.html](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/index.html>), [app.js](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/app.js>) und [styles.css](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/styles.css>) nutzt jetzt genau diese API für Preset-Speichern/Überschreiben, Varianten, Transition-Style, filterbaren Eventfeed und klarere Preview-Darstellung, ohne Parallelarchitektur. Die Doku ist auf den neuen Stand gezogen in [docs/host_api.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/host_api.md>), [README.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/README.md>), [docs/build_and_deploy.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/build_and_deploy.md>) und [docs/architecture.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/architecture.md>). Verifiziert habe ich `cargo check -q` und `cargo test -q`; dabei laufen die erweiterten Contract- und Persistenztests in [contract.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/tests/contract.rs>) sowie neue Core-Tests in [show_store.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/show_store.rs>) und [simulation.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/simulation.rs>). Nicht separat verifiziert habe ich einen echten Browserlauf der Web-UI; die JS-Datei wurde hier nicht mit `node` geprüft, weil `node` in dieser Umgebung nicht installiert ist.
196 lines
7.1 KiB
HTML
196 lines
7.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Infinity Vis Creative Console</title>
|
|
<link rel="stylesheet" href="/styles.css" />
|
|
</head>
|
|
<body>
|
|
<div class="page-shell">
|
|
<header class="hero">
|
|
<div class="hero-copy">
|
|
<p class="eyebrow">Infinity Vis / Creative Surface</p>
|
|
<h1 id="project-name">Loading project...</h1>
|
|
<p id="topology-label" class="hero-subtitle">
|
|
Shared host API bootstrap in progress.
|
|
</p>
|
|
</div>
|
|
<div class="hero-status">
|
|
<div class="status-card">
|
|
<span class="status-label">API stream</span>
|
|
<span id="connection-pill" class="pill pill-offline">connecting</span>
|
|
</div>
|
|
<div class="status-card">
|
|
<span class="status-label">Preview refresh</span>
|
|
<span id="preview-updated">waiting for data</span>
|
|
</div>
|
|
<button id="refresh-button" class="ghost-button" type="button">
|
|
Refresh snapshot
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="layout">
|
|
<section class="panel controls-panel">
|
|
<div class="section-heading">
|
|
<h2>Global Look</h2>
|
|
<p>Pattern, preset, group and transition control against the shared host API.</p>
|
|
</div>
|
|
|
|
<div class="control-grid">
|
|
<label class="field">
|
|
<span>Pattern</span>
|
|
<select id="pattern-select"></select>
|
|
</label>
|
|
|
|
<label class="field">
|
|
<span>Transition Duration</span>
|
|
<input id="transition-slider" type="range" min="0" max="3000" step="10" />
|
|
<strong id="transition-value">0 ms</strong>
|
|
</label>
|
|
|
|
<label class="field">
|
|
<span>Transition Style</span>
|
|
<select id="transition-style-select">
|
|
<option value="snap">Snap</option>
|
|
<option value="crossfade">Crossfade</option>
|
|
<option value="chase">Chase</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label class="field">
|
|
<span>Master Brightness</span>
|
|
<input id="brightness-slider" type="range" min="0" max="1" step="0.01" />
|
|
<strong id="brightness-value">0%</strong>
|
|
</label>
|
|
|
|
<div class="field">
|
|
<span>Blackout</span>
|
|
<button id="blackout-button" class="danger-button" type="button">
|
|
Enable blackout
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="subsection">
|
|
<div class="subsection-heading">
|
|
<h3>Presets</h3>
|
|
<p>Recall look snapshots without leaving the creative console.</p>
|
|
</div>
|
|
<div id="preset-list" class="pill-row"></div>
|
|
</div>
|
|
|
|
<div class="subsection">
|
|
<div class="subsection-heading">
|
|
<h3>Preset Capture</h3>
|
|
<p>Store or overwrite the current scene as a reusable preset through the same API.</p>
|
|
</div>
|
|
<div class="capture-grid">
|
|
<label class="field">
|
|
<span>Preset ID</span>
|
|
<input id="preset-id-input" type="text" placeholder="e.g. sunset_chase" />
|
|
</label>
|
|
<label class="field inline-checkbox">
|
|
<span>Overwrite Existing</span>
|
|
<input id="preset-overwrite-input" type="checkbox" />
|
|
</label>
|
|
<button id="save-preset-button" class="ghost-button" type="button">
|
|
Save Current Scene As Preset
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="subsection">
|
|
<div class="subsection-heading">
|
|
<h3>Groups</h3>
|
|
<p>Focus looks on a subset while keeping the core scene model shared.</p>
|
|
</div>
|
|
<input
|
|
id="group-filter-input"
|
|
class="filter-input"
|
|
type="text"
|
|
placeholder="Filter groups by id or tag"
|
|
/>
|
|
<div id="group-list" class="pill-row"></div>
|
|
</div>
|
|
|
|
<div class="subsection">
|
|
<div class="subsection-heading">
|
|
<h3>Creative Snapshots</h3>
|
|
<p>Capture exploratory variants without replacing curated presets.</p>
|
|
</div>
|
|
<div class="capture-grid">
|
|
<label class="field">
|
|
<span>Snapshot ID</span>
|
|
<input id="snapshot-id-input" type="text" placeholder="e.g. variant_afterglow" />
|
|
</label>
|
|
<label class="field">
|
|
<span>Label</span>
|
|
<input id="snapshot-label-input" type="text" placeholder="Readable label" />
|
|
</label>
|
|
<label class="field inline-checkbox">
|
|
<span>Overwrite Existing</span>
|
|
<input id="snapshot-overwrite-input" type="checkbox" />
|
|
</label>
|
|
<button id="save-snapshot-button" class="ghost-button" type="button">
|
|
Save Creative Snapshot
|
|
</button>
|
|
</div>
|
|
<div id="snapshot-list" class="snapshot-list"></div>
|
|
</div>
|
|
|
|
<div class="subsection">
|
|
<div class="subsection-heading">
|
|
<h3>Scene Parameters</h3>
|
|
<p>Rendered from the active scene schema, not hardcoded per frontend.</p>
|
|
</div>
|
|
<div id="scene-params" class="parameter-grid"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel preview-panel">
|
|
<div class="section-heading">
|
|
<h2>Preview</h2>
|
|
<p>Live panel previews from the host snapshot and stream feed.</p>
|
|
</div>
|
|
<div id="preview-grid" class="preview-grid"></div>
|
|
</section>
|
|
|
|
<section class="panel summary-panel">
|
|
<div class="section-heading">
|
|
<h2>Snapshot</h2>
|
|
<p>Operator-friendly scene state with a raw API view underneath.</p>
|
|
</div>
|
|
<div id="summary-cards" class="summary-cards"></div>
|
|
<pre id="snapshot-json" class="snapshot-json"></pre>
|
|
</section>
|
|
|
|
<section class="panel event-panel">
|
|
<div class="section-heading">
|
|
<h2>Event Stream</h2>
|
|
<p>Recent notices from the websocket feed.</p>
|
|
</div>
|
|
<div class="event-filter-bar">
|
|
<select id="event-kind-filter">
|
|
<option value="all">All kinds</option>
|
|
<option value="info">Info</option>
|
|
<option value="warning">Warning</option>
|
|
<option value="error">Error</option>
|
|
</select>
|
|
<input
|
|
id="event-search-filter"
|
|
class="filter-input"
|
|
type="text"
|
|
placeholder="Filter by code or message"
|
|
/>
|
|
</div>
|
|
<div id="event-list" class="event-list"></div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
|
|
<script src="/app.js"></script>
|
|
</body>
|
|
</html>
|