add synchronized dual-display workbench
This commit is contained in:
+26
-2
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { CircleAlert, LogOut, ShieldCheck, UserRound } from 'lucide-react'
|
||||
import { CircleAlert, LogOut, MonitorUp, ShieldCheck, UserRound } from 'lucide-react'
|
||||
import '@fontsource/manrope/latin-500.css'
|
||||
import '@fontsource/manrope/latin-600.css'
|
||||
import '@fontsource/manrope/latin-700.css'
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
type WorkspaceNavigationItem,
|
||||
} from './components/shell/WorkbenchNavigation'
|
||||
import { WorkspaceSignal } from './components/shell/WorkspaceSignal'
|
||||
import { useSecondaryDisplay } from './components/shell/SecondaryDisplay'
|
||||
import { useChangeDetectionWorkflow } from './hooks/useChangeDetectionWorkflow'
|
||||
import { useDemoWorkflow } from './hooks/useDemoWorkflow'
|
||||
import { useCoverageResolver } from './hooks/useCoverageResolver'
|
||||
@@ -119,6 +120,7 @@ function WorkbenchApp({ username, accessMode, loggingOut, onLogout }: WorkbenchA
|
||||
const [activeWorkspace, setActiveWorkspace] = useState<WorkspaceKey>('map')
|
||||
const [inspectorOpen, setInspectorOpen] = useState(false)
|
||||
const [guestDemoReady, setGuestDemoReady] = useState(!isGuest)
|
||||
const secondaryDisplay = useSecondaryDisplay()
|
||||
const guestDemoStartedRef = useRef(false)
|
||||
const visibleWorkspaceItems = useMemo(
|
||||
() => isGuest ? workspaceNavItems.filter((item) => guestWorkspaceKeys.has(item.key)) : workspaceNavItems,
|
||||
@@ -830,7 +832,7 @@ function WorkbenchApp({ username, accessMode, loggingOut, onLogout }: WorkbenchA
|
||||
: 'Geen actieve laag'
|
||||
|
||||
return (
|
||||
<div className={isGuest ? "app-shell workbench-shell workbench-shell-guest" : "app-shell workbench-shell"}>
|
||||
<div className={`${isGuest ? 'app-shell workbench-shell workbench-shell-guest' : 'app-shell workbench-shell'}${secondaryDisplay.isOpen ? ' workbench-shell-dual-display' : ''}`}>
|
||||
<a
|
||||
className="skip-link"
|
||||
href="#workspace-main"
|
||||
@@ -887,6 +889,20 @@ function WorkbenchApp({ username, accessMode, loggingOut, onLogout }: WorkbenchA
|
||||
<span aria-hidden="true" />
|
||||
<strong>{workspaceDataLoading ? 'Laden' : errorMessage ? 'Aandacht' : 'Gereed'}</strong>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={secondaryDisplay.isOpen ? 'secondary-display-launch secondary-display-launch-active' : 'secondary-display-launch'}
|
||||
aria-pressed={secondaryDisplay.isOpen}
|
||||
aria-describedby={secondaryDisplay.error ? 'secondary-display-error' : undefined}
|
||||
onClick={() => {
|
||||
setActiveWorkspace('map')
|
||||
if (secondaryDisplay.isOpen) secondaryDisplay.close()
|
||||
else secondaryDisplay.open()
|
||||
}}
|
||||
>
|
||||
<MonitorUp aria-hidden="true" />
|
||||
<span>{secondaryDisplay.isOpen ? 'Sluit tweede scherm' : 'Open tweede scherm'}</span>
|
||||
</button>
|
||||
{username || isGuest ? (
|
||||
<div
|
||||
className={isGuest ? 'context-account context-account-guest' : 'context-account'}
|
||||
@@ -902,6 +918,13 @@ function WorkbenchApp({ username, accessMode, loggingOut, onLogout }: WorkbenchA
|
||||
) : null}
|
||||
</header>
|
||||
|
||||
{secondaryDisplay.error ? (
|
||||
<div className="secondary-display-error" id="secondary-display-error" role="alert">
|
||||
<CircleAlert aria-hidden="true" />
|
||||
<span>{secondaryDisplay.error}</span>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{isGuest ? (
|
||||
<div className="guest-mode-banner" role="status">
|
||||
<ShieldCheck aria-hidden="true" />
|
||||
@@ -1031,6 +1054,7 @@ function WorkbenchApp({ username, accessMode, loggingOut, onLogout }: WorkbenchA
|
||||
<div className="workspace-persistent-map" hidden={activeWorkspace !== 'map'}>
|
||||
<MapWorkspace
|
||||
readOnly={false}
|
||||
secondaryResultsContainer={secondaryDisplay.container}
|
||||
selectedProjectId={selectedProjectId}
|
||||
projects={projects}
|
||||
areas={areas}
|
||||
|
||||
Reference in New Issue
Block a user