From 0b8f8568766a42b87144287b82b22fcd92466826 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Sat, 1 Nov 2025 23:37:12 +0100 Subject: [PATCH] folder-selection --- frontend/src/app/AppLayout.jsx | 56 +++++++++++------------ frontend/src/app/useDocumentSelection.js | 38 +++++++-------- frontend/src/documents/DocumentsTable.jsx | 2 +- frontend/src/styles.css | 3 +- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/frontend/src/app/AppLayout.jsx b/frontend/src/app/AppLayout.jsx index 11b6fce..9d5634d 100644 --- a/frontend/src/app/AppLayout.jsx +++ b/frontend/src/app/AppLayout.jsx @@ -346,8 +346,8 @@ const AppLayout = () => { const tagManager = tagManagerRef.current; const { - selectedRowKeys, - setSelectedRowKeys, + selectedEntries, + setSelectedEntries, selectionOrder, setSelectionOrder, selectionOrderRef, @@ -368,7 +368,7 @@ const AppLayout = () => { isDocumentRowKey, isFolderRowKey, getRowId, - initialSelection: initialRowSelection, + initialEntries: initialRowSelection, }); const getDocumentAsset = useCallback((doc, type) => { @@ -382,22 +382,22 @@ const AppLayout = () => { const selectedDocumentIds = useMemo( () => - selectedRowKeys + selectedEntries .filter(isDocumentRowKey) .map((key) => getRowId(key)) .filter(Boolean), - [selectedRowKeys], + [selectedEntries], ); const selectionCount = selectedDocumentIds.length; const selectedFolderIds = useMemo( () => - selectedRowKeys + selectedEntries .filter(isFolderRowKey) .map((key) => getRowId(key)) .filter(Boolean), - [selectedRowKeys], + [selectedEntries], ); @@ -409,7 +409,7 @@ const AppLayout = () => { setCurrentFolder(null); setCurrentSubfolders([]); setDocuments([]); - setSelectedRowKeys([]); + setSelectedEntries([]); setSelectionOrder([]); selectionOrderRef.current = []; setFocusedDocumentId(null); @@ -440,7 +440,7 @@ const AppLayout = () => { selectionInitializedRef, selectionOrderRef, setFocusedDocumentId, - setSelectedRowKeys, + setSelectedEntries, setSelectionOrder, ]); @@ -594,7 +594,7 @@ const AppLayout = () => { let nextDocKeys = []; let mergedSelection = []; - setSelectedRowKeys((previous) => { + setSelectedEntries((previous) => { const previousFolderKeys = previous .filter(isFolderRowKey) .filter((key) => availableFolderKeys.has(key)); @@ -638,7 +638,7 @@ const AppLayout = () => { selectionInitializedRef, selectionOrderRef, setFocusedDocumentId, - setSelectedRowKeys, + setSelectedEntries, setSelectionOrder, ], ); @@ -952,7 +952,7 @@ const AppLayout = () => { return; } - const selectedKey = selectedRowKeys.find((key) => navigableRowKeys.includes(key)); + const selectedKey = selectedEntries.find((key) => navigableRowKeys.includes(key)); if (selectedKey) { setFocusedRowKey(selectedKey); return; @@ -965,7 +965,7 @@ const AppLayout = () => { focusedRowKey, focusedDocumentId, navigableRowKeys, - selectedRowKeys, + selectedEntries, setFocusedRowKey, ]); @@ -2446,7 +2446,7 @@ const AppLayout = () => { } event.stopPropagation(); const folderKey = resolveFolderRowKey(folderId); - const isAlreadySelected = folderKey ? selectedRowKeys.includes(folderKey) : false; + const isAlreadySelected = folderKey ? selectedEntries.includes(folderKey) : false; let effectiveFolderSelection = selectedFolderIds; let effectiveDocumentSelection = selectedDocumentIds; @@ -2500,7 +2500,7 @@ const AppLayout = () => { event.currentTarget?.classList.add('dragging'); }, [ - selectedRowKeys, + selectedEntries, selectedFolderIds, selectedDocumentIds, setDraggedFolderId, @@ -2898,7 +2898,7 @@ const AppLayout = () => { return changed ? next : prev; }); - setSelectedRowKeys((prev) => pruneRowCollection(prev)); + setSelectedEntries((prev) => pruneRowCollection(prev)); setSelectionOrder((prev) => pruneRowCollection(prev)); selectionOrderRef.current = pruneRowCollection(selectionOrderRef.current); if ( @@ -2944,7 +2944,7 @@ const AppLayout = () => { focusedRowKey, setFocusedRowKey, setSelectionOrder, - setSelectedRowKeys, + setSelectedEntries, setStatusMessage, selectionAnchorRef, selectionOrderRef, @@ -3056,8 +3056,8 @@ const AppLayout = () => { } let resolvedKey = null; - for (let index = selectedRowKeys.length - 1; index >= 0; index -= 1) { - const candidate = selectedRowKeys[index]; + for (let index = selectedEntries.length - 1; index >= 0; index -= 1) { + const candidate = selectedEntries[index]; if (navigableRowKeys.includes(candidate)) { resolvedKey = candidate; break; @@ -3072,19 +3072,19 @@ const AppLayout = () => { return; } - if (selectedRowKeys.length === 0) { + if (selectedEntries.length === 0) { return; } setFocusedRowKey(resolvedKey); - if (!selectedRowKeys.includes(resolvedKey) && selectedRowKeys.length > 0) { + if (!selectedEntries.includes(resolvedKey) && selectedEntries.length > 0) { applySelection([resolvedKey], { anchor: resolvedKey, interactedKeys: [resolvedKey] }); } }, [ focusedRowKey, navigableRowKeys, - selectedRowKeys, + selectedEntries, navigableRows, applySelection, setFocusedRowKey, @@ -3110,8 +3110,8 @@ const AppLayout = () => { : null; if (!activeKey) { - for (let index = selectedRowKeys.length - 1; index >= 0; index -= 1) { - const candidate = selectedRowKeys[index]; + for (let index = selectedEntries.length - 1; index >= 0; index -= 1) { + const candidate = selectedEntries[index]; if (navigableRowKeys.includes(candidate)) { activeKey = candidate; break; @@ -3183,7 +3183,7 @@ const AppLayout = () => { navigableRows, navigableRowKeys, focusedRowKey, - selectedRowKeys, + selectedEntries, handleRowSelection, selectFolder, openDocumentPreview, @@ -3716,7 +3716,7 @@ const AppLayout = () => { if (!results.length) { setSearchLoading(false); - setSelectedRowKeys([]); + setSelectedEntries([]); setFocusedDocumentId(null); selectionOrderRef.current = []; setSelectionOrder([]); @@ -3731,7 +3731,7 @@ const AppLayout = () => { let targetKey = null; let nextSelectionKeys = []; - setSelectedRowKeys((previous) => { + setSelectedEntries((previous) => { const previousDocKeys = previous.filter(isDocumentRowKey); const filtered = previousDocKeys.filter((key) => resultKeys.includes(key)); if (filtered.length) { @@ -3788,7 +3788,7 @@ const AppLayout = () => { assetManager, selectionOrderRef, selectionAnchorRef, - setSelectedRowKeys, + setSelectedEntries, setSelectionOrder, setFocusedDocumentId, ]); diff --git a/frontend/src/app/useDocumentSelection.js b/frontend/src/app/useDocumentSelection.js index c07833c..171ff8e 100644 --- a/frontend/src/app/useDocumentSelection.js +++ b/frontend/src/app/useDocumentSelection.js @@ -1,6 +1,6 @@ import { useCallback, useRef, useState } from 'react'; -const DEFAULT_INITIAL_SELECTION = []; +const DEFAULT_INITIAL_ENTRIES = []; export const useDocumentSelection = ({ resolveDocumentRowKey, @@ -8,11 +8,11 @@ export const useDocumentSelection = ({ isDocumentRowKey, isFolderRowKey, getRowId, - initialSelection = DEFAULT_INITIAL_SELECTION, + initialEntries = DEFAULT_INITIAL_ENTRIES, }) => { - const [selectedRowKeys, setSelectedRowKeys] = useState(initialSelection); - const [selectionOrder, setSelectionOrder] = useState(initialSelection); - const selectionOrderRef = useRef(initialSelection); + const [selectedEntries, setSelectedEntries] = useState(initialEntries); + const [selectionOrder, setSelectionOrder] = useState(initialEntries); + const selectionOrderRef = useRef(initialEntries); const selectionAnchorRef = useRef(null); const selectionInitializedRef = useRef(false); const [focusedDocumentId, setFocusedDocumentId] = useState(null); @@ -69,7 +69,7 @@ export const useDocumentSelection = ({ const visibleRowKeySet = visibleRowKeySetRef.current; const unique = []; - (rowKeys || []).forEach((key) => { + (rowKeys || []).forEach((key) => { if (!key) return; let canonicalKey = null; if (visibleRowKeySet.has(key)) { @@ -96,7 +96,7 @@ export const useDocumentSelection = ({ resolvedAnchor = null; } - setSelectedRowKeys(unique); + setSelectedEntries(unique); updateSelectionOrder(unique, interactedKeys); const nextFocusedDocumentId = (() => { @@ -163,8 +163,8 @@ export const useDocumentSelection = ({ } let anchorKey = selectionAnchorRef.current; - if (!anchorKey && shiftKey && selectedRowKeys.length) { - anchorKey = selectedRowKeys[selectedRowKeys.length - 1]; + if (!anchorKey && shiftKey && selectedEntries.length) { + anchorKey = selectedEntries[selectedEntries.length - 1]; } if (!anchorKey) { anchorKey = rowKey; @@ -183,7 +183,7 @@ export const useDocumentSelection = ({ const range = navigableRowKeys.slice(start, end + 1); nextKeys = range; - const previousSet = new Set(selectedRowKeys); + const previousSet = new Set(selectedEntries); interactedKeys = range.filter((key) => key === rowKey || !previousSet.has(key)); if (!interactedKeys.includes(rowKey)) { interactedKeys.push(rowKey); @@ -193,11 +193,11 @@ export const useDocumentSelection = ({ interactedKeys = [rowKey]; } } else if (additive) { - if (selectedRowKeys.includes(rowKey)) { - nextKeys = selectedRowKeys.filter((key) => key !== rowKey); + if (selectedEntries.includes(rowKey)) { + nextKeys = selectedEntries.filter((key) => key !== rowKey); interactedKeys = []; } else { - nextKeys = [...selectedRowKeys, rowKey]; + nextKeys = [...selectedEntries, rowKey]; interactedKeys = [rowKey]; } anchorKey = rowKey; @@ -209,7 +209,7 @@ export const useDocumentSelection = ({ applySelection(nextKeys, { anchor: anchorKey, interactedKeys }); }, - [applySelection, selectedRowKeys], + [applySelection, selectedEntries], ); const promoteSelectionOrder = useCallback( @@ -218,18 +218,18 @@ export const useDocumentSelection = ({ const rowKey = resolveDocumentRowKey(docId); if (!rowKey) return; - if (!selectedRowKeys.includes(rowKey)) { + if (!selectedEntries.includes(rowKey)) { return; } - updateSelectionOrder(selectedRowKeys, [rowKey]); + updateSelectionOrder(selectedEntries, [rowKey]); }, - [resolveDocumentRowKey, selectedRowKeys, updateSelectionOrder], + [resolveDocumentRowKey, selectedEntries, updateSelectionOrder], ); return { - selectedRowKeys, - setSelectedRowKeys, + selectedEntries, + setSelectedEntries, selectionOrder, setSelectionOrder, selectionOrderRef, diff --git a/frontend/src/documents/DocumentsTable.jsx b/frontend/src/documents/DocumentsTable.jsx index 567bd87..5319eea 100644 --- a/frontend/src/documents/DocumentsTable.jsx +++ b/frontend/src/documents/DocumentsTable.jsx @@ -440,7 +440,7 @@ const DocumentsTable = ({ onRowSelection(rowKey, event); } - if (entry.type === EntryType.document) { + if (entry.type === EntryType.document) { if (typeof onOpenDetailPanel === 'function') { onOpenDetailPanel(); } diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 08ad91c..04e32b3 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -2078,7 +2078,8 @@ button.danger:hover:not([disabled]) { cursor: pointer; } -.documents-panel tbody tr.document.selected { +.documents-panel tbody tr.document.selected, +.documents-panel tbody tr.folder.selected { background: var(--selection-soft); box-shadow: inset 2px 0 0 var(--accent-outline-strong); }