Files
alert/src/pages/rules/components/CopyRule/comp/RuleCheckCard.tsx
Johnton Chen 3c636bcaa2 refactor(copy-rule): extract context and improve batch clone modal
- 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>
2026-06-15 23:05:56 +08:00

88 lines
2.4 KiB
TypeScript

import { CheckCard, ProCard } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { Col, Row, Spin } from 'antd';
import { useContext, useEffect, useState } from 'react';
import { getRuleList } from '@/services/api';
import { $t } from '@/utils/i18n';
import { RuleCardBodyInfo } from '../../RuleCardBody';
import { MultiCopyPopupContext } from '../context';
type RuleCheckCardProps = {
dataSourceId: string | number;
};
const RuleCheckCard = ({ dataSourceId }: RuleCheckCardProps) => {
const { ruleMeta, currentRuleType, setSelectRules } = useContext(
MultiCopyPopupContext,
);
const [ruleList, setRuleList] = useState<API.RuleListItem[]>([]);
const { loading } = useRequest(
() =>
getRuleList({
type: currentRuleType,
dataSourceId,
}),
{
refreshDeps: [dataSourceId, currentRuleType],
onSuccess: ({ data = [] }: { data: API.RuleListItem[] }) => {
setRuleList(data);
setSelectRules(data);
},
onError: () => {
setRuleList([]);
},
},
);
useEffect(() => {
return () => setSelectRules([]);
}, []);
if (!dataSourceId) return <div>{$t('pages.clones.step1.tips')}</div>;
if (loading) return <Spin />;
return (
<ProCard
title={$t('pages.clones.step1.sourceRules', {
count: ruleList.length,
ruleType: ruleMeta?.title || '-',
})}
collapsible
defaultCollapsed
className="clone-rule-card"
>
<CheckCard.Group
multiple
onChange={(value) => {
if (Array.isArray(value)) {
const selectedRules = value.map((item) =>
ruleList.find((rule) => rule.id === item),
) as API.RuleListItem[];
setSelectRules(selectedRules);
}
}}
className="w-100"
defaultValue={ruleList.map((item) => item.id)}
>
<Row gutter={12} style={{ maxHeight: '45vh', overflowY: 'auto' }}>
{ruleList.map((rule) => (
<Col span={8} key={rule.id}>
<CheckCard
title={$t('pages.rules.ruleName')}
extra={rule.name || 'N/A'}
value={rule.id}
description={
<RuleCardBodyInfo ruleMeta={ruleMeta} rule={rule} />
}
className="w-100"
/>
</Col>
))}
</Row>
</CheckCard.Group>
</ProCard>
);
};
export default RuleCheckCard;