207 lines
5.8 KiB
JavaScript
207 lines
5.8 KiB
JavaScript
import { useCallback } from 'react';
|
|
|
|
const useBulkDocumentActions = ({
|
|
api,
|
|
resolveTargetDocumentIds,
|
|
correspondentLookupByName,
|
|
handleCorrespondentCreate,
|
|
refreshCurrentFolder,
|
|
setStatusMessage,
|
|
selectedDocumentIds,
|
|
selectedFolderIds,
|
|
handleDocumentsDelete,
|
|
handleFolderDelete,
|
|
clearDocumentSelection,
|
|
setLoading,
|
|
}) => {
|
|
const handleBulkCorrespondentAdd = useCallback(
|
|
async ({ name, input, documentIds }) => {
|
|
const trimmed = typeof name === 'string' ? name.trim() : '';
|
|
if (!trimmed) {
|
|
setStatusMessage('Correspondent name is required.', 'error');
|
|
return;
|
|
}
|
|
const targets = resolveTargetDocumentIds(documentIds);
|
|
if (!targets.length) {
|
|
setStatusMessage('Select documents before assigning correspondents.', 'error');
|
|
return;
|
|
}
|
|
|
|
let target = correspondentLookupByName.get(trimmed.toLowerCase()) || null;
|
|
if (!target) {
|
|
try {
|
|
target = await handleCorrespondentCreate({ name: trimmed });
|
|
} catch {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!target?.id) {
|
|
setStatusMessage('Unable to resolve correspondent.', 'error');
|
|
return;
|
|
}
|
|
|
|
const response = await api.post('/documents/bulk/correspondents', {
|
|
document_ids: targets,
|
|
assignments: [
|
|
{
|
|
correspondent_id: target.id,
|
|
},
|
|
],
|
|
action: 'add',
|
|
});
|
|
|
|
const { assigned = 0, removed = 0 } = response.data || {};
|
|
|
|
await refreshCurrentFolder();
|
|
const assignedSuffix = assigned === 1 ? '' : 's';
|
|
if (removed > 0) {
|
|
const removedSuffix = removed === 1 ? '' : 's';
|
|
setStatusMessage(
|
|
`Correspondent assigned (${assigned}) and replaced ${removed} link${removedSuffix}.`,
|
|
'success',
|
|
);
|
|
} else {
|
|
setStatusMessage(
|
|
`Correspondent assigned to ${assigned} document${assignedSuffix}.`,
|
|
'success',
|
|
);
|
|
}
|
|
|
|
if (input) {
|
|
input.value = '';
|
|
}
|
|
},
|
|
[
|
|
api,
|
|
correspondentLookupByName,
|
|
handleCorrespondentCreate,
|
|
refreshCurrentFolder,
|
|
resolveTargetDocumentIds,
|
|
setStatusMessage,
|
|
],
|
|
);
|
|
|
|
const handleBulkCorrespondentRemove = useCallback(
|
|
async ({ assignments = [], documentIds }) => {
|
|
if (!assignments.length) {
|
|
setStatusMessage('Select a correspondent to remove.', 'error');
|
|
return;
|
|
}
|
|
|
|
const targets = resolveTargetDocumentIds(documentIds);
|
|
|
|
if (!targets.length) {
|
|
setStatusMessage('Select documents before removing correspondents.', 'error');
|
|
return;
|
|
}
|
|
|
|
const normalizedAssignments = assignments.map((entry) => ({
|
|
correspondent_id: entry.correspondent_id,
|
|
}));
|
|
|
|
const response = await api.post('/documents/bulk/correspondents', {
|
|
document_ids: targets,
|
|
assignments: normalizedAssignments,
|
|
action: 'remove',
|
|
});
|
|
|
|
const { assigned = 0, removed = 0 } = response.data || {};
|
|
await refreshCurrentFolder();
|
|
|
|
if (removed > 0) {
|
|
const removedSuffix = removed === 1 ? '' : 's';
|
|
setStatusMessage(
|
|
`Correspondent removed from ${removed} link${removedSuffix}.`,
|
|
'success',
|
|
);
|
|
} else if (assigned > 0) {
|
|
const assignedSuffix = assigned === 1 ? '' : 's';
|
|
setStatusMessage(`Correspondent updated ${assigned} link${assignedSuffix}.`, 'info');
|
|
} else {
|
|
setStatusMessage('No correspondents changed.', 'info');
|
|
}
|
|
},
|
|
[api, refreshCurrentFolder, resolveTargetDocumentIds, setStatusMessage],
|
|
);
|
|
|
|
const handleDeleteSelection = useCallback(async () => {
|
|
const docIds = Array.isArray(selectedDocumentIds) ? selectedDocumentIds : [];
|
|
const folderIds = Array.isArray(selectedFolderIds) ? selectedFolderIds : [];
|
|
|
|
if (docIds.length === 0 && folderIds.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const parts = [];
|
|
if (docIds.length) {
|
|
parts.push(`${docIds.length} document${docIds.length === 1 ? '' : 's'}`);
|
|
}
|
|
if (folderIds.length) {
|
|
parts.push(`${folderIds.length} folder${folderIds.length === 1 ? '' : 's'}`);
|
|
}
|
|
const descriptor = parts.join(' and ');
|
|
const confirmation = parts.length === 1
|
|
? `Delete ${descriptor}? Folders must be empty before deletion. You can restore documents later from trash.`
|
|
: `Delete ${descriptor}? Folders must be empty before deletion. You can restore documents later from trash.`;
|
|
|
|
if (!window.confirm(confirmation)) {
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
let docsOk = true;
|
|
let foldersOk = true;
|
|
|
|
try {
|
|
if (docIds.length) {
|
|
docsOk = await handleDocumentsDelete(docIds, { showMessage: false, manageLoading: false });
|
|
}
|
|
|
|
if (folderIds.length) {
|
|
for (const folderId of folderIds) {
|
|
const success = await handleFolderDelete(folderId, { showMessage: false, manageLoading: false });
|
|
if (!success) {
|
|
foldersOk = false;
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
|
|
if (!docsOk || !foldersOk) {
|
|
setStatusMessage('Some items could not be deleted. Ensure folders are empty before deletion.', 'error');
|
|
return;
|
|
}
|
|
|
|
clearDocumentSelection();
|
|
|
|
const successParts = [];
|
|
if (docIds.length) {
|
|
successParts.push(docIds.length === 1 ? 'Document deleted.' : 'Documents deleted.');
|
|
}
|
|
if (folderIds.length) {
|
|
successParts.push(folderIds.length === 1 ? 'Folder deleted.' : 'Folders deleted.');
|
|
}
|
|
|
|
setStatusMessage(successParts.join(' '), 'success');
|
|
}, [
|
|
clearDocumentSelection,
|
|
handleDocumentsDelete,
|
|
handleFolderDelete,
|
|
selectedDocumentIds,
|
|
selectedFolderIds,
|
|
setLoading,
|
|
setStatusMessage,
|
|
]);
|
|
|
|
return {
|
|
handleBulkCorrespondentAdd,
|
|
handleBulkCorrespondentRemove,
|
|
handleDeleteSelection,
|
|
};
|
|
};
|
|
|
|
export default useBulkDocumentActions;
|