/** * 编排画布 —— diagram-js 画布件的宿主(编码规范 §6.1「PRD 画布件 1:1 平移」)。 * * `FlowFigureBlock` 自原型 `HostExample` 平移:区块小标题右侧「编辑」芯片进手绘编辑器 * (FlowEditor,画布内工具栏含 取消/保存绘图);展示态 hero/cap 框 + FlowDiagram * (单击节点下钻/选中、双击活动就地改文字);图例贴在流程图正下方。 * 必须包在 `.process-desk > .process-doc` 纸面容器内(flow-canvas.css 规则 scoped 到它)。 * * `FlowFigure` 保留为只读便捷壳(任务页的流程图用它)。 */ import { useState } from 'react'; import type { ProcessPackage } from '@contracts'; import { Ico } from '@ui'; import { FlowDiagram } from './FlowDiagram.tsx'; import { FlowEditor } from './FlowEditor.tsx'; import type { FlowEdge, FlowGraph } from './flow-layout.ts'; import type { SpPosition } from './support.tsx'; import { packageToGraph } from './pkg-to-graph.ts'; import type { InstanceMark } from './pkg-to-graph.ts'; import './flow-canvas.css'; export function FlowFigureBlock({ title, oneLiner, graph, drilledIds, positions, canEdit, onNodeClick, onEdgeClick, onEditNodeText, onSaveFlowGraph, }: { title: string; oneLiner?: string | undefined; graph: FlowGraph | null; /** 已建立下钻内容的节点 id(删除这些节点时编辑器会二次确认) */ drilledIds: string[]; positions?: SpPosition[] | undefined; canEdit: boolean; onNodeClick: (nodeId: string) => void; /** 点击连线选中边(属性卡随之切到该边);不传则边不可点 */ onEdgeClick?: ((edge: FlowEdge) => void) | undefined; /** 双击流程图活动就地改文字(标题 / 主办) */ onEditNodeText?: ((nodeId: string, patch: { label: string; owner?: string }) => Promise) | undefined; /** 手工绘图:整图保存(idMap = 本次编辑会话 原id→现id,宿主用它重键下钻内容) */ onSaveFlowGraph?: ((graph: FlowGraph, idMap: Record) => Promise) | undefined; }) { const [editing, setEditing] = useState(false); return ( <>
流程图 · 顺序 {canEdit && onSaveFlowGraph !== undefined && !editing && ( )}
{editing && onSaveFlowGraph !== undefined ? (
FIG — {title}流程 · 手工绘图 珊格 10px · 直线与直角折线
{ await onSaveFlowGraph(next, idMap); setEditing(false); }} onCancel={() => setEditing(false)} />
) : (
FIG — {title}流程 {oneLiner ?? '活动 · 网关 · 顺序流'}
)} {/* 图例贴在流程图正下方,图标与绘图工具(元素盘)同款 SVG */}
图例 起始 结束 {/* 节点只分活动点/审批点 —— 标准/案例是实现方式,不进编排面的词汇表 */} 活动点 审批点 顺序流 | 责任 右上角标 责任人
); } /** 只读壳:流程包 → 图 → 画(任务页 / 工作流实例页用) */ export function FlowFigure({ pkg, instances, onNodeClick, }: { pkg: ProcessPackage; instances: readonly InstanceMark[]; onNodeClick?: (nodeId: string) => void; }) { const graph = packageToGraph(pkg, instances); return (
); }