import '@signature.digital/catalog'; import { html, render } from '@design.estate/dees-element'; import { appDocuments, appRecipients, documentIdOrDefault, fieldsForDocument, hashForRoute, isWorkspaceView, routeFromLocation, setAppRecipients, setFieldsForDocument, type IAppDocumentRow, type IAppFieldPlacement, type IAppRecipient, type TWorkspaceView } from './state.js'; let currentRoute = routeFromLocation(); let currentView = currentRoute.view; let activeDocumentId = currentRoute.documentId ? documentIdOrDefault(currentRoute.documentId) : ''; let appRoot: HTMLElement | null = null; let routeChangeFrame: number | null = null; const createAppRoot = () => { document.getElementById('signature-digital-app')?.remove(); appRoot = document.createElement('div'); appRoot.id = 'signature-digital-app'; document.body.append(appRoot); }; const handleViewChange = (event: Event) => { const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; if (!view || !isWorkspaceView(view)) return; currentView = view; const nextHash = hashForRoute(view, activeDocumentId); if (globalThis.location.hash !== nextHash) { globalThis.location.hash = nextHash.slice(1); } }; const handleDocumentOpen = (event: Event) => { const document = (event as CustomEvent<{ document?: IAppDocumentRow }>).detail?.document; if (!document) return; activeDocumentId = document.id; }; const handleFieldsChange = (event: Event) => { if (!activeDocumentId) return; const fields = (event as CustomEvent<{ fields?: IAppFieldPlacement[] }>).detail?.fields; if (!fields) return; setFieldsForDocument(activeDocumentId, fields); }; const handleRecipientsChange = (event: Event) => { const recipients = (event as CustomEvent<{ recipients?: IAppRecipient[] }>).detail?.recipients; if (!recipients) return; setAppRecipients(recipients); }; const handleWorkspaceViewRequest = (event: Event) => { const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view; if (!view || !isWorkspaceView(view)) return; currentView = view; const nextHash = hashForRoute(view, activeDocumentId); if (globalThis.location.hash !== nextHash) { globalThis.location.hash = nextHash.slice(1); } else { renderApp(); } }; const handleRouteChange = () => { if (routeChangeFrame !== null) { globalThis.cancelAnimationFrame(routeChangeFrame); } routeChangeFrame = globalThis.requestAnimationFrame(() => { routeChangeFrame = null; currentRoute = routeFromLocation(); currentView = currentRoute.view; activeDocumentId = currentRoute.documentId ? documentIdOrDefault(currentRoute.documentId) : ''; renderApp(); }); }; const renderApp = () => { if (!appRoot) createAppRoot(); const documentId = activeDocumentId || appDocuments[0].id; render( html` `, appRoot! ); }; const run = async () => { createAppRoot(); document.body.addEventListener('view-change', handleViewChange); document.body.addEventListener('document-open', handleDocumentOpen); document.body.addEventListener('fields-change', handleFieldsChange); document.body.addEventListener('recipients-change', handleRecipientsChange); document.body.addEventListener('routing-change', handleRecipientsChange); document.body.addEventListener('workspace-view-request', handleWorkspaceViewRequest); globalThis.addEventListener('popstate', handleRouteChange); globalThis.addEventListener('hashchange', handleRouteChange); renderApp(); }; run();