ui
This commit is contained in:
+31
-187
@@ -257,12 +257,6 @@ const AppLayout = () => {
|
||||
const previewReturnPathRef = useRef(null);
|
||||
const [tags, setTags] = useState([]);
|
||||
const [correspondents, setCorrespondents] = useState([]);
|
||||
const [webdavTokens, setWebdavTokens] = useState([]);
|
||||
const [webdavTokensLoading, setWebdavTokensLoading] = useState(false);
|
||||
const [creatingWebdavToken, setCreatingWebdavToken] = useState(false);
|
||||
const [deletingWebdavTokenId, setDeletingWebdavTokenId] = useState(null);
|
||||
const [regeneratingWebdavTokenId, setRegeneratingWebdavTokenId] = useState(null);
|
||||
const [webdavTokenSecret, setWebdavTokenSecret] = useState(null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [activeTagFilters, setActiveTagFilters] = useState([]);
|
||||
const [activeCorrespondentFilters, setActiveCorrespondentFilters] = useState([]);
|
||||
@@ -425,11 +419,6 @@ const AppLayout = () => {
|
||||
setSearchResults(null);
|
||||
setTags([]);
|
||||
setCorrespondents([]);
|
||||
setWebdavTokens([]);
|
||||
setWebdavTokensLoading(false);
|
||||
setCreatingWebdavToken(false);
|
||||
setDeletingWebdavTokenId(null);
|
||||
setWebdavTokenSecret(null);
|
||||
setSearchQuery('');
|
||||
setActiveTagFilters([]);
|
||||
setActiveCorrespondentFilters([]);
|
||||
@@ -927,32 +916,10 @@ const AppLayout = () => {
|
||||
],
|
||||
);
|
||||
|
||||
const handleDocumentRowClick = useCallback(
|
||||
(documentId, event) => {
|
||||
const rowKey = resolveDocumentRowKey(documentId);
|
||||
if (!rowKey) return;
|
||||
const hadSelection = selectionCount > 0;
|
||||
handleRowSelection(rowKey, event);
|
||||
if (!hadSelection) {
|
||||
detailPanelControlRef.current.open();
|
||||
}
|
||||
},
|
||||
[handleRowSelection, selectionCount],
|
||||
);
|
||||
|
||||
const clearDocumentSelection = useCallback(() => {
|
||||
clearSelectionInternal();
|
||||
}, [clearSelectionInternal]);
|
||||
|
||||
const handleFolderRowClick = useCallback(
|
||||
(folderId, event) => {
|
||||
const rowKey = resolveFolderRowKey(folderId);
|
||||
if (!rowKey) return;
|
||||
handleRowSelection(rowKey, event);
|
||||
},
|
||||
[handleRowSelection],
|
||||
);
|
||||
|
||||
const prevFocusedDocIdRef = useRef(focusedDocumentId);
|
||||
useEffect(() => {
|
||||
const previous = prevFocusedDocIdRef.current;
|
||||
@@ -968,23 +935,39 @@ const AppLayout = () => {
|
||||
}, [focusedDocumentId, setFocusedRowKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!focusedRowKey) {
|
||||
if (!navigableRowKeys.length) {
|
||||
if (focusedRowKey) {
|
||||
setFocusedRowKey(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (navigableRowKeys.includes(focusedRowKey)) {
|
||||
|
||||
if (focusedRowKey && navigableRowKeys.includes(focusedRowKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const docKey = focusedDocumentId ? resolveDocumentRowKey(focusedDocumentId) : null;
|
||||
if (docKey && navigableRowKeys.includes(docKey)) {
|
||||
setFocusedRowKey(docKey);
|
||||
return;
|
||||
}
|
||||
if (navigableRowKeys.length) {
|
||||
setFocusedRowKey(navigableRowKeys[0]);
|
||||
} else {
|
||||
|
||||
const selectedKey = selectedRowKeys.find((key) => navigableRowKeys.includes(key));
|
||||
if (selectedKey) {
|
||||
setFocusedRowKey(selectedKey);
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusedRowKey) {
|
||||
setFocusedRowKey(null);
|
||||
}
|
||||
}, [focusedRowKey, navigableRowKeys, focusedDocumentId, setFocusedRowKey]);
|
||||
}, [
|
||||
focusedRowKey,
|
||||
focusedDocumentId,
|
||||
navigableRowKeys,
|
||||
selectedRowKeys,
|
||||
setFocusedRowKey,
|
||||
]);
|
||||
|
||||
|
||||
const ensureFolderData = useCallback(
|
||||
@@ -1303,125 +1286,6 @@ const AppLayout = () => {
|
||||
}
|
||||
}, [notifyApiError]);
|
||||
|
||||
const refreshWebdavTokens = useCallback(async () => {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
setWebdavTokensLoading(true);
|
||||
try {
|
||||
const { data } = await api.get('/profile/webdav-tokens');
|
||||
setWebdavTokens(Array.isArray(data) ? data : []);
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to load WebDAV tokens.');
|
||||
} finally {
|
||||
setWebdavTokensLoading(false);
|
||||
}
|
||||
}, [notifyApiError, token]);
|
||||
|
||||
const createWebdavToken = useCallback(
|
||||
async ({ label, expires_at } = {}) => {
|
||||
if (creatingWebdavToken) {
|
||||
return false;
|
||||
}
|
||||
setCreatingWebdavToken(true);
|
||||
try {
|
||||
const payload = {};
|
||||
if (label) {
|
||||
payload.label = label;
|
||||
}
|
||||
if (expires_at) {
|
||||
payload.expires_at = expires_at;
|
||||
}
|
||||
const { data } = await api.post('/profile/webdav-tokens', payload);
|
||||
if (data?.token_info) {
|
||||
setWebdavTokens((previous) => {
|
||||
const filtered = previous.filter((entry) => entry.id !== data.token_info.id);
|
||||
return [data.token_info, ...filtered];
|
||||
});
|
||||
} else {
|
||||
await refreshWebdavTokens();
|
||||
}
|
||||
if (data?.token) {
|
||||
setWebdavTokenSecret(data.token);
|
||||
}
|
||||
setStatusMessage('WebDAV token created.', 'success');
|
||||
return data;
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to create WebDAV token.');
|
||||
return false;
|
||||
} finally {
|
||||
setCreatingWebdavToken(false);
|
||||
}
|
||||
},
|
||||
[creatingWebdavToken, notifyApiError, refreshWebdavTokens, setStatusMessage],
|
||||
);
|
||||
|
||||
const deleteWebdavToken = useCallback(
|
||||
async (tokenId) => {
|
||||
if (!tokenId) {
|
||||
return false;
|
||||
}
|
||||
setDeletingWebdavTokenId(tokenId);
|
||||
try {
|
||||
await api.delete(`/profile/webdav-tokens/${tokenId}`);
|
||||
await refreshWebdavTokens();
|
||||
setStatusMessage('WebDAV token revoked.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to revoke WebDAV token.');
|
||||
return false;
|
||||
} finally {
|
||||
setDeletingWebdavTokenId(null);
|
||||
}
|
||||
},
|
||||
[refreshWebdavTokens, notifyApiError, setStatusMessage],
|
||||
);
|
||||
|
||||
const regenerateWebdavToken = useCallback(
|
||||
async (tokenId) => {
|
||||
if (!tokenId) {
|
||||
return false;
|
||||
}
|
||||
setRegeneratingWebdavTokenId(tokenId);
|
||||
try {
|
||||
const { data } = await api.post(`/profile/webdav-tokens/${tokenId}/regenerate`);
|
||||
if (data?.token_info) {
|
||||
setWebdavTokens((previous) => {
|
||||
let found = false;
|
||||
const next = previous.map((entry) => {
|
||||
if (entry.id === data.token_info.id) {
|
||||
found = true;
|
||||
return data.token_info;
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
if (!found) {
|
||||
return [data.token_info, ...previous];
|
||||
}
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
await refreshWebdavTokens();
|
||||
}
|
||||
if (data?.token) {
|
||||
setWebdavTokenSecret(data.token);
|
||||
}
|
||||
setStatusMessage('WebDAV token regenerated.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to regenerate WebDAV token.');
|
||||
return false;
|
||||
} finally {
|
||||
setRegeneratingWebdavTokenId(null);
|
||||
}
|
||||
},
|
||||
[notifyApiError, refreshWebdavTokens, setStatusMessage],
|
||||
);
|
||||
|
||||
const dismissCreatedWebdavToken = useCallback(() => {
|
||||
setWebdavTokenSecret(null);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
passkeys,
|
||||
passkeysSupported,
|
||||
@@ -3208,9 +3072,13 @@ const AppLayout = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedRowKeys.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFocusedRowKey(resolvedKey);
|
||||
|
||||
if (!selectedRowKeys.includes(resolvedKey)) {
|
||||
if (!selectedRowKeys.includes(resolvedKey) && selectedRowKeys.length > 0) {
|
||||
applySelection([resolvedKey], { anchor: resolvedKey, interactedKeys: [resolvedKey] });
|
||||
}
|
||||
}, [
|
||||
@@ -4699,15 +4567,12 @@ const AppLayout = () => {
|
||||
onFolderDragEnd: handleFolderDragEnd,
|
||||
draggedFolderId,
|
||||
onFolderDelete: handleFolderDelete,
|
||||
onFolderRowClick: handleFolderRowClick,
|
||||
onFolderRename: handleFolderRename,
|
||||
onDocumentRowClick: handleDocumentRowClick,
|
||||
onDocumentOpen: openDocumentPreview,
|
||||
onDocumentDelete: handleDocumentDelete,
|
||||
onDocumentRename: handleDocumentTitleUpdate,
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
focusedDocumentId,
|
||||
focusedRowKey,
|
||||
draggingDocumentIds: draggedDocumentIds,
|
||||
onDocumentDragStart: handleDocumentDragStart,
|
||||
@@ -4730,6 +4595,8 @@ const AppLayout = () => {
|
||||
viewMode: documentsViewMode,
|
||||
onViewModeChange: handleDocumentsViewModeChange,
|
||||
onClearSelection: clearDocumentSelection,
|
||||
onRowSelection: handleRowSelection,
|
||||
onOpenDetailPanel: openDetailPanel,
|
||||
}),
|
||||
[
|
||||
activeCorrespondentFilters,
|
||||
@@ -4741,7 +4608,6 @@ const AppLayout = () => {
|
||||
documentsViewMode,
|
||||
draggedDocumentIds,
|
||||
draggedFolderId,
|
||||
focusedDocumentId,
|
||||
focusedRowKey,
|
||||
folderClickHandlers,
|
||||
handleDocumentDelete,
|
||||
@@ -4749,7 +4615,6 @@ const AppLayout = () => {
|
||||
handleDocumentDragStart,
|
||||
handleDocumentListFocus,
|
||||
handleDocumentListKeyDown,
|
||||
handleDocumentRowClick,
|
||||
handleDocumentTagDrop,
|
||||
handleDocumentTitleUpdate,
|
||||
handleDocumentsViewModeChange,
|
||||
@@ -4757,8 +4622,9 @@ const AppLayout = () => {
|
||||
handleFolderDragEnd,
|
||||
handleFolderDragStart,
|
||||
handleFolderRename,
|
||||
handleFolderRowClick,
|
||||
handleRowSelection,
|
||||
isFilterActive,
|
||||
openDetailPanel,
|
||||
openDocumentPreview,
|
||||
refreshCurrentFolder,
|
||||
searchLoading,
|
||||
@@ -4975,17 +4841,6 @@ const AppLayout = () => {
|
||||
handleDocumentCorrespondentAttach,
|
||||
handleCorrespondentRemove,
|
||||
handleCorrespondentAdd,
|
||||
webdavTokens,
|
||||
webdavTokensLoading,
|
||||
creatingWebdavToken,
|
||||
deletingWebdavTokenId,
|
||||
regeneratingWebdavTokenId,
|
||||
refreshWebdavTokens,
|
||||
createWebdavToken,
|
||||
deleteWebdavToken,
|
||||
regenerateWebdavToken,
|
||||
webdavTokenSecret,
|
||||
dismissCreatedWebdavToken,
|
||||
passkeys,
|
||||
passkeysSupported,
|
||||
passkeysLoading,
|
||||
@@ -5036,17 +4891,6 @@ const AppLayout = () => {
|
||||
handleDocumentCorrespondentAttach,
|
||||
handleCorrespondentRemove,
|
||||
handleCorrespondentAdd,
|
||||
webdavTokens,
|
||||
webdavTokensLoading,
|
||||
creatingWebdavToken,
|
||||
deletingWebdavTokenId,
|
||||
regeneratingWebdavTokenId,
|
||||
refreshWebdavTokens,
|
||||
createWebdavToken,
|
||||
deleteWebdavToken,
|
||||
regenerateWebdavToken,
|
||||
webdavTokenSecret,
|
||||
dismissCreatedWebdavToken,
|
||||
passkeys,
|
||||
passkeysSupported,
|
||||
passkeysLoading,
|
||||
|
||||
Reference in New Issue
Block a user