fix: sequence modal collection item loads

This commit is contained in:
Saberlve 2026-04-15 12:44:55 +08:00
parent 4b6c78105e
commit 3a1c046a68
2 changed files with 34 additions and 2 deletions

View File

@ -418,6 +418,10 @@
: []
),
visibleCollectionItems: [],
collectionItemsLoaded: false,
loadingCollectionKey: null,
nextCollectionItemsRequestToken: 0,
activeCollectionItemsRequestToken: 0,
};
const elements = {
@ -599,7 +603,7 @@
syncCurrentProjectLabels();
elements.importSelectedItemsButton.disabled = !hasProject || !hasSelection;
elements.importSelectedItemsButton.title = !hasProject ? "请先选择项目" : (hasSelection ? "" : "请先选择文献");
elements.selectDescendantsButton.disabled = !state.visibleCollectionItems.length;
elements.selectDescendantsButton.disabled = !state.collectionItemsLoaded || !state.visibleCollectionItems.length;
elements.clearSelectionButton.disabled = !state.selectedItemKeys.size;
renderSelectedCount();
}
@ -719,6 +723,11 @@
updateImportActionState();
return;
}
if (!state.collectionItemsLoaded) {
elements.collectionItems.innerHTML = '<div class="empty">正在加载当前 collection 文献。</div>';
updateImportActionState();
return;
}
if (!state.visibleCollectionItems.length) {
elements.collectionItems.innerHTML = '<div class="empty">当前目录及子目录下没有可导入文献。</div>';
updateImportActionState();
@ -759,14 +768,21 @@
return;
}
state.visibleCollectionItems = [];
state.collectionItemsLoaded = false;
state.loadingCollectionKey = null;
renderCollectionItems();
setStatus(elements.collectionStatus, "");
}
async function loadCollectionItems(collectionKey) {
if (!state.collectionItemsLoaded && state.loadingCollectionKey === collectionKey) {
return;
}
state.selectedCollectionKey = collectionKey;
if (normalizeSelectedCollectionKey() !== collectionKey) {
state.visibleCollectionItems = [];
state.collectionItemsLoaded = false;
state.loadingCollectionKey = null;
renderCollectionTree();
renderCollectionItems();
setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : "");
@ -778,9 +794,20 @@
ensureSelectedCollectionExpanded();
persistImportSessionState();
renderCollectionTree();
state.collectionItemsLoaded = false;
state.loadingCollectionKey = collectionKey;
const requestToken = state.nextCollectionItemsRequestToken + 1;
state.nextCollectionItemsRequestToken = requestToken;
state.activeCollectionItemsRequestToken = requestToken;
renderCollectionItems();
setStatus(elements.collectionStatus, "正在加载文献...");
const payload = await api(`/api/zotero/collections/${collectionKey}/items`);
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(
@ -847,7 +874,10 @@
} catch (error) {
setStatus(elements.collectionStatus, error.message, true);
}
} else if (state.selectedCollectionKey && !state.visibleCollectionItems.length) {
} else if (
state.selectedCollectionKey &&
(!state.collectionItemsLoaded && state.loadingCollectionKey !== state.selectedCollectionKey)
) {
try {
await loadCollectionItems(state.selectedCollectionKey);
} catch (error) {

View File

@ -42,6 +42,8 @@ def test_index_contains_import_modal_controls(tmp_path) -> None:
assert 'const ABSTRACT_PREVIEW_DELAY_MS = 3000;' 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 closeImportModal()" in html
assert "function updateImportActionState()" in html