@@ -4,6 +4,10 @@ import { ControlCenterNav } from "./ControlCenterNav";
44import { ControlCenterPluginPanel } from "./ControlCenterPluginPanel" ;
55import { ControlCenterTabContent } from "./ControlCenterTabContent" ;
66import { ControlCenterMainHeader } from "./ControlCenterMainHeader" ;
7+ import {
8+ ControlCenterDemoModeProvider ,
9+ useControlCenterDemoMode ,
10+ } from "./useControlCenterDemoMode" ;
711import { ControlCenterTabRefreshProvider } from "./useControlCenterTabRefresh" ;
812import {
913 addProfile ,
@@ -24,6 +28,31 @@ type Props = {
2428 apiBase : string ;
2529} ;
2630
31+ function DemoModeBanner ( ) {
32+ // Show a shell banner while Demo mode fills empty live state.
33+ //
34+ // Parameters:
35+ // None.
36+ //
37+ // Returns:
38+ // Banner element, or null when Demo mode is off.
39+ //
40+ // Options:
41+ // None.
42+ //
43+ // Example:
44+ // <DemoModeBanner />
45+
46+ const { demoMode } = useControlCenterDemoMode ( ) ;
47+ if ( ! demoMode ) return null ;
48+ return (
49+ < div className = "banner cc-demo-banner" role = "status" >
50+ Demo mode on — simulated telemetry and catalog examples fill empty live state. Turn off for
51+ runtime-only views.
52+ </ div >
53+ ) ;
54+ }
55+
2756export function ControlCenterPanel ( { apiBase } : Props ) {
2857 const [ profiles , setProfiles ] = useState < ControlCenterProfile [ ] > ( ( ) => ensureProfile ( apiBase ) ) ;
2958 const [ activeProfileId , setActiveProfileIdState ] = useState (
@@ -138,99 +167,103 @@ export function ControlCenterPanel({ apiBase }: Props) {
138167 } ;
139168
140169 return (
141- < div className = "cc-shell" >
142- < aside className = "cc-sidebar" >
143- < div className = "cc-sidebar-brand" >
144- < div className = "cc-sidebar-title-row" >
145- < span className = "cc-sidebar-title" > Control Center</ span >
146- < span className = "cc-sidebar-version" > v{ controlCenterVersion } </ span >
170+ < ControlCenterDemoModeProvider >
171+ < div className = "cc-shell" >
172+ < aside className = "cc-sidebar" >
173+ < div className = "cc-sidebar-brand" >
174+ < div className = "cc-sidebar-title-row" >
175+ < span className = "cc-sidebar-title" > Control Center</ span >
176+ < span className = "cc-sidebar-version" > v{ controlCenterVersion } </ span >
177+ </ div >
178+ < span className = "cc-sidebar-host" title = { base } >
179+ { apiHost }
180+ </ span >
147181 </ div >
148- < span className = "cc-sidebar-host" title = { base } >
149- { apiHost }
150- </ span >
151- </ div >
152- < ControlCenterNav
153- activeTab = { pluginTab ? null : tab }
154- pluginTab = { pluginTab }
155- pluginPanels = { core . pluginPanels }
156- isTabAllowed = { isTabAllowed }
157- onSelectTab = { selectTab }
158- onSelectPlugin = { setPluginTab }
159- />
160- < div className = "cc-sidebar-footer" >
161- < ControlCenterAuthBanner
162- compact
163- apiHost = { apiHost }
164- effectiveRole = { effectiveRole }
165- roleMeta = { roleMeta }
166- keyId = { rbacCtx ?. key_id }
167- tenantId = { rbacCtx ?. tenant_id ?? activeProfile ?. tenantId }
168- permissions = { rbacCtx ?. permissions ?? [ ] }
169- hasToken = { hasToken }
170- showAuthSetup = { showAuthSetup }
171- envKeyLocked = { envKeyLocked }
172- authError = { authError }
173- profiles = { profiles }
174- activeProfileId = { activeProfile ?. id }
175- onSwitchProfile = { switchProfile }
176- onAddConnection = { handleAddConnection }
177- onVerify = { verifyAndSetApiKey }
178- onSignInWithOidc = { signInWithOidc }
179- oidcLoginEnabled = { oidcLoginEnabled }
180- onForget = { forgetTokenAndProfile }
181- onOpenSetup = { ( ) => setShowAuthSetup ( true ) }
182- />
183- </ div >
184- </ aside >
185-
186- < main className = "cc-main" >
187- < ControlCenterTabRefreshProvider tab = { tab } >
188- < ControlCenterMainHeader
189- tab = { tab }
190- pluginTitle = { activePlugin ?. title ?? null }
191- coreBusy = { core . busy }
192- onCoreRefresh = { ( ) => void core . load ( ) }
193- onReadinessRefresh = { ( ) => void core . runReadiness ( ) }
182+ < ControlCenterNav
183+ activeTab = { pluginTab ? null : tab }
184+ pluginTab = { pluginTab }
185+ pluginPanels = { core . pluginPanels }
186+ isTabAllowed = { isTabAllowed }
187+ onSelectTab = { selectTab }
188+ onSelectPlugin = { setPluginTab }
194189 />
190+ < div className = "cc-sidebar-footer" >
191+ < ControlCenterAuthBanner
192+ compact
193+ apiHost = { apiHost }
194+ effectiveRole = { effectiveRole }
195+ roleMeta = { roleMeta }
196+ keyId = { rbacCtx ?. key_id }
197+ tenantId = { rbacCtx ?. tenant_id ?? activeProfile ?. tenantId }
198+ permissions = { rbacCtx ?. permissions ?? [ ] }
199+ hasToken = { hasToken }
200+ showAuthSetup = { showAuthSetup }
201+ envKeyLocked = { envKeyLocked }
202+ authError = { authError }
203+ profiles = { profiles }
204+ activeProfileId = { activeProfile ?. id }
205+ onSwitchProfile = { switchProfile }
206+ onAddConnection = { handleAddConnection }
207+ onVerify = { verifyAndSetApiKey }
208+ onSignInWithOidc = { signInWithOidc }
209+ oidcLoginEnabled = { oidcLoginEnabled }
210+ onForget = { forgetTokenAndProfile }
211+ onOpenSetup = { ( ) => setShowAuthSetup ( true ) }
212+ />
213+ </ div >
214+ </ aside >
195215
196- { core . error && < div className = "error" > { core . error } </ div > }
197- { core . usingCache && (
198- < div className = "banner cc-offline-banner" >
199- Showing cached dashboard from { core . cacheAge ?? "earlier" } — API unreachable.
200- </ div >
201- ) }
202-
203- < div className = "cc-main-body" >
204- { pluginTab && activePlugin ? (
205- < ControlCenterPluginPanel panel = { activePlugin } baseUrl = { base } />
206- ) : (
207- < ControlCenterTabContent
208- tab = { tab }
209- baseUrl = { base }
210- authHeaders = { authHeaders }
211- can = { can }
212- hasToken = { hasToken }
213- busy = { core . busy }
214- pool = { core . pool }
215- dashboard = { core . dashboard }
216- readiness = { core . readiness }
217- devices = { core . devices }
218- robots = { core . robots }
219- fleets = { core . fleets }
220- agents = { core . agents }
221- selectedRobot = { core . selectedRobot }
222- onRobotChange = { core . setSelectedRobot }
223- robotId = { core . robotId }
224- onNavigate = { selectTab }
225- onRunReadiness = { ( ) => void core . runReadiness ( ) }
226- onRefresh = { ( ) => void core . load ( ) }
227- onSignIn = { ( ) => setShowAuthSetup ( true ) }
228- deviceWorkflow = { deviceWorkflow }
229- />
216+ < main className = "cc-main" >
217+ < ControlCenterTabRefreshProvider tab = { tab } >
218+ < ControlCenterMainHeader
219+ tab = { tab }
220+ pluginTitle = { activePlugin ?. title ?? null }
221+ coreBusy = { core . busy }
222+ onCoreRefresh = { ( ) => void core . load ( ) }
223+ onReadinessRefresh = { ( ) => void core . runReadiness ( ) }
224+ />
225+
226+ < DemoModeBanner />
227+
228+ { core . error && < div className = "error" > { core . error } </ div > }
229+ { core . usingCache && (
230+ < div className = "banner cc-offline-banner" >
231+ Showing cached dashboard from { core . cacheAge ?? "earlier" } — API unreachable.
232+ </ div >
230233 ) }
231- </ div >
232- </ ControlCenterTabRefreshProvider >
233- </ main >
234- </ div >
234+
235+ < div className = "cc-main-body" >
236+ { pluginTab && activePlugin ? (
237+ < ControlCenterPluginPanel panel = { activePlugin } baseUrl = { base } />
238+ ) : (
239+ < ControlCenterTabContent
240+ tab = { tab }
241+ baseUrl = { base }
242+ authHeaders = { authHeaders }
243+ can = { can }
244+ hasToken = { hasToken }
245+ busy = { core . busy }
246+ pool = { core . pool }
247+ dashboard = { core . dashboard }
248+ readiness = { core . readiness }
249+ devices = { core . devices }
250+ robots = { core . robots }
251+ fleets = { core . fleets }
252+ agents = { core . agents }
253+ selectedRobot = { core . selectedRobot }
254+ onRobotChange = { core . setSelectedRobot }
255+ robotId = { core . robotId }
256+ onNavigate = { selectTab }
257+ onRunReadiness = { ( ) => void core . runReadiness ( ) }
258+ onRefresh = { ( ) => void core . load ( ) }
259+ onSignIn = { ( ) => setShowAuthSetup ( true ) }
260+ deviceWorkflow = { deviceWorkflow }
261+ />
262+ ) }
263+ </ div >
264+ </ ControlCenterTabRefreshProvider >
265+ </ main >
266+ </ div >
267+ </ ControlCenterDemoModeProvider >
235268 ) ;
236269}
0 commit comments