diff --git a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.tsx b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.tsx index 01cd95b3..5d016f62 100644 --- a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.tsx +++ b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.tsx @@ -63,6 +63,13 @@ const IntegrationForm = observer((props: IntegrationFormProps) => { const [showNewIntegrationForm, setShowNewIntegrationForm] = useState(false); const [selectedOption, setSelectedOption] = useState(undefined); const [showIntegrarionsListDrawer, setShowIntegrarionsListDrawer] = useState(id === 'new'); + const [allContactPoints, setAllContactPoints] = useState(undefined); + + useEffect(() => { + (async function () { + setAllContactPoints(await alertReceiveChannelStore.getGrafanaAlertingContactPoints()); + })(); + }, []); const data = id === 'new' @@ -154,6 +161,20 @@ const IntegrationForm = observer((props: IntegrationFormProps) => { ); function handleSubmit(data) { + const { alert_manager, contact_point, is_existing: isExisting } = data; + + const matchingAlertManager = allContactPoints.find((cp) => cp.uid === alert_manager); + const hasContactPointInput = alert_manager && contact_point; + + if ( + !isExisting && + hasContactPointInput && + matchingAlertManager?.contact_points.find((cp) => cp === contact_point) + ) { + openErrorNotification('A contact point already exists for this data source'); + return; + } + (id === 'new' ? createNewIntegration() : alertReceiveChannelStore.update(id, data)).then(() => { onHide(); onUpdate(); @@ -175,8 +196,8 @@ const IntegrationForm = observer((props: IntegrationFormProps) => { ? alertReceiveChannelStore.connectContactPoint(response.id, data.alert_manager, data.contact_point) : alertReceiveChannelStore.createContactPoint(response.id, data.alert_manager, data.contact_point) ) - .then(() => pushHistory(response.id)) - .catch(onCatch); + .catch(onCatch) + .finally(() => pushHistory(response.id)); }) .catch(onCatch); diff --git a/grafana-plugin/src/pages/integration/Integration.tsx b/grafana-plugin/src/pages/integration/Integration.tsx index 5891fb34..53a05aed 100644 --- a/grafana-plugin/src/pages/integration/Integration.tsx +++ b/grafana-plugin/src/pages/integration/Integration.tsx @@ -13,7 +13,7 @@ import { Alert, } from '@grafana/ui'; import cn from 'classnames/bind'; -import { get } from 'lodash-es'; +import { get, noop } from 'lodash-es'; import { observer } from 'mobx-react'; import CopyToClipboard from 'react-copy-to-clipboard'; import Emoji from 'react-emoji-render'; @@ -106,27 +106,13 @@ class Integration extends React.Component { } async componentDidMount() { - const { - match: { - params: { id }, - }, - query, - } = this.props; - - const { - store, - store: { alertReceiveChannelStore }, - } = this.props; + const { query } = this.props; if (query?.template) { this.openEditTemplateModal(query.template, query.routeId && query.routeId); } - await Promise.all([ - this.loadIntegration(), - IntegrationHelper.fetchChatOps(store), - alertReceiveChannelStore.updateTemplates(id), - ]); + await this.loadIntegration(); } render() { @@ -416,7 +402,7 @@ class Integration extends React.Component { Grouping: - {IntegrationHelper.truncateLine(templates['grouping_id_template'] || '')} + {IntegrationHelper.truncateLine(templates?.['grouping_id_template'] || '')} @@ -671,6 +657,7 @@ class Integration extends React.Component { async loadIntegration() { const { + store, store: { alertReceiveChannelStore }, match: { params: { id }, @@ -685,17 +672,21 @@ class Integration extends React.Component { promises.push(alertReceiveChannelStore.loadItem(id)); } - if (!alertReceiveChannelStore.counters?.length) { + if (!alertReceiveChannelStore.counters[id]) { promises.push(alertReceiveChannelStore.updateCounters()); } if (!alertReceiveChannelStore.channelFilterIds[id]) { - promises.push(await alertReceiveChannelStore.updateChannelFilters(id)); + promises.push(alertReceiveChannelStore.updateChannelFilters(id)); } + promises.push(alertReceiveChannelStore.updateTemplates(id)); + + promises.push(IntegrationHelper.fetchChatOps(store)); + // skip checking for grafana alerting so that we don't wait for the first request to complete // at the cost of getting a failed network request for all other types other than alerting - promises.push(alertReceiveChannelStore.updateConnectedContactPoints(id)); + promises.push(alertReceiveChannelStore.updateConnectedContactPoints(id).catch(noop)); await Promise.all(promises) .catch(() => {