170 lines
4.0 KiB
TypeScript

import './styles.scss';
import { toast } from '@signozhq/sonner';
import { Button, Tooltip, Typography } from 'antd';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import { Check, Send, X } from 'lucide-react';
import { useCallback, useMemo } from 'react';
import { useCreateAlertState } from '../context';
import {
buildCreateThresholdAlertRulePayload,
validateCreateAlertState,
} from './utils';
function Footer(): JSX.Element {
const {
alertType,
alertState: basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
discardAlertRule,
createAlertRule,
isCreatingAlertRule,
testAlertRule,
isTestingAlertRule,
} = useCreateAlertState();
const { currentQuery } = useQueryBuilder();
const { safeNavigate } = useSafeNavigate();
const handleDiscard = (): void => discardAlertRule();
const alertValidationMessage = useMemo(
() =>
validateCreateAlertState({
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
query: currentQuery,
}),
[
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
currentQuery,
],
);
const handleTestNotification = useCallback((): void => {
const payload = buildCreateThresholdAlertRulePayload({
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
query: currentQuery,
});
testAlertRule(payload, {
onSuccess: (response) => {
if (response.payload?.data?.alertCount === 0) {
toast.error(
'No alerts found during the evaluation. This happens when rule condition is unsatisfied. You may adjust the rule threshold and retry.',
);
return;
}
toast.success('Test notification sent successfully');
},
onError: (error) => {
toast.error(error.message);
},
});
}, [
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
currentQuery,
testAlertRule,
]);
const handleSaveAlert = useCallback((): void => {
const payload = buildCreateThresholdAlertRulePayload({
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
query: currentQuery,
});
createAlertRule(payload, {
onSuccess: () => {
toast.success('Alert rule created successfully');
safeNavigate('/alerts');
},
onError: (error) => {
toast.error(error.message);
},
});
}, [
alertType,
basicAlertState,
thresholdState,
advancedOptions,
evaluationWindow,
notificationSettings,
currentQuery,
createAlertRule,
safeNavigate,
]);
const disableButtons =
isCreatingAlertRule || isTestingAlertRule || !!alertValidationMessage;
const saveAlertButton = useMemo(() => {
let button = (
<Button type="primary" onClick={handleSaveAlert} disabled={disableButtons}>
<Check size={14} />
<Typography.Text>Save Alert Rule</Typography.Text>
</Button>
);
if (alertValidationMessage) {
button = <Tooltip title={alertValidationMessage}>{button}</Tooltip>;
}
return button;
}, [alertValidationMessage, disableButtons, handleSaveAlert]);
const testAlertButton = useMemo(() => {
let button = (
<Button
type="default"
onClick={handleTestNotification}
disabled={disableButtons}
>
<Send size={14} />
<Typography.Text>Test Notification</Typography.Text>
</Button>
);
if (alertValidationMessage) {
button = <Tooltip title={alertValidationMessage}>{button}</Tooltip>;
}
return button;
}, [alertValidationMessage, disableButtons, handleTestNotification]);
return (
<div className="create-alert-v2-footer">
<Button type="text" onClick={handleDiscard} disabled={disableButtons}>
<X size={14} /> Discard
</Button>
<div className="button-group">
{testAlertButton}
{saveAlertButton}
</div>
</div>
);
}
export default Footer;