fix: open #document deep-links on refresh and surface load errors (#631)
Add a hashchange handler for #document-<id> so refresh / URL-bar nav opens the document, and replace the silent console.error in loadDocument with a user-facing toast. Closes #560
This commit is contained in:
@@ -152,6 +152,8 @@ import * as Modals from './modalManager.js';
|
||||
addDocToTabs,
|
||||
syncDocIndicator: _syncDocIndicator,
|
||||
});
|
||||
_maybeOpenDocFromHash();
|
||||
window.addEventListener('hashchange', _maybeOpenDocFromHash);
|
||||
}
|
||||
|
||||
/** Update overflow-doc-btn accent indicator, toolbar indicator, and session list icon */
|
||||
@@ -5811,16 +5813,31 @@ import * as Modals from './modalManager.js';
|
||||
}
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/api/document/${docId}`);
|
||||
if (!res.ok) throw new Error('Not found');
|
||||
if (!res.ok) throw new Error(res.status === 404 ? 'Not found' : `HTTP ${res.status}`);
|
||||
const doc = await res.json();
|
||||
addDocToTabs(doc, doc.session_id);
|
||||
_ensureDocPaneMounted();
|
||||
switchToDoc(doc.id);
|
||||
} catch (e) {
|
||||
console.error('Failed to load document:', e);
|
||||
if (uiModule) {
|
||||
const msg = e.message === 'Not found'
|
||||
? 'Document not found — try opening it from the Library.'
|
||||
: 'Could not open document.';
|
||||
uiModule.showError(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deep-link: #document-<id> opens that document on load / URL-bar nav.
|
||||
// Clicks on in-chat document anchors are handled separately (they call
|
||||
// preventDefault, so they don't change the hash); this covers refresh
|
||||
// and pasted/typed document URLs, which previously did nothing.
|
||||
function _maybeOpenDocFromHash() {
|
||||
const m = (window.location.hash || '').match(/^#document-(.+)$/);
|
||||
if (m) loadDocument(m[1]);
|
||||
}
|
||||
|
||||
/** Open panel and ensure a document exists, creating a session if needed */
|
||||
export async function ensureDocPanel() {
|
||||
let sessionId = _lastSessionId
|
||||
|
||||
33
tests/test_document_deeplink.py
Normal file
33
tests/test_document_deeplink.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""Regression guards for in-chat document deep-links (#document-<id>).
|
||||
|
||||
The frontend module is browser-coupled (window/fetch/document) so there's
|
||||
no JS unit harness for it — these pin the source-level invariants that the
|
||||
404-silent-failure fix depends on. See issue #560.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
_REPO = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_chat_document_links_use_the_document_id():
|
||||
"""The list/open tool must anchor to the real document id, not a slug —
|
||||
a slug 404s against the UUID-keyed /api/document/<id> route."""
|
||||
src = (_REPO / "src" / "tool_implementations.py").read_text(encoding="utf-8")
|
||||
assert "(#document-{d.id})" in src
|
||||
assert "(#document-{doc.id})" in src
|
||||
|
||||
|
||||
def test_document_deeplink_handled_on_hashchange_and_load():
|
||||
"""#document-<id> in the URL must open the doc on refresh / URL-bar nav,
|
||||
not just on click."""
|
||||
js = (_REPO / "static" / "js" / "document.js").read_text(encoding="utf-8")
|
||||
assert "addEventListener('hashchange', _maybeOpenDocFromHash)" in js
|
||||
assert "#document-" in js
|
||||
|
||||
|
||||
def test_failed_document_load_surfaces_user_error():
|
||||
"""A missing/failed document must tell the user, not fail silently."""
|
||||
js = (_REPO / "static" / "js" / "document.js").read_text(encoding="utf-8")
|
||||
assert "uiModule.showError" in js
|
||||
assert "Document not found" in js
|
||||
Reference in New Issue
Block a user