Files
cameleer-server/ui/src/pages/Alerts/SilenceRuleMenu.tsx
hsiegeln 837fcbf926 feat(ui/alerts): SilenceRuleMenu — 1h/8h/24h/custom duration menu
Used by InboxPage row + bulk actions to silence an alert's underlying
rule for a chosen preset window. 'Custom…' routes to
/alerts/silences?ruleId=<id> (T13 adds the prefill wire).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:05:30 +02:00

72 lines
2.0 KiB
TypeScript

import { BellOff } from 'lucide-react';
import { useNavigate } from 'react-router';
import { Button, Dropdown, useToast } from '@cameleer/design-system';
import type { DropdownItem } from '@cameleer/design-system';
import { useCreateSilence } from '../../api/queries/alertSilences';
interface Props {
ruleId: string;
ruleTitle?: string;
onDone?: () => void;
variant?: 'row' | 'bulk';
}
const PRESETS: Array<{ label: string; hours: number }> = [
{ label: '1 hour', hours: 1 },
{ label: '8 hours', hours: 8 },
{ label: '24 hours', hours: 24 },
];
export function SilenceRuleMenu({ ruleId, ruleTitle, onDone, variant = 'row' }: Props) {
const navigate = useNavigate();
const { toast } = useToast();
const createSilence = useCreateSilence();
const handlePreset = (hours: number) => async () => {
const now = new Date();
const reason = ruleTitle
? `Silenced from inbox (${ruleTitle})`
: 'Silenced from inbox';
try {
await createSilence.mutateAsync({
matcher: { ruleId },
reason,
startsAt: now.toISOString(),
endsAt: new Date(now.getTime() + hours * 3_600_000).toISOString(),
});
toast({ title: `Silenced for ${hours}h`, variant: 'success' });
onDone?.();
} catch (e) {
toast({ title: 'Silence failed', description: String(e), variant: 'error' });
}
};
const handleCustom = () => {
navigate(`/alerts/silences?ruleId=${encodeURIComponent(ruleId)}`);
};
const items: DropdownItem[] = [
...PRESETS.map(({ label, hours }) => ({
label,
disabled: createSilence.isPending,
onClick: handlePreset(hours),
})),
{ divider: true, label: '' },
{ label: 'Custom…', onClick: handleCustom },
];
const buttonLabel = variant === 'bulk' ? 'Silence rules' : 'Silence rule…';
return (
<Dropdown
trigger={
<Button variant="secondary" size="sm">
<BellOff size={14} style={{ marginRight: 4 }} />
{buttonLabel}
</Button>
}
items={items}
/>
);
}