refactor: Consolidate mutation options, simplify tag attachment and removal logic, and remove unused tag drop handler.

This commit is contained in:
2025-12-02 13:01:14 +01:00
parent 5ffe9e4d27
commit ebe8b163b9
2 changed files with 16 additions and 79 deletions
@@ -78,22 +78,7 @@ interface DocumentTagExtras {
input?: { value?: string } | null;
}
interface DeleteOptions {
showMessage?: boolean;
}
interface TagAttachArgs {
documentId?: DocumentId;
tagId?: DocumentId;
tag?: Tag | null;
}
interface TagRemoveOptions {
refreshTagList?: boolean;
showMessage?: boolean;
}
interface FolderDeleteOptions {
interface MessageOptions {
showMessage?: boolean;
}
@@ -142,14 +127,14 @@ interface UseDocumentMutationsResult {
handleThumbnailRegeneration: (documentId: DocumentId) => Promise<void>;
handleDocumentsDelete: (
documentIds: DocumentId[],
options?: DeleteOptions,
options?: MessageOptions,
) => Promise<boolean>;
handleDocumentTagAdd: (
document: Document,
label: string,
extras?: DocumentTagExtras | null,
) => Promise<void>;
handleDocumentTagAttach: (args: TagAttachArgs) => Promise<boolean>;
handleDocumentTagAttach: (documentId: DocumentId, tagId: DocumentId) => Promise<boolean>;
handleDocumentTitleUpdate: (documentId: DocumentId, nextTitle: string) => Promise<boolean>;
handleDocumentIssuedUpdate: (
documentId: DocumentId,
@@ -158,9 +143,8 @@ interface UseDocumentMutationsResult {
handleTagRemove: (
documentId?: DocumentId,
tagId?: DocumentId,
options?: TagRemoveOptions,
) => Promise<boolean>;
handleFolderDelete: (folderId?: FolderId, options?: FolderDeleteOptions) => Promise<boolean>;
handleFolderDelete: (folderId?: FolderId, options?: MessageOptions) => Promise<boolean>;
}
const normalizeDocumentId = (value: unknown): DocumentId | null => {
@@ -404,7 +388,7 @@ const useDocumentMutations = ({
);
const handleDocumentsDelete = useCallback(
async (documentIds: DocumentId[], { showMessage = true }: DeleteOptions = {}) => {
async (documentIds: DocumentId[], { showMessage = true }: MessageOptions = {}) => {
if (!documentIds || documentIds.length === 0) {
return false;
}
@@ -596,25 +580,24 @@ const useDocumentMutations = ({
);
const handleDocumentTagAttach = useCallback(
async ({ documentId, tagId, tag: tagData = null }: TagAttachArgs) => {
async (documentId: DocumentId, tagId: DocumentId) => {
if (!documentId || !tagId) {
return false;
}
const resolveTagForCache = (): Tag | null => {
const lookupTag = tagLookupById.get(tagId);
const source = lookupTag ?? tagData;
if (!source || source.id == null) {
if (!lookupTag || lookupTag.id == null) {
return null;
}
const labelText = `${source.label ?? ''} `.trim();
const labelText = `${lookupTag.label ?? ''} `.trim();
if (!labelText) {
return null;
}
return {
id: source.id,
id: lookupTag.id,
label: labelText,
color: Object.prototype.hasOwnProperty.call(source, 'color') ? (source as Tag).color ?? null : null,
color: Object.prototype.hasOwnProperty.call(lookupTag, 'color') ? (lookupTag as Tag).color ?? null : null,
};
};
@@ -654,7 +637,6 @@ const useDocumentMutations = ({
async (
documentId?: DocumentId,
tagId?: DocumentId,
{ refreshTagList = true, showMessage = true }: TagRemoveOptions = {},
) => {
if (!documentId || !tagId) {
return false;
@@ -663,12 +645,7 @@ const useDocumentMutations = ({
try {
await deleteDocumentTag(documentId, tagId);
applyTagRemovalToCaches(documentId, tagId);
if (refreshTagList) {
await refreshTags();
}
if (showMessage) {
setStatusMessage('Tag removed.', 'success');
}
setStatusMessage('Tag removed.', 'success');
return true;
} catch (error) {
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to remove tag.';
@@ -676,11 +653,11 @@ const useDocumentMutations = ({
return false;
}
},
[applyTagRemovalToCaches, notifyApiError, refreshTags, setStatusMessage],
[applyTagRemovalToCaches, notifyApiError, setStatusMessage],
);
const handleFolderDelete = useCallback(
async (folderId?: FolderId, { showMessage = true }: FolderDeleteOptions = {}) => {
async (folderId?: FolderId, { showMessage = true }: MessageOptions = {}) => {
if (!token) {
if (showMessage) {
setStatusMessage('Log in to manage folders.', 'error');
@@ -936,16 +936,7 @@ const useDocumentsWorkspace = ({
[assetManager, updateDocumentCaches, notifyApiError],
);
const handleDocumentTagDrop = useCallback(
async (documentId, tagId) => {
if (!documentId || !tagId) {
return;
}
await handleDocumentTagAttach({ documentId, tagId });
},
[handleDocumentTagAttach],
);
const handlePromptCreateFolder = useCallback(async (parentId?: Identifier | null) => {
if (creatingFolder) {
@@ -1053,48 +1044,17 @@ const useDocumentsWorkspace = ({
setTagRemovalCursor(false);
};
const handleTagDrop = async (event) => {
if (!isTagTransfer(event)) {
return;
}
setTagRemovalCursor(false);
if (isDocumentDropTarget(event.target) || event.defaultPrevented) {
return;
}
event.preventDefault();
event.stopPropagation();
const raw =
event.dataTransfer.getData('application/x-papercrate-tag') ||
event.dataTransfer.getData('text/papercrate-tag');
if (!raw) {
return;
}
try {
const payload = JSON.parse(raw);
if (payload?.sourceDocId && payload?.id) {
await handleTagRemove(payload.sourceDocId, payload.id, {
refreshTagList: false,
showMessage: true,
});
}
} catch (error) {
console.warn('Failed to remove tag from drop target', error);
}
};
const handleTagDragEnd = () => {
setTagRemovalCursor(false);
};
host.addEventListener('dragover', handleTagDragOver, true);
host.addEventListener('dragleave', handleTagDragLeave, true);
host.addEventListener('drop', handleTagDrop, true);
window.addEventListener('dragend', handleTagDragEnd, true);
return () => {
host.removeEventListener('dragover', handleTagDragOver, true);
host.removeEventListener('dragleave', handleTagDragLeave, true);
host.removeEventListener('drop', handleTagDrop, true);
window.removeEventListener('dragend', handleTagDragEnd, true);
setTagRemovalCursor(false);
};
@@ -1204,7 +1164,7 @@ const useDocumentsWorkspace = ({
activeCorrespondentFilters,
ensureAssetUrl,
getDocumentAsset,
handleDocumentTagAttach: handleDocumentTagDrop,
handleDocumentTagAttach,
handleDocumentTagDetach: handleTagRemove,
documentsViewMode,
documentsSortField,
@@ -1280,7 +1240,7 @@ const useDocumentsWorkspace = ({
refreshTags,
handleTagUpdate,
handleTagDelete,
handleDocumentTagDrop,
handleDocumentTagDrop: handleDocumentTagAttach,
correspondents,
refreshCorrespondents,
handleCorrespondentUpdate,
@@ -1330,7 +1290,7 @@ const useDocumentsWorkspace = ({
refreshTags,
handleTagUpdate,
handleTagDelete,
handleDocumentTagDrop,
handleDocumentTagAttach,
correspondents,
refreshCorrespondents,
handleCorrespondentUpdate,