import { DeesElement, property, html, customElement, type TemplateResult, css } from '@design.estate/dees-element'; import { demoDocuments, demoFields, demoRecipients, icon, type IDocumentRow, type IFieldPlacement, type IRecipient, type TDensity, type TWorkspaceTheme, type TWorkspaceView } from './sdig-workspace.shared.js'; import './sdig-workspace-inbox.js'; import './sdig-workspace-compose.js'; import './sdig-workspace-sign.js'; import './sdig-workspace-audit.js'; import './sdig-workspace-developers.js'; import './sdig-workspace-placeholder.js'; declare global { interface HTMLElementTagNameMap { 'sdig-workspace': SdigWorkspace; } } @customElement('sdig-workspace') export class SdigWorkspace extends DeesElement { public static demo = () => html``; public static demoGroups = ['Signature Digital Workspace']; @property({ type: String }) public accessor accent: string = '#3b82f6'; @property({ type: String }) public accessor density: TDensity = 'comfortable'; @property({ type: String, reflect: true }) public accessor theme: TWorkspaceTheme = 'dark'; @property({ type: String }) public accessor initialView: TWorkspaceView = 'inbox'; @property({ type: String, reflect: true }) public accessor view: TWorkspaceView = 'inbox'; @property({ attribute: false }) public accessor documents: IDocumentRow[] = demoDocuments; @property({ type: String }) public accessor activeDocumentId: string = ''; @property({ attribute: false }) public accessor recipients: IRecipient[] = demoRecipients; @property({ attribute: false }) public accessor fields: IFieldPlacement[] = demoFields; public connectedCallback = async () => { await super.connectedCallback(); if (this.view === 'inbox' && this.initialView !== 'inbox') { this.view = this.initialView; } this.addEventListener('workspace-view-request', this.handleViewRequest as EventListener); }; public disconnectedCallback = async () => { this.removeEventListener('workspace-view-request', this.handleViewRequest as EventListener); await super.disconnectedCallback(); }; public static styles = css` :host { display: block; width: 100%; height: 100%; min-height: 720px; --accent: #3b82f6; --bg: hsl(0 0% 3.9%); --bg-el: hsl(0 0% 6%); --bg-card: hsl(0 0% 7%); --bg-input: hsl(0 0% 9%); --border: hsl(0 0% 14.9%); --border-subtle: hsl(0 0% 11%); --border-strong: hsl(0 0% 20%); --text: hsl(0 0% 98%); --text-sec: hsl(0 0% 63.9%); --text-muted: hsl(0 0% 48%); --text-dim: hsl(0 0% 32%); --hover: rgba(255,255,255,0.06); --hover-subtle: rgba(255,255,255,0.03); --row-hover: rgba(255,255,255,0.025); --success: #22c55e; --warning: #f59e0b; --error: #ef4444; font-family: Geist, Inter, Roboto, -apple-system, BlinkMacSystemFont, sans-serif; } :host([theme='light']) { --bg: hsl(0 0% 99%); --bg-el: hsl(0 0% 97%); --bg-card: hsl(0 0% 100%); --bg-input: hsl(0 0% 98%); --border: hsl(0 0% 90%); --border-subtle: hsl(0 0% 93%); --border-strong: hsl(0 0% 80%); --text: hsl(0 0% 9%); --text-sec: hsl(0 0% 32%); --text-muted: hsl(0 0% 45%); --text-dim: hsl(0 0% 62%); --hover: rgba(0,0,0,0.04); --hover-subtle: rgba(0,0,0,0.02); --row-hover: rgba(0,0,0,0.02); --success: #16a34a; --warning: #d97706; --error: #dc2626; } * { box-sizing: border-box; } button { font: inherit; border: 0; cursor: pointer; } .workspace { display: flex; height: 100%; min-height: 720px; background: var(--bg); color: var(--text); overflow: hidden; } .sidebar { width: 220px; background: var(--bg); border-right: 1px solid var(--border-subtle); display: flex; flex-direction: column; flex-shrink: 0; height: 100%; } .brand { padding: 14px 16px 12px; display: flex; align-items: center; gap: 8px; } .logomark { width: 26px; height: 26px; border-radius: 6px; background: var(--bg-el); border: 1px solid var(--border-strong); display: inline-flex; align-items: center; justify-content: center; font-family: 'Plus Jakarta Sans', Inter, sans-serif; font-size: 13px; font-weight: 700; position: relative; } .logomark::after, .wordmark::after { content: ''; display: inline-block; border-radius: 50%; background: var(--accent); } .logomark::after { width: 4px; height: 4px; position: absolute; right: 5px; bottom: 5px; } .wordmark { font-size: 13px; font-weight: 500; letter-spacing: -0.02em; white-space: nowrap; } .wordmark .dot { color: var(--text-muted); } .wordmark::after { width: 4px; height: 4px; margin-left: 3px; transform: translateY(-1px); } .workspace-card { margin: 0 12px 8px; padding: 7px 10px; background: var(--bg-el); border: 1px solid var(--border-subtle); border-radius: 6px; display: flex; align-items: center; gap: 8px; } .workspace-badge { width: 18px; height: 18px; border-radius: 4px; background: linear-gradient(135deg, var(--accent), hsl(280 70% 60%)); color: white; font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center; } .workspace-name { font-size: 12px; font-weight: 500; line-height: 1.2; } .workspace-plan { font-size: 10px; color: var(--text-muted); } .nav-block { padding: 4px 0; } .nav-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; margin: 1px 8px; border-radius: 6px; color: var(--text-muted); background: transparent; transition: all 0.1s ease; font-size: 13px; position: relative; width: calc(100% - 16px); text-align: left; } .compact .nav-item { padding: 5px 10px; } .nav-item:hover { background: var(--hover-subtle); color: var(--text-sec); } .nav-item.active { background: var(--hover); color: var(--text); font-weight: 500; } .nav-item.active::before { content: ''; position: absolute; left: -8px; width: 2px; height: 14px; border-radius: 2px; background: var(--accent); } .nav-count { margin-left: auto; min-width: 18px; padding: 1px 6px; border-radius: 999px; background: var(--bg-el); color: var(--text-muted); font-size: 10px; text-align: center; } .github-card { margin: 8px 12px; padding: 10px; border: 1px solid var(--border-subtle); border-radius: 6px; background: var(--bg-el); } .sparkline { margin-top: 8px; display: flex; gap: 2px; align-items: flex-end; height: 18px; } .sparkline span { flex: 1; background: var(--border-strong); border-radius: 1px; } .sparkline span:nth-last-child(-n+4) { background: var(--accent); } .user-card { padding: 8px 12px; border-top: 1px solid var(--border-subtle); display: flex; align-items: center; gap: 10px; } .avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--accent); color: white; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; } .main { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; } .view-host { flex: 1; min-height: 0; display: flex; flex-direction: column; } .statusbar { height: 24px; flex-shrink: 0; border-top: 1px solid var(--border-subtle); background: var(--bg); display: flex; align-items: center; padding: 0 16px; gap: 16px; font-size: 10px; color: var(--text-dim); font-family: 'Intel One Mono', ui-monospace, SFMono-Regular, Menlo, monospace; } @media (max-width: 920px) { .workspace { flex-direction: column; min-height: 100vh; } .sidebar { width: 100%; height: auto; border-right: 0; border-bottom: 1px solid var(--border-subtle); } .brand, .workspace-card, .github-card, .user-card { display: none; } .nav-block { display: flex; overflow-x: auto; padding: 8px; } .nav-item { width: auto; margin: 0 2px; } .statusbar { display: none; } } `; private handleViewRequest = (event: CustomEvent<{ view: TWorkspaceView }>) => { this.setView(event.detail.view); }; private setView(viewArg: TWorkspaceView) { this.view = viewArg; this.dispatchEvent(new CustomEvent('view-change', { detail: { view: viewArg }, bubbles: true, composed: true })); } private navButton(item: { id: TWorkspaceView; label: string; icon: string; count?: number }): TemplateResult { return html``; } private renderSidebar(): TemplateResult { const navItems = [ { id: 'inbox', label: 'Inbox', icon: 'inbox', count: this.documents.length }, { id: 'compose', label: 'Compose', icon: 'plus' }, { id: 'templates', label: 'Templates', icon: 'folder', count: 12 }, { id: 'audit', label: 'Audit Trail', icon: 'shield' }, { id: 'developers', label: 'Developers', icon: 'code' }, ] as Array<{ id: TWorkspaceView; label: string; icon: string; count?: number }>; const lowerItems = [ { id: 'team', label: 'Team', icon: 'user' }, { id: 'settings', label: 'Settings', icon: 'settings' }, ] as Array<{ id: TWorkspaceView; label: string; icon: string }>; return html` `; } private renderView(): TemplateResult { const activeDocument = this.documents.find((document) => document.id === this.activeDocumentId) || this.documents[0] || demoDocuments[0]; switch (this.view) { case 'inbox': return html``; case 'compose': return html``; case 'sign': return html``; case 'audit': return html``; case 'developers': return html``; case 'templates': return html``; case 'team': return html``; case 'settings': return html``; default: return html``; } } public render(): TemplateResult { return html`
${this.renderSidebar()}
${this.renderView()}
api.signature.digitaleu-central-14 sigs queued
Open Source · MITv0.42.1${icon('git', 11)} main
`; } }