From 86ea3cf9c1719d74d9aa81c70232f297e73211d2 Mon Sep 17 00:00:00 2001 From: jiangchu Date: Thu, 23 Nov 2023 16:13:27 +0800 Subject: [PATCH] :memo: feat: yuyan pipeline demo --- docs/useDocs/baseInrro.md | 16 +- docs/useDocs/demos/CoreNode.tsx | 5 +- docs/useDocs/demos/index.less | 109 ++++++++++ docs/useDocs/demos/pipelineDemo.tsx | 318 ++++++++++++++++++++++++++++ docs/useDocs/pipleLineDemo.md | 10 + src/FlowView/helper.tsx | 2 + src/constants.tsx | 1 + 7 files changed, 458 insertions(+), 3 deletions(-) create mode 100644 docs/useDocs/demos/index.less create mode 100644 docs/useDocs/demos/pipelineDemo.tsx create mode 100644 docs/useDocs/pipleLineDemo.md diff --git a/docs/useDocs/baseInrro.md b/docs/useDocs/baseInrro.md index 208cddb..7db97f6 100644 --- a/docs/useDocs/baseInrro.md +++ b/docs/useDocs/baseInrro.md @@ -25,12 +25,24 @@ ProFlow 中的节点是一个 React 组件。这意味着它可以渲染您喜 `Handle` 可以翻译为 “**句柄**” 或者 “**端口**”,是边缘连接到节点的位置。`Handle`可以放置在任何地方。 -可以用 `import { FlowView, Handle, Position } from '@ant-design/pro-flow';` 的方式引入 `Handle` 与 `Position`。来自定义 `Handle` 在节点中的位置。 +可以用以下方式式引入 `Handle` 与 `Position`,来自定义 `Handle` 在节点中的位置。 + +```ts +import { Handle, type Position } from '@ant-design/pro-flow'; +``` ### Edges -一条 Edge 连接两个节点。每个边缘都需要一个`source` 和 一个`target`。 ProFlow 内置了 'straight', 'step','smoothstep','bezier','radius' 五种边缘类型。FlowView 组件把 'smoothstep' 设置为默认类型。 你也可以自定义边缘类型。 +一条 Edge 连接两个节点。每个边缘都需要一个`source` 和 一个`target`。 ProFlow 内置了五种边缘类型: + +- 'straight' +- 'step' + -'smoothstep' + -'bezier' +- 'radius' 。 + +FlowView 把 `smoothstep` 设置为默认类型。 你也可以自定义边缘类型。 diff --git a/docs/useDocs/demos/CoreNode.tsx b/docs/useDocs/demos/CoreNode.tsx index c467844..0e95a9c 100644 --- a/docs/useDocs/demos/CoreNode.tsx +++ b/docs/useDocs/demos/CoreNode.tsx @@ -1,3 +1,6 @@ +/** + * compact: true + */ import { FlowView } from '@ant-design/pro-flow'; import styled from 'styled-components'; @@ -23,6 +26,6 @@ function App() { export default App; const Container = styled.div` - width: 800px; + width: 100%; height: 300px; `; diff --git a/docs/useDocs/demos/index.less b/docs/useDocs/demos/index.less new file mode 100644 index 0000000..fd0dad1 --- /dev/null +++ b/docs/useDocs/demos/index.less @@ -0,0 +1,109 @@ +.pipeNodeWrap { + width: 260px; + min-height: 100px; + background-color: #f6f8fa; + padding: 16px; + box-sizing: border-box; + border-radius: 8px; + + .handle { + top: 0; + } + + .stepTitle { + overflow: hidden; + color: #8c8c8c; + white-space: nowrap; + text-overflow: ellipsis; + } + .pipeNode { + margin-top: 10px; + width: 232px; + box-sizing: border-box; + border: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 8px; + + .mainBox { + width: 100%; + padding: 12px; + height: 70px; + background-color: white; + display: flex; + border-bottom: none; + border-radius: 8px; + box-sizing: border-box; + .logo { + img { + width: 16px; + height: 16px; + margin-top: 4px; + } + } + .wrap { + margin-left: 8px; + display: flex; + flex-direction: column; + .title { + color: #000; + font-weight: 500; + font-size: 14px; + line-height: 22px; + white-space: nowrap; + } + .des { + margin-top: 8px; + color: #00000073; + font-size: 12px; + } + } + } + } + + .children { + display: flex; + flex-direction: column; + align-items: center; + padding-bottom: 10px; + + .childrenBox { + width: 200px; + padding: 12px; + height: 70px; + background-color: white; + display: flex; + border: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 8px; + box-sizing: border-box; + margin-top: 10px; + + .logo { + img { + width: 16px; + height: 16px; + margin-top: 4px; + } + } + .wrap { + margin-left: 8px; + display: flex; + flex-direction: column; + .title { + color: #000; + font-weight: 500; + font-size: 14px; + line-height: 22px; + white-space: nowrap; + } + .des { + margin-top: 8px; + color: #00000073; + font-size: 12px; + } + } + } + } +} +.container { + width: 100%; + height: 600px; +} diff --git a/docs/useDocs/demos/pipelineDemo.tsx b/docs/useDocs/demos/pipelineDemo.tsx new file mode 100644 index 0000000..592c157 --- /dev/null +++ b/docs/useDocs/demos/pipelineDemo.tsx @@ -0,0 +1,318 @@ +/** + * compact: true + */ +import { + Background, + FlowView, + FlowViewProvider, + Handle, + Position, + useFlowViewer, +} from '@ant-design/pro-flow'; +import { FC, useCallback } from 'react'; +import { SelectType } from '../../../src'; +import './index.less'; + +interface PipeNodeChild { + title: string; + des: string; + logo: string; +} + +interface PipeNode { + stepTitle: string; + title: string; + des: string; + logo: string; + needSwitch?: boolean; + open?: boolean; + children?: PipeNodeChild[]; + selectType?: SelectType; +} + +const nodeWidth = 170; +const nodeHeight = 500; + +const PipeNode: FC<{ + data: PipeNode; +}> = ({ data }) => { + const { + stepTitle, + title, + des, + logo, + needSwitch = false, + open = false, + children = [], + selectType, + } = data; + + return ( +
+ +
{stepTitle}
+
+
+
+ +
+
+
{title}
+
{des}
+
+ {needSwitch && ( +
+
+
+
+
+ )} +
+ {children.length > 0 && ( +
+ {children.map((item, index) => ( +
+
+ +
+
+
{item.title}
+
{item.des}
+
+
+ ))} +
+ )} +
+ +
+ ); +}; + +const nodeTypes = { pipeNode: PipeNode }; + +const nodes = [ + { + id: 'a1', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 1: 部署平台 tnpmregistry@...', + title: 'tnpmregistry@DEFAULT ...', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '34秒', + needSwitch: true, + open: true, + children: [ + { + title: '参数初始化', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + { + title: 'NPM 组件初始化', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '30秒', + }, + { + title: '同步成员(仅子组件生...', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '0秒', + }, + { + title: '注册部署平台', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '0秒', + }, + ], + }, + }, + { + id: 'a2', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 2: 部署平台 hitu@DEFAULT ...', + title: 'hitu@DEFAULT 初始化', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '2秒', + needSwitch: true, + open: true, + children: [ + { + title: '初始化海图组件', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + { + title: '注册部署平台', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '0秒', + }, + ], + }, + }, + { + id: 'a3', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 3: 三方关联初始化', + title: '监控初始化', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + }, + { + id: 'a4', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 4: 准备组件仓库初始化', + title: '重命名 name', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + }, + { + id: 'a5', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 5: 代码初始化', + title: '仓库初始化', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*7gzVQJ63mfEAAAAAAAAAAAAADvl6AQ/original', + des: '6秒', + needSwitch: true, + open: true, + children: [ + { + title: '创建仓库', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '3秒', + }, + { + title: '接触分支保护', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*sko9RoPu-HgAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + { + title: '初始化代码模板', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*7gzVQJ63mfEAAAAAAAAAAAAADvl6AQ/original', + des: '1秒', + }, + { + title: '创建代码基线', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*Em_PQoTrMDgAAAAAAAAAAAAADvl6AQ/original', + des: '未开始', + }, + ], + }, + }, + { + id: 'a6', + type: 'pipeNode', + width: nodeWidth, + height: nodeHeight, + data: { + stepTitle: '阶段 6: 仓库权限同步', + title: '同步至埋点平台', + logo: 'https://mdn.alipayobjects.com/huamei_d2ejos/afts/img/A*Em_PQoTrMDgAAAAAAAAAAAAADvl6AQ/original', + des: '未开始', + }, + }, +]; + +const edges = [ + { + id: 'e1', + source: 'a1', + target: 'a2', + animated: true, + }, + { + id: 'e2', + source: 'a2', + target: 'a3', + animated: true, + }, + { + id: 'e3', + source: 'a3', + target: 'a4', + animated: true, + }, + { + id: 'e4', + source: 'a4', + target: 'a5', + animated: true, + }, + { + id: 'e5', + source: 'a5', + target: 'a6', + animated: true, + }, +]; + +function App() { + const flowViewer = useFlowViewer(); + + const handleClick = useCallback( + (e, n) => { + flowViewer?.zoomToNode(n.id, 1000); + }, + [flowViewer], + ); + + const handlePaneClick = useCallback(() => { + // flowViewer?.zoomToNode(n.id, 1000); + }, [flowViewer]); + + return ( +
+ + + +
+ ); +} + +function ProApp() { + return ( + + + + ); +} + +export default ProApp; diff --git a/docs/useDocs/pipleLineDemo.md b/docs/useDocs/pipleLineDemo.md new file mode 100644 index 0000000..2e03487 --- /dev/null +++ b/docs/useDocs/pipleLineDemo.md @@ -0,0 +1,10 @@ +--- +nav: 使用文档 +group: + title: 案例展示 + order: 10 +title: 雨燕 PipeLine +description: +--- + + diff --git a/src/FlowView/helper.tsx b/src/FlowView/helper.tsx index 3192fb4..9892f45 100644 --- a/src/FlowView/helper.tsx +++ b/src/FlowView/helper.tsx @@ -161,6 +161,7 @@ export function getRenderEdges(edges: FlowViewEdge[]) { select = SelectType.DEFAULT, type = 'smoothstep', label, + animated, sourceHandle, targetHandle, } = edge; @@ -172,6 +173,7 @@ export function getRenderEdges(edges: FlowViewEdge[]) { sourceHandle, targetHandle, type, + animated, label, className: getEdgeClsFromSelectType(select), }; diff --git a/src/constants.tsx b/src/constants.tsx index 57b6808..23c2493 100644 --- a/src/constants.tsx +++ b/src/constants.tsx @@ -70,6 +70,7 @@ export interface FlowViewEdge { target: string; sourceHandle?: string; targetHandle?: string; + animated?: boolean; select?: SelectType; label?: string; type?: EdgeType;