ux
This commit is contained in:
@@ -5030,7 +5030,7 @@ const AppLayout = () => {
|
||||
onExit: handleDeskExit,
|
||||
onRefresh: refreshCurrentFolder,
|
||||
onDocumentOpen: handleDeskDocumentOpen,
|
||||
onInspectDocument: null,
|
||||
onInspectDocument: inspectDocument,
|
||||
onEntryPointer: handleEntryPointerCore,
|
||||
onDocumentStackSelect: handleDeskDocumentStackSelect,
|
||||
onPromoteSelection: promoteSelectionOrder,
|
||||
@@ -5088,6 +5088,7 @@ const AppLayout = () => {
|
||||
detailPanelOpen,
|
||||
handleDetailPanelClose,
|
||||
handleDeskDocumentOpen,
|
||||
inspectDocument,
|
||||
resolveThumbnailUrlForDoc,
|
||||
handleDocumentTagDrop,
|
||||
handleTagRemove,
|
||||
|
||||
@@ -703,7 +703,6 @@ const DesktopWorkspace = ({
|
||||
onDocumentOpen,
|
||||
onDocumentStackSelect,
|
||||
onEntryPointer,
|
||||
onInspectDocument,
|
||||
onPromoteSelection,
|
||||
openOverlayForDoc,
|
||||
overlayDisplay,
|
||||
@@ -717,6 +716,7 @@ const DesktopWorkspace = ({
|
||||
setDraggingId,
|
||||
selectedDocumentIds,
|
||||
detailPanelOpen,
|
||||
onInspectDocument,
|
||||
markLayoutDirty,
|
||||
tagDropTargetId,
|
||||
visibleDocIds,
|
||||
@@ -804,7 +804,7 @@ const DesktopWorkspaceView = ({
|
||||
markLayoutDirty,
|
||||
});
|
||||
|
||||
const { getCardPointerHandlers, handleShellKeyDown } = useDeskPointer({
|
||||
const { getCardPointerHandlers, handleShellKeyDown, focusShell } = useDeskPointer({
|
||||
containerRef,
|
||||
items,
|
||||
layoutRef,
|
||||
@@ -819,11 +819,27 @@ const DesktopWorkspaceView = ({
|
||||
onPromoteSelection,
|
||||
onDocumentOpen,
|
||||
selectedDocumentIds,
|
||||
onClearSelection,
|
||||
detailPanelOpen,
|
||||
onCloseDetailPanel,
|
||||
openOverlayForDoc,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
focusShell();
|
||||
}, [focusShell]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDocumentIds.length) {
|
||||
focusShell();
|
||||
}
|
||||
}, [focusShell, selectedDocumentIds.length]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!detailPanelOpen) {
|
||||
focusShell();
|
||||
}
|
||||
}, [detailPanelOpen, focusShell]);
|
||||
|
||||
|
||||
|
||||
const allSizesReady = items.every((doc) => ensureDocumentSize(doc));
|
||||
@@ -834,6 +850,7 @@ const DesktopWorkspaceView = ({
|
||||
if (event.target === event.currentTarget && typeof onClearSelection === 'function') {
|
||||
onClearSelection();
|
||||
}
|
||||
focusShell();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -848,6 +865,7 @@ const DesktopWorkspaceView = ({
|
||||
if (event.target === event.currentTarget && typeof onClearSelection === 'function') {
|
||||
onClearSelection();
|
||||
}
|
||||
focusShell();
|
||||
}}
|
||||
>
|
||||
{!allSizesReady ? (
|
||||
|
||||
@@ -40,7 +40,7 @@ export const createPointerIntent = ({
|
||||
clickAction = CLICK_ACTIONS.addStack;
|
||||
dragAction = DRAG_ACTIONS.dragSelectStack;
|
||||
} else if (alreadySelected) {
|
||||
clickAction = CLICK_ACTIONS.openDetail;
|
||||
clickAction = CLICK_ACTIONS.selectSingle;
|
||||
dragAction = selectionCount > 1 ? DRAG_ACTIONS.dragSelection : DRAG_ACTIONS.dragSelectSingle;
|
||||
} else {
|
||||
clickAction = CLICK_ACTIONS.selectSingle;
|
||||
|
||||
@@ -37,9 +37,9 @@ export const useDeskPointer = ({
|
||||
onPromoteSelection,
|
||||
onDocumentOpen,
|
||||
selectedDocumentIds,
|
||||
onClearSelection,
|
||||
detailPanelOpen,
|
||||
onCloseDetailPanel,
|
||||
openOverlayForDoc = null,
|
||||
}) => {
|
||||
const pointerIntentRef = useRef(null);
|
||||
const pointerStartRef = useRef({ x: 0, y: 0 });
|
||||
@@ -401,9 +401,16 @@ export const useDeskPointer = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(selectedDocumentIds) && selectedDocumentIds.length > 0) {
|
||||
if (
|
||||
typeof openOverlayForDoc === 'function'
|
||||
&& Array.isArray(selectedDocumentIds)
|
||||
&& selectedDocumentIds.length > 0
|
||||
) {
|
||||
event.preventDefault();
|
||||
onClearSelection?.();
|
||||
const targetId = selectedDocumentIds[selectedDocumentIds.length - 1];
|
||||
if (targetId) {
|
||||
openOverlayForDoc(targetId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -412,12 +419,18 @@ export const useDeskPointer = ({
|
||||
safeInvoke(onCloseDetailPanel);
|
||||
}
|
||||
},
|
||||
[detailPanelOpen, onClearSelection, onCloseDetailPanel, selectedDocumentIds],
|
||||
[detailPanelOpen, onCloseDetailPanel, openOverlayForDoc, selectedDocumentIds],
|
||||
);
|
||||
|
||||
return {
|
||||
getCardPointerHandlers,
|
||||
handleShellKeyDown,
|
||||
focusShell: () => {
|
||||
const shell = containerRef.current;
|
||||
if (shell && typeof shell.focus === 'function') {
|
||||
shell.focus({ preventScroll: true });
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -54,25 +54,18 @@ const useDocumentDrag = (options = {}) => {
|
||||
|
||||
const tapHandler = usePointerTap({
|
||||
delay: 220,
|
||||
onSingle: ({ data, event }) => {
|
||||
if (!data || !data.docId) {
|
||||
return;
|
||||
}
|
||||
if (event && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
|
||||
return;
|
||||
}
|
||||
if (typeof onInspectDocument === 'function') {
|
||||
onInspectDocument(data.docId);
|
||||
}
|
||||
},
|
||||
onSingle: () => {},
|
||||
onDouble: ({ data, event }) => {
|
||||
if (!data || !data.docId) {
|
||||
return;
|
||||
}
|
||||
if (event && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
|
||||
if (event?.altKey) {
|
||||
openOverlayForDoc(data.docId, data.originInfo);
|
||||
return;
|
||||
}
|
||||
openOverlayForDoc(data.docId, data.originInfo);
|
||||
if (typeof onInspectDocument === 'function') {
|
||||
onInspectDocument(data.docId, event);
|
||||
}
|
||||
},
|
||||
});
|
||||
const dragStateRef = useRef(null);
|
||||
|
||||
@@ -204,6 +204,9 @@ const DocumentsPanel = ({
|
||||
|
||||
const handleDocumentActivate = useCallback(
|
||||
(doc, event) => {
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
if (event) {
|
||||
if (typeof event.preventDefault === 'function') {
|
||||
event.preventDefault();
|
||||
@@ -212,9 +215,13 @@ const DocumentsPanel = ({
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
handleDocumentPreviewZoom(doc);
|
||||
if (event?.altKey) {
|
||||
handleDocumentPreviewZoom(doc);
|
||||
return;
|
||||
}
|
||||
onInspectDocument?.(doc.id, event);
|
||||
},
|
||||
[handleDocumentPreviewZoom],
|
||||
[handleDocumentPreviewZoom, onInspectDocument],
|
||||
);
|
||||
|
||||
const selectedRowKeySet = useMemo(() => new Set(selectedEntries || []), [selectedEntries]);
|
||||
@@ -318,8 +325,7 @@ const DocumentsPanel = ({
|
||||
} else {
|
||||
const entry = getEntryByKey(activeRow.key);
|
||||
if (entry?.document) {
|
||||
handleDocumentActivate(entry.document, event);
|
||||
onInspectDocument?.(entry.document.id, event);
|
||||
handleDocumentPreviewZoom(entry.document);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,14 +361,13 @@ const DocumentsPanel = ({
|
||||
[
|
||||
focusedRowKey,
|
||||
getEntryByKey,
|
||||
handleDocumentActivate,
|
||||
navigableRowKeys,
|
||||
navigableRows,
|
||||
onEntrySelection,
|
||||
onFocusedRowChange,
|
||||
onFolderSelect,
|
||||
onInspectDocument,
|
||||
selectedEntries,
|
||||
handleDocumentPreviewZoom,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -500,16 +505,8 @@ const DocumentsPanel = ({
|
||||
event,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
typeof onInspectDocument === 'function'
|
||||
&& !isPointerModifierEvent(event)
|
||||
&& isPrimaryPointerEvent(event)
|
||||
) {
|
||||
onInspectDocument(doc.id, event);
|
||||
}
|
||||
},
|
||||
[onEntryPointer, onInspectDocument],
|
||||
[onEntryPointer],
|
||||
);
|
||||
|
||||
const handleFolderClick = useCallback(
|
||||
@@ -980,6 +977,7 @@ export const createDocumentsSurface = ({
|
||||
onMoveDocumentsToFolder,
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants,
|
||||
onInspectDocument,
|
||||
} = tableProps;
|
||||
|
||||
const title = Array.isArray(searchResults) ? 'Search results' : currentFolderName;
|
||||
@@ -1044,7 +1042,13 @@ export const createDocumentsSurface = ({
|
||||
breadcrumbs,
|
||||
selectionLabel: null,
|
||||
floatingActions,
|
||||
content: <DocumentsPanel {...tableProps} showHeader={false} />,
|
||||
content: (
|
||||
<DocumentsPanel
|
||||
{...tableProps}
|
||||
showHeader={false}
|
||||
onInspectDocument={onInspectDocument}
|
||||
/>
|
||||
),
|
||||
detail,
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
IconLoader,
|
||||
IconSortAscendingLetters,
|
||||
IconSortDescendingLetters,
|
||||
IconFileInfo,
|
||||
} from '@tabler/icons-react';
|
||||
import FolderSvg from '../assets/folder.svg';
|
||||
|
||||
@@ -176,6 +177,15 @@ export const InfoIcon = ({ className, size = '1em', stroke = 1.6, ...rest }) =>
|
||||
/>
|
||||
);
|
||||
|
||||
export const FileInfoIcon = ({ className, size = '1em', stroke = 1.6, ...rest }) => (
|
||||
<IconFileInfo
|
||||
className={composeClassName('icon', className)}
|
||||
size={size}
|
||||
stroke={stroke}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
||||
export const DetailPanelCollapseIcon = ({ className, size = '1em', stroke = 1.6, ...rest }) => (
|
||||
<IconLayoutSidebarRightCollapse
|
||||
className={composeClassName('icon', className)}
|
||||
|
||||
Reference in New Issue
Block a user