tags drags
This commit is contained in:
@@ -3,6 +3,8 @@ import { resolveDocumentAssetUrl } from '../asset_manager';
|
||||
import { getTagColorStyle } from '../utils/colors';
|
||||
import { DownloadIcon, FolderIcon, EditIcon } from '../ui/icons';
|
||||
|
||||
const TAG_MIME_TYPES = ['application/x-papercrate-tag', 'text/papercrate-tag'];
|
||||
|
||||
const DocumentThumbnailImage = ({ document, ensureAssetUrl, getDocumentAsset, alt }) => {
|
||||
const url = useMemo(
|
||||
() =>
|
||||
@@ -71,6 +73,7 @@ const DocumentsTable = ({
|
||||
getDownloadHref,
|
||||
onTagClick,
|
||||
isSearchLoading = false,
|
||||
onDocumentTagDrop,
|
||||
}) => {
|
||||
const showingSearchResults = searchResults !== null;
|
||||
const rows = showingSearchResults ? searchResults : documents;
|
||||
@@ -88,6 +91,10 @@ const DocumentsTable = ({
|
||||
[draggingDocumentIds],
|
||||
);
|
||||
const scrollRef = useRef(null);
|
||||
const isTagDragEvent = useCallback((event) => {
|
||||
const types = Array.from(event.dataTransfer?.types || []);
|
||||
return TAG_MIME_TYPES.some((type) => types.includes(type));
|
||||
}, []);
|
||||
const ensureFocusedRowVisible = useCallback(() => {
|
||||
if (!focusedRowKey) return;
|
||||
const container = scrollRef.current;
|
||||
@@ -139,6 +146,58 @@ const DocumentsTable = ({
|
||||
return undefined;
|
||||
}, [focusedRowKey]);
|
||||
|
||||
const handleDocumentTagDragOver = useCallback(
|
||||
(event) => {
|
||||
if (!isTagDragEvent(event)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
event.currentTarget.classList.add('tag-drop-target');
|
||||
},
|
||||
[isTagDragEvent],
|
||||
);
|
||||
|
||||
const handleDocumentTagDragLeave = useCallback(
|
||||
(event) => {
|
||||
if (!isTagDragEvent(event)) {
|
||||
return;
|
||||
}
|
||||
if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
event.currentTarget.classList.remove('tag-drop-target');
|
||||
},
|
||||
[isTagDragEvent],
|
||||
);
|
||||
|
||||
const handleDocumentTagDrop = useCallback(
|
||||
(event, documentId) => {
|
||||
if (!isTagDragEvent(event)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.currentTarget.classList.remove('tag-drop-target');
|
||||
const payload =
|
||||
event.dataTransfer.getData('application/x-papercrate-tag') ||
|
||||
event.dataTransfer.getData('text/papercrate-tag');
|
||||
if (!payload) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(payload);
|
||||
if (parsed?.id && onDocumentTagDrop) {
|
||||
onDocumentTagDrop(documentId, parsed);
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
},
|
||||
[isTagDragEvent, onDocumentTagDrop],
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="documents-panel column">
|
||||
<div className="column-header">
|
||||
@@ -336,6 +395,9 @@ const DocumentsTable = ({
|
||||
draggable
|
||||
onDragStart={(event) => onDocumentDragStart(event, doc)}
|
||||
onDragEnd={onDocumentDragEnd}
|
||||
onDragOver={handleDocumentTagDragOver}
|
||||
onDragLeave={handleDocumentTagDragLeave}
|
||||
onDrop={(event) => handleDocumentTagDrop(event, doc.id)}
|
||||
>
|
||||
<td className="thumb-cell">
|
||||
<DocumentThumbnailImage
|
||||
@@ -393,6 +455,29 @@ const DocumentsTable = ({
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
draggable
|
||||
onDragStart={(event) => {
|
||||
event.stopPropagation();
|
||||
try {
|
||||
if (event.dataTransfer) {
|
||||
event.dataTransfer.effectAllowed = 'copyMove';
|
||||
}
|
||||
const payload = JSON.stringify({
|
||||
id: tag.id,
|
||||
label: tag.label,
|
||||
sourceDocId: doc.id,
|
||||
});
|
||||
event.dataTransfer?.setData('application/x-papercrate-tag', payload);
|
||||
event.dataTransfer?.setData('text/papercrate-tag', payload);
|
||||
event.dataTransfer?.setData('text/plain', tag.label || 'Tag');
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
}}
|
||||
onDragEnd={(event) => {
|
||||
event.stopPropagation();
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user