diff --git a/frontend/src/lib/components/Alerts/alertFormLogic.ts b/frontend/src/lib/components/Alerts/alertFormLogic.ts index 2727653f5f73c..47e322f501429 100644 --- a/frontend/src/lib/components/Alerts/alertFormLogic.ts +++ b/frontend/src/lib/components/Alerts/alertFormLogic.ts @@ -27,6 +27,15 @@ export type AlertFormType = Pick< insight?: QueryBasedInsightModel['id'] } +export function canCheckOngoingInterval(alert?: AlertType | AlertFormType): boolean { + return ( + (alert?.condition.type === AlertConditionType.ABSOLUTE_VALUE || + alert?.condition.type === AlertConditionType.RELATIVE_INCREASE) && + alert?.threshold.configuration.bounds?.upper != null && + !isNaN(alert?.threshold.configuration.bounds.upper) + ) +} + export interface AlertFormLogicProps { alert: AlertType | null insightId: QueryBasedInsightModel['id'] @@ -85,11 +94,7 @@ export const alertFormLogic = kea([ // can only check ongoing interval for absolute value/increase alerts with upper threshold config: { ...alert.config, - check_ongoing_interval: - (alert.condition.type === AlertConditionType.ABSOLUTE_VALUE || - alert.condition.type === AlertConditionType.RELATIVE_INCREASE) && - alert.threshold.configuration.bounds?.upper != null && - alert.config.check_ongoing_interval, + check_ongoing_interval: canCheckOngoingInterval(alert) && alert.config.check_ongoing_interval, }, } diff --git a/frontend/src/lib/components/Alerts/views/EditAlertModal.tsx b/frontend/src/lib/components/Alerts/views/EditAlertModal.tsx index 8a30608195013..66120e26fe3da 100644 --- a/frontend/src/lib/components/Alerts/views/EditAlertModal.tsx +++ b/frontend/src/lib/components/Alerts/views/EditAlertModal.tsx @@ -20,12 +20,13 @@ import { LemonButton } from 'lib/lemon-ui/LemonButton' import { LemonField } from 'lib/lemon-ui/LemonField' import { LemonModal } from 'lib/lemon-ui/LemonModal' import { alphabet, formatDate } from 'lib/utils' +import { useCallback } from 'react' import { trendsDataLogic } from 'scenes/trends/trendsDataLogic' import { AlertCalculationInterval, AlertConditionType, AlertState, InsightThresholdType } from '~/queries/schema' import { InsightShortId, QueryBasedInsightModel } from '~/types' -import { alertFormLogic } from '../alertFormLogic' +import { alertFormLogic, canCheckOngoingInterval } from '../alertFormLogic' import { alertLogic } from '../alertLogic' import { SnoozeButton } from '../SnoozeButton' import { AlertType } from '../types' @@ -87,9 +88,17 @@ export function EditAlertModal({ onClose, onEditSuccess, }: EditAlertModalProps): JSX.Element { - const { alert, alertLoading } = useValues(alertLogic({ alertId })) + const _alertLogic = alertLogic({ alertId }) + const { alert, alertLoading } = useValues(_alertLogic) + const { loadAlert } = useActions(_alertLogic) - const formLogicProps = { alert, insightId, onEditSuccess } + // need to reload edited alert as well + const _onEditSuccess = useCallback(() => { + loadAlert() + onEditSuccess() + }, [loadAlert, onEditSuccess]) + + const formLogicProps = { alert, insightId, onEditSuccess: _onEditSuccess } const formLogic = alertFormLogic(formLogicProps) const { alertForm, isAlertFormSubmitting, alertFormChanged } = useValues(formLogic) const { deleteAlert, snoozeAlert, clearSnooze } = useActions(formLogic) @@ -100,10 +109,7 @@ export function EditAlertModal({ const creatingNewAlert = alertForm.id === undefined // can only check ongoing interval for absolute value/increase alerts with upper threshold - const can_check_ongoing_interval = - (alertForm?.condition.type === AlertConditionType.ABSOLUTE_VALUE || - alertForm?.condition.type === AlertConditionType.RELATIVE_INCREASE) && - alertForm.threshold.configuration.bounds?.upper != null + const can_check_ongoing_interval = canCheckOngoingInterval(alertForm) return ( @@ -167,14 +173,18 @@ export function EditAlertModal({ ({ - label: isBreakdownValid - ? 'any breakdown value' - : formula - ? `Formula (${formula})` - : `${alphabet[index]} - ${event}`, - value: isBreakdownValid || formula ? 0 : index, - }))} + options={alertSeries?.map( + ({ custom_name, name, event }, index) => ({ + label: isBreakdownValid + ? 'any breakdown value' + : formula + ? `Formula (${formula})` + : `${alphabet[index]} - ${ + custom_name ?? name ?? event + }`, + value: isBreakdownValid || formula ? 0 : index, + }) + )} disabledReason={ (isBreakdownValid && `For trends with breakdown, the alert will fire if any of the breakdown diff --git a/frontend/src/lib/components/Alerts/views/ManageAlertsModal.tsx b/frontend/src/lib/components/Alerts/views/ManageAlertsModal.tsx index e46b7bb83a0fe..16df9ee7dc988 100644 --- a/frontend/src/lib/components/Alerts/views/ManageAlertsModal.tsx +++ b/frontend/src/lib/components/Alerts/views/ManageAlertsModal.tsx @@ -45,10 +45,10 @@ export function AlertListItem({ alert, onClick }: AlertListItemProps): JSX.Eleme {alert.enabled ? (
- {bounds?.lower !== undefined && + {bounds?.lower != null && `Low ${isPercentage ? bounds.lower * 100 : bounds.lower}${isPercentage ? '%' : ''}`} - {bounds?.lower !== undefined && bounds?.upper ? ' · ' : ''} - {bounds?.upper !== undefined && + {bounds?.lower != null && bounds?.upper != null ? ' · ' : ''} + {bounds?.upper != null && `High ${isPercentage ? bounds.upper * 100 : bounds.upper}${isPercentage ? '%' : ''}`}
) : ( diff --git a/posthog/tasks/alerts/checks.py b/posthog/tasks/alerts/checks.py index 9bcb8925d1b5c..7c205e6010fd7 100644 --- a/posthog/tasks/alerts/checks.py +++ b/posthog/tasks/alerts/checks.py @@ -222,6 +222,10 @@ def check_alert(alert_id: str, capture_ph_event: Callable = lambda *args, **kwar "Skipping alert check because weekend checking is disabled", alert=alert, ) + + # ignore alert check until due again + alert.next_check_at = next_check_time(alert) + alert.save() return if alert.snoozed_until: diff --git a/posthog/tasks/alerts/test/test_alert_checks.py b/posthog/tasks/alerts/test/test_alert_checks.py index f03dc7b9c35de..7f36f578d500f 100644 --- a/posthog/tasks/alerts/test/test_alert_checks.py +++ b/posthog/tasks/alerts/test/test_alert_checks.py @@ -408,6 +408,11 @@ def test_alert_is_not_checked_on_weekend_when_skip_weekends_is_true( checks = AlertCheck.objects.filter(alert_configuration=self.alert["id"]) assert len(checks) == 0 + def test_alert_is_checked_on_weekday_when_skip_weekends_is_true( + self, mock_send_notifications_for_breaches: MagicMock, mock_send_errors: MagicMock + ) -> None: + self.skip_weekend(True) + # run on week day with freeze_time("2024-12-19T07:55:00.000Z"): check_alert(self.alert["id"]) diff --git a/posthog/tasks/alerts/utils.py b/posthog/tasks/alerts/utils.py index 145a450227e9b..7388e68386cdc 100644 --- a/posthog/tasks/alerts/utils.py +++ b/posthog/tasks/alerts/utils.py @@ -66,7 +66,7 @@ def skip_because_of_weekend(alert: AlertConfiguration) -> bool: team_timezone = pytz.timezone(alert.team.timezone) now_local = now.astimezone(team_timezone) - return now_local.isoweekday() in [5, 6] + return now_local.isoweekday() in [6, 7] def next_check_time(alert: AlertConfiguration) -> datetime: