layout fixes

This commit is contained in:
2025-12-09 12:04:44 +01:00
parent 116e839f67
commit 463046c970
2 changed files with 65 additions and 30 deletions
@@ -110,22 +110,71 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
}
}, [layoutStore, tenantId, viewId]);
// Only set layout ready when both container has size AND layout is loaded
useEffect(() => {
setIsLayoutReady(hasContainerSize && isLayoutLoaded);
}, [hasContainerSize, isLayoutLoaded]);
const metadataMap = usePreviewMetadata(items, getDocumentAsset, ensureAssetUrl);
// Sync LayoutStore items with current entries to remove stale items
const ensureDocumentSize = useCallback((doc: Document): DocumentSizeInfo => {
if (doc.id) {
const meta = metadataMap.get(String(doc.id));
if (meta && meta.width && meta.height)
return { width: meta.width, height: meta.height, source: 'metadata' };
}
return computeFallbackCardSize(doc, defaultCardSize);
}, [metadataMap, defaultCardSize]);
// Synchronize LayoutStore with current items (Initialization & Cleanup)
useEffect(() => {
if (!hasContainerSize || !isLayoutLoaded) return;
// Cleanup Stale Items
const currentIds = new Set(items.map((doc, index) => doc.id ? String(doc.id) : `temp-${index}`));
// Identify and remove items that are no longer present
for (const id of layoutStore.items.keys()) {
if (!currentIds.has(id)) {
layoutStore.unregister(id);
}
}
}, [items, layoutStore]);
// Initialize / Update Items (Saved first, then others)
const itemsWithSavedLayout: Document[] = [];
const itemsWithoutSavedLayout: Document[] = [];
items.forEach(doc => {
// If already initialized in store, we don't strictly need to prioritize it for collision,
// but keeping the order ensures consistent behavior on re-runs.
// However, usually we only care about *new* items for collision logic.
if (doc.id && layoutStore.hasSavedLayout(String(doc.id))) {
itemsWithSavedLayout.push(doc);
} else {
itemsWithoutSavedLayout.push(doc);
}
});
const initializeDoc = (doc: Document) => {
const size = ensureDocumentSize(doc);
const metadata = doc.current_version?.metadata as { page_count?: number } | undefined;
const pageCount = metadata?.page_count ?? 1;
layoutStore.initialize(doc.id, null, {
width: size.width,
height: size.height,
pageCount,
maxSize: defaultCardSize
});
};
itemsWithSavedLayout.forEach(initializeDoc);
itemsWithoutSavedLayout.forEach(initializeDoc);
// Save newly placed items
if (itemsWithoutSavedLayout.length > 0) {
void layoutStore.saveLayout();
}
// Enforce constraints
layoutStore.relayout();
setIsLayoutReady(true);
}, [hasContainerSize, isLayoutLoaded, items, layoutStore, ensureDocumentSize, defaultCardSize]);
// Selection Context
const {
@@ -155,18 +204,6 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
clearSelection ? clearSelection() : handleSelectionChange([]);
}, [clearSelection, handleSelectionChange]);
const metadataMap = usePreviewMetadata(items, getDocumentAsset, ensureAssetUrl);
const ensureDocumentSize = useCallback((doc: Document): DocumentSizeInfo => {
if (doc.id) {
const meta = metadataMap.get(String(doc.id));
if (meta && meta.width && meta.height)
return { width: meta.width, height: meta.height, source: 'metadata' };
}
return computeFallbackCardSize(doc, defaultCardSize);
}, [metadataMap, defaultCardSize]);
// Sync LayoutStore to layoutRef
useEffect(() => {
const sync = () => {
@@ -351,18 +388,12 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
{isLayoutReady && items.map((doc, index) => {
const docId = doc.id ? String(doc.id) : `temp-${index}`;
const isSelected = selectedDocumentIds.includes(docId);
const size = ensureDocumentSize(doc);
// Extract page count
const metadata = doc.current_version?.metadata as { page_count?: number } | undefined;
const pageCount = metadata?.page_count ?? 1;
const layoutCard = layoutStore.items.get(docId);
const layoutCard = layoutStore.initialize(docId, null, {
width: size.width,
height: size.height,
pageCount,
maxSize: defaultCardSize
});
if (!layoutCard) {
return null;
}
return (
<DesktopDocumentCard
@@ -538,6 +538,10 @@ export class LayoutStore {
this.relayout();
}
hasSavedLayout(id: string): boolean {
return this.savedLayouts.has(id);
}
async saveLayout() {
if (!this.tenantId || !this.viewId) return;