feat(app): route selected documents into workspace views

This commit is contained in:
2026-05-05 19:48:18 +00:00
parent 4cb9d4a394
commit 9fefd6856e
3 changed files with 31 additions and 16 deletions
+1 -1
View File
@@ -16,7 +16,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-element": "^2.2.4", "@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/interfaces": "file:../interfaces",
"@signature.digital/tools": "file:../tools" "@signature.digital/tools": "file:../tools"
}, },
+5 -5
View File
@@ -12,8 +12,8 @@ importers:
specifier: ^2.2.4 specifier: ^2.2.4
version: 2.2.4 version: 2.2.4
'@signature.digital/catalog': '@signature.digital/catalog':
specifier: ^1.6.0 specifier: ^1.6.1
version: 1.6.0(@tiptap/pm@2.27.2) version: 1.6.1(@tiptap/pm@2.27.2)
'@signature.digital/interfaces': '@signature.digital/interfaces':
specifier: file:../interfaces specifier: file:../interfaces
version: file:../interfaces version: file:../interfaces
@@ -1035,8 +1035,8 @@ packages:
'@sec-ant/readable-stream@0.4.1': '@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
'@signature.digital/catalog@1.6.0': '@signature.digital/catalog@1.6.1':
resolution: {integrity: sha512-VS940UUIwms4YRP3djJfdxyeBfJDqlBKemp1xHVlfYG3awGhYV2bRKaHMw5wrBQ8m+zvlEmnG5IakQuRwPE/vg==} resolution: {integrity: sha512-WER9SO5gYsnYCpcz5+2gP+8ayZMrbQ76oK1hbuO935Yef2Fv6rtyY63W5bB27uhptly4BAD1A3RHGrh3BZMtjg==}
'@signature.digital/interfaces@1.2.0': '@signature.digital/interfaces@1.2.0':
resolution: {integrity: sha512-Aym4CYEJ5TDXshNI/kiBPPjDIkQ+TRXeu5u1d0aVC7aShwHmLj38mWLXHqFnAnQSvpXDRje4vAZML9NTU9Q7sg==} resolution: {integrity: sha512-Aym4CYEJ5TDXshNI/kiBPPjDIkQ+TRXeu5u1d0aVC7aShwHmLj38mWLXHqFnAnQSvpXDRje4vAZML9NTU9Q7sg==}
@@ -4512,7 +4512,7 @@ snapshots:
'@sec-ant/readable-stream@0.4.1': {} '@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: dependencies:
'@design.estate/dees-catalog': 3.81.0(@tiptap/pm@2.27.2) '@design.estate/dees-catalog': 3.81.0(@tiptap/pm@2.27.2)
'@design.estate/dees-domtools': 2.5.6 '@design.estate/dees-domtools': 2.5.6
+25 -10
View File
@@ -24,12 +24,18 @@ const appDocuments: TDocumentRow[] = [
const isWorkspaceView = (view: string): view is TWorkspaceView => workspaceViews.includes(view as TWorkspaceView); const isWorkspaceView = (view: string): view is TWorkspaceView => workspaceViews.includes(view as TWorkspaceView);
const viewFromLocation = (): TWorkspaceView => { const routeFromLocation = (): { view: TWorkspaceView; documentId: string } => {
const view = globalThis.location.hash.replace(/^#/, ''); const [view = '', documentId = ''] = globalThis.location.hash.replace(/^#/, '').split(':');
return isWorkspaceView(view) ? view : 'inbox'; 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 appRoot: HTMLElement | null = null;
let routeChangeFrame: number | null = null; let routeChangeFrame: number | null = null;
@@ -44,19 +50,25 @@ const handleViewChange = (event: Event) => {
const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view;
if (!view || !isWorkspaceView(view)) return; if (!view || !isWorkspaceView(view)) return;
currentView = view; currentView = view;
const nextHash = `#${view}`; const nextHash = hashForRoute(view, activeDocumentId);
if (globalThis.location.hash !== nextHash) { 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 handleWorkspaceViewRequest = (event: Event) => {
const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view;
if (!view || !isWorkspaceView(view)) return; if (!view || !isWorkspaceView(view)) return;
currentView = view; currentView = view;
const nextHash = `#${view}`; const nextHash = hashForRoute(view, activeDocumentId);
if (globalThis.location.hash !== nextHash) { if (globalThis.location.hash !== nextHash) {
globalThis.location.hash = view; globalThis.location.hash = nextHash.slice(1);
} else { } else {
renderApp(); renderApp();
} }
@@ -68,7 +80,9 @@ const handleRouteChange = () => {
} }
routeChangeFrame = globalThis.requestAnimationFrame(() => { routeChangeFrame = globalThis.requestAnimationFrame(() => {
routeChangeFrame = null; routeChangeFrame = null;
currentView = viewFromLocation(); currentRoute = routeFromLocation();
currentView = currentRoute.view;
activeDocumentId = currentRoute.documentId;
renderApp(); renderApp();
}); });
}; };
@@ -96,7 +110,7 @@ const renderApp = () => {
height: 100vh; height: 100vh;
} }
</style> </style>
<sdig-workspace accent="#3b82f6" density="comfortable" theme="dark" initialView=${currentView} .initialView=${currentView} view=${currentView} .view=${currentView} .documents=${appDocuments}></sdig-workspace> <sdig-workspace accent="#3b82f6" density="comfortable" theme="dark" initialView=${currentView} .initialView=${currentView} view=${currentView} .view=${currentView} activeDocumentId=${activeDocumentId} .activeDocumentId=${activeDocumentId} .documents=${appDocuments}></sdig-workspace>
`, `,
appRoot! appRoot!
); );
@@ -105,6 +119,7 @@ const renderApp = () => {
const run = async () => { const run = async () => {
createAppRoot(); createAppRoot();
document.body.addEventListener('view-change', handleViewChange); document.body.addEventListener('view-change', handleViewChange);
document.body.addEventListener('document-open', handleDocumentOpen);
document.body.addEventListener('workspace-view-request', handleWorkspaceViewRequest); document.body.addEventListener('workspace-view-request', handleWorkspaceViewRequest);
globalThis.addEventListener('popstate', handleRouteChange); globalThis.addEventListener('popstate', handleRouteChange);
globalThis.addEventListener('hashchange', handleRouteChange); globalThis.addEventListener('hashchange', handleRouteChange);