Skip to content

Commit 39b8300

Browse files
RonnyChan96CodeCasterX
authored andcommitted
[elsa] 1.开始节点添加应用配置 2.添加getShapeIdsByType方法至graphOperator (#29)
1 parent bff3196 commit 39b8300

File tree

7 files changed

+1001
-797
lines changed

7 files changed

+1001
-797
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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+
import {useDispatch, useFormContext} from '@/components/DefaultRoot.jsx';
8+
import {useTranslation} from 'react-i18next';
9+
import PropTypes from 'prop-types';
10+
import React from 'react';
11+
import {Collapse, Form, Image} from 'antd';
12+
import {EyeOutlined} from '@ant-design/icons';
13+
14+
const {Panel} = Collapse;
15+
16+
/**
17+
* 开始节点应用配置表单。
18+
*
19+
* @param item 应用配置结构体。
20+
* @param disabled 是否禁用。
21+
* @param configs 开始节点相关配置。
22+
* @returns {JSX.Element} 开始节点应用配置表单的DOM。
23+
*/
24+
const _AppConfiguration = ({item, disabled, configs}) => {
25+
const dispatch = useDispatch();
26+
const form = useFormContext();
27+
const {t} = useTranslation();
28+
const appChatStyle = item?.value?.find(v => v.name === 'appChatStyle') ?? {};
29+
30+
const renderOption = (config, option) => {
31+
const isSelected = appChatStyle.value === option.value;
32+
const optionCount = config.options.length;
33+
const flexBasis = optionCount >= 3 ? 'calc(33.333% - 11px)' : '1';
34+
35+
return (
36+
<div
37+
key={option.value}
38+
onClick={() => !disabled && handleOptionClick(config, option)}
39+
style={{
40+
flex: `0 0 ${flexBasis}`,
41+
padding: '12px',
42+
border: `2px solid ${isSelected ? '#1890ff' : '#d9d9d9'}`,
43+
borderRadius: '4px',
44+
cursor: disabled ? 'not-allowed' : 'pointer',
45+
textAlign: 'center',
46+
background: disabled ? '#f5f5f5' : 'white',
47+
opacity: disabled ? 0.6 : 1,
48+
}}
49+
>
50+
{option.image && (
51+
<div className={'jade-custom-image-container'}>
52+
<Image
53+
src={option.image}
54+
width={111}
55+
height={62.28}
56+
style={{borderRadius: '4px'}}
57+
preview={{
58+
mask: (
59+
<div style={{
60+
display: 'flex',
61+
justifyContent: 'center',
62+
alignItems: 'center',
63+
height: '100%',
64+
backgroundColor: 'transparent',
65+
}}>
66+
<EyeOutlined style={{fontSize: '20px', color: '#000'}}/>
67+
</div>
68+
),
69+
}}
70+
/>
71+
</div>
72+
)}
73+
<span className={'jade-font-size jade-font-color'}>
74+
{t(option.label)}
75+
</span>
76+
</div>
77+
);
78+
};
79+
80+
const handleOptionClick = (config, option) => {
81+
form.setFieldsValue({[`${config.name}`]: option.value});
82+
dispatch({
83+
actionType: 'changeAppConfig',
84+
name: config.name,
85+
value: option.value,
86+
});
87+
};
88+
89+
return (
90+
<Collapse bordered={false} className="jade-custom-collapse" defaultActiveKey={['configPanel']}>
91+
<Panel
92+
key={'configPanel'}
93+
header={
94+
<div className="panel-header" style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-start'}}>
95+
<span className="jade-panel-header-font">{t('appConfig')}</span>
96+
</div>
97+
}
98+
className="jade-panel"
99+
>
100+
<div className={`jade-custom-panel-content`}>
101+
{configs?.appChatStyle && (() => {
102+
const appChatStyleConfig = configs.appChatStyle;
103+
return (
104+
<Form.Item
105+
key={appChatStyleConfig.name}
106+
className="jade-form-item"
107+
label={t(appChatStyleConfig.label)}
108+
name={`${appChatStyleConfig.name}`}
109+
rules={appChatStyleConfig.rules}
110+
validateTrigger="onBlur"
111+
initialValue={appChatStyle.value}
112+
>
113+
<div style={{display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: '16px', width: '100%'}}>
114+
{appChatStyleConfig.options.map(option => renderOption(appChatStyleConfig, option))}
115+
</div>
116+
</Form.Item>
117+
);
118+
})()}
119+
</div>
120+
</Panel>
121+
</Collapse>
122+
);
123+
};
124+
125+
_AppConfiguration.propTypes = {
126+
item: PropTypes.shape({
127+
value: PropTypes.arrayOf(
128+
PropTypes.shape({
129+
name: PropTypes.string.isRequired,
130+
value: PropTypes.any
131+
})
132+
).isRequired
133+
}).isRequired,
134+
disabled: PropTypes.bool.isRequired,
135+
configs: PropTypes.shape({
136+
appChatStyle: PropTypes.shape({
137+
name: PropTypes.string,
138+
options: PropTypes.arrayOf(
139+
PropTypes.shape({
140+
value: PropTypes.any.isRequired,
141+
label: PropTypes.string.isRequired,
142+
image: PropTypes.string
143+
})
144+
)
145+
})
146+
})
147+
};
148+
149+
const areEqual = (prevProps, nextProps) => {
150+
return prevProps.item === nextProps.item &&
151+
prevProps.disabled === nextProps.disabled &&
152+
prevProps.config === nextProps.config;
153+
};
154+
155+
export const AppConfiguration = React.memo(_AppConfiguration, areEqual);

framework/elsa/fit-elsa-react/src/components/start/StartFormWrapper.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {v4 as uuidv4} from 'uuid';
1414
import MultiConversation from '@/components/start/MultiConversation.jsx';
1515
import PropTypes from 'prop-types';
1616
import {Trans, useTranslation} from 'react-i18next';
17+
import {AppConfiguration} from '@/components/start/AppConfiguration.jsx';
1718

1819
const {Panel} = Collapse;
1920

@@ -41,6 +42,7 @@ export default function StartFormWrapper({data, shapeStatus}) {
4142
const multiConversationSwitchValue = multiConversationSwitch?.value ?? true;
4243
const multiConversationTypeValue = memory.value.find(item => item.name === "type").value;
4344
const multiConversationValueValue = memory.value.find(item => item.name === "value")?.value ?? null;
45+
const appConfig = data.find(item => item.name === "appConfig");
4446

4547
// items中所有初始都为打开状态
4648
const [openItems, setOpenItems] = useState(() => {
@@ -186,6 +188,7 @@ export default function StartFormWrapper({data, shapeStatus}) {
186188
onChange: handleMultiConversationValueChange
187189
}
188190
}}/>
191+
{appConfig && <AppConfiguration item={appConfig} disabled={shapeStatus.disabled} configs={config.appConfig}/>}
189192
</div>
190193
</>);
191194
}

framework/elsa/fit-elsa-react/src/components/start/startComponent.jsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ export const startComponent = (jadeConfig) => {
171171
});
172172
};
173173

174+
const changeAppConfig = () => {
175+
return data.map(item => {
176+
if (item.name === 'appConfig') {
177+
return {
178+
...item, value: item.value.map(configItem => {
179+
if (configItem.name === action.name) {
180+
return {...configItem, value: action.value};
181+
} else {
182+
return configItem;
183+
}
184+
}),
185+
};
186+
} else {
187+
return item;
188+
}
189+
});
190+
};
191+
174192
switch (action.actionType) {
175193
case 'addInputParam': {
176194
return addInputParam();
@@ -187,6 +205,9 @@ export const startComponent = (jadeConfig) => {
187205
case 'deleteInputParam': {
188206
return deleteInputParam();
189207
}
208+
case 'changeAppConfig': {
209+
return changeAppConfig();
210+
}
190211
case 'changeFlowMeta': {
191212
return {
192213
...data,

framework/elsa/fit-elsa-react/src/data/GraphOperator.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ const graphOperator = (graphString) => {
169169
return shapes.filter(shape => shape.type === 'startNodeStart').map(startNode => startNode.flowMeta.inputParams);
170170
};
171171

172+
/**
173+
* 根据节点类型获取对应节点id列表.
174+
*
175+
* @param type 节点类型.
176+
* @returns {array} 对应节点id列表.
177+
*/
178+
self.getShapeIdsByType = (type) => {
179+
return shapes.filter((shape) => shape.type === type).map((shape) => shape.id);
180+
};
181+
172182
return self;
173183
};
174184

framework/elsa/fit-elsa-react/src/en_US.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,5 +408,8 @@
408408
"chooseToBeLoopParam": "待翻译",
409409
"loopRadioIsRequired": "待翻译",
410410
"loopSkillPopover": "待翻译",
411-
"pushResultToChat": "待翻译"
411+
"pushResultToChat": "待翻译",
412+
"appConfig": "App Configuration",
413+
"appChatStyle": "App Interface Configuration",
414+
"appChatStyleCannotBeEmpty": "App interface configuration cannot be empty"
412415
}

0 commit comments

Comments
 (0)