work
This commit is contained in:
+114
-1
@@ -539,6 +539,11 @@ const AppLayout = () => {
|
||||
const [searchResults, setSearchResults] = useState(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 [webdavTokenSecret, setWebdavTokenSecret] = useState(null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [activeTagFilters, setActiveTagFilters] = useState([]);
|
||||
const [activeCorrespondentFilters, setActiveCorrespondentFilters] = useState([]);
|
||||
@@ -743,6 +748,11 @@ const AppLayout = () => {
|
||||
setSearchResults(null);
|
||||
setTags([]);
|
||||
setCorrespondents([]);
|
||||
setWebdavTokens([]);
|
||||
setWebdavTokensLoading(false);
|
||||
setCreatingWebdavToken(false);
|
||||
setDeletingWebdavTokenId(null);
|
||||
setWebdavTokenSecret(null);
|
||||
setSearchQuery('');
|
||||
setActiveTagFilters([]);
|
||||
setDropOverlayState({ active: false, folderName: DEFAULT_FOLDER_NAME });
|
||||
@@ -1734,6 +1744,97 @@ const AppLayout = () => {
|
||||
}
|
||||
}, [api, 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);
|
||||
}
|
||||
}, [api, 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);
|
||||
}
|
||||
},
|
||||
[api, creatingWebdavToken, notifyApiError, refreshWebdavTokens, setStatusMessage],
|
||||
);
|
||||
|
||||
const deleteWebdavToken = useCallback(
|
||||
async (tokenId) => {
|
||||
if (!tokenId) {
|
||||
return false;
|
||||
}
|
||||
setDeletingWebdavTokenId(tokenId);
|
||||
try {
|
||||
await api.delete(`/profile/webdav-tokens/${tokenId}`);
|
||||
setWebdavTokens((previous) => previous.filter((entry) => entry.id !== tokenId));
|
||||
setStatusMessage('WebDAV token revoked.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to revoke WebDAV token.');
|
||||
return false;
|
||||
} finally {
|
||||
setDeletingWebdavTokenId(null);
|
||||
}
|
||||
},
|
||||
[api, notifyApiError, setStatusMessage],
|
||||
);
|
||||
|
||||
const dismissCreatedWebdavToken = useCallback(() => {
|
||||
setWebdavTokenSecret(null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSettingsModalOpen) {
|
||||
return;
|
||||
}
|
||||
refreshWebdavTokens();
|
||||
}, [isSettingsModalOpen, refreshWebdavTokens]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSettingsModalOpen) {
|
||||
setWebdavTokenSecret(null);
|
||||
}
|
||||
}, [isSettingsModalOpen]);
|
||||
|
||||
const handleTagUpdate = useCallback(
|
||||
async (tagId, changes) => {
|
||||
if (!tagId) {
|
||||
@@ -5404,7 +5505,19 @@ const AppLayout = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<SettingsModal open={isSettingsModalOpen} onClose={closeSettingsModal} />
|
||||
<SettingsModal
|
||||
open={isSettingsModalOpen}
|
||||
onClose={closeSettingsModal}
|
||||
tokens={webdavTokens}
|
||||
loading={webdavTokensLoading}
|
||||
creating={creatingWebdavToken}
|
||||
deletingId={deletingWebdavTokenId}
|
||||
onRefresh={refreshWebdavTokens}
|
||||
onCreate={createWebdavToken}
|
||||
onDelete={deleteWebdavToken}
|
||||
createdToken={webdavTokenSecret}
|
||||
onDismissCreatedToken={dismissCreatedWebdavToken}
|
||||
/>
|
||||
</div>
|
||||
</AppShellContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user