mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-22 12:20:34 +00:00
4.8.10 fix (#2572)
* fix: circle workflow response modal * perf: workflow runtime check
This commit is contained in:
1
packages/global/core/chat/type.d.ts
vendored
1
packages/global/core/chat/type.d.ts
vendored
@@ -151,6 +151,7 @@ export type ChatHistoryItemType = HistoryItemType & {
|
||||
/* ------- response data ------------ */
|
||||
export type ChatHistoryItemResType = DispatchNodeResponseType & {
|
||||
nodeId: string;
|
||||
id: string;
|
||||
moduleType: FlowNodeTypeEnum;
|
||||
moduleName: string;
|
||||
};
|
||||
|
@@ -159,6 +159,9 @@ export type DispatchNodeResponseType = {
|
||||
|
||||
// user select
|
||||
userSelectResult?: string;
|
||||
|
||||
// update var
|
||||
updateVarResult?: any[];
|
||||
};
|
||||
|
||||
export type DispatchNodeResultType<T> = {
|
||||
|
@@ -117,39 +117,6 @@ export const filterWorkflowEdges = (edges: RuntimeEdgeItemType[]) => {
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
区分普通连线和递归连线
|
||||
递归连线:可以通过往上查询 nodes,最终追溯到自身
|
||||
*/
|
||||
export const splitEdges2WorkflowEdges = ({
|
||||
edges,
|
||||
allEdges,
|
||||
currentNode
|
||||
}: {
|
||||
edges: RuntimeEdgeItemType[];
|
||||
allEdges: RuntimeEdgeItemType[];
|
||||
currentNode: RuntimeNodeItemType;
|
||||
}) => {
|
||||
const commonEdges: RuntimeEdgeItemType[] = [];
|
||||
const recursiveEdges: RuntimeEdgeItemType[] = [];
|
||||
|
||||
edges.forEach((edge) => {
|
||||
const checkIsCurrentNode = (edge: RuntimeEdgeItemType): boolean => {
|
||||
const sourceEdge = allEdges.find((item) => item.target === edge.source);
|
||||
if (!sourceEdge) return false;
|
||||
if (sourceEdge.source === currentNode.nodeId) return true;
|
||||
return checkIsCurrentNode(sourceEdge);
|
||||
};
|
||||
if (checkIsCurrentNode(edge)) {
|
||||
recursiveEdges.push(edge);
|
||||
} else {
|
||||
commonEdges.push(edge);
|
||||
}
|
||||
});
|
||||
|
||||
return { commonEdges, recursiveEdges };
|
||||
};
|
||||
|
||||
/*
|
||||
1. 输入线分类:普通线和递归线(可以追溯到自身)
|
||||
2. 起始线全部非 waiting 执行,或递归线全部非 waiting 执行
|
||||
@@ -161,31 +128,72 @@ export const checkNodeRunStatus = ({
|
||||
node: RuntimeNodeItemType;
|
||||
runtimeEdges: RuntimeEdgeItemType[];
|
||||
}) => {
|
||||
const workflowEdges = filterWorkflowEdges(runtimeEdges).filter(
|
||||
/*
|
||||
区分普通连线和递归连线
|
||||
递归连线:可以通过往上查询 nodes,最终追溯到自身
|
||||
*/
|
||||
const splitEdges2WorkflowEdges = ({
|
||||
sourceEdges,
|
||||
allEdges,
|
||||
currentNode
|
||||
}: {
|
||||
sourceEdges: RuntimeEdgeItemType[];
|
||||
allEdges: RuntimeEdgeItemType[];
|
||||
currentNode: RuntimeNodeItemType;
|
||||
}) => {
|
||||
const commonEdges: RuntimeEdgeItemType[] = [];
|
||||
const recursiveEdges: RuntimeEdgeItemType[] = [];
|
||||
|
||||
const checkIsCircular = (edge: RuntimeEdgeItemType, visited: Set<string>): boolean => {
|
||||
if (edge.source === currentNode.nodeId) {
|
||||
return true; // 检测到环,并且环中包含当前节点
|
||||
}
|
||||
if (visited.has(edge.source)) {
|
||||
return false; // 检测到环,但不包含当前节点(子节点成环)
|
||||
}
|
||||
visited.add(edge.source);
|
||||
|
||||
const nextEdges = allEdges.filter((item) => item.target === edge.source);
|
||||
return nextEdges.some((nextEdge) => checkIsCircular(nextEdge, new Set(visited)));
|
||||
};
|
||||
|
||||
sourceEdges.forEach((edge) => {
|
||||
if (checkIsCircular(edge, new Set([currentNode.nodeId]))) {
|
||||
recursiveEdges.push(edge);
|
||||
} else {
|
||||
commonEdges.push(edge);
|
||||
}
|
||||
});
|
||||
|
||||
return { commonEdges, recursiveEdges };
|
||||
};
|
||||
|
||||
const runtimeNodeSourceEdge = filterWorkflowEdges(runtimeEdges).filter(
|
||||
(item) => item.target === node.nodeId
|
||||
);
|
||||
|
||||
// Entry
|
||||
if (workflowEdges.length === 0) {
|
||||
if (runtimeNodeSourceEdge.length === 0) {
|
||||
return 'run';
|
||||
}
|
||||
|
||||
// Classify edges
|
||||
const { commonEdges, recursiveEdges } = splitEdges2WorkflowEdges({
|
||||
edges: workflowEdges,
|
||||
sourceEdges: runtimeNodeSourceEdge,
|
||||
allEdges: runtimeEdges,
|
||||
currentNode: node
|
||||
});
|
||||
|
||||
// check skip
|
||||
if (commonEdges.every((item) => item.status === 'skipped')) {
|
||||
// check skip(其中一组边,全 skip)
|
||||
if (commonEdges.length > 0 && commonEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
|
||||
// check active
|
||||
if (commonEdges.every((item) => item.status !== 'waiting')) {
|
||||
// check active(有一类边,不全是 wait 即可运行)
|
||||
if (commonEdges.length > 0 && commonEdges.every((item) => item.status !== 'waiting')) {
|
||||
return 'run';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status !== 'waiting')) {
|
||||
|
@@ -19,7 +19,7 @@ import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { getNanoid, replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
||||
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils';
|
||||
|
||||
@@ -434,6 +434,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
const formatResponseData: ChatHistoryItemResType = (() => {
|
||||
if (!dispatchRes[DispatchNodeResponseKeyEnum.nodeResponse]) return undefined;
|
||||
return {
|
||||
id: getNanoid(),
|
||||
nodeId: node.nodeId,
|
||||
moduleName: node.name,
|
||||
moduleType: node.flowNodeType,
|
||||
|
@@ -19,12 +19,12 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
const { params, variables, runtimeNodes, workflowStreamResponse, node } = props;
|
||||
|
||||
const { updateList } = params;
|
||||
updateList.forEach((item) => {
|
||||
const result = updateList.map((item) => {
|
||||
const varNodeId = item.variable?.[0];
|
||||
const varKey = item.variable?.[1];
|
||||
|
||||
if (!varNodeId || !varKey) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = (() => {
|
||||
@@ -48,10 +48,11 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
}
|
||||
})();
|
||||
|
||||
// Global variable
|
||||
if (varNodeId === VARIABLE_NODE_ID) {
|
||||
// update global variable
|
||||
variables[varKey] = value;
|
||||
} else {
|
||||
// Other nodes
|
||||
runtimeNodes
|
||||
.find((node) => node.nodeId === varNodeId)
|
||||
?.outputs?.find((output) => {
|
||||
@@ -61,6 +62,8 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
|
||||
workflowStreamResponse?.({
|
||||
@@ -70,7 +73,7 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
|
||||
return {
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: 0
|
||||
updateVarResult: result
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@@ -565,6 +565,7 @@
|
||||
"plugin output": "Plugin output value",
|
||||
"search using reRank": "Result rearrangement",
|
||||
"text output": "text output",
|
||||
"update_var_result": "Variable update results (display multiple variable update results in order)",
|
||||
"user_select_result": "User select result"
|
||||
},
|
||||
"retry": "Regenerate",
|
||||
|
@@ -10,6 +10,8 @@
|
||||
"auto_renew_q": "订阅套餐会自动续费么?",
|
||||
"change_package_a": "当前套餐价格大于新套餐时,无法立即切换,将会在当前套餐过期后以“续费”形式进行切换。\n当前套餐价格小于新套餐时,系统会自动计算当前套餐剩余余额,您可支付差价进行套餐切换。",
|
||||
"change_package_q": "能否切换订阅套餐?",
|
||||
"check_subscription_a": "账号-个人信息-套餐详情-使用情况。您可以查看所拥有套餐的生效和到期时间。当付费套餐到期后将自动切换免费版。",
|
||||
"check_subscription_q": "在哪里查看已订阅的套餐?",
|
||||
"dataset_compute_a": "1条知识库存储等于1条知识库索引。一条知识库数据可以包含1条或多条知识库索引。增强训练中,1条数据会生成5条索引。",
|
||||
"dataset_compute_q": "知识库存储怎么计算?",
|
||||
"dataset_index_a": "不会。但知识库索引超出时,无法插入和更新知识库内容。",
|
||||
@@ -18,19 +20,15 @@
|
||||
"free_user_clean_q": "免费版数据会清除么?",
|
||||
"package_overlay_a": "可以的。每次购买的资源包都是独立的,在其有效期内将会叠加使用。AI积分会优先扣除最先过期的资源包。",
|
||||
"package_overlay_q": "额外资源包可以叠加么?",
|
||||
"switch_package_q": "是否切换订阅套餐?",
|
||||
"switch_package_a": "套餐使用规则为优先使用更高级的套餐,因此,购买的新套餐若比当前套餐更高级,则新套餐立即生效:否则将继续使用当前套餐。",
|
||||
"check_subscription_q": "在哪里查看已订阅的套餐?",
|
||||
"check_subscription_a": "账号-个人信息-套餐详情-使用情况。您可以查看所拥有套餐的生效和到期时间。当付费套餐到期后将自动切换免费版。"
|
||||
"switch_package_q": "是否切换订阅套餐?"
|
||||
},
|
||||
"Folder": "文件夹",
|
||||
"Login": "登录",
|
||||
"is_using": "正在使用",
|
||||
"Move": "移动",
|
||||
"Name": "名称",
|
||||
"Rename": "重命名",
|
||||
"Resume": "恢复",
|
||||
"free": "免费",
|
||||
"Running": "运行中",
|
||||
"UnKnow": "未知",
|
||||
"Warning": "提示",
|
||||
@@ -119,7 +117,6 @@
|
||||
"Cancel": "取消",
|
||||
"Choose": "选择",
|
||||
"Close": "关闭",
|
||||
"base_config": "基础配置",
|
||||
"Config": "配置",
|
||||
"Confirm": "确认",
|
||||
"Confirm Create": "确认创建",
|
||||
@@ -224,6 +221,7 @@
|
||||
"Select Avatar": "点击选择头像",
|
||||
"Select Failed": "选择头像异常"
|
||||
},
|
||||
"base_config": "基础配置",
|
||||
"choosable": "可选",
|
||||
"confirm": {
|
||||
"Common Tip": "操作确认"
|
||||
@@ -567,6 +565,7 @@
|
||||
"plugin output": "插件输出值",
|
||||
"search using reRank": "结果重排",
|
||||
"text output": "文本输出",
|
||||
"update_var_result": "变量更新结果(按顺序展示多个变量更新结果)",
|
||||
"user_select_result": "用户选择结果"
|
||||
},
|
||||
"retry": "重新生成",
|
||||
@@ -639,7 +638,8 @@
|
||||
"success": "开始同步"
|
||||
}
|
||||
},
|
||||
"training": {}
|
||||
"training": {
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"Auxiliary Data": "辅助数据",
|
||||
@@ -775,7 +775,6 @@
|
||||
"test result tip": "根据知识库内容与测试文本的相似度进行排序,你可以根据测试结果调整对应的文本。\n注意:测试记录中的数据可能已经被修改过,点击某条测试数据后将展示最新的数据。"
|
||||
},
|
||||
"training": {
|
||||
"tag": "排队情况",
|
||||
"Agent queue": "QA 训练排队",
|
||||
"Auto mode": "增强处理(实验)",
|
||||
"Auto mode Tip": "通过子索引以及调用模型生成相关问题与摘要,来增加数据块的语义丰富度,更利于检索。需要消耗更多的存储空间和增加 AI 调用次数。",
|
||||
@@ -785,7 +784,8 @@
|
||||
"QA mode": "问答拆分",
|
||||
"Vector queue": "索引排队",
|
||||
"Waiting": "预计 5 分钟",
|
||||
"Website Sync": "Web 站点同步"
|
||||
"Website Sync": "Web 站点同步",
|
||||
"tag": "排队情况"
|
||||
},
|
||||
"website": {
|
||||
"Base Url": "根地址",
|
||||
@@ -1078,6 +1078,7 @@
|
||||
},
|
||||
"extraction_results": "提取结果",
|
||||
"field_name": "字段名",
|
||||
"free": "免费",
|
||||
"get_QR_failed": "获取二维码失败",
|
||||
"get_app_failed": "获取应用失败",
|
||||
"get_laf_failed": "获取Laf函数列表失败",
|
||||
@@ -1097,6 +1098,7 @@
|
||||
},
|
||||
"invalid_variable": "无效变量",
|
||||
"is_open": "是否开启",
|
||||
"is_using": "正在使用",
|
||||
"item_description": "字段描述",
|
||||
"item_name": "字段名",
|
||||
"key_repetition": "key 重复",
|
||||
@@ -1125,14 +1127,14 @@
|
||||
"notice": "请勿关闭页面",
|
||||
"old_package_price": "旧套餐余额",
|
||||
"other": "其他金额,请取整数",
|
||||
"to_recharge": "余额不足,去充值",
|
||||
"wechat": "请微信扫码支付: {{price}}元\n请勿关闭页面",
|
||||
"yuan": "{{amount}}元",
|
||||
"package_tip": {
|
||||
"buy": "您购买的套餐等级低于当前套餐,该套餐将在当前套餐过期后生效。您可在账号—个人信息—套餐详情里,查看套餐使用情况。",
|
||||
"renewal": "您正在续费套餐。您可在账号—个人信息—套餐详情里,查看套餐使用情况。",
|
||||
"upgrade": "您购买的套餐等级高于当前套餐,该套餐将即刻生效,当前套餐将延后生效。您可在账号—个人信息—套餐详情里,查看套餐使用情况。"
|
||||
}
|
||||
},
|
||||
"to_recharge": "余额不足,去充值",
|
||||
"wechat": "请微信扫码支付: {{price}}元\n请勿关闭页面",
|
||||
"yuan": "{{amount}}元"
|
||||
},
|
||||
"permission": {
|
||||
"Collaborator": "协作者",
|
||||
@@ -1217,8 +1219,8 @@
|
||||
"standard": {
|
||||
"AI Bonus Points": "AI 积分",
|
||||
"Expired Time": "结束时间",
|
||||
"due_date": "到期时间",
|
||||
"Start Time": "开始时间",
|
||||
"due_date": "到期时间",
|
||||
"storage": "存储量",
|
||||
"type": "类型"
|
||||
},
|
||||
@@ -1334,11 +1336,6 @@
|
||||
"noBill": "无账单记录~",
|
||||
"no_invoice": "暂无开票记录",
|
||||
"subscription": {
|
||||
"status": {
|
||||
"expired": "已过期",
|
||||
"active": "生效中",
|
||||
"inactive": "待使用"
|
||||
},
|
||||
"AI points": "AI 积分",
|
||||
"AI points click to read tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分(类似于 token)。点击可查看详细计算规则。",
|
||||
"AI points usage": "AI 积分使用量",
|
||||
@@ -1384,13 +1381,18 @@
|
||||
"standardSubLevel": {
|
||||
"custom": "自定义版",
|
||||
"enterprise": "企业版",
|
||||
"enterprise_desc": "适合中小企业在生产环境构建知识库应用",
|
||||
"experience": "体验版",
|
||||
"experience_desc": "可解锁 FastGPT 完整功能",
|
||||
"free": "免费版",
|
||||
"free desc": "每月均可免费使用基础功能,连续 30 天未登录系统,将会自动清除知识库",
|
||||
"team": "团队版",
|
||||
"experience_desc": "可解锁 FastGPT 完整功能",
|
||||
"team_desc": "适合小团队构建知识库应用并提供对外服务",
|
||||
"enterprise_desc": "适合中小企业在生产环境构建知识库应用"
|
||||
"team_desc": "适合小团队构建知识库应用并提供对外服务"
|
||||
},
|
||||
"status": {
|
||||
"active": "生效中",
|
||||
"expired": "已过期",
|
||||
"inactive": "待使用"
|
||||
},
|
||||
"token_compute": "点击查看在线 Tokens 计算器",
|
||||
"type": {
|
||||
|
@@ -24,7 +24,8 @@ type sideTabItemType = {
|
||||
moduleName: string;
|
||||
runningTime?: number;
|
||||
moduleType: string;
|
||||
nodeId: string;
|
||||
// nodeId:string; // abandon
|
||||
id: string;
|
||||
children: sideTabItemType[];
|
||||
};
|
||||
|
||||
@@ -149,18 +150,28 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { isPc } = useSystem();
|
||||
const flattedResponse = useMemo(() => flattenArray(response), [response]);
|
||||
|
||||
const flattedResponse = useMemo(
|
||||
() =>
|
||||
flattenArray(response).map((item) => ({
|
||||
...item,
|
||||
id: item.id ?? item.nodeId
|
||||
})),
|
||||
[response]
|
||||
);
|
||||
const [currentNodeId, setCurrentNodeId] = useState(
|
||||
flattedResponse[0]?.nodeId ? flattedResponse[0].nodeId : ''
|
||||
flattedResponse[0]?.id ?? flattedResponse[0]?.nodeId ?? ''
|
||||
);
|
||||
|
||||
const activeModule = useMemo(
|
||||
() => flattedResponse.find((item) => item.nodeId === currentNodeId) as ChatHistoryItemResType,
|
||||
() => flattedResponse.find((item) => item.id === currentNodeId) as ChatHistoryItemResType,
|
||||
[currentNodeId, flattedResponse]
|
||||
);
|
||||
const sideResponse: sideTabItemType[] = useMemo(() => {
|
||||
|
||||
const sliderResponseList: sideTabItemType[] = useMemo(() => {
|
||||
return pretreatmentResponse(response);
|
||||
}, [response]);
|
||||
|
||||
const {
|
||||
isOpen: isOpenMobileModal,
|
||||
onOpen: onOpenMobileModal,
|
||||
@@ -174,7 +185,7 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
<Box flex={'2 0 0'} borderRight={'sm'} p={3}>
|
||||
<Box overflow={'auto'} height={'100%'}>
|
||||
<WholeResponseSideTab
|
||||
response={sideResponse}
|
||||
response={sliderResponseList}
|
||||
value={currentNodeId}
|
||||
onChange={setCurrentNodeId}
|
||||
/>
|
||||
@@ -192,7 +203,7 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
<Box h={'100%'} overflow={'auto'}>
|
||||
{!isOpenMobileModal && (
|
||||
<WholeResponseSideTab
|
||||
response={sideResponse}
|
||||
response={sliderResponseList}
|
||||
value={currentNodeId}
|
||||
onChange={(item: string) => {
|
||||
setCurrentNodeId(item);
|
||||
@@ -442,11 +453,11 @@ export const WholeResponseContent = ({
|
||||
/>
|
||||
{/* code */}
|
||||
<>
|
||||
<Row label={t('workflow:response.Custom inputs')} value={activeModule?.customInputs} />
|
||||
<Row
|
||||
label={t('workflow:response.Custom outputs')}
|
||||
value={activeModule?.customOutputs}
|
||||
/>
|
||||
<Row label={t('workflow:response.Custom inputs')} value={activeModule?.customInputs} />
|
||||
<Row label={t('workflow:response.Code log')} value={activeModule?.codeLog} />
|
||||
</>
|
||||
|
||||
@@ -491,6 +502,12 @@ export const WholeResponseContent = ({
|
||||
label={t('common:core.chat.response.user_select_result')}
|
||||
value={activeModule?.userSelectResult}
|
||||
/>
|
||||
|
||||
{/* update var */}
|
||||
<Row
|
||||
label={t('common:core.chat.response.update_var_result')}
|
||||
value={activeModule?.updateVarResult}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
@@ -512,7 +529,7 @@ const WholeResponseSideTab = ({
|
||||
<>
|
||||
{response.map((item) => (
|
||||
<Box
|
||||
key={item.nodeId}
|
||||
key={item.id}
|
||||
bg={isMobile ? 'myGray.100' : ''}
|
||||
m={isMobile ? 3 : 0}
|
||||
borderRadius={'md'}
|
||||
@@ -532,7 +549,7 @@ const AccordionSideTabItem = ({
|
||||
index
|
||||
}: {
|
||||
sideBarItem: sideTabItemType;
|
||||
onChange: (nodeId: string) => void;
|
||||
onChange: (id: string) => void;
|
||||
value: string;
|
||||
index: number;
|
||||
}) => {
|
||||
@@ -565,7 +582,7 @@ const AccordionSideTabItem = ({
|
||||
{sideBarItem.children.map((item) => (
|
||||
<SideTabItem
|
||||
value={value}
|
||||
key={item.nodeId}
|
||||
key={item.id}
|
||||
sideBarItem={item}
|
||||
onChange={onChange}
|
||||
index={index + 1}
|
||||
@@ -585,7 +602,7 @@ const NormalSideTabItem = ({
|
||||
children
|
||||
}: {
|
||||
sideBarItem: sideTabItemType;
|
||||
onChange: (nodeId: string) => void;
|
||||
onChange: (id: string) => void;
|
||||
value: string;
|
||||
index: number;
|
||||
children?: React.ReactNode;
|
||||
@@ -596,9 +613,9 @@ const NormalSideTabItem = ({
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
onClick={() => {
|
||||
onChange(sideBarItem.nodeId);
|
||||
onChange(sideBarItem.id);
|
||||
}}
|
||||
background={value === sideBarItem.nodeId ? 'myGray.100' : ''}
|
||||
background={value === sideBarItem.id ? 'myGray.100' : ''}
|
||||
_hover={{ background: 'myGray.100' }}
|
||||
p={2}
|
||||
width={'100%'}
|
||||
@@ -647,7 +664,7 @@ const SideTabItem = ({
|
||||
index
|
||||
}: {
|
||||
sideBarItem: sideTabItemType;
|
||||
onChange: (nodeId: string) => void;
|
||||
onChange: (id: string) => void;
|
||||
value: string;
|
||||
index: number;
|
||||
}) => {
|
||||
@@ -668,6 +685,7 @@ const SideTabItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
/* Format response data to slider data */
|
||||
function pretreatmentResponse(res: ChatHistoryItemResType[]): sideTabItemType[] {
|
||||
return res.map((item) => {
|
||||
let children: sideTabItemType[] = [];
|
||||
@@ -681,12 +699,13 @@ function pretreatmentResponse(res: ChatHistoryItemResType[]): sideTabItemType[]
|
||||
moduleName: item.moduleName,
|
||||
runningTime: item.runningTime,
|
||||
moduleType: item.moduleType,
|
||||
nodeId: item.nodeId,
|
||||
id: item.id ?? item.nodeId,
|
||||
children
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* Flat response */
|
||||
function flattenArray(arr: ChatHistoryItemResType[]) {
|
||||
const result: ChatHistoryItemResType[] = [];
|
||||
|
||||
|
@@ -56,9 +56,9 @@ const FlowController = React.memo(function FlowController() {
|
||||
<>
|
||||
<MiniMap
|
||||
style={{
|
||||
height: 98,
|
||||
width: 184,
|
||||
marginBottom: 72,
|
||||
height: 92,
|
||||
width: 150,
|
||||
marginBottom: 62,
|
||||
borderRadius: '10px',
|
||||
boxShadow: '0px 0px 1px rgba(19, 51, 107, 0.10), 0px 4px 10px rgba(19, 51, 107, 0.10)'
|
||||
}}
|
||||
@@ -68,7 +68,7 @@ const FlowController = React.memo(function FlowController() {
|
||||
position={'bottom-right'}
|
||||
style={{
|
||||
display: 'flex',
|
||||
marginBottom: 24,
|
||||
marginBottom: 16,
|
||||
padding: '5px 8px',
|
||||
background: 'white',
|
||||
borderRadius: '6px',
|
||||
|
@@ -375,15 +375,21 @@ const ConditionSelect = ({
|
||||
return [];
|
||||
}, [valueType]);
|
||||
const filterQuiredConditionList = useMemo(() => {
|
||||
if (required) {
|
||||
return conditionList.filter(
|
||||
(item) =>
|
||||
item.value !== VariableConditionEnum.isEmpty &&
|
||||
item.value !== VariableConditionEnum.isNotEmpty
|
||||
);
|
||||
}
|
||||
return conditionList;
|
||||
}, [conditionList, required]);
|
||||
const list = (() => {
|
||||
if (required) {
|
||||
return conditionList.filter(
|
||||
(item) =>
|
||||
item.value !== VariableConditionEnum.isEmpty &&
|
||||
item.value !== VariableConditionEnum.isNotEmpty
|
||||
);
|
||||
}
|
||||
return conditionList;
|
||||
})();
|
||||
return list.map((item) => ({
|
||||
...item,
|
||||
label: t(item.label)
|
||||
}));
|
||||
}, [conditionList, required, t]);
|
||||
|
||||
return (
|
||||
<MySelect
|
||||
|
@@ -87,7 +87,9 @@ export const getEditorVariables = ({
|
||||
appDetail: AppDetailType;
|
||||
t: TFunction;
|
||||
}) => {
|
||||
const currentNode = nodeList.find((node) => node.nodeId === nodeId)!;
|
||||
const currentNode = nodeList.find((node) => node.nodeId === nodeId);
|
||||
if (!currentNode) return [];
|
||||
|
||||
const nodeVariables = currentNode.inputs
|
||||
.filter((input) => input.canEdit)
|
||||
.map((item) => ({
|
||||
|
Reference in New Issue
Block a user