This commit is contained in:
2025-11-12 02:24:46 +01:00
parent 44c982f015
commit 32ef3ced59
12 changed files with 700 additions and 31 deletions
+4 -3
View File
@@ -3,10 +3,11 @@ import Sidebar from '../sidebar/Sidebar';
import { useSidebarContext } from '../sidebar/SidebarContext';
const DocumentsLayout = ({ sidebarProps, children }) => {
const { collapsed } = useSidebarContext();
const { collapsed, sidebarSuppressed } = useSidebarContext();
const sidebarHidden = collapsed || sidebarSuppressed;
return (
<main className={`documents-main${collapsed ? ' documents-main--sidebar-collapsed' : ''}`}>
{!collapsed ? <Sidebar {...sidebarProps} /> : null}
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
{!sidebarHidden ? <Sidebar {...sidebarProps} /> : null}
{children}
</main>
);
+102 -4
View File
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAppShell } from '../appShellContext';
import DocumentsLayout from './DocumentsLayout';
@@ -28,9 +28,105 @@ const DocumentsRouteContent = () => {
notifyApiError,
} = useAppShell();
const navigate = useNavigate();
const { collapsed: sidebarCollapsed, setCollapsed } = useSidebarContext();
const { collapsed: sidebarCollapsed, sidebarSuppressed, setCollapsed, setSidebarSuppressed } = useSidebarContext();
const expandSidebar = useCallback(() => setCollapsed(false), [setCollapsed]);
const getDetailPanelWidth = useCallback(() => {
if (typeof window === 'undefined') {
return null;
}
const panelEl = document.querySelector('.detail-panel');
if (panelEl) {
const rect = panelEl.getBoundingClientRect();
if (Number.isFinite(rect?.width)) {
return rect.width;
}
}
const rootStyles = window.getComputedStyle(document.documentElement);
const varValue = rootStyles.getPropertyValue('--detail-panel-width');
const parsed = parseFloat(varValue);
return Number.isFinite(parsed) ? parsed : null;
}, []);
const getSidebarWidth = useCallback(() => {
if (typeof window === 'undefined') {
return null;
}
const sidebarEl = document.querySelector('.sidebar');
if (sidebarEl) {
const rect = sidebarEl.getBoundingClientRect();
if (Number.isFinite(rect?.width)) {
return rect.width;
}
}
const rootStyles = window.getComputedStyle(document.documentElement);
const varValue = rootStyles.getPropertyValue('--sidebar-width');
const parsed = parseFloat(varValue);
return Number.isFinite(parsed) ? parsed : null;
}, []);
const shouldCloseDetailPanelForSidebar = useCallback(() => {
if (typeof window === 'undefined') {
return false;
}
if (!detailPanelOpen && !previewDocumentId) {
return false;
}
const detailWidth = getDetailPanelWidth();
const sidebarWidth = getSidebarWidth();
if (!Number.isFinite(detailWidth) || !Number.isFinite(sidebarWidth)) {
return false;
}
return detailWidth + sidebarWidth > window.innerWidth * (2 / 3);
}, [detailPanelOpen, previewDocumentId, getDetailPanelWidth, getSidebarWidth]);
const closeAnyDetailPanel = useCallback(() => {
if (previewDocumentId && typeof closeDocumentPreview === 'function') {
closeDocumentPreview();
return true;
}
if (detailPanelOpen && typeof detailPanelProps?.onClose === 'function') {
detailPanelProps.onClose();
return true;
}
return false;
}, [previewDocumentId, closeDocumentPreview, detailPanelOpen, detailPanelProps]);
const sidebarWidthRef = useRef(null);
useEffect(() => {
sidebarWidthRef.current = getSidebarWidth();
}, [getSidebarWidth]);
const expandSidebar = useCallback(() => {
if (shouldCloseDetailPanelForSidebar()) {
closeAnyDetailPanel();
}
setSidebarSuppressed(false);
setCollapsed(false);
}, [setCollapsed, setSidebarSuppressed, shouldCloseDetailPanelForSidebar, closeAnyDetailPanel]);
useEffect(() => {
if (typeof window === 'undefined') {
return undefined;
}
const handleSidebarResize = (event) => {
const nextWidth = Number.isFinite(event?.detail?.width)
? event.detail.width
: getSidebarWidth();
const prevWidth = sidebarWidthRef.current;
if (Number.isFinite(nextWidth)) {
sidebarWidthRef.current = nextWidth;
}
if (Number.isFinite(nextWidth) && Number.isFinite(prevWidth) && nextWidth <= prevWidth) {
return;
}
if (shouldCloseDetailPanelForSidebar()) {
closeAnyDetailPanel();
}
};
window.addEventListener('sidebar-width-change', handleSidebarResize);
return () => window.removeEventListener('sidebar-width-change', handleSidebarResize);
}, [shouldCloseDetailPanelForSidebar, closeAnyDetailPanel, getSidebarWidth]);
const sidebarPropsWithActions = useMemo(
() => ({
@@ -67,8 +163,10 @@ const DocumentsRouteContent = () => {
navigate(target);
}, [navigate]);
const sidebarHidden = sidebarCollapsed || sidebarSuppressed;
const { surface } = useWorkspaceSurface({
sidebarCollapsed,
sidebarHidden,
onExpandSidebar: expandSidebar,
documentsTableProps,
detailPanelProps,
+3 -3
View File
@@ -5,7 +5,7 @@ import { createDocumentViewerSurface } from '../preview/DocumentViewerPanel';
import createDesktopSurface from '../desktop/createDesktopSurface';
export const useWorkspaceSurface = ({
sidebarCollapsed,
sidebarHidden,
onExpandSidebar,
documentsTableProps,
detailPanelProps,
@@ -25,7 +25,7 @@ export const useWorkspaceSurface = ({
onNavigateParent,
}) => {
const renderSidebarToggle = useCallback(() => {
if (!sidebarCollapsed) {
if (!sidebarHidden) {
return null;
}
return (
@@ -39,7 +39,7 @@ export const useWorkspaceSurface = ({
<SidebarExpandIcon />
</button>
);
}, [sidebarCollapsed, onExpandSidebar]);
}, [sidebarHidden, onExpandSidebar]);
const documentsSurface = useMemo(() => {
if (!documentsTableProps) {