diff --git a/public/app/features/alerting/unified/components/contact-points/__snapshots__/useContactPoints.test.tsx.snap b/public/app/features/alerting/unified/components/contact-points/__snapshots__/useContactPoints.test.tsx.snap
index dd84a65a6ae..ea4fc89ca90 100644
--- a/public/app/features/alerting/unified/components/contact-points/__snapshots__/useContactPoints.test.tsx.snap
+++ b/public/app/features/alerting/unified/components/contact-points/__snapshots__/useContactPoints.test.tsx.snap
@@ -144,5 +144,6 @@ exports[`useContactPoints should return contact points with status 1`] = `
],
"error": undefined,
"isLoading": false,
+ "refetchReceivers": [Function],
}
`;
diff --git a/public/app/features/alerting/unified/components/contact-points/useContactPoints.tsx b/public/app/features/alerting/unified/components/contact-points/useContactPoints.tsx
index 90557614f0e..d5b3a841ed6 100644
--- a/public/app/features/alerting/unified/components/contact-points/useContactPoints.tsx
+++ b/public/app/features/alerting/unified/components/contact-points/useContactPoints.tsx
@@ -97,6 +97,7 @@ export function useContactPointsWithStatus() {
error,
isLoading,
contactPoints,
+ refetchReceivers: fetchAlertmanagerConfiguration.refetch,
};
}
diff --git a/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/AlertManagerRouting.tsx b/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/AlertManagerRouting.tsx
index acd91ad4865..ad8151d4ebe 100644
--- a/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/AlertManagerRouting.tsx
+++ b/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/AlertManagerRouting.tsx
@@ -1,8 +1,8 @@
-import { css } from '@emotion/css';
+import { css, cx } from '@emotion/css';
import React, { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
-import { Alert, CollapsableSection, LoadingPlaceholder, Stack, TextLink, useStyles2 } from '@grafana/ui';
+import { Alert, CollapsableSection, IconButton, LoadingPlaceholder, Stack, TextLink, useStyles2 } from '@grafana/ui';
import { AlertManagerDataSource } from 'app/features/alerting/unified/utils/datasource';
import { createUrl } from 'app/features/alerting/unified/utils/url';
@@ -18,15 +18,32 @@ interface AlertManagerManualRoutingProps {
alertManager: AlertManagerDataSource;
}
+const LOADING_SPINNER_DURATION = 1000;
+
export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRoutingProps) {
const styles = useStyles2(getStyles);
const alertManagerName = alertManager.name;
- const { isLoading, error: errorInContactPointStatus, contactPoints } = useContactPointsWithStatus();
+ const { isLoading, error: errorInContactPointStatus, contactPoints, refetchReceivers } = useContactPointsWithStatus();
const [selectedContactPointWithMetadata, setSelectedContactPointWithMetadata] = useState<
ContactPointWithMetadata | undefined
>();
+ // We need to provide a fake loading state for the contact points, because it might be that the response is so fast that the loading spinner is not shown,
+ // and the user might think that the contact points are not fetched.
+ // We will show the loading spinner for 1 second, and if the fetching takes more than 1 second, we will show the loading spinner until the fetching is done.
+
+ const [loadingContactPoints, setLoadingContactPoints] = useState(false);
+ // we need to keep track if the fetching takes more than 1 second, so we can show the loading spinner until the fetching is done
+ const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
+
+ const onClickRefresh = () => {
+ setLoadingContactPoints(true);
+ Promise.all([refetchReceivers(), sleep(LOADING_SPINNER_DURATION)]).finally(() => {
+ setLoadingContactPoints(false);
+ });
+ };
+
if (errorInContactPointStatus) {
return