ui
This commit is contained in:
@@ -14,6 +14,9 @@ import DocumentsGrid from './DocumentsGrid';
|
||||
import DocumentsList from './DocumentsList';
|
||||
import { isTagTransferEvent } from './tagTransfer';
|
||||
import SelectionFloatingActions from './SelectionFloatingActions';
|
||||
import PreviewZoomOverlay from '../detail/PreviewZoomOverlay';
|
||||
import { useAssetNavigator } from '../hooks/useAssetNavigator';
|
||||
import { isPointerModifierEvent, isPrimaryPointerEvent } from './useEntryPointer';
|
||||
|
||||
const DEFAULT_GRID_ICON_SIZE = 144;
|
||||
|
||||
@@ -39,15 +42,13 @@ const DocumentsPanel = ({
|
||||
draggedFolderId,
|
||||
onFolderRename,
|
||||
selectedFolderIds = [],
|
||||
onDocumentOpen,
|
||||
selectedDocumentIds = [],
|
||||
focusedRowKey,
|
||||
draggingDocumentIds = [],
|
||||
onDocumentDragStart,
|
||||
onDocumentDragEnd,
|
||||
onDocumentRename,
|
||||
onEntrySelection = null,
|
||||
onOpenDetailPanel = null,
|
||||
onEntryPointer = null,
|
||||
tagLookupById,
|
||||
activeCorrespondentIds = [],
|
||||
onDocumentListFocus,
|
||||
@@ -118,6 +119,85 @@ const DocumentsPanel = ({
|
||||
}, []);
|
||||
const isGridView = viewMode === 'grid';
|
||||
const isDeskView = viewMode === 'desk';
|
||||
|
||||
const [previewDocId, setPreviewDocId] = useState(null);
|
||||
|
||||
const previewDoc = useMemo(() => {
|
||||
if (!previewDocId) {
|
||||
return null;
|
||||
}
|
||||
return rows.find((doc) => doc?.id === previewDocId) || null;
|
||||
}, [previewDocId, rows]);
|
||||
|
||||
useEffect(() => {
|
||||
if (previewDocId && !previewDoc) {
|
||||
setPreviewDocId(null);
|
||||
}
|
||||
}, [previewDocId, previewDoc]);
|
||||
|
||||
const previewNavigator = useAssetNavigator({
|
||||
document: previewDoc,
|
||||
assetType: 'preview',
|
||||
ensureAssetUrl,
|
||||
getAsset: getDocumentAsset,
|
||||
prefetch: 3,
|
||||
});
|
||||
|
||||
const {
|
||||
currentUrl: previewUrl,
|
||||
canGoPrev: previewCanGoPrev,
|
||||
canGoNext: previewCanGoNext,
|
||||
goPrev: previewGoPrev,
|
||||
goNext: previewGoNext,
|
||||
} = previewNavigator;
|
||||
|
||||
const previewDisplay = useMemo(() => {
|
||||
if (!previewDoc || !previewUrl) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
url: previewUrl,
|
||||
alt: previewDoc.title,
|
||||
canGoPrev: Boolean(previewCanGoPrev),
|
||||
canGoNext: Boolean(previewCanGoNext),
|
||||
goPrev: previewGoPrev,
|
||||
goNext: previewGoNext,
|
||||
};
|
||||
}, [previewDoc, previewUrl, previewCanGoPrev, previewCanGoNext, previewGoPrev, previewGoNext]);
|
||||
|
||||
const closePreviewOverlay = useCallback(() => {
|
||||
setPreviewDocId(null);
|
||||
}, []);
|
||||
|
||||
const handleDocumentPreviewZoom = useCallback(
|
||||
(doc) => {
|
||||
if (!doc || !doc.id) {
|
||||
return;
|
||||
}
|
||||
const previewAsset = typeof getDocumentAsset === 'function' ? getDocumentAsset(doc, 'preview') : null;
|
||||
if (!previewAsset) {
|
||||
return;
|
||||
}
|
||||
setPreviewDocId(doc.id);
|
||||
},
|
||||
[getDocumentAsset],
|
||||
);
|
||||
|
||||
const handleDocumentActivate = useCallback(
|
||||
(doc, event) => {
|
||||
if (event) {
|
||||
if (typeof event.preventDefault === 'function') {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (typeof event.stopPropagation === 'function') {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
handleDocumentPreviewZoom(doc);
|
||||
},
|
||||
[handleDocumentPreviewZoom],
|
||||
);
|
||||
|
||||
const isListView = viewMode === 'list';
|
||||
const gridIconSize = DEFAULT_GRID_ICON_SIZE;
|
||||
const handleSetViewMode = useCallback(
|
||||
@@ -240,56 +320,20 @@ const DocumentsPanel = ({
|
||||
[isTagDragEvent, onDocumentTagDrop],
|
||||
);
|
||||
|
||||
const handleEntryClick = useCallback(
|
||||
(entry, event) => {
|
||||
if (!entry || !entry.id) {
|
||||
return;
|
||||
}
|
||||
if (entry.type === EntryType.document && suppressDocumentClickRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rowKey = entry.type === EntryType.document ? `document:${entry.id}` : `folder:${entry.id}`;
|
||||
|
||||
if (rowKey && typeof onEntrySelection === 'function') {
|
||||
onEntrySelection(rowKey, event);
|
||||
}
|
||||
|
||||
if (entry.type === EntryType.document) {
|
||||
const hasModifier = Boolean(
|
||||
event && (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey),
|
||||
);
|
||||
if (!hasModifier && typeof onOpenDetailPanel === 'function') {
|
||||
onOpenDetailPanel();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.type === EntryType.folder) {
|
||||
const hasModifier = Boolean(
|
||||
event && (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey),
|
||||
);
|
||||
const isPrimaryClick = Boolean(event && event.type === 'click' && event.button === 0);
|
||||
if (!hasModifier && isPrimaryClick && typeof onFolderSelect === 'function') {
|
||||
onFolderSelect(entry.id);
|
||||
}
|
||||
if (scrollRef.current) {
|
||||
scrollRef.current.focus({ preventScroll: true });
|
||||
}
|
||||
onFocusedRowChange?.(rowKey);
|
||||
}
|
||||
},
|
||||
[onEntrySelection, onOpenDetailPanel, onFocusedRowChange, onFolderSelect],
|
||||
);
|
||||
|
||||
const handleDocumentClick = useCallback(
|
||||
(doc, event) => {
|
||||
if (!doc) {
|
||||
if (!doc || suppressDocumentClickRef.current) {
|
||||
return;
|
||||
}
|
||||
handleEntryClick({ type: EntryType.document, id: doc.id, document: doc }, event);
|
||||
|
||||
if (typeof onEntryPointer === 'function') {
|
||||
onEntryPointer(
|
||||
{ type: EntryType.document, id: doc.id, key: `document:${doc.id}`, document: doc },
|
||||
event,
|
||||
);
|
||||
}
|
||||
},
|
||||
[handleEntryClick],
|
||||
[onEntryPointer],
|
||||
);
|
||||
|
||||
const handleFolderClick = useCallback(
|
||||
@@ -297,9 +341,24 @@ const DocumentsPanel = ({
|
||||
if (!folder) {
|
||||
return;
|
||||
}
|
||||
handleEntryClick({ type: EntryType.folder, id: folder.id, folder }, event);
|
||||
|
||||
if (typeof onEntryPointer === 'function') {
|
||||
onEntryPointer(
|
||||
{ type: EntryType.folder, id: folder.id, key: `folder:${folder.id}`, folder },
|
||||
event,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!isPointerModifierEvent(event)
|
||||
&& isPrimaryPointerEvent(event)
|
||||
&& scrollRef.current
|
||||
) {
|
||||
scrollRef.current.focus({ preventScroll: true });
|
||||
onFocusedRowChange?.(`folder:${folder.id}`);
|
||||
}
|
||||
},
|
||||
[handleEntryClick],
|
||||
[onEntryPointer, onFocusedRowChange],
|
||||
);
|
||||
|
||||
const handleDocumentDragStartLocal = useCallback(
|
||||
@@ -345,7 +404,8 @@ const DocumentsPanel = ({
|
||||
}, [breadcrumbEntries, currentFolderName, onFolderSelect]);
|
||||
|
||||
return (
|
||||
<section
|
||||
<>
|
||||
<section
|
||||
className={`documents-panel documents-panel--view-${isGridView ? 'grid' : 'list'}`}
|
||||
>
|
||||
{showHeader ? (
|
||||
@@ -455,7 +515,7 @@ const DocumentsPanel = ({
|
||||
onFolderDragStart={onFolderDragStart}
|
||||
onFolderDragEnd={onFolderDragEnd}
|
||||
onDocumentClick={handleDocumentClick}
|
||||
onDocumentOpen={onDocumentOpen}
|
||||
onDocumentActivate={handleDocumentActivate}
|
||||
onDocumentDragStart={handleDocumentDragStartLocal}
|
||||
onDocumentDragEnd={handleDocumentDragEndLocal}
|
||||
onDocumentTagDragOver={handleDocumentTagDragOver}
|
||||
@@ -492,7 +552,7 @@ const DocumentsPanel = ({
|
||||
onFolderDragEnd={onFolderDragEnd}
|
||||
onFolderRename={onFolderRename}
|
||||
onDocumentClick={handleDocumentClick}
|
||||
onDocumentOpen={onDocumentOpen}
|
||||
onDocumentActivate={handleDocumentActivate}
|
||||
onDocumentDragStart={handleDocumentDragStartLocal}
|
||||
onDocumentDragEnd={handleDocumentDragEndLocal}
|
||||
onDocumentTagDragOver={handleDocumentTagDragOver}
|
||||
@@ -516,6 +576,12 @@ const DocumentsPanel = ({
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
<PreviewZoomOverlay
|
||||
open={Boolean(previewDocId)}
|
||||
display={previewDisplay}
|
||||
onClose={closePreviewOverlay}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user