From 9fefd6856e221e603d351c1a541ac60cf0d475de Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 5 May 2026 19:48:18 +0000 Subject: [PATCH] feat(app): route selected documents into workspace views --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- ts_web/index.ts | 35 +++++++++++++++++++++++++---------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 6385ffa..a10daf1 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "license": "MIT", "dependencies": { "@design.estate/dees-element": "^2.2.4", - "@signature.digital/catalog": "^1.6.0", + "@signature.digital/catalog": "^1.6.1", "@signature.digital/interfaces": "file:../interfaces", "@signature.digital/tools": "file:../tools" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f56a9a1..d8b7714 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^2.2.4 version: 2.2.4 '@signature.digital/catalog': - specifier: ^1.6.0 - version: 1.6.0(@tiptap/pm@2.27.2) + specifier: ^1.6.1 + version: 1.6.1(@tiptap/pm@2.27.2) '@signature.digital/interfaces': specifier: file:../interfaces version: file:../interfaces @@ -1035,8 +1035,8 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@signature.digital/catalog@1.6.0': - resolution: {integrity: sha512-VS940UUIwms4YRP3djJfdxyeBfJDqlBKemp1xHVlfYG3awGhYV2bRKaHMw5wrBQ8m+zvlEmnG5IakQuRwPE/vg==} + '@signature.digital/catalog@1.6.1': + resolution: {integrity: sha512-WER9SO5gYsnYCpcz5+2gP+8ayZMrbQ76oK1hbuO935Yef2Fv6rtyY63W5bB27uhptly4BAD1A3RHGrh3BZMtjg==} '@signature.digital/interfaces@1.2.0': resolution: {integrity: sha512-Aym4CYEJ5TDXshNI/kiBPPjDIkQ+TRXeu5u1d0aVC7aShwHmLj38mWLXHqFnAnQSvpXDRje4vAZML9NTU9Q7sg==} @@ -4512,7 +4512,7 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} - '@signature.digital/catalog@1.6.0(@tiptap/pm@2.27.2)': + '@signature.digital/catalog@1.6.1(@tiptap/pm@2.27.2)': dependencies: '@design.estate/dees-catalog': 3.81.0(@tiptap/pm@2.27.2) '@design.estate/dees-domtools': 2.5.6 diff --git a/ts_web/index.ts b/ts_web/index.ts index add88bd..340f03c 100644 --- a/ts_web/index.ts +++ b/ts_web/index.ts @@ -24,12 +24,18 @@ const appDocuments: TDocumentRow[] = [ const isWorkspaceView = (view: string): view is TWorkspaceView => workspaceViews.includes(view as TWorkspaceView); -const viewFromLocation = (): TWorkspaceView => { - const view = globalThis.location.hash.replace(/^#/, ''); - return isWorkspaceView(view) ? view : 'inbox'; +const routeFromLocation = (): { view: TWorkspaceView; documentId: string } => { + const [view = '', documentId = ''] = globalThis.location.hash.replace(/^#/, '').split(':'); + return { view: isWorkspaceView(view) ? view : 'inbox', documentId }; }; -let currentView = viewFromLocation(); +const hashForRoute = (view: TWorkspaceView, documentId = ''): string => { + return documentId && (view === 'sign' || view === 'audit') ? `#${view}:${documentId}` : `#${view}`; +}; + +let currentRoute = routeFromLocation(); +let currentView = currentRoute.view; +let activeDocumentId = currentRoute.documentId; let appRoot: HTMLElement | null = null; let routeChangeFrame: number | null = null; @@ -44,19 +50,25 @@ const handleViewChange = (event: Event) => { const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; if (!view || !isWorkspaceView(view)) return; currentView = view; - const nextHash = `#${view}`; + const nextHash = hashForRoute(view, activeDocumentId); if (globalThis.location.hash !== nextHash) { - globalThis.location.hash = view; + globalThis.location.hash = nextHash.slice(1); } }; +const handleDocumentOpen = (event: Event) => { + const document = (event as CustomEvent<{ document?: TDocumentRow }>).detail?.document; + if (!document) return; + activeDocumentId = document.id; +}; + const handleWorkspaceViewRequest = (event: Event) => { const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; if (!view || !isWorkspaceView(view)) return; currentView = view; - const nextHash = `#${view}`; + const nextHash = hashForRoute(view, activeDocumentId); if (globalThis.location.hash !== nextHash) { - globalThis.location.hash = view; + globalThis.location.hash = nextHash.slice(1); } else { renderApp(); } @@ -68,7 +80,9 @@ const handleRouteChange = () => { } routeChangeFrame = globalThis.requestAnimationFrame(() => { routeChangeFrame = null; - currentView = viewFromLocation(); + currentRoute = routeFromLocation(); + currentView = currentRoute.view; + activeDocumentId = currentRoute.documentId; renderApp(); }); }; @@ -96,7 +110,7 @@ const renderApp = () => { height: 100vh; } - + `, appRoot! ); @@ -105,6 +119,7 @@ const renderApp = () => { const run = async () => { createAppRoot(); document.body.addEventListener('view-change', handleViewChange); + document.body.addEventListener('document-open', handleDocumentOpen); document.body.addEventListener('workspace-view-request', handleWorkspaceViewRequest); globalThis.addEventListener('popstate', handleRouteChange); globalThis.addEventListener('hashchange', handleRouteChange);