mirror of
https://github.com/tencentmusic/supersonic.git
synced 2026-01-08 18:57:39 +08:00
first commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Form, Button, Drawer, Space, Input, Select, message } from 'antd';
|
||||
import { formLayout } from '@/components/FormHelper/utils';
|
||||
import { createOrUpdateDatasourceRela } from '../../service';
|
||||
import { getRelationConfigInfo } from '../utils';
|
||||
import { useXFlowApp } from '@antv/xflow';
|
||||
import { CustomCommands } from '../CmdExtensions/constants';
|
||||
|
||||
export type DataSourceRelationFormDrawerProps = {
|
||||
domainId: number;
|
||||
nodeDataSource: any;
|
||||
open: boolean;
|
||||
onClose?: () => void;
|
||||
};
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { Option } = Select;
|
||||
|
||||
const DataSourceRelationFormDrawer: React.FC<DataSourceRelationFormDrawerProps> = ({
|
||||
domainId,
|
||||
open,
|
||||
nodeDataSource,
|
||||
onClose,
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const [saveLoading, setSaveLoading] = useState(false);
|
||||
const [dataSourceOptions, setDataSourceOptions] = useState<any[]>([]);
|
||||
|
||||
const app = useXFlowApp();
|
||||
|
||||
const getRelationListInfo = async () => {
|
||||
await app.commandService.executeCommand(CustomCommands.DATASOURCE_RELATION.id, {});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const { sourceData, targetData } = nodeDataSource;
|
||||
const dataSourceFromIdentifiers = sourceData?.datasourceDetail?.identifiers || [];
|
||||
const dataSourceToIdentifiers = targetData?.datasourceDetail?.identifiers || [];
|
||||
const dataSourceToIdentifiersNames = dataSourceToIdentifiers.map((item) => {
|
||||
return item.name;
|
||||
});
|
||||
const keyOptions = dataSourceFromIdentifiers.reduce((options: any[], item: any) => {
|
||||
const { name } = item;
|
||||
if (dataSourceToIdentifiersNames.includes(name)) {
|
||||
options.push(item);
|
||||
}
|
||||
return options;
|
||||
}, []);
|
||||
setDataSourceOptions(
|
||||
keyOptions.map((item: any) => {
|
||||
const { name } = item;
|
||||
return {
|
||||
label: name,
|
||||
value: name,
|
||||
};
|
||||
}),
|
||||
);
|
||||
}, [nodeDataSource]);
|
||||
|
||||
useEffect(() => {
|
||||
const { sourceData, targetData } = nodeDataSource;
|
||||
if (!sourceData || !targetData) {
|
||||
return;
|
||||
}
|
||||
const relationList = app.commandService.getGlobal('dataSourceRelationList') || [];
|
||||
const config = getRelationConfigInfo(sourceData.id, targetData.id, relationList);
|
||||
if (config) {
|
||||
form.setFieldsValue({
|
||||
joinKey: config.joinKey,
|
||||
});
|
||||
} else {
|
||||
form.setFieldsValue({
|
||||
joinKey: '',
|
||||
});
|
||||
}
|
||||
}, [nodeDataSource]);
|
||||
|
||||
const renderContent = () => {
|
||||
return (
|
||||
<>
|
||||
<FormItem hidden={true} name="id" label="ID">
|
||||
<Input placeholder="id" />
|
||||
</FormItem>
|
||||
<FormItem label="主数据源:">{nodeDataSource?.sourceData?.name}</FormItem>
|
||||
<FormItem label="关联数据源:">{nodeDataSource?.targetData?.name}</FormItem>
|
||||
<FormItem
|
||||
name="joinKey"
|
||||
label="可关联Key:"
|
||||
tooltip="主从数据源中必须具有相同的主键或外键才可建立关联关系"
|
||||
rules={[{ required: true, message: '请选择关联Key' }]}
|
||||
>
|
||||
<Select placeholder="请选择关联Key">
|
||||
{dataSourceOptions.map((item) => (
|
||||
<Option key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</FormItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const saveRelation = async () => {
|
||||
const values = await form.validateFields();
|
||||
setSaveLoading(true);
|
||||
const { code, msg } = await createOrUpdateDatasourceRela({
|
||||
domainId,
|
||||
datasourceFrom: nodeDataSource?.sourceData?.id,
|
||||
datasourceTo: nodeDataSource?.targetData?.id,
|
||||
...values,
|
||||
});
|
||||
setSaveLoading(false);
|
||||
if (code === 200) {
|
||||
message.success('保存成功');
|
||||
getRelationListInfo();
|
||||
onClose?.();
|
||||
return;
|
||||
}
|
||||
message.error(msg);
|
||||
};
|
||||
|
||||
const renderFooter = () => {
|
||||
return (
|
||||
<Space>
|
||||
<Button
|
||||
onClick={() => {
|
||||
onClose?.();
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
loading={saveLoading}
|
||||
onClick={() => {
|
||||
saveRelation();
|
||||
}}
|
||||
>
|
||||
完成
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
forceRender
|
||||
width={400}
|
||||
getContainer={false}
|
||||
title={'数据源关联信息'}
|
||||
mask={false}
|
||||
open={open}
|
||||
footer={renderFooter()}
|
||||
onClose={() => {
|
||||
onClose?.();
|
||||
}}
|
||||
>
|
||||
<Form {...formLayout} form={form}>
|
||||
{renderContent()}
|
||||
</Form>
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataSourceRelationFormDrawer;
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { WorkspacePanel } from '@antv/xflow';
|
||||
import type { NsJsonSchemaForm } from '@antv/xflow';
|
||||
import XflowJsonSchemaFormDrawerForm from './XflowJsonSchemaFormDrawerForm';
|
||||
|
||||
export type CreateFormProps = {
|
||||
controlMapService?: any;
|
||||
formSchemaService?: any;
|
||||
formValueUpdateService?: any;
|
||||
};
|
||||
|
||||
const XflowJsonSchemaFormDrawer: React.FC<CreateFormProps> = ({
|
||||
controlMapService,
|
||||
formSchemaService,
|
||||
formValueUpdateService,
|
||||
}) => {
|
||||
const defaultFormValueUpdateService: NsJsonSchemaForm.IFormValueUpdateService = async () => {};
|
||||
const defaultFormSchemaService: NsJsonSchemaForm.IFormSchemaService = async () => {
|
||||
return { tabs: [] };
|
||||
};
|
||||
const defaultControlMapService: NsJsonSchemaForm.IControlMapService = (controlMap) => {
|
||||
return controlMap;
|
||||
};
|
||||
return (
|
||||
<WorkspacePanel position={{}}>
|
||||
<XflowJsonSchemaFormDrawerForm
|
||||
controlMapService={controlMapService || defaultControlMapService}
|
||||
formSchemaService={formSchemaService || defaultFormSchemaService}
|
||||
formValueUpdateService={formValueUpdateService || defaultFormValueUpdateService}
|
||||
/>
|
||||
</WorkspacePanel>
|
||||
);
|
||||
};
|
||||
|
||||
export default XflowJsonSchemaFormDrawer;
|
||||
@@ -0,0 +1,125 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Drawer } from 'antd';
|
||||
import { WorkspacePanel, useXFlowApp, useModelAsync, XFlowGraphCommands } from '@antv/xflow';
|
||||
import { useJsonSchemaFormModel } from '@antv/xflow-extension/es/canvas-json-schema-form/service';
|
||||
import { NS_DATA_SOURCE_RELATION_MODAL_OPEN_STATE } from '../ConfigModelService';
|
||||
import { connect } from 'umi';
|
||||
import { DATASOURCE_NODE_RENDER_ID } from '../constant';
|
||||
import DataSourceRelationFormDrawer from './DataSourceRelationFormDrawer';
|
||||
import { GraphApi } from '../service';
|
||||
import type { StateType } from '../../model';
|
||||
import DataSource from '../../Datasource';
|
||||
|
||||
export type CreateFormProps = {
|
||||
controlMapService: any;
|
||||
formSchemaService: any;
|
||||
formValueUpdateService: any;
|
||||
domainManger: StateType;
|
||||
};
|
||||
|
||||
const XflowJsonSchemaFormDrawerForm: React.FC<CreateFormProps> = (props) => {
|
||||
const { domainManger } = props;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [createModalVisible, setCreateModalVisible] = useState<boolean>(false);
|
||||
const [dataSourceItem, setDataSourceItem] = useState<any>();
|
||||
const [nodeDataSource, setNodeDataSource] = useState<any>({
|
||||
sourceData: {},
|
||||
targetData: {},
|
||||
});
|
||||
|
||||
const app = useXFlowApp();
|
||||
// 借用JsonSchemaForm钩子函数对元素状态进行监听
|
||||
const { state, commandService, modelService } = useJsonSchemaFormModel({
|
||||
...props,
|
||||
targetType: ['node', 'edge', 'canvas', 'group'],
|
||||
position: {},
|
||||
});
|
||||
|
||||
const [modalOpenState] = useModelAsync({
|
||||
getModel: async () => {
|
||||
return await modelService.awaitModel(NS_DATA_SOURCE_RELATION_MODAL_OPEN_STATE.ID);
|
||||
},
|
||||
initialState: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const { open } = modalOpenState as any;
|
||||
setVisible(open);
|
||||
}, [modalOpenState]);
|
||||
|
||||
useEffect(() => {
|
||||
const { targetType, targetData } = state;
|
||||
if (targetType && ['node', 'edge'].includes(targetType)) {
|
||||
const { renderKey, payload } = targetData as any;
|
||||
if (renderKey === DATASOURCE_NODE_RENDER_ID) {
|
||||
setDataSourceItem(payload);
|
||||
setCreateModalVisible(true);
|
||||
} else {
|
||||
const { sourceNodeData, targetNodeData } = targetData as any;
|
||||
setNodeDataSource({
|
||||
sourceData: sourceNodeData.payload,
|
||||
targetData: targetNodeData.payload,
|
||||
});
|
||||
setVisible(true);
|
||||
}
|
||||
}
|
||||
}, [state]);
|
||||
|
||||
const resetSelectedNode = async () => {
|
||||
const x6Graph = await app.graphProvider.getGraphInstance();
|
||||
x6Graph.resetSelection();
|
||||
};
|
||||
|
||||
const handleDataSourceRelationDrawerClose = () => {
|
||||
resetSelectedNode();
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<WorkspacePanel position={{}}>
|
||||
<DataSourceRelationFormDrawer
|
||||
domainId={domainManger.selectDomainId}
|
||||
nodeDataSource={nodeDataSource}
|
||||
onClose={() => {
|
||||
handleDataSourceRelationDrawerClose();
|
||||
}}
|
||||
open={visible}
|
||||
/>
|
||||
<Drawer
|
||||
width={'100%'}
|
||||
destroyOnClose
|
||||
title="数据源编辑"
|
||||
open={createModalVisible}
|
||||
onClose={() => {
|
||||
resetSelectedNode();
|
||||
setCreateModalVisible(false);
|
||||
setDataSourceItem(undefined);
|
||||
}}
|
||||
footer={null}
|
||||
>
|
||||
<DataSource
|
||||
initialValues={dataSourceItem}
|
||||
domainId={Number(domainManger?.selectDomainId)}
|
||||
onSubmitSuccess={(dataSourceInfo: any) => {
|
||||
setCreateModalVisible(false);
|
||||
const { targetCell, targetData } = state;
|
||||
targetCell?.setData({
|
||||
...targetData,
|
||||
label: dataSourceInfo.name,
|
||||
payload: dataSourceInfo,
|
||||
id: `dataSource-${dataSourceInfo.id}`,
|
||||
});
|
||||
setDataSourceItem(undefined);
|
||||
commandService.executeCommand(XFlowGraphCommands.SAVE_GRAPH_DATA.id, {
|
||||
saveGraphDataService: (meta, graphData) => GraphApi.saveGraphData!(meta, graphData),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
</WorkspacePanel>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ domainManger }: { domainManger: StateType }) => ({
|
||||
domainManger,
|
||||
}))(XflowJsonSchemaFormDrawerForm);
|
||||
Reference in New Issue
Block a user