REAL SHOWCASE SOURCEtabbed-workspace-clinical
2 个文件 · 127 行 · TypeScript
// ===== showcase/src/examples/components/tabbed_workspace.ts ===== import { RenderButton, RenderPageHeader, RenderStackPanel, RenderTabbedWorkspace, RenderText, RenderWrapPanel, TabbedDocumentManager,} from 'ds-ui'import { createClinicalWorkspaceDocument } from './workspace_shared' export function createTabbedWorkspaceExample(): RenderStackPanel { const manager = new TabbedDocumentManager() const status = new RenderText('', { role: 'secondary' }) const workspace = new RenderTabbedWorkspace({ manager, emptyTitle: '暂无打开的临床模块', emptyDescription: '使用上方按钮打开患者总览、医嘱录入或检验结果。', disposeManagerOnDispose: true, }) const openDocument = (key: 'overview' | 'orders' | 'labs'): void => { const definitions = { overview: { tabId: 'patient-overview', title: '患者总览', icon: 'window' as const, content: createClinicalWorkspaceDocument('患者总览', '集中查看生命体征、诊断和当前治疗计划。'), }, orders: { tabId: 'medical-orders', title: '医嘱录入', icon: 'plus' as const, dirty: true, content: createClinicalWorkspaceDocument('医嘱录入', '未保存文档会在标签标题中显示 dirty 状态。', 'warning'), }, labs: { tabId: 'lab-results', title: '检验结果', icon: 'search' as const, content: createClinicalWorkspaceDocument('检验结果', '查看最近检验数据和危急值处理状态。', 'success'), }, } const definition = definitions[key] if (manager.hasDocument(definition.tabId)) manager.activateDocument(definition.tabId) else manager.openDocument(definition) } manager.subscribe(() => { status.text = `已打开 ${manager.documents.length} 个文档;当前:${manager.activeDocument?.title ?? '无'}。` }) openDocument('overview') openDocument('orders') openDocument('labs') const actions = new RenderWrapPanel({ spacing: 8, runSpacing: 8 }) actions.addChild(new RenderButton({ label: '患者总览', onClick: () => openDocument('overview') })) actions.addChild(new RenderButton({ label: '医嘱录入', onClick: () => openDocument('orders') })) actions.addChild(new RenderButton({ label: '检验结果', onClick: () => openDocument('labs') })) actions.addChild(new RenderButton({ label: '下一个文档', onClick: () => manager.activateRelativeDocument(1), })) actions.addChild(new RenderButton({ label: '保存当前', variant: 'primary', onClick: () => { const active = manager.activeDocument if (active) manager.updateDocument(active.tabId, { dirty: false }) }, })) actions.addChild(new RenderButton({ label: '关闭当前', onClick: () => { void manager.closeActiveDocument() }, })) const panel = new RenderStackPanel({ orientation: 'vertical', spacing: 12, crossAxisAlignment: 'stretch' }) panel.addChild(new RenderPageHeader({ title: 'TabbedWorkspace 多文档临床工作区', description: '管理文档打开、去重、激活、重排、dirty 状态、关闭保护和 Ctrl+Tab/Ctrl+W。', })) panel.addChild(actions) panel.addChild(status) panel.addChild(workspace, 1) panel.padding = 18 return panel} // ===== showcase/src/examples/components/workspace_shared.ts ===== import { RenderBadge, RenderBorder, RenderStackPanel, RenderText,} from 'ds-ui' export function createClinicalWorkspaceDocument( title: string, description: string, status: 'primary' | 'success' | 'warning' | 'danger' = 'primary',): RenderStackPanel { const heading = new RenderStackPanel({ orientation: 'horizontal', spacing: 10, crossAxisAlignment: 'center' }) heading.addChild(new RenderBadge({ value: 'LIVE', status, compact: true })) heading.addChild(new RenderText(title, { role: 'title', size: 'large', weight: 'semibold' })) const metrics = new RenderStackPanel({ orientation: 'horizontal', spacing: 12, crossAxisAlignment: 'stretch' }) metrics.addChild(createMetric('患者', '李安然'), 1) metrics.addChild(createMetric('就诊号', 'MZ20260717018'), 1) metrics.addChild(createMetric('接诊医生', '林医生'), 1) const panel = new RenderStackPanel({ orientation: 'vertical', spacing: 14, crossAxisAlignment: 'stretch' }) panel.addChild(heading) panel.addChild(new RenderText(description, { role: 'secondary' })) panel.addChild(metrics) panel.padding = 18 return panel} function createMetric(label: string, value: string): RenderBorder { const content = new RenderStackPanel({ orientation: 'vertical', spacing: 4 }) content.addChild(new RenderText(label, { role: 'secondary', size: 'small' })) content.addChild(new RenderText(value, { role: 'title', weight: 'semibold' })) return new RenderBorder({ background: 'panel', padding: 12, child: content })}