From 7dda7cc89cc982c15f921d5ffe4d5090b91f8465 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Fri, 22 May 2026 10:02:55 -0400 Subject: [PATCH] feat(ui): wire data.jsx to real API; add loading gate in app.jsx: app.jsx --- services/web-ui/public/app.jsx | 175 ++++++++++++--------------------- 1 file changed, 62 insertions(+), 113 deletions(-) diff --git a/services/web-ui/public/app.jsx b/services/web-ui/public/app.jsx index ab56b7d..68b112d 100644 --- a/services/web-ui/public/app.jsx +++ b/services/web-ui/public/app.jsx @@ -1,164 +1,113 @@ -// app.jsx — main shell wiring all screens together + tweaks +// app.jsx — main shell -const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ - "accent": "#5B7CFA", - "density": "comfortable", - "gridSize": "md", - "showSearch": true, - "sidebarMode": "expanded" -}/*EDITMODE-END*/; +const ACCENT = '#5B7CFA'; function App() { - const [route, setRoute] = React.useState("home"); + const [route, setRoute] = React.useState('home'); const [openAsset, setOpenAsset] = React.useState(null); const [openProject, setOpenProject] = React.useState(null); const [showNewRecorder, setShowNewRecorder] = React.useState(false); - const [t, setTweak] = (window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}]); + const [dataReady, setDataReady] = React.useState(false); React.useEffect(() => { - document.documentElement.style.setProperty("--accent", t.accent); - document.documentElement.style.setProperty("--accent-soft", hexToRgba(t.accent, 0.14)); - document.documentElement.style.setProperty("--accent-soft-2", hexToRgba(t.accent, 0.22)); - document.documentElement.style.setProperty("--accent-text", lighten(t.accent, 0.25)); - document.documentElement.style.setProperty("--accent-hover", lighten(t.accent, 0.08)); - }, [t.accent]); + document.documentElement.style.setProperty('--accent', ACCENT); + document.documentElement.style.setProperty('--accent-soft', hexToRgba(ACCENT, 0.14)); + document.documentElement.style.setProperty('--accent-soft-2', hexToRgba(ACCENT, 0.22)); + document.documentElement.style.setProperty('--accent-text', lighten(ACCENT, 0.25)); + document.documentElement.style.setProperty('--accent-hover', lighten(ACCENT, 0.08)); + }, []); - const navigate = (id) => { - setOpenAsset(null); - setRoute(id); - }; + React.useEffect(() => { + window.ZAMPP_API.loadData() + .then(() => setDataReady(true)) + .catch(err => { console.error('[Dragonflight] load failed:', err); setDataReady(true); }); + }, []); + + const navigate = (id) => { setOpenAsset(null); setRoute(id); }; const crumbs = React.useMemo(() => { if (openAsset) return [ - { label: "Library", to: "library" }, - { label: openAsset.project, to: "library" }, + { label: 'Library', to: 'library' }, + { label: openAsset.project || 'Library', to: 'library' }, { label: openAsset.name }, ]; if (openProject) return [ - { label: "Projects", to: "projects" }, + { label: 'Projects', to: 'projects' }, { label: openProject.name }, ]; const labels = { - home: ["Home"], - library: ["Library", "Protour 2026"], - projects: ["Projects"], - upload: ["Ingest", "Upload"], - recorders: ["Ingest", "Recorders"], - capture: ["Ingest", "Capture"], - monitors: ["Ingest", "Monitors"], - jobs: ["Jobs"], - editor: ["Editor"], - users: ["Admin", "Users & Groups"], - tokens: ["Admin", "Tokens"], - containers: ["Admin", "Containers"], - cluster: ["Admin", "Cluster"], - settings: ["Admin", "Settings"], + home: ['Home'], library: ['Library'], projects: ['Projects'], + upload: ['Ingest', 'Upload'], recorders: ['Ingest', 'Recorders'], + capture: ['Ingest', 'Capture'], monitors: ['Ingest', 'Monitors'], + jobs: ['Jobs'], editor: ['Editor'], + users: ['Admin', 'Users & Groups'], tokens: ['Admin', 'Tokens'], + containers: ['Admin', 'Containers'], cluster: ['Admin', 'Cluster'], + settings: ['Admin', 'Settings'], }; - return (labels[route] || ["Home"]).map((label, i, arr) => i < arr.length - 1 ? { label } : { label }); + return (labels[route] || ['Home']).map(label => ({ label })); }, [route, openAsset, openProject]); + if (!dataReady) { + return ( + <> + +
+
+
Loading Dragonflight…
+
+ + ); + } + let content; if (openAsset) { content = setOpenAsset(null)} />; } else { switch (route) { - case "home": content = ; break; - case "library": content = ; break; - case "projects": content = { setOpenProject(p); setRoute("library"); }} />; break; - case "upload": content = ; break; - case "recorders": content = setShowNewRecorder(true)} />; break; - case "capture": content = ; break; - case "monitors": content = ; break; - case "jobs": content = ; break; - case "editor": content = ; break; - case "users": content = ; break; - case "tokens": content = ; break; - case "containers": content = ; break; - case "cluster": content = ; break; - case "settings": content = ; break; - default: content = ; + case 'home': content = ; break; + case 'library': content = ; break; + case 'projects': content = { setOpenProject(p); setRoute('library'); }} />; break; + case 'upload': content = ; break; + case 'recorders': content = setShowNewRecorder(true)} />; break; + case 'capture': content = ; break; + case 'monitors': content = ; break; + case 'jobs': content = ; break; + case 'editor': content = ; break; + case 'users': content = ; break; + case 'tokens': content = ; break; + case 'containers':content = ; break; + case 'cluster': content = ; break; + case 'settings': content = ; break; + default: content = ; } } return ( -
- +
+
{!openAsset && } {content}
{showNewRecorder && setShowNewRecorder(false)} />} - {window.TweaksPanel && ( - - - setTweak("accent", v)} - options={["#5B7CFA", "#7C5CFF", "#2DD4A8", "#FF5B5B", "#F5A623", "#E8E8E8"]} - /> - - - setTweak("density", v)} - options={[{ value: "comfortable", label: "Comfy" }, { value: "compact", label: "Compact" }]} - /> - setTweak("gridSize", v)} - options={[{ value: "sm", label: "S" }, { value: "md", label: "M" }, { value: "lg", label: "L" }]} - /> - - - setTweak("sidebarMode", v)} - options={[{ value: "expanded", label: "Expanded" }, { value: "collapsed", label: "Icons" }]} - /> - - -
- {[ - ["home", "Home"], ["library", "Library"], ["recorders", "Recorders"], - ["capture", "Capture"], ["monitors", "Monitors"], ["jobs", "Jobs"], - ["editor", "Editor"], ["cluster", "Cluster"], - ].map(([k, l]) => ( - - ))} - - -
-
-
- )}
); } function hexToRgba(hex, a) { - const h = hex.replace("#", ""); + const h = hex.replace('#', ''); const r = parseInt(h.slice(0, 2), 16); const g = parseInt(h.slice(2, 4), 16); const b = parseInt(h.slice(4, 6), 16); - return `rgba(${r}, ${g}, ${b}, ${a})`; + return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; } function lighten(hex, amt) { - const h = hex.replace("#", ""); + const h = hex.replace('#', ''); const r = Math.min(255, parseInt(h.slice(0, 2), 16) + Math.round(amt * 255)); const g = Math.min(255, parseInt(h.slice(2, 4), 16) + Math.round(amt * 255)); const b = Math.min(255, parseInt(h.slice(4, 6), 16) + Math.round(amt * 255)); - return `rgb(${r}, ${g}, ${b})`; + return 'rgb(' + r + ',' + g + ',' + b + ')'; } -const root = ReactDOM.createRoot(document.getElementById("root")); +const root = ReactDOM.createRoot(document.getElementById('root')); root.render();