detailpanel
This commit is contained in:
@@ -1859,7 +1859,7 @@ const AppLayout = () => {
|
||||
);
|
||||
|
||||
const handleCorrespondentAdd = useCallback(
|
||||
async ({ document, name, input }) => {
|
||||
async ({ document, name, input = null, option = null }) => {
|
||||
if (!document?.id) {
|
||||
throw new Error('Missing document for correspondent assignment.');
|
||||
}
|
||||
@@ -1869,7 +1869,12 @@ const AppLayout = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
let target = correspondentLookupByName.get(trimmed.toLowerCase()) || null;
|
||||
let target = null;
|
||||
if (option && option.id) {
|
||||
target = correspondentLookupByName.get(trimmed.toLowerCase()) || option;
|
||||
} else {
|
||||
target = correspondentLookupByName.get(trimmed.toLowerCase()) || null;
|
||||
}
|
||||
if (!target) {
|
||||
try {
|
||||
target = await handleCorrespondentCreate({ name: trimmed });
|
||||
@@ -3585,6 +3590,35 @@ const AppLayout = () => {
|
||||
[notifyApiError, setStatusMessage, updateDocumentCaches, extractDocumentFromResponse],
|
||||
);
|
||||
|
||||
const handleDocumentIssuedUpdate = useCallback(
|
||||
async (documentId, nextIssuedDate) => {
|
||||
setLoading(true);
|
||||
const payload = { issued_at: nextIssuedDate || null };
|
||||
try {
|
||||
const { data } = await api.patch(`/documents/${documentId}`, payload);
|
||||
const updatedDocument = extractDocumentFromResponse(data);
|
||||
|
||||
updateDocumentCaches(documentId, (doc) => {
|
||||
if (updatedDocument) {
|
||||
return { ...doc, ...updatedDocument };
|
||||
}
|
||||
return { ...doc, issued_at: payload.issued_at };
|
||||
});
|
||||
|
||||
const message = payload.issued_at ? 'Issued date updated.' : 'Issued date cleared.';
|
||||
setStatusMessage(message, 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = error.response?.data?.error || 'Failed to update issued date.';
|
||||
notifyApiError(error, message);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[extractDocumentFromResponse, notifyApiError, setStatusMessage, updateDocumentCaches],
|
||||
);
|
||||
|
||||
const applyTagRemovalToCaches = useCallback(
|
||||
(documentId, tagId) => {
|
||||
if (!documentId || !tagId) {
|
||||
@@ -3631,10 +3665,21 @@ const AppLayout = () => {
|
||||
);
|
||||
|
||||
const handleTagAdd = useCallback(
|
||||
async (document, label, input) => {
|
||||
async (document, label, extras = null) => {
|
||||
const normalizedLabel = tagManager.normalizeLabel(label);
|
||||
let tag =
|
||||
tags.find((item) => item.label.toLowerCase() === normalizedLabel.toLowerCase()) || null;
|
||||
const optionCandidate =
|
||||
extras && typeof extras === 'object' && 'option' in extras ? extras.option : null;
|
||||
const input =
|
||||
extras && typeof extras === 'object' && 'input' in extras ? extras.input : null;
|
||||
|
||||
let tag = null;
|
||||
if (optionCandidate && optionCandidate.id) {
|
||||
tag = tags.find((item) => item.id === optionCandidate.id) || optionCandidate;
|
||||
}
|
||||
if (!tag) {
|
||||
tag =
|
||||
tags.find((item) => item.label.toLowerCase() === normalizedLabel.toLowerCase()) || null;
|
||||
}
|
||||
try {
|
||||
if (!tag) {
|
||||
const payload = tagManager.buildPayload({ label: normalizedLabel });
|
||||
@@ -3644,7 +3689,9 @@ const AppLayout = () => {
|
||||
}
|
||||
await api.post(`/documents/${document.id}/tags`, { tag_ids: [tag.id] });
|
||||
setStatusMessage('Tag assigned.', 'success');
|
||||
input.value = '';
|
||||
if (input && typeof input === 'object') {
|
||||
input.value = '';
|
||||
}
|
||||
await refreshCurrentFolder();
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to assign tag.');
|
||||
@@ -5104,6 +5151,7 @@ const AppLayout = () => {
|
||||
onPromoteSelection: promoteSelectionOrder,
|
||||
activePreviewId,
|
||||
onUpdateTitle: handleDocumentTitleUpdate,
|
||||
onUpdateIssued: handleDocumentIssuedUpdate,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
ensurePreviewData,
|
||||
@@ -5131,6 +5179,7 @@ const AppLayout = () => {
|
||||
handleCorrespondentRemove,
|
||||
handleDetailPanelClose,
|
||||
handleDocumentTitleUpdate,
|
||||
handleDocumentIssuedUpdate,
|
||||
handleTagAdd,
|
||||
handleTagRemove,
|
||||
handleThumbnailRegeneration,
|
||||
|
||||
@@ -68,6 +68,20 @@ export const useWorkspaceSurface = ({
|
||||
if (!showPreviewWorkspace || !previewWorkspaceDocument) {
|
||||
return null;
|
||||
}
|
||||
const detailExtras = detailPanelProps || {};
|
||||
const {
|
||||
tagLookupById,
|
||||
tags: tagOptions,
|
||||
onTagAdd,
|
||||
onTagRemove,
|
||||
correspondents,
|
||||
onCorrespondentAdd,
|
||||
onCorrespondentRemove,
|
||||
onUpdateTitle,
|
||||
onUpdateIssued,
|
||||
resolveFolderPath,
|
||||
onFolderNavigate,
|
||||
} = detailExtras;
|
||||
return createPreviewSurface({
|
||||
document: previewWorkspaceDocument,
|
||||
previewEntry: previewWorkspaceEntry,
|
||||
@@ -79,6 +93,17 @@ export const useWorkspaceSurface = ({
|
||||
onRegenerate: handleThumbnailRegeneration,
|
||||
onClose: closeDocumentPreview,
|
||||
renderSidebarToggle,
|
||||
tagLookupById,
|
||||
tagOptions,
|
||||
onTagAdd,
|
||||
onTagRemove,
|
||||
correspondents,
|
||||
onCorrespondentAdd,
|
||||
onCorrespondentRemove,
|
||||
onUpdateTitle,
|
||||
onUpdateIssued,
|
||||
resolveFolderPath,
|
||||
onFolderNavigate,
|
||||
});
|
||||
}, [
|
||||
showPreviewWorkspace,
|
||||
@@ -92,6 +117,7 @@ export const useWorkspaceSurface = ({
|
||||
handleThumbnailRegeneration,
|
||||
closeDocumentPreview,
|
||||
renderSidebarToggle,
|
||||
detailPanelProps,
|
||||
]);
|
||||
|
||||
const workspaceSurface = useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user