Files
kevisual-center-v1/src/pages/panel/flow/properties/NodeProperties.tsx

124 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Panel, useReactFlow, useStore, useStoreApi } from '@xyflow/react';
import clsx from 'clsx';
import { useEffect, useState } from 'react';
import { debounce } from 'lodash-es';
import { Button, Form, Input, message, Tooltip } from 'antd';
import { Select } from '@/pages/container/module/Select';
import { MessageOutlined, SaveOutlined } from '@ant-design/icons';
import { emitter } from '@kevisual/container';
import { usePanelStore } from '../../store';
import { useShallow } from 'zustand/react/shallow';
import { useAiStore } from '@/pages/ai-chat';
export const NodeProperties = () => {
const reactflow = useReactFlow();
const [open, setOpen] = useState(false);
const [form] = Form.useForm();
const panelStore = usePanelStore((state) => {
return {
updateNodeData: state.updateNodeData,
};
});
const aiStore = useAiStore(
useShallow((state) => {
return {
setOpen: state.setOpen,
setKey: state.setKey,
};
}),
);
const store = useStore((state) => {
const setNode = (node: any) => {
const newNodes = state.nodes.map((item) => {
if (item.id === node.id) {
// return { ...item, ...node };
return { ...node };
}
return item;
});
// console.log('newNodes', newNodes);
// state.setNodes(newNodes); // 会丢失数据因为最终没有调用context的setNodes方法
emitter.emit('setNodes', newNodes);
};
return {
nodesFocusable: state.nodesFocusable,
selected: state.nodes.filter((node) => node.selected),
setNode: setNode,
};
});
const [nodeData] = store.selected as any[];
useEffect(() => {
if (!nodeData) return;
// console.log('nodeData', nodeData);
const { data } = nodeData || {};
form.setFieldsValue({
cid: data.cid,
title: data.title,
});
}, [nodeData]);
const onSave = () => {
const values = form.getFieldsValue();
// console.log('values', values);
const { cid, title } = values;
if (!cid) {
message.error('请选择容器');
return;
}
const { data, id, position, type } = nodeData || {};
// console.log('data', data, cid);
const newNodeData = {
id,
position,
selected: true,
type,
data: {
...data,
cid,
title,
},
};
// console.log('newNodeData', newNodeData, nodeData);
store.setNode(newNodeData);
panelStore.updateNodeData(newNodeData);
};
return (
<Panel title='节点属性' position='bottom-center' className='w-full'>
<div className={clsx('w-full h-[200px] card', store.selected.length > 0 ? '' : 'hidden')}>
<div className='card-title'>
{nodeData?.data?.label}
<Button.Group className='ml-2'>
<Tooltip title='Save'>
<Button onClick={onSave} icon={<SaveOutlined />}></Button>
</Tooltip>
<Tooltip title='Ai Chat'>
<Button
onClick={() => {
aiStore.setKey(location.pathname);
aiStore.setOpen(true);
}}
icon={<MessageOutlined />}></Button>
</Tooltip>
</Button.Group>
</div>
<div className='p-4'>
<Form form={form}>
<Form.Item label='名称' name='cid'>
<Select
onChange={(e, options) => {
if (Array.isArray(options)) {
} else {
const title = options?.label;
form.setFieldsValue({ title });
}
}}
/>
</Form.Item>
<Form.Item label='标题' name='title'>
<Input />
</Form.Item>
</Form>
</div>
</div>
</Panel>
);
};