feat(workspace): move connection status indicator to top tabs header
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 57s

This commit is contained in:
sandrodach committed 2026-10-27 11:32:25 +01:00
1 parent 3d780856b0
commit 37948d3a6a
2 files changed
+73 -31

No files matched your search

@@ -22,6 +22,7 @@ import {
PanelLeftClose,
PanelLeftOpen,
ChevronLeft,
Radio,
} from 'lucide-react';
import {
Document,
@@ -34,7 +35,16 @@ import {
UnifiedShare,
User,
} from '../../lib/types';
import { api, onWebSocketMessage, triggerHaptic } from '../../lib/api';
import {
api,
onWebSocketMessage,
triggerHaptic,
onRealtimeStatus,
isRealtimeConnected,
getRealtimeTransport,
RealtimeTransport,
} from '../../lib/api';
import { DocSyncStatus } from '../../lib/useDocumentSync';
import { UnifiedShareModal } from '../../components/UnifiedShareModal';
import { useMobileActions } from '../../context/MobileActionContext';
import { DocumentEditor } from './DocumentEditor';
@@ -289,6 +299,19 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
});
}, []);
// Realtime connection status for top header indicator (identical to SharedListsView)
const [realtimeConnected, setRealtimeConnected] = useState<boolean>(() => isRealtimeConnected());
const [realtimeTransport, setRealtimeTransport] = useState<RealtimeTransport>(() => getRealtimeTransport());
const [activeDocSyncStatus, setActiveDocSyncStatus] = useState<DocSyncStatus>('connected');
useEffect(() => {
const unsub = onRealtimeStatus((connected, transport) => {
setRealtimeConnected(connected);
setRealtimeTransport(transport);
});
return unsub;
}, []);
// Drag and Drop state
const [draggingDocId, setDraggingDocId] = useState<string | null>(null);
const [draggingFolderPath, setDraggingFolderPath] = useState<string | null>(null);
@@ -1096,6 +1119,47 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
{tagsSummary.length > 0 && <span className="ml-1 badge-neutral text-[10px]">{tagsSummary.length}</span>}
</button>
</div>
{/* Right Header Section: Live Sync Status (identical to SharedListsView) */}
<div className="flex items-center gap-2">
{(() => {
const isDocActive = subView === 'editor' && Boolean(selectedDocId);
const isConnected = isDocActive
? activeDocSyncStatus === 'connected'
: realtimeConnected;
const isConnecting = isDocActive && (activeDocSyncStatus === 'connecting' || activeDocSyncStatus === 'reconnecting');
const isSSE = !isDocActive && realtimeTransport === 'sse';
return (
<div
className={`h-8 w-8 flex items-center justify-center rounded-btn border transition-colors ${
isConnected
? isSSE
? 'bg-teal-500/10 border-teal-500/30 text-teal-400'
: 'bg-emerald-500/10 border-emerald-500/30 text-emerald-500'
: isConnecting
? 'bg-amber-500/10 border-amber-500/30 text-amber-500'
: 'bg-canvas border-border text-muted'
}`}
title={
isConnected
? isSSE
? 'Live synchronisiert (Server-Sent Events / Proxy-Stream)'
: 'Live synchronisiert (WebSocket online)'
: isConnecting
? 'Verbindung wird aufgebaut…'
: 'Offline'
}
>
<Radio
className={`w-3.5 h-3.5 ${
isConnected ? 'animate-pulse' : isConnecting ? 'animate-spin' : ''
}`}
/>
</div>
);
})()}
</div>
</div>
{/* Main Workspace Split Pane */}
@@ -1336,6 +1400,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
onSelectTag={handleSelectTag}
onWikiLinkClick={handleWikiLinkClick}
onBackMobile={() => setMobileShowDetail(false)}
onSyncStatusChange={setActiveDocSyncStatus}
/>
) : subView === 'tags' ? (
/* =========================================================================