mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard scenes: Display alerts in scenes dashboard (#81260)
Display alerts in scenes dashboard
This commit is contained in:
@@ -12,6 +12,6 @@ interface Props extends Omit<TabProps, 'counter' | 'ref'> {
|
||||
|
||||
// it will load rule count from backend
|
||||
export const PanelAlertTab = ({ panel, dashboard, ...otherProps }: Props) => {
|
||||
const { rules, loading } = usePanelCombinedRules({ panel, dashboard });
|
||||
const { rules, loading } = usePanelCombinedRules({ panelId: panel.id, dashboardUID: dashboard.uid });
|
||||
return <Tab {...otherProps} counter={loading ? null : rules.length} />;
|
||||
};
|
||||
|
||||
@@ -20,8 +20,8 @@ interface Props {
|
||||
export const PanelAlertTabContent = ({ dashboard, panel }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { errors, loading, rules } = usePanelCombinedRules({
|
||||
dashboard,
|
||||
panel,
|
||||
dashboardUID: dashboard.uid,
|
||||
panelId: panel.id,
|
||||
poll: true,
|
||||
});
|
||||
const permissions = getRulesPermissions('grafana');
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SerializedError } from '@reduxjs/toolkit';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { CombinedRule } from 'app/types/unified-alerting';
|
||||
|
||||
@@ -14,8 +13,8 @@ import { useCombinedRuleNamespaces } from './useCombinedRuleNamespaces';
|
||||
import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';
|
||||
|
||||
interface Options {
|
||||
dashboard: DashboardModel;
|
||||
panel: PanelModel;
|
||||
dashboardUID: string;
|
||||
panelId: number;
|
||||
|
||||
poll?: boolean;
|
||||
}
|
||||
@@ -27,7 +26,7 @@ interface ReturnBag {
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
export function usePanelCombinedRules({ dashboard, panel, poll = false }: Options): ReturnBag {
|
||||
export function usePanelCombinedRules({ dashboardUID, panelId, poll = false }: Options): ReturnBag {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const promRuleRequest =
|
||||
@@ -41,13 +40,13 @@ export function usePanelCombinedRules({ dashboard, panel, poll = false }: Option
|
||||
dispatch(
|
||||
fetchPromRulesAction({
|
||||
rulesSourceName: GRAFANA_RULES_SOURCE_NAME,
|
||||
filter: { dashboardUID: dashboard.uid, panelId: panel.id },
|
||||
filter: { dashboardUID, panelId },
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
fetchRulerRulesAction({
|
||||
rulesSourceName: GRAFANA_RULES_SOURCE_NAME,
|
||||
filter: { dashboardUID: dashboard.uid, panelId: panel.id },
|
||||
filter: { dashboardUID, panelId },
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -59,7 +58,7 @@ export function usePanelCombinedRules({ dashboard, panel, poll = false }: Option
|
||||
};
|
||||
}
|
||||
return () => {};
|
||||
}, [dispatch, poll, panel.id, dashboard.uid]);
|
||||
}, [dispatch, poll, panelId, dashboardUID]);
|
||||
|
||||
const loading = promRuleRequest.loading || rulerRuleRequest.loading;
|
||||
const errors = [promRuleRequest.error, rulerRuleRequest.error].filter(
|
||||
@@ -76,10 +75,10 @@ export function usePanelCombinedRules({ dashboard, panel, poll = false }: Option
|
||||
.flatMap((group) => group.rules)
|
||||
.filter(
|
||||
(rule) =>
|
||||
rule.annotations[Annotation.dashboardUID] === dashboard.uid &&
|
||||
rule.annotations[Annotation.panelID] === String(panel.id)
|
||||
rule.annotations[Annotation.dashboardUID] === dashboardUID &&
|
||||
rule.annotations[Annotation.panelID] === String(panelId)
|
||||
),
|
||||
[combinedNamespaces, dashboard, panel]
|
||||
[combinedNamespaces, dashboardUID, panelId]
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -2,7 +2,11 @@ import React from 'react';
|
||||
|
||||
import { IconName } from '@grafana/data';
|
||||
import { SceneObjectBase, SceneComponentProps } from '@grafana/scenes';
|
||||
import { Alert, LoadingPlaceholder } from '@grafana/ui';
|
||||
import { RulesTable } from 'app/features/alerting/unified/components/rules/RulesTable';
|
||||
import { usePanelCombinedRules } from 'app/features/alerting/unified/hooks/usePanelCombinedRules';
|
||||
|
||||
import { getDashboardSceneFor, getPanelIdForVizPanel } from '../../utils/utils';
|
||||
import { VizPanelManager } from '../VizPanelManager';
|
||||
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
|
||||
@@ -22,11 +26,55 @@ export class PanelDataAlertingTab extends SceneObjectBase<PanelDataPaneTabState>
|
||||
return 'Alert';
|
||||
}
|
||||
|
||||
getDashboardUID() {
|
||||
const dashboard = getDashboardSceneFor(this._panelManager);
|
||||
return dashboard.state.uid!;
|
||||
}
|
||||
|
||||
getPanelId() {
|
||||
return getPanelIdForVizPanel(this._panelManager.state.panel);
|
||||
}
|
||||
|
||||
get panelManager() {
|
||||
return this._panelManager;
|
||||
}
|
||||
}
|
||||
|
||||
function PanelDataAlertingTabRendered(props: SceneComponentProps<PanelDataAlertingTab>) {
|
||||
return <div>TODO Alerting</div>;
|
||||
const { model } = props;
|
||||
|
||||
const { errors, loading, rules } = usePanelCombinedRules({
|
||||
dashboardUID: model.getDashboardUID(),
|
||||
panelId: model.getPanelId(),
|
||||
poll: true,
|
||||
});
|
||||
|
||||
const alert = errors.length ? (
|
||||
<Alert title="Errors loading rules" severity="error">
|
||||
{errors.map((error, index) => (
|
||||
<div key={index}>Failed to load Grafana rules state: {error.message || 'Unknown error.'}</div>
|
||||
))}
|
||||
</Alert>
|
||||
) : null;
|
||||
|
||||
if (loading && !rules.length) {
|
||||
return (
|
||||
<>
|
||||
{alert}
|
||||
<LoadingPlaceholder text="Loading rules..." />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (rules.length) {
|
||||
return <RulesTable rules={rules} />;
|
||||
}
|
||||
|
||||
// TODO: this is the tricky part, converting queries and such to pre populate the new alert form when clicking the button
|
||||
return (
|
||||
<div>
|
||||
<p>There are no alert rules linked to this panel.</p>
|
||||
<button>New alert placeholder</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user