diff --git a/public/app/features/alerting/unified/home/Insights.tsx b/public/app/features/alerting/unified/home/Insights.tsx index 9f2c4cf08e4..289b77c7def 100644 --- a/public/app/features/alerting/unified/home/Insights.tsx +++ b/public/app/features/alerting/unified/home/Insights.tsx @@ -1,9 +1,12 @@ import React from 'react'; +import { DataSourceInstanceSettings, DataSourceJsonData } from '@grafana/data'; +import { getDataSourceSrv } from '@grafana/runtime'; import { EmbeddedScene, NestedScene, QueryVariable, + SceneControlsSpacer, SceneFlexItem, SceneFlexLayout, SceneReactObject, @@ -14,6 +17,7 @@ import { VariableValueSelectors, } from '@grafana/scenes'; +import { SectionSubheader } from '../insights/SectionSubheader'; import { getGrafanaInstancesByStateScene } from '../insights/grafana/AlertsByStateScene'; import { getGrafanaEvalSuccessVsFailuresScene } from '../insights/grafana/EvalSuccessVsFailuresScene'; import { getFiringGrafanaAlertsScene } from '../insights/grafana/Firing'; @@ -42,19 +46,27 @@ import { getMissedIterationsScene } from '../insights/mimir/rules/MissedIteratio import { getMostFiredRulesScene } from '../insights/mimir/rules/MostFiredRules'; import { getPendingCloudAlertsScene } from '../insights/mimir/rules/Pending'; -const ashDs = { +export interface DataSourceInformation { + type: string; + uid: string; + settings: DataSourceInstanceSettings | undefined; +} +const ashDs: DataSourceInformation = { type: 'loki', uid: 'grafanacloud-alert-state-history', + settings: undefined, }; -const cloudUsageDs = { +const cloudUsageDs: DataSourceInformation = { type: 'prometheus', uid: 'grafanacloud-usage', + settings: undefined, }; -const grafanaCloudPromDs = { +const grafanaCloudPromDs: DataSourceInformation = { type: 'prometheus', uid: 'grafanacloud-prom', + settings: undefined, }; const SERIES_COLORS = { @@ -82,38 +94,80 @@ export const PANEL_STYLES = { minHeight: 300 }; const THIS_WEEK_TIME_RANGE = new SceneTimeRange({ from: 'now-1w', to: 'now' }); -export function SectionSubheader({ children }: React.PropsWithChildren) { - return
{children}
; -} - export function getInsightsScenes() { + const dataSourceSrv = getDataSourceSrv(); + + [ashDs, cloudUsageDs, grafanaCloudPromDs].forEach((ds) => { + ds.settings = dataSourceSrv.getInstanceSettings(ds.uid); + }); + + const categories = []; + + const showGrafanaManaged = ashDs.settings && cloudUsageDs.settings; + const showGrafanaAlertmanager = Boolean(cloudUsageDs.settings); + const showMimirAlertmanager = Boolean(cloudUsageDs.settings); + const showMimirManaged = cloudUsageDs.settings && grafanaCloudPromDs.settings; + const showMimirManagedPerGroup = Boolean(cloudUsageDs.settings); + + if (showGrafanaManaged) { + categories.push( + new SceneFlexItem({ + ySizing: 'content', + body: getGrafanaManagedScenes(), + }) + ); + } + + if (showGrafanaAlertmanager) { + categories.push( + new SceneFlexItem({ + ySizing: 'content', + body: getGrafanaAlertmanagerScenes(), + }) + ); + } + + if (showMimirAlertmanager) { + categories.push( + new SceneFlexItem({ + ySizing: 'content', + body: getCloudScenes(), + }) + ); + } + + if (showMimirManaged) { + categories.push( + new SceneFlexItem({ + ySizing: 'content', + body: getMimirManagedRulesScenes(), + }) + ); + } + + if (showMimirManagedPerGroup) { + categories.push( + new SceneFlexItem({ + ySizing: 'content', + body: getMimirManagedRulesPerGroupScenes(), + }) + ); + } + return new EmbeddedScene({ $timeRange: THIS_WEEK_TIME_RANGE, - controls: [new SceneTimePicker({}), new SceneRefreshPicker({})], + controls: [ + new SceneReactObject({ + component: SectionSubheader, + props: { children:
Monitor the status of your system.
, datasources: [] }, + }), + new SceneControlsSpacer(), + new SceneTimePicker({}), + new SceneRefreshPicker({}), + ], body: new SceneFlexLayout({ direction: 'column', - children: [ - new SceneFlexItem({ - ySizing: 'content', - body: getGrafanaManagedScenes(), - }), - new SceneFlexItem({ - ySizing: 'content', - body: getGrafanaAlertmanagerScenes(), - }), - new SceneFlexItem({ - ySizing: 'content', - body: getCloudScenes(), - }), - new SceneFlexItem({ - ySizing: 'content', - body: getMimirManagedRulesScenes(), - }), - new SceneFlexItem({ - ySizing: 'content', - body: getMimirManagedRulesPerGroupScenes(), - }), - ], + children: categories, }), }); } @@ -129,7 +183,7 @@ function getGrafanaManagedScenes() { new SceneFlexItem({ body: new SceneReactObject({ component: SectionSubheader, - props: { children:
Grafana-managed rules
}, + props: { children:
Grafana-managed rules
, datasources: [] }, }), }), new SceneFlexLayout({ @@ -196,7 +250,7 @@ function getGrafanaAlertmanagerScenes() { new SceneFlexItem({ body: new SceneReactObject({ component: SectionSubheader, - props: { children:
Grafana Alertmanager
}, + props: { children:
Grafana Alertmanager
, datasources: [] }, }), }), new SceneFlexLayout({ @@ -221,7 +275,7 @@ function getCloudScenes() { new SceneFlexItem({ body: new SceneReactObject({ component: SectionSubheader, - props: { children:
Mimir Alertmanager
}, + props: { children:
Mimir Alertmanager
, datasources: [cloudUsageDs] }, }), }), new SceneFlexLayout({ @@ -252,7 +306,7 @@ function getMimirManagedRulesScenes() { new SceneFlexItem({ body: new SceneReactObject({ component: SectionSubheader, - props: { children:
Mimir-managed rules
}, + props: { children:
Mimir-managed rules
, datasources: [grafanaCloudPromDs, cloudUsageDs] }, }), }), new SceneFlexLayout({ @@ -297,7 +351,7 @@ function getMimirManagedRulesPerGroupScenes() { new SceneFlexItem({ body: new SceneReactObject({ component: SectionSubheader, - props: { children:
Mimir-managed Rules - Per Rule Group
}, + props: { children:
Mimir-managed Rules - Per Rule Group
, datasources: [cloudUsageDs] }, }), }), new SceneFlexLayout({ diff --git a/public/app/features/alerting/unified/insights/DataSourcesInfo.tsx b/public/app/features/alerting/unified/insights/DataSourcesInfo.tsx new file mode 100644 index 00000000000..764cdc9fd44 --- /dev/null +++ b/public/app/features/alerting/unified/insights/DataSourcesInfo.tsx @@ -0,0 +1,38 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data/src/themes'; +import { useStyles2 } from '@grafana/ui'; + +import { DataSourceInformation } from '../home/Insights'; + +export function DataSourcesInfo({ datasources }: { datasources: DataSourceInformation[] }) { + const styles = useStyles2(getStyles); + + const displayDs = datasources.map((ds) => ( +
+ {ds.settings?.meta.info.logos.small && ( + {ds.settings?.name + )} + {ds.settings?.name || ds.uid} +
+ )); + + return
{displayDs}
; +} + +const getStyles = (theme: GrafanaTheme2) => ({ + dsImage: css({ + label: 'ds-image', + width: '16px', + marginRight: '3px', + }), + dsContainer: css({ + display: 'flex', + flexDirection: 'row', + fontSize: theme.typography.bodySmall.fontSize, + gap: '10px', + marginBottom: '10px', + justifyContent: 'flex-end', + }), +}); diff --git a/public/app/features/alerting/unified/insights/SectionSubheader.tsx b/public/app/features/alerting/unified/insights/SectionSubheader.tsx new file mode 100644 index 00000000000..7c0a9dda0a3 --- /dev/null +++ b/public/app/features/alerting/unified/insights/SectionSubheader.tsx @@ -0,0 +1,31 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data/src/themes'; +import { useStyles2 } from '@grafana/ui'; + +import { DataSourceInformation } from '../home/Insights'; + +import { DataSourcesInfo } from './DataSourcesInfo'; + +export function SectionSubheader({ + children, + datasources, +}: React.PropsWithChildren<{ datasources: DataSourceInformation[] }>) { + const styles = useStyles2(getStyles); + + return ( +
+
{children}
+ +
+ ); +} + +const getStyles = (theme: GrafanaTheme2) => ({ + container: css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + }), +}); diff --git a/public/app/features/alerting/unified/insights/grafana/alertmanager/NotificationsScene.tsx b/public/app/features/alerting/unified/insights/grafana/alertmanager/NotificationsScene.tsx index 8749f00783c..6f018f1492e 100644 --- a/public/app/features/alerting/unified/insights/grafana/alertmanager/NotificationsScene.tsx +++ b/public/app/features/alerting/unified/insights/grafana/alertmanager/NotificationsScene.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { PanelBuilders, SceneFlexItem, SceneQueryRunner } from '@grafana/scenes'; -import { DataSourceRef, GraphDrawStyle } from '@grafana/schema'; +import { DataSourceRef, GraphDrawStyle, TooltipDisplayMode } from '@grafana/schema'; import { overrideToFixedColor, PANEL_STYLES } from '../../../home/Insights'; import { InsightsRatingModal } from '../../RatingModal'; @@ -32,6 +32,7 @@ export function getGrafanaAlertmanagerNotificationsScene(datasource: DataSourceR .setDescription(panelTitle) .setData(query) .setCustomFieldConfig('drawStyle', GraphDrawStyle.Line) + .setOption('tooltip', { mode: TooltipDisplayMode.Multi }) .setOverrides((b) => b .matchFieldsWithName('success') diff --git a/public/app/features/alerting/unified/insights/grafana/alertmanager/SilencesByStateScene.tsx b/public/app/features/alerting/unified/insights/grafana/alertmanager/SilencesByStateScene.tsx index 64fc461096f..a4c908df7ee 100644 --- a/public/app/features/alerting/unified/insights/grafana/alertmanager/SilencesByStateScene.tsx +++ b/public/app/features/alerting/unified/insights/grafana/alertmanager/SilencesByStateScene.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { PanelBuilders, SceneFlexItem, SceneQueryRunner } from '@grafana/scenes'; -import { DataSourceRef, GraphDrawStyle } from '@grafana/schema'; +import { DataSourceRef, GraphDrawStyle, TooltipDisplayMode } from '@grafana/schema'; import { PANEL_STYLES } from '../../../home/Insights'; import { InsightsRatingModal } from '../../RatingModal'; @@ -26,6 +26,7 @@ export function getGrafanaAlertmanagerSilencesScene(datasource: DataSourceRef, p .setDescription(panelTitle) .setData(query) .setCustomFieldConfig('drawStyle', GraphDrawStyle.Line) + .setOption('tooltip', { mode: TooltipDisplayMode.Multi }) .setHeaderActions() .build(), });