Skip to content

Commit eaf49a5

Browse files
xlorneclaude
andcommitted
fix: prevent infinite loop on reset and handle legacy default scripts
- Add userModifiedModeRef to prevent useEffect from overriding user mode changes - Detect legacy default script format and treat as normal mode - Fix flickering issue when clicking reset button Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c5cd84c commit eaf49a5

2 files changed

Lines changed: 31 additions & 3 deletions

File tree

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/TitleConfigModal.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect } from 'react';
1+
import React, { useState, useEffect, useRef } from 'react';
22
import { Modal, Input, Alert, Button, Space, message } from 'antd';
33
import { EditOutlined, CodeOutlined, RollbackOutlined } from '@ant-design/icons';
44
import { GroovyVariableMapping } from '@flow-engine/flow-types';
@@ -33,24 +33,35 @@ export const TitleConfigModal: React.FC<TitleConfigModalProps> = ({
3333
const [content, setContent] = useState('');
3434
const [showVariablePicker, setShowVariablePicker] = useState(false);
3535

36+
// 标记用户是否手动修改了模式(防止 useEffect 覆盖用户操作)
37+
const userModifiedModeRef = useRef(false);
38+
3639
// 获取变量映射
3740
const mappings = GroovyVariableService.getAllMappings(formFields);
3841

3942
useEffect(() => {
40-
// 解析当前脚本模式
43+
// 如果用户手动修改了模式,不再覆盖
44+
if (userModifiedModeRef.current) {
45+
return;
46+
}
47+
48+
// 只在 script 改变时重新解析(初始化)
4149
const parsedMode = TitleSyntaxConverter.parseMode(script);
4250

4351
if (parsedMode === 'normal') {
4452
// 尝试解析为标签表达式
4553
const labelExpr = TitleSyntaxConverter.toLabelExpression(script, mappings);
54+
// 如果是默认 legacy 脚本,显示空内容(让用户重新输入)
55+
// 如果能解析成标签表达式,显示解析结果
56+
// 否则显示空内容
4657
setContent(labelExpr || '');
4758
} else {
4859
// 高级模式,直接使用原脚本
4960
setContent(script);
5061
}
5162

5263
setMode(parsedMode);
53-
}, [script, mappings]);
64+
}, [script]);
5465

5566
// 插入变量
5667
const handleInsertVariable = (mapping: GroovyVariableMapping) => {
@@ -59,6 +70,7 @@ export const TitleConfigModal: React.FC<TitleConfigModalProps> = ({
5970

6071
// 切换到高级模式
6172
const handleSwitchToAdvanced = () => {
73+
userModifiedModeRef.current = true;
6274
if (mode === 'normal') {
6375
// 转换为Groovy脚本
6476
const groovyScript = TitleSyntaxConverter.toGroovySyntax(content, mappings);
@@ -69,6 +81,7 @@ export const TitleConfigModal: React.FC<TitleConfigModalProps> = ({
6981

7082
// 重置为普通模式
7183
const handleResetToNormal = () => {
84+
userModifiedModeRef.current = true;
7285
setContent('');
7386
setMode('normal');
7487
};

frontend/packages/flow-pc/flow-pc-design/src/utils/title-syntax-converter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ export class TitleSyntaxConverter {
157157
* 解析脚本模式
158158
*/
159159
static parseMode(script: string): 'normal' | 'advanced' {
160+
// 特殊处理:检测是否为默认的 legacy 脚本
161+
// 如果是默认脚本,视为 normal 模式(可以重新编辑)
162+
if (this.isDefaultLegacyScript(script)) {
163+
return 'normal';
164+
}
165+
160166
if (GroovyVariableService.isAdvancedMode(script)) {
161167
// 尝试解析为正常模式
162168
const mappings = GroovyVariableService.getPredefinedMappings();
@@ -167,6 +173,15 @@ export class TitleSyntaxConverter {
167173
return 'advanced';
168174
}
169175

176+
/**
177+
* 检查是否为默认的 legacy 脚本
178+
*/
179+
private static isDefaultLegacyScript(script: string): boolean {
180+
const trimmed = script.trim();
181+
// 匹配默认脚本格式: def run(request){return '你有一条待办'}
182+
return /^\s*def\s+run\s*\(\s*request\s*\)\s*\{\s*return\s+'[^']*'\s*\}\s*$/.test(trimmed);
183+
}
184+
170185
/**
171186
* 验证Groovy脚本语法(基础检查)
172187
*/

0 commit comments

Comments
 (0)