fix: sequence modal collection item loads
This commit is contained in:
parent
4b6c78105e
commit
3a1c046a68
@ -418,6 +418,10 @@
|
|||||||
: []
|
: []
|
||||||
),
|
),
|
||||||
visibleCollectionItems: [],
|
visibleCollectionItems: [],
|
||||||
|
collectionItemsLoaded: false,
|
||||||
|
loadingCollectionKey: null,
|
||||||
|
nextCollectionItemsRequestToken: 0,
|
||||||
|
activeCollectionItemsRequestToken: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const elements = {
|
const elements = {
|
||||||
@ -599,7 +603,7 @@
|
|||||||
syncCurrentProjectLabels();
|
syncCurrentProjectLabels();
|
||||||
elements.importSelectedItemsButton.disabled = !hasProject || !hasSelection;
|
elements.importSelectedItemsButton.disabled = !hasProject || !hasSelection;
|
||||||
elements.importSelectedItemsButton.title = !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;
|
elements.clearSelectionButton.disabled = !state.selectedItemKeys.size;
|
||||||
renderSelectedCount();
|
renderSelectedCount();
|
||||||
}
|
}
|
||||||
@ -719,6 +723,11 @@
|
|||||||
updateImportActionState();
|
updateImportActionState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!state.collectionItemsLoaded) {
|
||||||
|
elements.collectionItems.innerHTML = '<div class="empty">正在加载当前 collection 文献。</div>';
|
||||||
|
updateImportActionState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!state.visibleCollectionItems.length) {
|
if (!state.visibleCollectionItems.length) {
|
||||||
elements.collectionItems.innerHTML = '<div class="empty">当前目录及子目录下没有可导入文献。</div>';
|
elements.collectionItems.innerHTML = '<div class="empty">当前目录及子目录下没有可导入文献。</div>';
|
||||||
updateImportActionState();
|
updateImportActionState();
|
||||||
@ -759,14 +768,21 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.visibleCollectionItems = [];
|
state.visibleCollectionItems = [];
|
||||||
|
state.collectionItemsLoaded = false;
|
||||||
|
state.loadingCollectionKey = null;
|
||||||
renderCollectionItems();
|
renderCollectionItems();
|
||||||
setStatus(elements.collectionStatus, "");
|
setStatus(elements.collectionStatus, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadCollectionItems(collectionKey) {
|
async function loadCollectionItems(collectionKey) {
|
||||||
|
if (!state.collectionItemsLoaded && state.loadingCollectionKey === collectionKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
state.selectedCollectionKey = collectionKey;
|
state.selectedCollectionKey = collectionKey;
|
||||||
if (normalizeSelectedCollectionKey() !== collectionKey) {
|
if (normalizeSelectedCollectionKey() !== collectionKey) {
|
||||||
state.visibleCollectionItems = [];
|
state.visibleCollectionItems = [];
|
||||||
|
state.collectionItemsLoaded = false;
|
||||||
|
state.loadingCollectionKey = null;
|
||||||
renderCollectionTree();
|
renderCollectionTree();
|
||||||
renderCollectionItems();
|
renderCollectionItems();
|
||||||
setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : "");
|
setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : "");
|
||||||
@ -778,9 +794,20 @@
|
|||||||
ensureSelectedCollectionExpanded();
|
ensureSelectedCollectionExpanded();
|
||||||
persistImportSessionState();
|
persistImportSessionState();
|
||||||
renderCollectionTree();
|
renderCollectionTree();
|
||||||
|
state.collectionItemsLoaded = false;
|
||||||
|
state.loadingCollectionKey = collectionKey;
|
||||||
|
const requestToken = state.nextCollectionItemsRequestToken + 1;
|
||||||
|
state.nextCollectionItemsRequestToken = requestToken;
|
||||||
|
state.activeCollectionItemsRequestToken = requestToken;
|
||||||
|
renderCollectionItems();
|
||||||
setStatus(elements.collectionStatus, "正在加载文献...");
|
setStatus(elements.collectionStatus, "正在加载文献...");
|
||||||
const payload = await api(`/api/zotero/collections/${collectionKey}/items`);
|
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.visibleCollectionItems = Array.isArray(payload.items) ? payload.items : [];
|
||||||
|
state.collectionItemsLoaded = true;
|
||||||
|
state.loadingCollectionKey = null;
|
||||||
renderCollectionItems();
|
renderCollectionItems();
|
||||||
const visibleCount = state.visibleCollectionItems.length;
|
const visibleCount = state.visibleCollectionItems.length;
|
||||||
setStatus(
|
setStatus(
|
||||||
@ -847,7 +874,10 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
setStatus(elements.collectionStatus, error.message, true);
|
setStatus(elements.collectionStatus, error.message, true);
|
||||||
}
|
}
|
||||||
} else if (state.selectedCollectionKey && !state.visibleCollectionItems.length) {
|
} else if (
|
||||||
|
state.selectedCollectionKey &&
|
||||||
|
(!state.collectionItemsLoaded && state.loadingCollectionKey !== state.selectedCollectionKey)
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
await loadCollectionItems(state.selectedCollectionKey);
|
await loadCollectionItems(state.selectedCollectionKey);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -42,6 +42,8 @@ def test_index_contains_import_modal_controls(tmp_path) -> None:
|
|||||||
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 "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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user