From 6218e28ee9c884b852822fa510c320c7781fda7e Mon Sep 17 00:00:00 2001
From: Sonia Aguilar <33540275+soniaAguilarPeiron@users.noreply.github.com>
Date: Thu, 25 Jan 2024 08:53:54 +0100
Subject: [PATCH] Alerting: Add refresh button to contact points selector in
simplified routing section. (#80748)
* Add refresh button for contact points selector in simplified routing section
* Clear timeout when unmounting component
* Fix timeout not being correclty removed when component unmounts
* Update css field name
* Kepp loading spinner if refetching receivers takes more than one second
* Fix test snapshot in useContactPointsWithStatus hook
* refactor how we wait for the request response and the timeout to finish
---
.../useContactPoints.test.tsx.snap | 1 +
.../contact-points/useContactPoints.tsx | 1 +
.../simplifiedRouting/AlertManagerRouting.tsx | 50 +++++++++++++++++--
3 files changed, 49 insertions(+), 3 deletions(-)
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