From 4166cc98616b057f37306a61156e30d40be28cbb Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 19 Jul 2026 10:57:28 +0800 Subject: [PATCH] =?UTF-8?q?docs(waf):=20=E8=A7=84=E6=A0=BC=20=E2=80=94=20?= =?UTF-8?q?=E8=A7=84=E5=88=99=E7=BC=96=E8=BE=91=E5=99=A8=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=8E=E6=8B=96=E6=94=BE=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 确认仅前端消费已有 label,节点库改为拖到画布落点,不做备注。 --- ...07-19-waf-editor-node-label-drag-design.md | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-19-waf-editor-node-label-drag-design.md diff --git a/docs/superpowers/specs/2026-07-19-waf-editor-node-label-drag-design.md b/docs/superpowers/specs/2026-07-19-waf-editor-node-label-drag-design.md new file mode 100644 index 00000000..f1048fd3 --- /dev/null +++ b/docs/superpowers/specs/2026-07-19-waf-editor-node-label-drag-design.md @@ -0,0 +1,122 @@ +# WAF 规则编辑器:节点命名与拖放添加 + +日期:2026-07-19 +范围:`/waf/rules/editor` 前端交互与类型对齐 +状态:已确认,待实现 + +## 背景 + +当前 WAF 规则流图编辑器有两处体验问题: + +1. 画布节点只显示类型固定名称(如「IP 匹配」),无法自定义命名,复杂规则难以区分。 +2. 节点库通过点击添加,新节点落在固定偏移位置(`x: 240, y: 140 + n*24`),无法在目标位置放置。 + +后端 `RuleNode` 已具备 `label` 字段(`json:"label,omitempty"`),前端类型与 UI 尚未消费。 + +## 目标 + +1. 用户可为可编辑节点自定义**显示名称**(`label`),画布与属性栏一致展示。 +2. 从节点库**拖放到画布**,在鼠标松手处生成节点;**取消点击固定位置添加**。 +3. 不做备注字段、不做拖到连线中插入、不改后端 schema / `schema_version`。 + +## 非目标 + +- 节点备注 / note / remark +- 拖到边自动拆边插入 +- 系统节点 `start` / `allow` 可改名 +- 后端校验、编译或运行时语义变更 +- 侧栏式节点库大改版 + +## 数据模型 + +### 后端(已有,不改) + +```go +type RuleNode struct { + ID string `json:"id"` + Type RuleNodeType `json:"type"` + Label string `json:"label,omitempty"` + Position RulePosition `json:"position"` + Config json.RawMessage `json:"config"` +} +``` + +`label` 为空则 omit;现有大小限制与图校验保持不变。 + +### 前端 + +`WAFRuleNode` 各变体增加可选字段: + +```ts +label?: string; +``` + +- 保存时:空字符串不写入或写 `undefined`,与 `omitempty` 对齐。 +- 显示时:`label?.trim() || typeDefaultLabel`。 +- 新建节点:不设 `label`(显示类型默认名)。 +- `start` / `allow`:属性栏仍为「系统节点无需配置」,不提供改名输入;若历史数据带 `label`,画布仍可按上述规则显示,但不提供编辑入口。 + +## UI 行为 + +### 画布节点(`rule-node.tsx`) + +| 区域 | 行为 | +|------|------| +| 主标题 | `label` 去空白后非空则用 `label`,否则用类型默认中文名 | +| 副标题 | 仍显示 `rule.id`(mono 小字) | +| 图标 / handle | 不变 | + +### 属性栏(`node-properties.tsx`) + +对非系统节点(`ip_match` | `geo_match` | `pow` | `block`),在类型专属配置**之上**增加: + +- 字段标签:`显示名称` +- 控件:`Input`,受控绑定 `node.label ?? ''` +- 变更:`onChange({ ...node, label: value })`;清空时写 `''` 或去掉字段(实现任选其一,保存序列化时不落空 label) + +系统节点保持现有文案。 + +### 节点库与添加(`node-library.tsx` + `rule-flow-canvas.tsx`) + +1. 节点库项设为 `draggable`,`dragstart` 写入节点类型(如 `application/openflare-waf-node` 或等价自定义 MIME + `text/plain` 回退)。 +2. 移除 `onClick` → `onAdd(type)` 的点击添加路径。 +3. React Flow 画布容器: + - `onDragOver`:`preventDefault`,允许 drop + - `onDrop`:读取类型 → `screenToFlowPosition({ x: clientX, y: clientY })` → 创建节点(默认 config 逻辑与现有 `addNode` 相同,但 `position` 为落点) +4. 落点后选中新节点,清除边选中(与现有一致)。 +5. 工具栏仍在画布左上角浮动区域,仅改为拖源,不改为侧栏。 + +## 实现落点(文件) + +| 文件 | 变更 | +|------|------| +| `frontend/lib/services/openflare/types.ts` | `WAFRuleNode` 增加 `label?` | +| `frontend/app/(main)/waf/rules/editor/components/rule-node.tsx` | 标题显示逻辑 | +| `frontend/app/(main)/waf/rules/editor/components/node-properties.tsx` | 「显示名称」字段 | +| `frontend/app/(main)/waf/rules/editor/components/node-library.tsx` | 拖放源,去掉点击添加 | +| `frontend/app/(main)/waf/rules/editor/components/rule-flow-canvas.tsx` | drop 落点创建;`addNode` 接受 position | +| 相关 `*.test.tsx` / `*.test.ts` | label 展示/编辑、拖放 payload、落点 | + +可选:若序列化路径有显式字段白名单,确认 `label` 会进入保存 payload。 + +## 错误与边界 + +- 未知 / 非法 drag type:忽略 drop。 +- 落在画布外:不创建。 +- 超长 `label`:依赖后端既有图大小/字段限制;前端可不设硬上限,或与常见 Input 一致(如 64–128 字符)——实现阶段若后端有明确上限则对齐。 +- Undo/脏检查:`label` 与 `position` 变更走现有 `onGraphChange` 路径,不新增独立历史机制。 + +## 测试要点 + +1. 有 `label` 的节点主标题为自定义名;无 `label` 为类型默认名。 +2. 属性栏修改 `label` 后 graph 节点更新且画布同步。 +3. 节点库项可拖;drop 后节点 `position` 接近 flow 坐标(允许测试中 mock `screenToFlowPosition`)。 +4. 不再通过点击节点库按钮创建节点(无 click-add 行为)。 +5. 系统节点属性栏仍无「显示名称」。 + +## 验收标准 + +- [ ] 可编辑节点可命名,保存再打开名称仍在。 +- [ ] 画布显示自定义名(空则类型名)。 +- [ ] 仅拖放添加,松手位置为节点位置。 +- [ ] 无后端 API / schema 变更;`make code-check` 与相关 vitest 通过。