feat(flows): 新增流程编辑器基础功能与相关组件
feat(backend): 添加流程模型与服务支持 feat(frontend): 实现流程编辑器UI与交互 feat(assets): 添加流程节点图标资源 feat(plugins): 实现上下文菜单和运行时插件 feat(components): 新增基础节点和侧边栏组件 feat(routes): 添加流程相关路由配置 feat(models): 创建流程和运行日志数据模型 feat(services): 实现流程服务层逻辑 feat(migration): 添加流程相关数据库迁移 feat(config): 更新前端配置支持流程编辑器 feat(utils): 增强axios错误处理和工具函数
This commit is contained in:
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
import { NodePanelResult, WorkflowNodePanelService } from '@flowgram.ai/free-node-panel-plugin';
|
||||
import {
|
||||
Layer,
|
||||
injectable,
|
||||
inject,
|
||||
FreeLayoutPluginContext,
|
||||
WorkflowHoverService,
|
||||
WorkflowNodeEntity,
|
||||
WorkflowNodeJSON,
|
||||
WorkflowSelectService,
|
||||
WorkflowDocument,
|
||||
PositionSchema,
|
||||
WorkflowDragService,
|
||||
} from '@flowgram.ai/free-layout-editor';
|
||||
import { ContainerUtils } from '@flowgram.ai/free-container-plugin';
|
||||
|
||||
@injectable()
|
||||
export class ContextMenuLayer extends Layer {
|
||||
@inject(FreeLayoutPluginContext) ctx: FreeLayoutPluginContext;
|
||||
|
||||
@inject(WorkflowNodePanelService) nodePanelService: WorkflowNodePanelService;
|
||||
|
||||
@inject(WorkflowHoverService) hoverService: WorkflowHoverService;
|
||||
|
||||
@inject(WorkflowSelectService) selectService: WorkflowSelectService;
|
||||
|
||||
@inject(WorkflowDocument) document: WorkflowDocument;
|
||||
|
||||
@inject(WorkflowDragService) dragService: WorkflowDragService;
|
||||
|
||||
onReady() {
|
||||
this.listenPlaygroundEvent('contextmenu', (e) => {
|
||||
if (this.config.readonlyOrDisabled) return;
|
||||
this.openNodePanel(e);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
openNodePanel(e: MouseEvent) {
|
||||
const mousePos = this.getPosFromMouseEvent(e);
|
||||
const containerNode = this.getContainerNode(mousePos);
|
||||
this.nodePanelService.callNodePanel({
|
||||
position: mousePos,
|
||||
containerNode,
|
||||
panelProps: {},
|
||||
// handle node selection from panel - 处理从面板中选择节点
|
||||
onSelect: async (panelParams?: NodePanelResult) => {
|
||||
if (!panelParams) {
|
||||
return;
|
||||
}
|
||||
const { nodeType, nodeJSON } = panelParams;
|
||||
const position = this.dragService.adjustSubNodePosition(nodeType, containerNode, mousePos);
|
||||
// create new workflow node based on selected type - 根据选择的类型创建新的工作流节点
|
||||
const node: WorkflowNodeEntity = this.ctx.document.createWorkflowNodeByType(
|
||||
nodeType,
|
||||
position,
|
||||
nodeJSON ?? ({} as WorkflowNodeJSON),
|
||||
containerNode?.id
|
||||
);
|
||||
// select the newly created node - 选择新创建的节点
|
||||
this.selectService.select(node);
|
||||
},
|
||||
// handle panel close - 处理面板关闭
|
||||
onClose: () => {},
|
||||
});
|
||||
}
|
||||
|
||||
private getContainerNode(mousePos: PositionSchema): WorkflowNodeEntity | undefined {
|
||||
const allNodes = this.document.getAllNodes();
|
||||
const containerTransforms = ContainerUtils.getContainerTransforms(allNodes);
|
||||
const collisionTransform = ContainerUtils.getCollisionTransform({
|
||||
targetPoint: mousePos,
|
||||
transforms: containerTransforms,
|
||||
document: this.document,
|
||||
});
|
||||
return collisionTransform?.entity;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
import {
|
||||
definePluginCreator,
|
||||
PluginCreator,
|
||||
FreeLayoutPluginContext,
|
||||
} from '@flowgram.ai/free-layout-editor';
|
||||
|
||||
import { ContextMenuLayer } from './context-menu-layer';
|
||||
|
||||
export interface ContextMenuPluginOptions {}
|
||||
|
||||
/**
|
||||
* Creates a plugin of contextmenu
|
||||
* @param ctx - The plugin context, containing the document and other relevant information.
|
||||
* @param options - Plugin options, currently an empty object.
|
||||
*/
|
||||
export const createContextMenuPlugin: PluginCreator<ContextMenuPluginOptions> = definePluginCreator<
|
||||
ContextMenuPluginOptions,
|
||||
FreeLayoutPluginContext
|
||||
>({
|
||||
onInit(ctx, options) {
|
||||
ctx.playground.registerLayer(ContextMenuLayer);
|
||||
},
|
||||
});
|
||||
6
frontend/src/flows/plugins/context-menu-plugin/index.ts
Normal file
6
frontend/src/flows/plugins/context-menu-plugin/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
export { createContextMenuPlugin } from './context-menu-plugin';
|
||||
Reference in New Issue
Block a user