forked from ChaiHao/BPOS-MVP
基线:鉴权会话+工作组+工作台三区修复+编排工作区+产品设计文档
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -1,16 +1,125 @@
|
||||
/**
|
||||
* 编排画布 —— diagram-js 画布件的宿主(编码规范 §6.1「PRD 画布件 1:1 平移」)。
|
||||
*
|
||||
* 原型的 `HostExample.FlowFigureBlock` 同时带手绘编辑器;此处先接**只读态**:
|
||||
* 流程包 → `FlowGraph`(`pkg-to-graph`)→ 布局引擎算几何 → `FlowDiagram` 绘制。
|
||||
* 节点实例落位以角注呈现,几何不因运行态而变——**图是定义,标注是运行**。
|
||||
* `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 { 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,
|
||||
onEditNodeText,
|
||||
onSaveFlowGraph,
|
||||
}: {
|
||||
title: string;
|
||||
oneLiner?: string | undefined;
|
||||
graph: FlowGraph | null;
|
||||
/** 已建立下钻内容的节点 id(删除这些节点时编辑器会二次确认) */
|
||||
drilledIds: string[];
|
||||
positions?: SpPosition[] | undefined;
|
||||
canEdit: boolean;
|
||||
onNodeClick: (nodeId: string) => void;
|
||||
/** 双击流程图活动就地改文字(标题 / 主办) */
|
||||
onEditNodeText?: ((nodeId: string, patch: { label: string; owner?: string }) => Promise<void>) | undefined;
|
||||
/** 手工绘图:整图保存(idMap = 本次编辑会话 原id→现id,宿主用它重键下钻内容) */
|
||||
onSaveFlowGraph?: ((graph: FlowGraph, idMap: Record<string, string>) => Promise<void>) | undefined;
|
||||
}) {
|
||||
const [editing, setEditing] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<div className="view-lbl">
|
||||
流程图 · 顺序
|
||||
{canEdit && onSaveFlowGraph !== undefined && !editing && (
|
||||
<button
|
||||
type="button"
|
||||
className="dc2-addbtn"
|
||||
title="手工绘图(珊格正交:活动/网关/起止/卡点,拖拽连线);画布内工具栏有 取消/保存绘图"
|
||||
onClick={() => setEditing(true)}
|
||||
>
|
||||
<Ico name="pen-line" s={11} /> 编辑
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{editing && onSaveFlowGraph !== undefined ? (
|
||||
<div className="hero">
|
||||
<div className="cap">
|
||||
<span>FIG — {title}流程 · 手工绘图</span>
|
||||
<span>珊格 10px · 直线与直角折线</span>
|
||||
</div>
|
||||
<FlowEditor
|
||||
initial={graph}
|
||||
drilledIds={drilledIds}
|
||||
positions={positions}
|
||||
onSave={async (next, idMap) => {
|
||||
await onSaveFlowGraph(next, idMap);
|
||||
setEditing(false);
|
||||
}}
|
||||
onCancel={() => setEditing(false)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="hero">
|
||||
<div className="cap">
|
||||
<span>FIG — {title}流程</span>
|
||||
<span>{oneLiner ?? '活动 · 网关 · 顺序流'}</span>
|
||||
</div>
|
||||
<div className="fig-body">
|
||||
<FlowDiagram
|
||||
graph={graph}
|
||||
variant="business"
|
||||
onNodeClick={onNodeClick}
|
||||
onEditNode={canEdit ? onEditNodeText : undefined}
|
||||
ownerOptions={positions}
|
||||
ariaLabel={`${title}业务流程图`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 图例贴在流程图正下方,图标与绘图工具(元素盘)同款 SVG */}
|
||||
<div className="legend">
|
||||
<span>
|
||||
<b>图例</b>
|
||||
</span>
|
||||
<span><i className="lg-i fe-pi-start" aria-hidden /> 起始</span>
|
||||
<span><i className="lg-i fe-pi-end" aria-hidden /> 结束</span>
|
||||
<span><i className="lg-i fe-pi-sop" aria-hidden /> 标准活动</span>
|
||||
<span><i className="lg-i fe-pi-case" aria-hidden /> 案例活动</span>
|
||||
<span><i className="lg-i fe-pi-approval" aria-hidden /> 审批点</span>
|
||||
<span><i className="lg-i fe-pi-gwx" aria-hidden /> 判断网关</span>
|
||||
<span><i className="lg-i fe-pi-gwand" aria-hidden /> 并行网关</span>
|
||||
<span><i className="lg-i fe-pi-callout" aria-hidden /> 卡点</span>
|
||||
<span><i className="lg-i lg-flow" aria-hidden /> 顺序流</span>
|
||||
<span className="sep">|</span>
|
||||
<span>
|
||||
<b>责任</b>
|
||||
</span>
|
||||
<span>右上角标 责任人</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/** 只读壳:流程包 → 图 → 画(任务页 / 工作流实例页用) */
|
||||
export function FlowFigure({
|
||||
pkg,
|
||||
instances,
|
||||
|
||||
Reference in New Issue
Block a user