- Extract MultiCopyPopupContext to standalone context.ts file - Add Task type and improve type safety in BatchCloneModal - Use useRef/useCallback to stabilize batch clone handlers - Add cleanup effect for selectRules in RuleCheckCard on unmount Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
132 lines
4.0 KiB
TypeScript
132 lines
4.0 KiB
TypeScript
import { ArrowDownOutlined } from '@ant-design/icons';
|
|
import { ProFormDependency, ProFormSelect } from '@ant-design/pro-components';
|
|
import { Divider, Flex, Tag, Typography } from 'antd';
|
|
import { useContext, useEffect, useMemo } from 'react';
|
|
import { $t } from '@/utils/i18n';
|
|
import { MultiCopyPopupContext } from '../context';
|
|
import RuleCheckCard from './RuleCheckCard';
|
|
|
|
type Step1Props = {
|
|
formMapRef: any;
|
|
setTargetDataSourceId: (id: string | number | null) => void;
|
|
};
|
|
const Step1 = ({ formMapRef, setTargetDataSourceId }: Step1Props) => {
|
|
const { dataSourceList } = useContext(MultiCopyPopupContext);
|
|
|
|
const buildOptions = (sourceId?: string | number) => {
|
|
const sourceType = dataSourceList.find((item) => item.id === sourceId)
|
|
?.sourceType;
|
|
return dataSourceList.map((item) => ({
|
|
...item,
|
|
disabled: item.sourceType !== sourceType,
|
|
label: (
|
|
<Flex justify="space-between" align="center">
|
|
<span>{item.sourceName}</span>
|
|
<Typography.Text
|
|
type="secondary"
|
|
style={{ fontSize: 12, marginLeft: 8 }}
|
|
>
|
|
MT{item.sourceType}
|
|
</Typography.Text>
|
|
</Flex>
|
|
),
|
|
}));
|
|
};
|
|
|
|
const sourceOptions = useMemo(
|
|
() => dataSourceList.map((item) => ({
|
|
...item,
|
|
label: (
|
|
<Flex justify="space-between" align="center">
|
|
<span>{item.sourceName}</span>
|
|
<Typography.Text
|
|
type="secondary"
|
|
style={{ fontSize: 12, marginLeft: 8 }}
|
|
>
|
|
MT{item.sourceType}
|
|
</Typography.Text>
|
|
</Flex>
|
|
),
|
|
})),
|
|
[dataSourceList],
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (dataSourceList?.length) {
|
|
const sourceItem = dataSourceList[0];
|
|
const sourceDataSourceId = sourceItem?.id || '';
|
|
const sameTypeItem = dataSourceList.find(
|
|
(item) => item.id !== sourceDataSourceId && item.sourceType === sourceItem?.sourceType,
|
|
);
|
|
const targetDataSourceId = sameTypeItem?.id || sourceDataSourceId;
|
|
const curFormRef = formMapRef?.current?.[0]?.current;
|
|
if (curFormRef) {
|
|
curFormRef?.setFieldsValue({
|
|
sourceDataSourceId,
|
|
targetDataSourceId,
|
|
});
|
|
setTargetDataSourceId(targetDataSourceId);
|
|
}
|
|
}
|
|
}, [dataSourceList]);
|
|
|
|
return (
|
|
<>
|
|
<ProFormSelect
|
|
name="sourceDataSourceId"
|
|
label={$t('pages.clones.step1.source')}
|
|
options={sourceOptions}
|
|
rules={[{ required: true, message: $t('form.required') }]}
|
|
fieldProps={{
|
|
allowClear: false,
|
|
fieldNames: {
|
|
label: 'label',
|
|
value: 'id',
|
|
},
|
|
optionLabelProp: 'label',
|
|
}}
|
|
/>
|
|
<ProFormDependency name={['sourceDataSourceId']}>
|
|
{({ sourceDataSourceId }) => {
|
|
if (!sourceDataSourceId) return null;
|
|
return <RuleCheckCard dataSourceId={sourceDataSourceId} />;
|
|
}}
|
|
</ProFormDependency>
|
|
|
|
<Divider>
|
|
<Tag style={{ borderRadius: 30, padding: '4px 16px' }}>
|
|
<ArrowDownOutlined /> {$t('pages.clones.step1.dividerText')}
|
|
</Tag>
|
|
</Divider>
|
|
|
|
<ProFormDependency name={['sourceDataSourceId']}>
|
|
{({ sourceDataSourceId }) => {
|
|
if (!sourceDataSourceId) return null;
|
|
const targetOptions = buildOptions(sourceDataSourceId);
|
|
return (
|
|
<ProFormSelect
|
|
name="targetDataSourceId"
|
|
label={$t('pages.clones.step1.target')}
|
|
options={targetOptions}
|
|
rules={[{ required: true, message: $t('form.required') }]}
|
|
fieldProps={{
|
|
allowClear: false,
|
|
fieldNames: {
|
|
label: 'label',
|
|
value: 'id',
|
|
},
|
|
optionLabelProp: 'label',
|
|
}}
|
|
onChange={(value: string | number | null) => {
|
|
setTargetDataSourceId(value || null);
|
|
}}
|
|
/>
|
|
);
|
|
}}
|
|
</ProFormDependency>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Step1;
|