diff --git a/static/js/documentLibrary.js b/static/js/documentLibrary.js index 6d86a8e..aabf7a9 100644 --- a/static/js/documentLibrary.js +++ b/static/js/documentLibrary.js @@ -652,9 +652,10 @@ let _libraryArchivedView = false; // Documents tab showing archived docs? if (doc.session_id) { openItem.addEventListener('click', (e) => { e.stopPropagation(); hideCardDropdown(); libraryOpenInSession(doc); }); } else { - openItem.disabled = true; - openItem.style.opacity = '0.35'; - openItem.title = 'Not linked to a session'; + // Orphaned doc (closed / session detached) is still openable in the editor + // by id — libraryOpenDocument handles the no-session case (#1602). + openItem.title = 'Open in the editor'; + openItem.addEventListener('click', (e) => { e.stopPropagation(); hideCardDropdown(); libraryOpenDocument(doc); }); } dropdown.appendChild(openItem); @@ -772,10 +773,10 @@ let _libraryArchivedView = false; // Documents tab showing archived docs? openBtn.title = 'Open in original session'; openBtn.addEventListener('click', (e) => { e.stopPropagation(); libraryOpenInSession(doc); }); } else { - openBtn.disabled = true; - openBtn.style.opacity = '0.35'; - openBtn.style.cursor = 'not-allowed'; - openBtn.title = 'This document is not linked to a session'; + // Orphaned doc (closed / session detached) is still openable in the editor + // by id — libraryOpenDocument handles the no-session case (#1602). + openBtn.title = 'Open in the editor'; + openBtn.addEventListener('click', (e) => { e.stopPropagation(); libraryOpenDocument(doc); }); } const cloneBtn = document.createElement('button'); diff --git a/tests/test_doc_library_open_orphaned.py b/tests/test_doc_library_open_orphaned.py new file mode 100644 index 0000000..b164cd4 --- /dev/null +++ b/tests/test_doc_library_open_orphaned.py @@ -0,0 +1,47 @@ +"""Regression for issue #1602 — after closing an AI-written document, its "Open" +button in the Documents library is grayed out, so the user can't reopen it. + +Root cause: closing/detaching a document nulls its session_id (the detach +behaviour from #1238), and both Open controls in static/js/documentLibrary.js +(the card's expanded Open button AND the card dropdown's Open item) gated on +`doc.session_id` — wiring `libraryOpenInSession` (which early-returns when there's +no session) and DISABLING the control otherwise. But the module already has +`libraryOpenDocument`, which explicitly handles the orphaned case ("just open in +editor without switching session"). The fix routes the no-session path there +instead of disabling. + +documentLibrary.js pulls in browser-only modules so it can't run under node; this +guards the wiring at the source level (red→green via git-stash). +""" + +import re +from pathlib import Path + +SRC = Path(__file__).resolve().parent.parent / "static/js/documentLibrary.js" + + +def _src() -> str: + return SRC.read_text(encoding="utf-8") + + +def test_orphaned_doc_open_controls_are_not_disabled(): + text = _src() + # Neither Open control may hard-disable itself for a session-less doc anymore. + assert "openItem.disabled = true" not in text, "dropdown Open must not be disabled for orphaned docs (#1602)" + assert "openBtn.disabled = true" not in text, "card Open button must not be disabled for orphaned docs (#1602)" + # The old 'not linked to a session' dead-end titles are gone. + assert "not linked to a session" not in text.lower() + + +def test_orphaned_doc_open_routes_to_editor_load(): + """Both Open controls' no-session branch must call libraryOpenDocument, the + function that opens an orphaned doc directly in the editor by id.""" + text = _src() + # definition + two wirings (dropdown item + card button) + assert text.count("libraryOpenDocument(doc)") >= 3, \ + "both Open controls must route the no-session case to libraryOpenDocument" + # libraryOpenDocument genuinely handles the orphaned case. + body = text[text.index("async function libraryOpenDocument(doc)"):] + body = body[: body.index("async function libraryOpenInSession")] + assert "if (!doc.session_id)" in body and "_loadDocument(doc.id)" in body, \ + "libraryOpenDocument must open a session-less doc by id"