fix: validate modal session state

This commit is contained in:
Saberlve 2026-04-15 12:41:21 +08:00
parent a117a29b0d
commit 4b6c78105e
2 changed files with 30 additions and 9 deletions

View File

@ -436,7 +436,6 @@
selectDescendantsButton: document.getElementById("modal-select-descendants-button"), selectDescendantsButton: document.getElementById("modal-select-descendants-button"),
clearSelectionButton: document.getElementById("modal-clear-selection-button"), clearSelectionButton: document.getElementById("modal-clear-selection-button"),
importSelectedItemsButton: document.getElementById("modal-import-selected-items-button"), importSelectedItemsButton: document.getElementById("modal-import-selected-items-button"),
previewPopover: document.getElementById("item-preview-popover"),
currentProjectLabel: document.getElementById("current-project-label"), currentProjectLabel: document.getElementById("current-project-label"),
cardList: document.getElementById("card-list"), cardList: document.getElementById("card-list"),
cardDetail: document.getElementById("card-detail"), cardDetail: document.getElementById("card-detail"),
@ -613,6 +612,24 @@
return lookup; return lookup;
} }
function normalizeSelectedCollectionKey() {
if (!state.collectionTree.length) {
state.selectedCollectionKey = null;
state.expandedCollectionKeys.clear();
persistImportSessionState();
return null;
}
const parentLookup = collectCollectionParents(state.collectionTree);
if (!state.selectedCollectionKey || !parentLookup.has(state.selectedCollectionKey)) {
state.selectedCollectionKey = state.collectionTree[0].collection_key;
}
state.expandedCollectionKeys = new Set(
Array.from(state.expandedCollectionKeys).filter((key) => parentLookup.has(key))
);
persistImportSessionState();
return state.selectedCollectionKey;
}
function ensureSelectedCollectionExpanded() { function ensureSelectedCollectionExpanded() {
if (!state.selectedCollectionKey) { if (!state.selectedCollectionKey) {
return; return;
@ -733,9 +750,7 @@
setStatus(elements.collectionStatus, "正在加载 collection..."); setStatus(elements.collectionStatus, "正在加载 collection...");
const payload = await api("/api/zotero/collections/tree"); const payload = await api("/api/zotero/collections/tree");
state.collectionTree = Array.isArray(payload.collections) ? payload.collections : []; state.collectionTree = Array.isArray(payload.collections) ? payload.collections : [];
if (!state.selectedCollectionKey && state.collectionTree.length) { normalizeSelectedCollectionKey();
state.selectedCollectionKey = state.collectionTree[0].collection_key;
}
ensureSelectedCollectionExpanded(); ensureSelectedCollectionExpanded();
persistImportSessionState(); persistImportSessionState();
renderCollectionTree(); renderCollectionTree();
@ -750,6 +765,16 @@
async function loadCollectionItems(collectionKey) { async function loadCollectionItems(collectionKey) {
state.selectedCollectionKey = collectionKey; state.selectedCollectionKey = collectionKey;
if (normalizeSelectedCollectionKey() !== collectionKey) {
state.visibleCollectionItems = [];
renderCollectionTree();
renderCollectionItems();
setStatus(elements.collectionStatus, state.selectedCollectionKey ? "已切换到可用 collection。" : "");
if (state.selectedCollectionKey) {
await loadCollectionItems(state.selectedCollectionKey);
}
return;
}
ensureSelectedCollectionExpanded(); ensureSelectedCollectionExpanded();
persistImportSessionState(); persistImportSessionState();
renderCollectionTree(); renderCollectionTree();
@ -815,8 +840,6 @@
elements.importModal.hidden = false; elements.importModal.hidden = false;
elements.importModal.setAttribute("aria-hidden", "false"); elements.importModal.setAttribute("aria-hidden", "false");
document.body.classList.toggle("modal-open", true); document.body.classList.toggle("modal-open", true);
elements.previewPopover.hidden = true;
elements.previewPopover.textContent = "";
updateImportActionState(); updateImportActionState();
if (!state.collectionTree.length) { if (!state.collectionTree.length) {
try { try {
@ -841,8 +864,6 @@
elements.importModal.hidden = true; elements.importModal.hidden = true;
elements.importModal.setAttribute("aria-hidden", "true"); elements.importModal.setAttribute("aria-hidden", "true");
document.body.classList.toggle("modal-open", false); document.body.classList.toggle("modal-open", false);
elements.previewPopover.hidden = true;
elements.previewPopover.textContent = "";
} }
async function loadProjects() { async function loadProjects() {

View File

@ -45,5 +45,5 @@ def test_index_contains_import_modal_controls(tmp_path) -> None:
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
assert "${item.abstract" not in html