Coze源码分析-资源库-编辑工作流-前端源码-核心组件
概述
本文深入分析Coze Studio中用户创建工作流功能的前端实现。该功能允许用户在资源库中创建、编辑和管理工作流资源,为开发者提供了强大的自动化流程构建和业务逻辑编排能力。通过对源码的详细解析,我们将了解从资源库入口到工作流配置弹窗的完整架构设计、组件实现、状态管理和用户体验优化等核心技术要点。
功能特性
核心功能
- 工作流创建:支持自定义工作流名称、描述和图标配置
- 工作流管理:提供工作流列表展示、编辑和删除功能
- 多种工作流类型:支持Workflow(通用工作流)和ChatFlow(对话流)两种模式
- 模板支持:支持从模板创建工作流,快速构建业务场景
- 状态管理:支持工作流启用/禁用状态切换和协作模式
用户体验特性
- 即时反馈:操作结果实时展示和验证
- 表单验证:完善的工作流信息验证机制
- 便捷操作:支持一键创建、快速编辑和复制功能
- 国际化支持:多语言界面适配
技术架构
整体架构设计
┌─────────────────────────────────────────────────────────────┐
│ 工作流管理模块 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ LibraryPage │ │LibraryHeader│ │CreateWorkflow │ │
│ │ (资源库页面) │ │ (添加按钮) │ │ Modal │ │
│ └─────────────┘ └─────────────┘ │ (创建/编辑弹窗) │ │
│ ┌─────────────┐ ┌─────────────┐ └─────────────────────┘ │
│ │BaseLibrary │ │ Table │ ┌─────────────────────┐ │
│ │ Page │ │ (资源列表) │ │WorkflowModal │ │
│ └─────────────┘ └─────────────┘ │(模板选择弹窗) │ │
│ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 状态管理层 │
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │useWorkflowConfig │ │ useWorkflowResourceAction │ │
│ │ (配置逻辑) │ │ useCreateWorkflowModal │ │
│ └─────────────────┘ └─────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ API服务层 │
│ ┌─────────────────────────────────────────────────────────┐
│ │ Workflow API │
│ │ 工作流创建/删除/更新相关API接口 │
│ └─────────────────────────────────────────────────────────┘
└────────────────────────────────────────────────────────────┘
核心模块结构
frontend/
├── apps/coze-studio/src/
│ └── pages/
│ ├── library.tsx # 资源库入口页面
│ ├── plugin/ # 插件相关页面
│ └── develop.tsx # 开发页面
├── packages/studio/workspace/
│ ├── entry-adapter/src/pages/library/
│ │ └── index.tsx # LibraryPage适配器组件
│ └── entry-base/src/pages/library/
│ ├── index.tsx # BaseLibraryPage核心组件
│ ├── components/
│ │ └── library-header.tsx # LibraryHeader头部组件
│ └── hooks/use-entity-configs/
│ └── use-workflow-config.tsx # 工作流配置Hook
├── packages/workflow/
│ ├── components/src/
│ │ ├── hooks/use-workflow-resource-action/
│ │ │ ├── index.tsx # useWorkflowResourceAction Hook
│ │ │ └── use-create-workflow-modal.tsx # 创建工作流弹窗Hook
│ │ ├── workflow-modal/ # 工作流模板选择弹窗
│ │ └── workflow-edit/ # 工作流编辑组件(包含CreateWorkflowModal)
│ ├── playground/src/ # 工作流画布和编辑器
│ └── base/src/
│ ├── api/ # 工作流API定义
│ └── types/ # 工作流类型定义
├── packages/arch/idl/src/auto-generated/
│ ├── workflow_api/ # 工作流API相关类型
│ └── plugin_develop/ # 插件开发相关类型
└── packages/arch/bot-api/src/└── workflow-api.ts # WorkflowApi实例定义
用户创建工作流流程概述
用户登录Coze Studio↓点击"资源库"菜单↓LibraryPage 组件加载↓点击右上角"+"按钮↓LibraryHeader 显示创建菜单↓点击"工作流"或"对话流"选项↓openCreateModal(WorkflowMode) 触发↓CreateWorkflowModal 弹窗显示↓用户选择工作流模式(Workflow/ChatFlow)↓用户输入工作流名称(name字段)↓用户输入工作流描述(description字段)↓用户选择工作流图标和配置项↓表单验证(名称必填,描述可选)↓用户点击"创建"按钮↓createWorkflow() 触发↓工作流创建API调用↓后端创建新工作流资源↓onSuccess() 处理成功响应↓导航到工作流编辑器页面↓刷新资源库列表
该流程包含多层验证和处理:
- 前端表单验证:通过Form组件进行名称等必填字段验证
- 工作流类型选择:支持Workflow(通用工作流)和ChatFlow(对话流)两种模式
- API调用:通过workflow相关API处理工作流创建
- 成功处理:创建成功后直接导航到工作流编辑器页面进行流程设计
- 状态管理:通过useWorkflowConfig和useWorkflowResourceAction Hook管理弹窗状态和数据流
整个流程确保了工作流创建的便捷性和用户体验的流畅性。
核心组件实现
组件层次结构
插件编辑功能涉及多个层次的组件:
- LibraryPage组件:资源库主页面
- BaseLibraryPage组件:资源库核心逻辑
- LibraryHeader组件:包含创建按钮的头部
- usePluginConfig Hook:插件配置和状态管理
- useBotCodeEditOutPlugin Hook:代码插件编辑弹窗管理
- CreateCodePluginModal组件:代码插件编辑弹窗
- CreateFormPluginModal组件:表单插件编辑弹窗
1. 资源库入口组件(LibraryPage)
文件位置:frontend/packages/studio/workspace/entry-adapter/src/pages/library/index.tsx
作为资源库的适配器组件,整合各种资源配置,包括插件配置:
import { type FC, useRef } from 'react';import {BaseLibraryPage,useDatabaseConfig,usePluginConfig,useWorkflowConfig,usePromptConfig,useKnowledgeConfig,
} from '@coze-studio/workspace-base/library';export const LibraryPage: FC<{ spaceId: string }> = ({ spaceId }) => {const basePageRef = useRef<{ reloadList: () => void }>(null);const configCommonParams = {spaceId,reloadList: () => {basePageRef.current?.reloadList();},};const { config: pluginConfig, modals: pluginModals } =usePluginConfig(configCommonParams);const { config: workflowConfig, modals: workflowModals } =useWorkflowConfig(configCommonParams);const { config: knowledgeConfig, modals: knowledgeModals } =useKnowledgeConfig(configCommonParams);const { config: promptConfig, modals: promptModals } =usePromptConfig(configCommonParams);const { config: databaseConfig, modals: databaseModals } =useDatabaseConfig(configCommonParams);return (<><BaseLibraryPagespaceId={spaceId}ref={basePageRef}entityConfigs={[pluginConfig,workflowConfig,knowledgeConfig,promptConfig,databaseConfig,]}/>{pluginModals}{workflowModals}{promptModals}{databaseModals}{knowledgeModals}</>);
};
设计亮点:
- 状态集中管理:通过
useWorkflowConfig
Hook统一管理组件状态 - 组件解耦:各子组件职责明确,通过props进行通信
- 数据流清晰:单向数据流,状态变更可追踪
2. 插件配置Hook(usePluginConfig)
文件位置:frontend/packages/studio/workspace/entry-base/src/pages/library/hooks/use-entity-configs/use-plugin-config.tsx
管理插件资源的配置和编辑状态,是插件编辑功能的核心Hook:
import { useNavigate } from 'react-router-dom';
import { useState } from 'react';import {ActionKey,PluginType,ResType,type ResourceInfo,
} from '@coze-arch/idl/plugin_develop';
import { I18n } from '@coze-arch/i18n';
import { PluginDevelopApi } from '@coze-arch/bot-api';
import { useBotCodeEditOutPlugin } from '@coze-agent-ide/bot-plugin/hook';
import { CreateFormPluginModal } from '@coze-agent-ide/bot-plugin/component';
import { IconCozPlugin } from '@coze-arch/coze-design/icons';
import { Menu, Tag, Toast, Table } from '@coze-arch/coze-design';export const usePluginConfig: UseEntityConfigHook = ({spaceId,reloadList,getCommonActions,
}) => {const [showFormPluginModel, setShowFormPluginModel] = useState(false);const navigate = useNavigate();const { modal: editPluginCodeModal, open } = useBotCodeEditOutPlugin({modalProps: {onSuccess: reloadList,},});return {modals: (<><CreateFormPluginModalisCreate={true}visible={showFormPluginModel}onSuccess={pluginID => {navigate(`/space/${spaceId}/plugin/${pluginID}`);reloadList();}}onCancel={() => {setShowFormPluginModel(false);}}/>{editPluginCodeModal}</>),config: {typeFilter: {label: I18n.t('library_resource_type_plugin'),value: ResType.Plugin,},renderCreateMenu: () => (<Menu.Itemdata-testid="workspace.library.header.create.plugin"icon={<IconCozPlugin />}onClick={() => {setShowFormPluginModel(true);}}>{I18n.t('library_resource_type_plugin')}</Menu.Item>),target: [ResType.Plugin],onItemClick: (item: ResourceInfo) => {if (item.res_type === ResType.Plugin &&item.res_sub_type === 2 //Plugin:1-Http; 2-App; 6-Local;) {const disable = !item.actions?.find(action => action.key === ActionKey.Delete,)?.enable;open(item.res_id || '', disable);} else {navigate(`/space/${spaceId}/plugin/${item.res_id}`);}},renderItem: item => (<BaseLibraryItemresourceInfo={item}defaultIcon={PluginDefaultIcon}tag={item.res_type === ResType.Plugin &&item.res_sub_type === PluginType.LOCAL ? (<Tagdata-testid="workspace.library.item.tag"color="cyan"size="mini"className="flex-shrink-0 flex-grow-0">{I18n.t('local_plugin_label')}</Tag>) : null}/>),renderActions: (item: ResourceInfo) => {const deleteDisabled = !item.actions?.find(action => action.key === ActionKey.Delete,)?.enable;const deleteProps = {disabled: deleteDisabled,deleteDesc: I18n.t('library_delete_desc'),handler: async () => {await PluginDevelopApi.DelPlugin({ plugin_id: item.res_id });reloadList();Toast.success(I18n.t('Delete_success'));},};return (<TableActiondeleteProps={deleteProps}actionList={getCommonActions?.(item)}/>);},},};
};
核心功能:
- 插件类型管理:支持不同类型插件的处理逻辑
- 编辑弹窗集成:集成代码插件编辑弹窗
- 菜单渲染:在创建菜单中显示插件选项
- 本地插件标识:为本地开发的插件显示特殊标签
- 资源操作:集成插件的点击、编辑、删除等操作
- 权限控制:根据操作权限控制删除功能的可用性
3. 代码插件编辑Hook(useBotCodeEditOutPlugin)
文件位置:frontend/packages/agent-ide/bot-plugin/export/src/component/bot_edit/plugin-edit/index.tsx
管理代码插件编辑弹窗的状态和编辑逻辑:
export const useBotCodeEditOutPlugin = ({modalProps,
}: {modalProps: Pick<CreatePluginProps, 'onSuccess'>;
}) => {const [pluginInfo, setPluginInfo] = useState<PluginInfoProps>({});const [modalVisible, setModalVisible] = useState(false);const [editable, setEditable] = useState(false);const [disableEdit, setDisableEdit] = useState(false);const pluginId = pluginInfo?.plugin_id || '';const action = useMemo(() => {if (disableEdit) {return null;}return (<div className={styles.actions}>{editable ? (<UIButtononClick={() => {setEditable(false);unlockOutPluginContext(pluginId);}}>{I18n.t('Cancel')}</UIButton>) : (<UIButtontheme="solid"onClick={async () => {const isLocked = await checkOutPluginContext(pluginId);if (isLocked) {return;}setEditable(true);}}>{I18n.t('Edit')}</UIButton>)}</div>);}, [editable, pluginId, disableEdit]);useEffect(() => {if (modalVisible) {setEditable(false);}}, [modalVisible]);const modal = (<CreateCodePluginModal{...modalProps}editInfo={pluginInfo}isCreate={false}visible={modalVisible}onCancel={() => {setModalVisible(false);if (!disableEdit) {unlockOutPluginContext(pluginId);}}}disabled={!editable}actions={action}/>);const open = useCallback(async (id: string, disable: boolean) => {const res = await PluginDevelopApi.GetPluginInfo({plugin_id: id || '',});setPluginInfo({plugin_id: id,code_info: {plugin_desc: res.code_info?.plugin_desc,openapi_desc: res.code_info?.openapi_desc,client_id: res.code_info?.client_id,client_secret: res.code_info?.client_secret,service_token: res.code_info?.service_token,},});setDisableEdit(disable);setModalVisible(true);}, []);return { modal, open };
};
核心功能:
- 状态管理:管理插件信息、编辑状态和弹窗可见性
- 插件锁定机制:编辑前自动检查和锁定插件,防止多人同时编辑
- 权限控制:根据disableEdit参数控制编辑权限
- 插件信息加载:通过API获取插件详细信息
- 弹窗渲染:渲染代码插件编辑弹窗组件
- 解锁机制:编辑完成或取消时自动解锁插件
4. 插件锁定检查(checkOutPluginContext)
文件位置:frontend/packages/studio/stores/bot-plugin/src/utils/api.ts
负责检查插件的锁定状态,确保编辑安全性:
export const checkOutPluginContext = async (pluginId: string) => {const resp = await PluginDevelopApi.CheckAndLockPluginEdit({plugin_id: pluginId,});if (resp.code !== 0) {return false;}const { data } = resp;const user = data?.user;/*** Someone occupies & not themselves*/if (data?.Occupied && user && !user.self) {UIModal.info({okText: I18n.t('guidance_got_it'),title: I18n.t('plugin_team_edit_tip_unable_to_edit'),content: `${user.name}(${user.space_roly_type}) ${I18n.t('plugin_team_edit_tip_another_user_is_editing')}`,hasCancel: false,});return true;}return false;
};
核心功能:
- 锁定检查:检查插件是否被其他用户锁定
- 用户提示:当插件被其他用户占用时,显示友好的提示信息
- 权限验证:确保只有合法用户可以编辑插件
- 冲突避免:通过锁定机制避免编辑冲突