Skip to content

Commit

Permalink
Workflow experience optimization (#2681)
Browse files Browse the repository at this point in the history
* perf: workflow handle connect

* feat: pan drag mode

* perf: workflow keyboard and touchTable adapt

* perf: teaxtarea no wheel

* remove render error
  • Loading branch information
c121914yu committed Sep 12, 2024
1 parent e5b26e0 commit 985a5a0
Show file tree
Hide file tree
Showing 22 changed files with 250 additions and 189 deletions.
19 changes: 8 additions & 11 deletions docSite/content/zh-cn/docs/development/upgrading/4811.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ weight: 813

-------

## V4.8.11 更新预告
## V4.8.11 更新说明

1.
2. 新增 - 工作流循环执行节点。
3. 新增 - 工作流用户表单输入节点。
4. 新增 - 插件输出,支持指定某些字段为工具调用结果。
5. 新增 - 插件支持配置使用引导、全局变量和文件输入。
6. 新增 - 简易模式支持新的版本管理方式。
7. 新增 - 聊天记录滚动加载,不再只加载 30 条。
8. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。
9. 优化 - 工作流 handler 性能优化。
10. 修复 - 知识库选择权限问题。
11. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。
2. 新增 - 聊天记录滚动加载,不再只加载 30 条。
3. 新增 - 工作流增加触摸板优先模式。
4. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。
5. 优化 - 工作流 handler 性能优化。
6. 优化 - 工作流快捷键,避免调试测试时也会触发。
7. 修复 - 知识库选择权限问题。
8. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。
6 changes: 4 additions & 2 deletions packages/web/components/common/Icon/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

export const iconPaths = {
book: () => import('./icons/book.svg'),
visible: () => import('./icons/visible.svg'),
change: () => import('./icons/change.svg'),
chatSend: () => import('./icons/chatSend.svg'),
configmap: () => import('./icons/configmap.svg'),
closeSolid: () => import('./icons/closeSolid.svg'),
collectionLight: () => import('./icons/collectionLight.svg'),
collectionSolid: () => import('./icons/collectionSolid.svg'),
Expand Down Expand Up @@ -80,6 +78,7 @@ export const iconPaths = {
'common/voiceLight': () => import('./icons/common/voiceLight.svg'),
'common/warn': () => import('./icons/common/warn.svg'),
'common/wechatFill': () => import('./icons/common/wechatFill.svg'),
configmap: () => import('./icons/configmap.svg'),
copy: () => import('./icons/copy.svg'),
'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'),
'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'),
Expand Down Expand Up @@ -199,6 +198,7 @@ export const iconPaths = {
import('./icons/core/workflow/inputType/selectLLM.svg'),
'core/workflow/inputType/switch': () => import('./icons/core/workflow/inputType/switch.svg'),
'core/workflow/inputType/textarea': () => import('./icons/core/workflow/inputType/textarea.svg'),
'core/workflow/mouse': () => import('./icons/core/workflow/mouse.svg'),
'core/workflow/publish': () => import('./icons/core/workflow/publish.svg'),
'core/workflow/redo': () => import('./icons/core/workflow/redo.svg'),
'core/workflow/revertVersion': () => import('./icons/core/workflow/revertVersion.svg'),
Expand Down Expand Up @@ -249,6 +249,7 @@ export const iconPaths = {
import('./icons/core/workflow/template/variableUpdate.svg'),
'core/workflow/template/workflowStart': () =>
import('./icons/core/workflow/template/workflowStart.svg'),
'core/workflow/touchTable': () => import('./icons/core/workflow/touchTable.svg'),
'core/workflow/undo': () => import('./icons/core/workflow/undo.svg'),
'core/workflow/upload': () => import('./icons/core/workflow/upload.svg'),
'core/workflow/versionHistories': () => import('./icons/core/workflow/versionHistories.svg'),
Expand Down Expand Up @@ -332,5 +333,6 @@ export const iconPaths = {
text: () => import('./icons/text.svg'),
union: () => import('./icons/union.svg'),
user: () => import('./icons/user.svg'),
visible: () => import('./icons/visible.svg'),
wx: () => import('./icons/wx.svg')
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const MultipleRowSelect = ({
return (
<>
<Box
className="nowheel"
flex={'1 0 auto'}
// width={0}
px={2}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default function Editor({

return (
<Box
className="nowheel"
position={'relative'}
width={'full'}
h={`${height}px`}
Expand Down
4 changes: 3 additions & 1 deletion packages/web/i18n/en/workflow.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@
"less_than_or_equal_to": "Less Than or Equal To",
"max_dialog_rounds": "Maximum Number of Dialog Rounds",
"max_tokens": "Maximum Tokens",
"mouse_priority": "Mouse first",
"new_context": "New Context",
"not_contains": "Does Not Contain",
"only_the_reference_type_is_supported": "Only reference type is supported",
"optional_value_type": "Optional Value Type",
"optional_value_type_tip": "You can specify one or more data types. When dynamically adding fields, users can only select the configured types.",
"other_questions": "Other Questions",
"pan_priority": "Touchpad first",
"pass_returned_object_as_output_to_next_nodes": "Pass the object returned in the code as output to the next nodes. The variable name needs to correspond to the return key.",
"plugin": {
"Instruction_Tip": "You can configure an instruction to explain the purpose of the plugin. This instruction will be displayed each time the plugin is used. Supports standard Markdown syntax.",
Expand Down Expand Up @@ -151,4 +153,4 @@
"Team cloud": "Team Cloud",
"exit_tips": "Your changes have not been saved. 'Exit directly' will not save your edits."
}
}
}
4 changes: 3 additions & 1 deletion packages/web/i18n/zh/workflow.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@
"less_than_or_equal_to": "小于等于",
"max_dialog_rounds": "最多携带多少轮对话记录",
"max_tokens": "最大 Tokens",
"mouse_priority": "鼠标优先",
"new_context": "新的上下文",
"not_contains": "不包含",
"only_the_reference_type_is_supported": "仅支持引用类型",
"optional_value_type": "可选的数据类型",
"optional_value_type_tip": "可以指定 1 个或多个数据类型,用户在动态添加字段时,仅可选择配置的类型",
"other_questions": "其他问题",
"pan_priority": "触摸板优先",
"pass_returned_object_as_output_to_next_nodes": "将代码中 return 的对象作为输出,传递给后续的节点。变量名需要对应 return 的 key",
"plugin": {
"Instruction_Tip": "可以配置一段说明,以解释该插件的用途。每次使用插件前,会显示该段说明。支持标准 Markdown 语法。",
Expand Down Expand Up @@ -151,4 +153,4 @@
"Team cloud": "团队云端",
"exit_tips": "您的更改尚未保存,「直接退出」将不会保存您的编辑记录。"
}
}
}
8 changes: 7 additions & 1 deletion projects/app/src/components/Select/AIModelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ const AIModelSelector = ({ list, onchange, disableTip, ...props }: Props) => {

return (
<MyTooltip label={disableTip}>
<MySelect isDisabled={!!disableTip} list={expandList} {...props} onchange={onSelect} />
<MySelect
className="nowheel"
isDisabled={!!disableTip}
list={expandList}
{...props}
onchange={onSelect}
/>
</MyTooltip>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ const AppCard = ({

const { appDetail, onOpenInfoEdit, onOpenTeamTagModal, onDelApp, currentTab } =
useContextSelector(AppContext, (v) => v);
const { historiesDefaultData, onSaveWorkflow, isSaving } = useContextSelector(
WorkflowContext,
(v) => v
);
const { historiesDefaultData } = useContextSelector(WorkflowContext, (v) => v);

const { isOpen: isOpenImport, onOpen: onOpenImport, onClose: onCloseImport } = useDisclosure();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,58 @@
import React, { useEffect, useMemo } from 'react';
import React, { useMemo } from 'react';
import { Background, ControlButton, MiniMap, Panel, useReactFlow, useViewport } from 'reactflow';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '../../context';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { Box } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { useTranslation } from 'next-i18next';
import styles from './index.module.scss';
import { maxZoom, minZoom } from '../index';
import { useKeyPress } from 'ahooks';

const buttonStyle = {
border: 'none',
borderRadius: '6px',
padding: '7px'
};

const FlowController = React.memo(function FlowController() {
const { fitView, zoomIn, zoomOut } = useReactFlow();
const { zoom } = useViewport();
const { undo, redo, canRedo, canUndo } = useContextSelector(WorkflowContext, (v) => v);
const {
undo,
redo,
canRedo,
canUndo,
workflowControlMode,
setWorkflowControlMode,
mouseInCanvas
} = useContextSelector(WorkflowContext, (v) => v);
const { t } = useTranslation();

const isMac = !window ? false : window.navigator.userAgent.toLocaleLowerCase().includes('mac');

useEffect(() => {
const keyDownHandler = (event: KeyboardEvent) => {
if (
(event.key === 'z' || event.key === 'Z') &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey
) {
event.preventDefault();
redo();
} else if (event.key === 'z' && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
undo();
} else if ((event.key === '=' || event.key === '+') && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
zoomIn();
} else if (event.key === '-' && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
zoomOut();
}
};

document.addEventListener('keydown', keyDownHandler);

return () => {
document.removeEventListener('keydown', keyDownHandler);
};
}, [undo, redo, zoomIn, zoomOut]);

const buttonStyle = {
border: 'none',
borderRadius: '6px',
padding: '7px'
};
// Controller shortcut key
useKeyPress(['ctrl.z', 'meta.z'], (e) => {
e.preventDefault();
if (!mouseInCanvas) return;
undo();
});
useKeyPress(['ctrl.shift.z', 'meta.shift.z', 'ctrl.y', 'meta.y'], (e) => {
e.preventDefault();
if (!mouseInCanvas) return;
redo();
});
useKeyPress(['ctrl.add', 'meta.add', 'ctrl.equalsign', 'meta.equalsign'], (e) => {
e.preventDefault();
if (!mouseInCanvas) return;
zoomIn();
});
useKeyPress(['ctrl.dash', 'meta.dash'], (e) => {
e.preventDefault();
if (!mouseInCanvas) return;
zoomOut();
});

const Render = useMemo(() => {
return (
Expand Down Expand Up @@ -79,6 +82,35 @@ const FlowController = React.memo(function FlowController() {
'0px 0px 1px 0px rgba(19, 51, 107, 0.20), 0px 12px 16px -4px rgba(19, 51, 107, 0.20)'
}}
>
{/* Control Mode */}
<MyTooltip
label={
workflowControlMode === 'select'
? t('workflow:pan_priority')
: t('workflow:mouse_priority')
}
>
<ControlButton
onClick={() => {
setWorkflowControlMode(workflowControlMode === 'select' ? 'drag' : 'select');
}}
style={{
...buttonStyle
}}
className={`${styles.customControlButton}`}
>
<MyIcon
name={
workflowControlMode === 'select'
? 'core/workflow/touchTable'
: 'core/workflow/mouse'
}
/>
</ControlButton>
</MyTooltip>

<Box w="1px" h="20px" bg="gray.200" mx={1.5}></Box>

{/* undo */}
<MyTooltip label={isMac ? t('common:common.undo_tip_mac') : t('common:common.undo_tip')}>
<ControlButton
Expand Down Expand Up @@ -107,7 +139,7 @@ const FlowController = React.memo(function FlowController() {

{/* zoom out */}
<MyTooltip
label={isMac ? t('common:common.zoomout_tip_mac') : t('common:common.zoomout_tip')}
label={isMac ? t('common:common.zoomin_tip_mac') : t('common:common.zoomin_tip')}
>
<ControlButton
onClick={() => zoomOut()}
Expand All @@ -121,7 +153,7 @@ const FlowController = React.memo(function FlowController() {

{/* zoom in */}
<MyTooltip
label={isMac ? t('common:common.zoomin_tip_mac') : t('common:common.zoomin_tip')}
label={isMac ? t('common:common.zoomout_tip_mac') : t('common:common.zoomout_tip')}
>
<ControlButton
onClick={() => zoomIn()}
Expand Down Expand Up @@ -149,7 +181,20 @@ const FlowController = React.memo(function FlowController() {
<Background />
</>
);
}, [isMac, t, undo, buttonStyle, canUndo, redo, canRedo, zoom, zoomOut, zoomIn, fitView]);
}, [
workflowControlMode,
isMac,
t,
undo,
canUndo,
redo,
canRedo,
zoom,
setWorkflowControlMode,
zoomOut,
zoomIn,
fitView
]);

return Render;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useTranslation } from 'next-i18next';

type FormType = {
versionName: string;
isPublish: boolean | undefined;
Expand Down
Loading

0 comments on commit 985a5a0

Please sign in to comment.