Skip to content

Commit e88a178

Browse files
authored
feat: Add readOnly mode to JadeFlowEntry for history view (#131)
* [elsa] add readOnly method in jadeFlowEntry.jsx * [elsa] readOnly method add conditionNode logic * [elsa] fix(conditionNode): preserve branch disabled state in serializer
1 parent 0bd7f86 commit e88a178

File tree

9 files changed

+422
-504
lines changed

9 files changed

+422
-504
lines changed

framework/elsa/fit-elsa-react/src/components/common/JadeObservableOutput.jsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,20 @@ function _JadeObservableOutput({disabled, output}) {
9595

9696
return (<>
9797
<JadeCollapse defaultActiveKey={['codeOutputPanel']}>
98-
{<Panel key={'codeOutputPanel'}
99-
header={<div className='panel-header'>
100-
<span className='jade-panel-header-font'>{t('output')}</span>
101-
<Popover
102-
content={content}
103-
align={{offset: [0, 3]}}
104-
overlayClassName={'jade-custom-popover'}
105-
>
106-
<QuestionCircleOutlined className='jade-panel-header-popover-content'/>
107-
</Popover>
108-
</div>}
109-
className='jade-panel'
98+
{<Panel
99+
key={'codeOutputPanel'}
100+
header={<div className="panel-header">
101+
<span className="jade-panel-header-font">{t('output')}</span>
102+
<Popover
103+
content={content}
104+
align={{offset: [0, 3]}}
105+
overlayClassName={'jade-custom-popover'}
106+
>
107+
<QuestionCircleOutlined className="jade-panel-header-popover-content"/>
108+
</Popover>
109+
</div>}
110+
className="jade-panel"
111+
forceRender
110112
>
111113
<Tree blockNode={true}
112114
switcherIcon={({expanded}) => <TreeSwitcherIcon expanded={expanded}/>}

framework/elsa/fit-elsa-react/src/components/common/JadeObservableTree.jsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import {Tree} from "antd";
88
import {useShapeContext} from "../DefaultRoot.jsx";
9-
import {useEffect} from "react";
9+
import React, {useEffect} from "react";
1010
import "./jadeObservableTree.css";
1111
import TreeSwitcherIcon from "@/components/common/TreeSwitcherIcon.jsx";
1212

@@ -50,7 +50,7 @@ const buildNode = (nodeData, parent, level, shape) => {
5050
* @return {JSX.Element}
5151
* @constructor
5252
*/
53-
export const JadeObservableTree = ({data}) => {
53+
const _JadeObservableTree = ({data}) => {
5454
if (!Array.isArray(data)) {
5555
throw new Error("data must be array.");
5656
}
@@ -119,4 +119,10 @@ export const JadeObservableTree = ({data}) => {
119119
{renderTreeNodes(treeData)}
120120
</Tree>
121121
</>;
122-
};
122+
};
123+
124+
const areEqual = (prevProps, nextProps) => {
125+
return prevProps.data === nextProps.data;
126+
};
127+
128+
export const JadeObservableTree = React.memo(_JadeObservableTree, areEqual);

framework/elsa/fit-elsa-react/src/components/common/OutputForm.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const _OutputForm = ({outputParams, outputPopover}) => {
4343
}
4444
className='jade-panel'
4545
key='Output'
46+
forceRender
4647
>
4748
<div className={'jade-custom-panel-content'}>
4849
<JadeObservableTree data={outputParams}/>

framework/elsa/fit-elsa-react/src/components/condition/conditionNodeCondition.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ export const conditionNodeCondition = (id, x, y, width, height, parent, drawer)
5959
* @override
6060
*/
6161
self.serializerJadeConfig = (jadeConfig) => {
62-
jadeConfig.branches.forEach(branch => delete branch.disabled);
6362
self.flowMeta.conditionParams = jadeConfig;
6463
self.flowMeta.enableStageDesc = self.flowMeta.conditionParams.enableStageDesc;
6564
self.flowMeta.stageDesc = self.flowMeta.conditionParams.stageDesc;

framework/elsa/fit-elsa-react/src/components/llm/LlmOutput.jsx

Lines changed: 1 addition & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,6 @@ _LlmOutput.propTypes = {
3232
*/
3333
function _LlmOutput({outputItems, enableLogData, disabled}) {
3434
const dispatch = useDispatch();
35-
// 430演示大模型输出不需要新增和删除,暂时屏蔽
36-
// 添加新元素到 items 数组中,并将其 key 添加到当前展开的面板数组中
37-
// const addItem = () => {
38-
// dispatch({actionType: "addOutputParam", id: "uuidv4()})
39-
// };
40-
41-
// 430演示大模型输出不允许用户修改,暂时屏蔽
42-
// const handleItemChange = (name, value, itemId) => {
43-
// dispatch({actionType: "changeOutputParam", id: itemId, type: name, value: value});
44-
// if (name === "type") {
45-
// document.activeElement.blur();// 在选择后取消焦点
46-
// }
47-
// };
48-
49-
// 430演示大模型输出不需要新增和删除,暂时屏蔽
50-
// const handleDelete = (itemId) => {
51-
// dispatch({actionType: "deleteOutputParam", id: itemId});
52-
// };
53-
54-
// 430演示大模型输出不需要新增和删除,暂时屏蔽
55-
// const handleSelectClick = (event) => {
56-
// event.stopPropagation(); // 阻止事件冒泡
57-
// };
5835
const {t} = useTranslation();
5936

6037
const content = (
@@ -79,18 +56,10 @@ function _LlmOutput({outputItems, enableLogData, disabled}) {
7956
>
8057
<QuestionCircleOutlined className="jade-panel-header-popover-content"/>
8158
</Popover>
82-
{/* 430演示大模型输出不需要新增和删除,暂时屏蔽*/}
83-
{/* <Button type="text" className="icon-button"*/}
84-
{/* style={{"height": "22px", "marginLeft": "auto"}}*/}
85-
{/* onClick={(event) => {*/}
86-
{/* addItem();*/}
87-
{/* handleSelectClick(event);*/}
88-
{/* }}>*/}
89-
{/* <PlusOutlined/>*/}
90-
{/* </Button>*/}
9159
</div>
9260
}
9361
className="jade-panel"
62+
forceRender
9463
>
9564
<div className={"jade-custom-panel-content"}>
9665
<Form.Item className='jade-form-item' name={`enableLog-${enableLogData.id}`}>
@@ -99,93 +68,6 @@ function _LlmOutput({outputItems, enableLogData, disabled}) {
9968
className={'jade-font-size'}>{t('pushResultToChat')}</span></Checkbox>
10069
</Form.Item>
10170
<JadeObservableTree data={outputItems}/>
102-
{/* 430演示大模型输出不允许用户操作,写死*/}
103-
{/* <Row gutter={16}>*/}
104-
{/* <Col span={7}>*/}
105-
{/* <Form.Item>*/}
106-
{/* <span style={{color: "rgba(28,31,35,.35)"}}>Name</span>*/}
107-
{/* </Form.Item>*/}
108-
{/* </Col>*/}
109-
{/* <Col span={5}>*/}
110-
{/* <Form.Item>*/}
111-
{/* <span style={{color: "rgba(28,31,35,.35)"}}>Type</span>*/}
112-
{/* </Form.Item>*/}
113-
{/* </Col>*/}
114-
{/* <Col span={12}>*/}
115-
{/* <Form.Item>*/}
116-
{/* <span style={{color: "rgba(28,31,35,.35)"}}>Description</span>*/}
117-
{/* </Form.Item>*/}
118-
{/* </Col>*/}
119-
{/* </Row>*/}
120-
{/* 430演示大模型输出不允许用户操作,写死*/}
121-
{/* {outputItems.map((item) => (*/}
122-
{/* <Row*/}
123-
{/* key={item.id}*/}
124-
{/* gutter={16}*/}
125-
{/* >*/}
126-
{/* <Col span={7}>*/}
127-
{/* <Form.Item*/}
128-
{/* id={`name-${item.id}`}*/}
129-
{/* name={`name-${item.id}`}*/}
130-
{/* rules={[{required: true, message: '输出参数名称不能为空!'}]}*/}
131-
{/* initialValue={item.name}*/}
132-
{/* >*/}
133-
{/* <JInput*/}
134-
{/* style={{paddingRight: "12px"}}*/}
135-
{/* value={item.name}*/}
136-
{/* onChange={(e) => handleItemChange('name', e.target.value, item.id)}*/}
137-
{/* />*/}
138-
{/* </Form.Item>*/}
139-
{/* </Col>*/}
140-
{/* <Col span={5}>*/}
141-
{/* <Form.Item*/}
142-
{/* id={`type-${item.id}`}*/}
143-
{/* initialValue='String'*/}
144-
{/* >*/}
145-
{/* <JadeStopPropagationSelect*/}
146-
{/* id={`type-select-${item.id}`}*/}
147-
{/* style={{width: "100%"}}*/}
148-
{/* onChange={(value) => handleItemChange('type', value, item.id)}*/}
149-
{/* options={[*/}
150-
{/* {value: 'String', label: 'String'},*/}
151-
{/* {value: 'Integer', label: 'Integer'},*/}
152-
{/* {value: 'Boolean', label: 'Boolean'},*/}
153-
{/* {value: 'Number', label: 'Number'},*/}
154-
{/* {value: 'Object', label: 'Object', disabled: true},*/}
155-
{/* {value: 'Array<String>', label: 'Array<String>'},*/}
156-
{/* {value: 'Array<Integer>', label: 'Array<Integer>'},*/}
157-
{/* {value: 'Array<Boolean>', label: 'Array<Boolean>'},*/}
158-
{/* {value: 'Array<Number>', label: 'Array<Number>'},*/}
159-
{/* {value: 'Array<Object>', label: 'Array<Object>', disabled: true},*/}
160-
{/* ]}*/}
161-
{/* value={item.type}*/}
162-
{/* />*/}
163-
{/* </Form.Item>*/}
164-
{/* </Col>*/}
165-
{/* <Col span={11}>*/}
166-
{/* <Form.Item*/}
167-
{/* id={`description-${item.id}`}*/}
168-
{/* >*/}
169-
{/* <JInput*/}
170-
{/* style={{paddingRight: "12px"}}*/}
171-
{/* value={item.description}*/}
172-
{/* onChange={(e) => handleItemChange('description', e.target.value, item.id)}*/}
173-
{/* />*/}
174-
{/* </Form.Item>*/}
175-
{/* </Col>*/}
176-
177-
{/* 430演示大模型输出不需要新增和删除,暂时屏蔽*/}
178-
{/* <Col span={1} style={{paddingLeft: "2px"}}>*/}
179-
{/* <Form.Item>*/}
180-
{/* <Button type="text" className="icon-button"*/}
181-
{/* style={{"height": "100%", "marginLeft": "auto"}}*/}
182-
{/* onClick={() => handleDelete(item.id)}>*/}
183-
{/* <MinusCircleOutlined/>*/}
184-
{/* </Button>*/}
185-
{/* </Form.Item>*/}
186-
{/* </Col>*/}
187-
{/* </Row>*/}
188-
{/* ))}*/}
18971
</div>
19072
</Panel>
19173
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
3+
* This file is a part of the ModelEngine Project.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
7+
export const setBranchDisabled = (node, disabled) => {
8+
const flowMeta = node.getFlowMeta();
9+
node.drawer.dispatch({
10+
actionType: 'changeBranchesStatus',
11+
changes: [
12+
{key: 'ids', value: flowMeta.conditionParams.branches.map(b => b.id)},
13+
{key: 'disabled', value: disabled},
14+
{key: 'jadeNodeConfigChangeIgnored', value: true},
15+
],
16+
});
17+
};

0 commit comments

Comments
 (0)