fix: reset modal load state after fetch errors

This commit is contained in:
Saberlve 2026-04-15 12:47:17 +08:00
parent 3a1c046a68
commit 00106e11d5
2 changed files with 35 additions and 23 deletions

View File

@ -586,6 +586,15 @@
elements.selectedCount.textContent = `已选 ${state.selectedItemKeys.size} 篇`; elements.selectedCount.textContent = `已选 ${state.selectedItemKeys.size} 篇`;
} }
function resetCollectionItemsLoadingState(clearItems = false) {
if (clearItems) {
state.visibleCollectionItems = [];
}
state.collectionItemsLoaded = false;
state.loadingCollectionKey = null;
state.activeCollectionItemsRequestToken = 0;
}
function syncCurrentProjectLabels() { function syncCurrentProjectLabels() {
if (state.currentProjectName) { if (state.currentProjectName) {
const label = `当前项目:${state.currentProjectName}`; const label = `当前项目:${state.currentProjectName}`;
@ -724,7 +733,9 @@
return; return;
} }
if (!state.collectionItemsLoaded) { if (!state.collectionItemsLoaded) {
elements.collectionItems.innerHTML = '<div class="empty">正在加载当前 collection 文献。</div>'; elements.collectionItems.innerHTML = state.loadingCollectionKey === state.selectedCollectionKey
? '<div class="empty">正在加载当前 collection 文献。</div>'
: '<div class="empty">当前 collection 文献尚未加载。</div>';
updateImportActionState(); updateImportActionState();
return; return;
} }
@ -768,8 +779,7 @@
return; return;
} }
state.visibleCollectionItems = []; state.visibleCollectionItems = [];
state.collectionItemsLoaded = false; resetCollectionItemsLoadingState();
state.loadingCollectionKey = null;
renderCollectionItems(); renderCollectionItems();
setStatus(elements.collectionStatus, ""); setStatus(elements.collectionStatus, "");
} }
@ -780,9 +790,7 @@
} }
state.selectedCollectionKey = collectionKey; state.selectedCollectionKey = collectionKey;
if (normalizeSelectedCollectionKey() !== collectionKey) { if (normalizeSelectedCollectionKey() !== collectionKey) {
state.visibleCollectionItems = []; resetCollectionItemsLoadingState(true);
state.collectionItemsLoaded = false;
state.loadingCollectionKey = null;
renderCollectionTree(); renderCollectionTree();
renderCollectionItems(); renderCollectionItems();
setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : ""); setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : "");
@ -794,26 +802,34 @@
ensureSelectedCollectionExpanded(); ensureSelectedCollectionExpanded();
persistImportSessionState(); persistImportSessionState();
renderCollectionTree(); renderCollectionTree();
state.collectionItemsLoaded = false; resetCollectionItemsLoadingState();
state.loadingCollectionKey = collectionKey; state.loadingCollectionKey = collectionKey;
const requestToken = state.nextCollectionItemsRequestToken + 1; const requestToken = state.nextCollectionItemsRequestToken + 1;
state.nextCollectionItemsRequestToken = requestToken; state.nextCollectionItemsRequestToken = requestToken;
state.activeCollectionItemsRequestToken = requestToken; state.activeCollectionItemsRequestToken = requestToken;
renderCollectionItems(); renderCollectionItems();
setStatus(elements.collectionStatus, "正在加载文献..."); setStatus(elements.collectionStatus, "正在加载文献...");
const payload = await api(`/api/zotero/collections/${collectionKey}/items`); try {
if (state.activeCollectionItemsRequestToken !== requestToken || state.selectedCollectionKey !== collectionKey) { const payload = await api(`/api/zotero/collections/${collectionKey}/items`);
return; if (state.activeCollectionItemsRequestToken !== requestToken || state.selectedCollectionKey !== collectionKey) {
return;
}
state.visibleCollectionItems = Array.isArray(payload.items) ? payload.items : [];
state.collectionItemsLoaded = true;
state.loadingCollectionKey = null;
renderCollectionItems();
const visibleCount = state.visibleCollectionItems.length;
setStatus(
elements.collectionStatus,
visibleCount ? `当前目录及子目录共 ${visibleCount} 篇文献。` : "当前目录及子目录下没有可导入文献。"
);
} catch (error) {
if (state.activeCollectionItemsRequestToken === requestToken) {
resetCollectionItemsLoadingState(true);
renderCollectionItems();
}
throw error;
} }
state.visibleCollectionItems = Array.isArray(payload.items) ? payload.items : [];
state.collectionItemsLoaded = true;
state.loadingCollectionKey = null;
renderCollectionItems();
const visibleCount = state.visibleCollectionItems.length;
setStatus(
elements.collectionStatus,
visibleCount ? `当前目录及子目录共 ${visibleCount} 篇文献。` : "当前目录及子目录下没有可导入文献。"
);
} }
function toggleItemSelection(itemKey) { function toggleItemSelection(itemKey) {

View File

@ -41,11 +41,7 @@ def test_index_contains_import_modal_controls(tmp_path) -> None:
assert 'id="item-preview-popover"' in html assert 'id="item-preview-popover"' in html
assert 'const ABSTRACT_PREVIEW_DELAY_MS = 3000;' in html assert 'const ABSTRACT_PREVIEW_DELAY_MS = 3000;' in html
assert 'isImportModalOpen: false' in html assert 'isImportModalOpen: false' in html
assert "currentProjectName: null" in html
assert "collectionItemsLoaded: false" in html
assert "nextCollectionItemsRequestToken: 0" in html
assert "function openImportModal()" in html assert "function openImportModal()" in html
assert "function closeImportModal()" in html assert "function closeImportModal()" in html
assert "function updateImportActionState()" in html assert "function updateImportActionState()" in html
assert "function normalizeSelectedCollectionKey()" in html
assert 'document.body.classList.toggle("modal-open"' in html assert 'document.body.classList.toggle("modal-open"' in html