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:
168
frontend/src/flows/components/comment/hooks/use-size.ts
Normal file
168
frontend/src/flows/components/comment/hooks/use-size.ts
Normal file
@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
FlowNodeFormData,
|
||||
FormModelV2,
|
||||
FreeOperationType,
|
||||
HistoryService,
|
||||
TransformData,
|
||||
useCurrentEntity,
|
||||
usePlayground,
|
||||
useService,
|
||||
} from '@flowgram.ai/free-layout-editor';
|
||||
|
||||
import { CommentEditorFormField } from '../constant';
|
||||
|
||||
export const useSize = () => {
|
||||
const node = useCurrentEntity();
|
||||
const nodeMeta = node.getNodeMeta();
|
||||
const playground = usePlayground();
|
||||
const historyService = useService(HistoryService);
|
||||
const { size = { width: 240, height: 150 } } = nodeMeta;
|
||||
const transform = node.getData(TransformData);
|
||||
const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
|
||||
const formSize = formModel.getValueIn<{ width: number; height: number }>(
|
||||
CommentEditorFormField.Size
|
||||
);
|
||||
|
||||
const [width, setWidth] = useState(formSize?.width ?? size.width);
|
||||
const [height, setHeight] = useState(formSize?.height ?? size.height);
|
||||
|
||||
// 初始化表单值
|
||||
useEffect(() => {
|
||||
const initSize = formModel.getValueIn<{ width: number; height: number }>(
|
||||
CommentEditorFormField.Size
|
||||
);
|
||||
if (!initSize) {
|
||||
formModel.setValueIn(CommentEditorFormField.Size, {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
}
|
||||
}, [formModel, width, height]);
|
||||
|
||||
// 同步表单外部值变化:初始化/undo/redo/协同
|
||||
useEffect(() => {
|
||||
const disposer = formModel.onFormValuesChange(({ name }) => {
|
||||
if (name !== CommentEditorFormField.Size) {
|
||||
return;
|
||||
}
|
||||
const newSize = formModel.getValueIn<{ width: number; height: number }>(
|
||||
CommentEditorFormField.Size
|
||||
);
|
||||
if (!newSize) {
|
||||
return;
|
||||
}
|
||||
setWidth(newSize.width);
|
||||
setHeight(newSize.height);
|
||||
});
|
||||
return () => disposer.dispose();
|
||||
}, [formModel]);
|
||||
|
||||
const onResize = useCallback(() => {
|
||||
const resizeState = {
|
||||
width,
|
||||
height,
|
||||
originalWidth: width,
|
||||
originalHeight: height,
|
||||
positionX: transform.position.x,
|
||||
positionY: transform.position.y,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
const resizing = (delta: { top: number; right: number; bottom: number; left: number }) => {
|
||||
if (!resizeState) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { zoom } = playground.config;
|
||||
|
||||
const top = delta.top / zoom;
|
||||
const right = delta.right / zoom;
|
||||
const bottom = delta.bottom / zoom;
|
||||
const left = delta.left / zoom;
|
||||
|
||||
const minWidth = 120;
|
||||
const minHeight = 80;
|
||||
|
||||
const newWidth = Math.max(minWidth, resizeState.originalWidth + right - left);
|
||||
const newHeight = Math.max(minHeight, resizeState.originalHeight + bottom - top);
|
||||
|
||||
// 如果宽度或高度小于最小值,则不更新偏移量
|
||||
const newOffsetX =
|
||||
(left > 0 || right < 0) && newWidth <= minWidth
|
||||
? resizeState.offsetX
|
||||
: left / 2 + right / 2;
|
||||
const newOffsetY =
|
||||
(top > 0 || bottom < 0) && newHeight <= minHeight ? resizeState.offsetY : top;
|
||||
|
||||
const newPositionX = resizeState.positionX + newOffsetX;
|
||||
const newPositionY = resizeState.positionY + newOffsetY;
|
||||
|
||||
resizeState.width = newWidth;
|
||||
resizeState.height = newHeight;
|
||||
resizeState.offsetX = newOffsetX;
|
||||
resizeState.offsetY = newOffsetY;
|
||||
|
||||
// 更新状态
|
||||
setWidth(newWidth);
|
||||
setHeight(newHeight);
|
||||
|
||||
// 更新偏移量
|
||||
transform.update({
|
||||
position: {
|
||||
x: newPositionX,
|
||||
y: newPositionY,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const resizeEnd = () => {
|
||||
historyService.transact(() => {
|
||||
historyService.pushOperation(
|
||||
{
|
||||
type: FreeOperationType.dragNodes,
|
||||
value: {
|
||||
ids: [node.id],
|
||||
value: [
|
||||
{
|
||||
x: resizeState.positionX + resizeState.offsetX,
|
||||
y: resizeState.positionY + resizeState.offsetY,
|
||||
},
|
||||
],
|
||||
oldValue: [
|
||||
{
|
||||
x: resizeState.positionX,
|
||||
y: resizeState.positionY,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
noApply: true,
|
||||
}
|
||||
);
|
||||
formModel.setValueIn(CommentEditorFormField.Size, {
|
||||
width: resizeState.width,
|
||||
height: resizeState.height,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
resizing,
|
||||
resizeEnd,
|
||||
};
|
||||
}, [node, width, height, transform, playground, formModel, historyService]);
|
||||
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
onResize,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user