mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: use SupportedPlugin.OnCall detecting OnCall types as a single source of truth (#61473)
Use SupportedPlugin.OnCall detecting OnCall types as a single source of truth
This commit is contained in:
@@ -3,7 +3,7 @@ import { setupServer } from 'msw/node';
|
||||
|
||||
// bit of setup to mock HTTP request responses
|
||||
import 'whatwg-fetch';
|
||||
import { SupportedPlugin } from './PluginBridge';
|
||||
import { SupportedPlugin } from '../types/pluginBridges';
|
||||
|
||||
export const NON_EXISTING_PLUGIN = '__does_not_exist__';
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import React from 'react';
|
||||
import { setBackendSrv } from '@grafana/runtime';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
|
||||
import { createBridgeURL, PluginBridge, SupportedPlugin } from './PluginBridge';
|
||||
import { SupportedPlugin } from '../types/pluginBridges';
|
||||
|
||||
import { createBridgeURL, PluginBridge } from './PluginBridge';
|
||||
import { server, NON_EXISTING_PLUGIN } from './PluginBridge.mock';
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import React, { FC, ReactElement } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { PluginMeta } from '@grafana/data';
|
||||
import { getPluginSettings } from 'app/features/plugins/pluginSettings';
|
||||
|
||||
export enum SupportedPlugin {
|
||||
Incident = 'grafana-incident-app',
|
||||
OnCall = 'grafana-oncall-app',
|
||||
MachineLearning = 'grafana-ml-app',
|
||||
}
|
||||
import { usePluginBridge } from '../hooks/usePluginBridge';
|
||||
import { SupportedPlugin } from '../types/pluginBridges';
|
||||
|
||||
export type PluginID = SupportedPlugin | string;
|
||||
|
||||
@@ -20,13 +13,6 @@ export interface PluginBridgeProps {
|
||||
loadingComponent?: ReactElement;
|
||||
}
|
||||
|
||||
interface PluginBridgeHookResponse {
|
||||
loading: boolean;
|
||||
installed?: boolean;
|
||||
error?: Error;
|
||||
settings?: PluginMeta<{}>;
|
||||
}
|
||||
|
||||
export const PluginBridge: FC<PluginBridgeProps> = ({ children, plugin, loadingComponent, notInstalledFallback }) => {
|
||||
const { loading, installed } = usePluginBridge(plugin);
|
||||
|
||||
@@ -41,24 +27,6 @@ export const PluginBridge: FC<PluginBridgeProps> = ({ children, plugin, loadingC
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export function usePluginBridge(plugin: PluginID): PluginBridgeHookResponse {
|
||||
const { loading, error, value } = useAsync(() => getPluginSettings(plugin, { showErrorAlert: false }));
|
||||
|
||||
const installed = value && !error && !loading;
|
||||
const enabled = value?.enabled;
|
||||
const isLoading = loading && !value;
|
||||
|
||||
if (isLoading) {
|
||||
return { loading: true };
|
||||
}
|
||||
|
||||
if (!installed || !enabled) {
|
||||
return { loading: false, installed: false };
|
||||
}
|
||||
|
||||
return { loading, installed: true, settings: value };
|
||||
}
|
||||
|
||||
export function createBridgeURL(plugin: PluginID, path?: string, options?: Record<string, string>) {
|
||||
const searchParams = new URLSearchParams(options).toString();
|
||||
const pluginPath = `/a/${plugin}${path}`;
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
|
||||
import { useMuteTimingOptions } from '../../hooks/useMuteTimingOptions';
|
||||
import { FormAmRoute } from '../../types/amroutes';
|
||||
import { SupportedPlugin } from '../../types/pluginBridges';
|
||||
import { matcherFieldOptions } from '../../utils/alertmanager';
|
||||
import {
|
||||
emptyArrayFieldMatcher,
|
||||
@@ -32,7 +33,7 @@ import {
|
||||
commonGroupByOptions,
|
||||
} from '../../utils/amroutes';
|
||||
import { timeOptions } from '../../utils/time';
|
||||
import { AmRouteReceiver, GrafanaAppReceiverEnum } from '../receivers/grafanaAppReceivers/types';
|
||||
import { AmRouteReceiver } from '../receivers/grafanaAppReceivers/types';
|
||||
|
||||
import { getFormStyles } from './formStyles';
|
||||
|
||||
@@ -50,7 +51,7 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
const muteTimingOptions = useMuteTimingOptions();
|
||||
|
||||
const receiversWithOnCallOnTop = receivers.sort((receiver1, receiver2) => {
|
||||
if (receiver1.grafanaAppReceiverType === GrafanaAppReceiverEnum.GRAFANA_ONCALL) {
|
||||
if (receiver1.grafanaAppReceiverType === SupportedPlugin.OnCall) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
@@ -2,7 +2,9 @@ import React, { FC } from 'react';
|
||||
|
||||
import { Button, LinkButton, Tooltip } from '@grafana/ui';
|
||||
|
||||
import { createBridgeURL, usePluginBridge, SupportedPlugin } from '../PluginBridge';
|
||||
import { usePluginBridge } from '../../hooks/usePluginBridge';
|
||||
import { SupportedPlugin } from '../../types/pluginBridges';
|
||||
import { createBridgeURL } from '../PluginBridge';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Authorize } from '../../components/Authorize';
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
import { deleteReceiverAction } from '../../state/actions';
|
||||
import { getAlertTableStyles } from '../../styles/table';
|
||||
import { SupportedPlugin } from '../../types/pluginBridges';
|
||||
import { getNotificationsPermissions } from '../../utils/access-control';
|
||||
import { isReceiverUsed } from '../../utils/alertmanager';
|
||||
import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource';
|
||||
@@ -26,7 +27,7 @@ import { ActionIcon } from '../rules/ActionIcon';
|
||||
import { ReceiversSection } from './ReceiversSection';
|
||||
import { GrafanaAppBadge } from './grafanaAppReceivers/GrafanaAppBadge';
|
||||
import { useGetReceiversWithGrafanaAppTypes } from './grafanaAppReceivers/grafanaApp';
|
||||
import { GrafanaAppReceiverEnum, ReceiverWithTypes } from './grafanaAppReceivers/types';
|
||||
import { ReceiverWithTypes } from './grafanaAppReceivers/types';
|
||||
|
||||
interface UpdateActionProps extends ActionProps {
|
||||
onClickDeleteReceiver: (receiverName: string) => void;
|
||||
@@ -131,7 +132,7 @@ interface ReceiverItem {
|
||||
name: string;
|
||||
types: string[];
|
||||
provisioned?: boolean;
|
||||
grafanaAppReceiverType?: GrafanaAppReceiverEnum;
|
||||
grafanaAppReceiverType?: SupportedPlugin;
|
||||
}
|
||||
|
||||
interface NotifierStatus {
|
||||
|
||||
@@ -4,9 +4,11 @@ import React from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { HorizontalGroup, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { GRAFANA_APP_RECEIVERS_SOURCE_IMAGE, GrafanaAppReceiverEnum } from './types';
|
||||
import { SupportedPlugin } from '../../../types/pluginBridges';
|
||||
|
||||
export const GrafanaAppBadge = ({ grafanaAppType }: { grafanaAppType: GrafanaAppReceiverEnum }) => {
|
||||
import { GRAFANA_APP_RECEIVERS_SOURCE_IMAGE } from './types';
|
||||
|
||||
export const GrafanaAppBadge = ({ grafanaAppType }: { grafanaAppType: SupportedPlugin }) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { Receiver } from 'app/plugins/datasource/alertmanager/types';
|
||||
|
||||
import { useGetOnCallIntegrationsQuery } from '../../../api/onCallApi';
|
||||
import { SupportedPlugin, usePluginBridge } from '../../PluginBridge';
|
||||
import { usePluginBridge } from '../../../hooks/usePluginBridge';
|
||||
import { SupportedPlugin } from '../../../types/pluginBridges';
|
||||
|
||||
import { isOnCallReceiver } from './onCall/onCall';
|
||||
import { AmRouteReceiver, GrafanaAppReceiverEnum, ReceiverWithTypes } from './types';
|
||||
import { AmRouteReceiver, ReceiverWithTypes } from './types';
|
||||
|
||||
export const useGetGrafanaReceiverTypeChecker = () => {
|
||||
const { installed: isOnCallEnabled } = usePluginBridge(SupportedPlugin.OnCall);
|
||||
const { data } = useGetOnCallIntegrationsQuery(undefined, {
|
||||
skip: !isOnCallEnabled,
|
||||
});
|
||||
const getGrafanaReceiverType = (receiver: Receiver): GrafanaAppReceiverEnum | undefined => {
|
||||
const getGrafanaReceiverType = (receiver: Receiver): SupportedPlugin | undefined => {
|
||||
//CHECK FOR ONCALL PLUGIN
|
||||
const onCallIntegrations = data ?? [];
|
||||
if (isOnCallEnabled && isOnCallReceiver(receiver, onCallIntegrations)) {
|
||||
return GrafanaAppReceiverEnum.GRAFANA_ONCALL;
|
||||
return SupportedPlugin.OnCall;
|
||||
}
|
||||
//WE WILL ADD IN HERE IF THERE ARE MORE TYPES TO CHECK
|
||||
return undefined;
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
import { Receiver } from '../../../../../../plugins/datasource/alertmanager/types';
|
||||
// we will add in here more types if needed
|
||||
export enum GrafanaAppReceiverEnum {
|
||||
GRAFANA_ONCALL = 'Grafana OnCall',
|
||||
}
|
||||
import { SupportedPlugin } from '../../../types/pluginBridges';
|
||||
|
||||
export interface AmRouteReceiver {
|
||||
label: string;
|
||||
value: string;
|
||||
grafanaAppReceiverType?: GrafanaAppReceiverEnum;
|
||||
grafanaAppReceiverType?: SupportedPlugin;
|
||||
}
|
||||
|
||||
export interface ReceiverWithTypes extends Receiver {
|
||||
grafanaAppReceiverType?: GrafanaAppReceiverEnum;
|
||||
grafanaAppReceiverType?: SupportedPlugin;
|
||||
}
|
||||
export const GRAFANA_APP_RECEIVERS_SOURCE_IMAGE: Record<SupportedPlugin, string> = {
|
||||
[SupportedPlugin.OnCall]: 'public/img/alerting/oncall_logo.svg',
|
||||
|
||||
export const GRAFANA_APP_RECEIVERS_SOURCE_IMAGE = {
|
||||
'Grafana OnCall': 'public/img/alerting/oncall_logo.svg',
|
||||
[SupportedPlugin.Incident]: '',
|
||||
[SupportedPlugin.MachineLearning]: '',
|
||||
};
|
||||
|
||||
export enum GRAFANA_APP_PLUGIN_IDS {
|
||||
'Grafana OnCall' = 'grafana-oncall-app',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { PluginMeta } from '@grafana/data';
|
||||
import { getPluginSettings } from 'app/features/plugins/pluginSettings';
|
||||
|
||||
import { PluginID } from '../components/PluginBridge';
|
||||
interface PluginBridgeHookResponse {
|
||||
loading: boolean;
|
||||
installed?: boolean;
|
||||
error?: Error;
|
||||
settings?: PluginMeta<{}>;
|
||||
}
|
||||
|
||||
export function usePluginBridge(plugin: PluginID): PluginBridgeHookResponse {
|
||||
const { loading, error, value } = useAsync(() => getPluginSettings(plugin, { showErrorAlert: false }));
|
||||
|
||||
const installed = value && !error && !loading;
|
||||
const enabled = value?.enabled;
|
||||
const isLoading = loading && !value;
|
||||
|
||||
if (isLoading) {
|
||||
return { loading: true };
|
||||
}
|
||||
|
||||
if (!installed || !enabled) {
|
||||
return { loading: false, installed: false };
|
||||
}
|
||||
|
||||
return { loading, installed: true, settings: value };
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum SupportedPlugin {
|
||||
Incident = 'grafana-incident-app',
|
||||
OnCall = 'grafana-oncall-app',
|
||||
MachineLearning = 'grafana-ml-app',
|
||||
}
|
||||
Reference in New Issue
Block a user