Files
alert/src/pages/rules/components/CopyRule/SingleCopyPopup.tsx
2026-04-24 20:30:52 +08:00

249 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ArrowDownOutlined, ArrowRightOutlined } from '@ant-design/icons';
import {
BetaSchemaForm,
ProForm,
ProFormDependency,
ProFormSelect,
useBreakpoint,
} from '@ant-design/pro-components';
import {
Alert,
App,
Col,
Divider,
Flex,
type FormInstance,
Modal,
Row,
Typography,
} from 'antd';
import { useEffect, useRef, useState } from 'react';
import useRichFormat from '@/hooks/useRichI18n';
import { $t } from '@/utils/i18n';
import { type SchemaType, schemaMap } from '../../ruleFormSchema';
import { handleEmptyValuesFunc, processSingleRule } from '../../utils';
import AssetsSelect from '../AssetsSelect';
import SymbolSelect from '../SymbolSelect';
type RuleListItem = Partial<API.RuleListItem>;
type CopyPopupProps = {
visible: boolean;
formValues: Partial<RuleListItem | undefined>;
dataSourceList: API.DataSourceListItem[];
currentRuleType: number;
onDone: (refresh?: boolean) => void;
};
const { Text } = Typography;
const SingleCopyPopup = ({
visible,
onDone,
currentRuleType,
formValues,
dataSourceList,
}: CopyPopupProps) => {
const { richFormat } = useRichFormat();
const screens = useBreakpoint();
const { message, modal } = App.useApp();
const formRef = useRef<FormInstance>(null);
const [confirmLoading, setConfirmLoading] = useState(false);
const [errMsg, setErrMsg] = useState('');
useEffect(() => {
if (!visible) {
setErrMsg('');
}
return () => {
setErrMsg('');
};
}, [visible]);
const {
leftForm,
symbolFormShow,
assetFormShow,
transformInitialValue,
transformSubmitValue,
} =
schemaMap[currentRuleType as unknown as SchemaType]?.({ richFormat }) || {};
const rightDataSourceList = dataSourceList.filter(
(item) => item.id !== formValues?.dataSourceId,
);
const initialValues = transformInitialValue?.(formValues) || formValues;
const rightFirstDataSource = rightDataSourceList[0];
const copyFormValues = {
...initialValues,
name: initialValues?.name
? `${initialValues.name} - ${rightFirstDataSource?.sourceName}`
: `${Date.now()} - ${rightFirstDataSource?.sourceName}`,
groupFilter: '',
id: void 0,
dataSourceId: rightFirstDataSource?.id || '',
};
if (symbolFormShow) {
copyFormValues.param2 = '';
}
if (assetFormShow) {
copyFormValues.param1 = '';
}
const formContent = ({
dataSourceList,
formAttr,
}: {
dataSourceList: API.DataSourceListItem[];
formAttr: Record<string, any>;
}) => {
return (
<ProForm {...formAttr} submitter={false}>
<ProFormSelect
name="dataSourceId"
label={$t('table.dataSource')}
options={dataSourceList}
rules={[{ required: true, message: $t('form.required') }]}
fieldProps={{
allowClear: false,
fieldNames: {
label: 'sourceName',
value: 'id',
},
}}
/>
<BetaSchemaForm layoutType="Embed" columns={leftForm} />
{(symbolFormShow || assetFormShow) && (
<ProFormDependency name={['dataSourceId']}>
{({ dataSourceId }) => (
<>
{symbolFormShow && (
<ProForm.Item name="param2" noStyle>
<SymbolSelect dataSourceId={dataSourceId} />
</ProForm.Item>
)}
{assetFormShow && (
<ProForm.Item name="param1" noStyle>
<AssetsSelect dataSourceId={dataSourceId} />
</ProForm.Item>
)}
</>
)}
</ProFormDependency>
)}
</ProForm>
);
};
return (
<Modal
title={$t('pages.rules.cloneRule')}
open={visible}
onCancel={() => onDone()}
destroyOnHidden
centered
width={['xl', 'xxl'].includes(screens || '') ? '60%' : '95%'}
confirmLoading={confirmLoading}
okText={$t('pages.rules.cloneConfirm')}
onOk={async () => {
setConfirmLoading(true);
const values = formRef.current?.getFieldsValue();
const tmpValues = handleEmptyValuesFunc(values);
const submitValues = transformSubmitValue?.(tmpValues) || tmpValues;
submitValues.type = currentRuleType;
try {
await processSingleRule({ payload: submitValues });
message.success($t('pages.tips.operationSuccess'));
onDone(true);
} catch (error: any) {
console.log('error', error);
switch (error?.errType) {
case 1:
case 2:
modal.warning({
content: error?.respMessage || $t(error?.errMsg),
centered: true,
onOk: () => {
setErrMsg('');
setConfirmLoading(false);
onDone(true);
},
});
return;
case 3:
setErrMsg($t(error?.errMsg));
formRef.current?.setFieldsValue({
...error.data,
});
break;
default:
break;
}
}
setConfirmLoading(false);
}}
styles={{
body: {
maxHeight: '82vh',
overflowY: 'auto',
overflowX: 'hidden',
marginRight: -10,
paddingRight: 8,
},
}}
>
<Row>
<Col xs={24} sm={11}>
<div style={{ marginBottom: 12 }}>
<Text strong>📋 {$t('pages.rules.originalRule')}</Text>
</div>
{formContent({
dataSourceList,
formAttr: { initialValues, disabled: true },
})}
</Col>
<Col xs={0} sm={1}>
<Flex vertical align="center" style={{ height: '100%' }}>
<ArrowRightOutlined style={{ marginTop: 2, fontSize: 18 }} />
<Divider type="vertical" style={{ flex: 1, marginTop: 16 }} />
</Flex>
</Col>
<Col xs={24} sm={0}>
<div className="text-center" style={{ marginBottom: 16 }}>
<ArrowDownOutlined />
</div>
</Col>
<Col xs={24} sm={12}>
<div style={{ marginBottom: 12 }}>
<Text strong> {$t('pages.rules.cloneRulePreview')}</Text>
</div>
{formContent({
dataSourceList: rightDataSourceList,
formAttr: {
initialValues: copyFormValues,
formRef: formRef,
disabled: confirmLoading,
},
})}
{errMsg && (
<Alert
message={errMsg}
type="error"
showIcon
style={{ marginBottom: 16 }}
/>
)}
</Col>
</Row>
</Modal>
);
};
export default SingleCopyPopup;