diff --git a/package.json b/package.json index 726758ef107..c443e2185be 100644 --- a/package.json +++ b/package.json @@ -251,7 +251,7 @@ "@grafana/lezer-traceql": "0.0.6", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "^1.1.1", + "@grafana/scenes": "^1.3.1", "@grafana/schema": "workspace:*", "@grafana/ui": "workspace:*", "@kusto/monaco-kusto": "^7.4.0", diff --git a/public/app/features/alerting/routes.tsx b/public/app/features/alerting/routes.tsx index c9e925ce599..66e2b708fd7 100644 --- a/public/app/features/alerting/routes.tsx +++ b/public/app/features/alerting/routes.tsx @@ -93,6 +93,13 @@ const unifiedRoutes: RouteDescriptor[] = [ () => import(/* webpackChunkName: "AlertingHome" */ 'app/features/alerting/unified/home/Home') ), }, + { + path: '/alerting/home', + exact: false, + component: SafeDynamicImport( + () => import(/* webpackChunkName: "AlertingHome" */ 'app/features/alerting/unified/home/Home') + ), + }, { path: '/alerting/list', roles: evaluateAccess([AccessControlAction.AlertingRuleRead, AccessControlAction.AlertingRuleExternalRead]), diff --git a/public/app/features/alerting/unified/home/GettingStarted.tsx b/public/app/features/alerting/unified/home/GettingStarted.tsx index 95d3591d652..263dd94428d 100644 --- a/public/app/features/alerting/unified/home/GettingStarted.tsx +++ b/public/app/features/alerting/unified/home/GettingStarted.tsx @@ -4,8 +4,23 @@ import SVG from 'react-inlinesvg'; import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; +import { EmbeddedScene, SceneFlexLayout, SceneFlexItem, SceneReactObject } from '@grafana/scenes'; import { Icon, useStyles2, useTheme2 } from '@grafana/ui'; +export const getOverviewScene = () => { + return new EmbeddedScene({ + body: new SceneFlexLayout({ + children: [ + new SceneFlexItem({ + body: new SceneReactObject({ + component: GettingStarted, + }), + }), + ], + }), + }); +}; + export default function GettingStarted({ showWelcomeHeader }: { showWelcomeHeader?: boolean }) { const theme = useTheme2(); const styles = useStyles2(getWelcomePageStyles); @@ -130,32 +145,43 @@ export function WelcomeHeader({ className }: { className?: string }) { const styles = useStyles2(getWelcomeHeaderStyles); return ( - - -
- -
- - +
+
Learn about problems in your systems moments after they occur
+ + + +
+ +
+ + +
); } const getWelcomeHeaderStyles = (theme: GrafanaTheme2) => ({ + welcomeHeaderWrapper: css({ + color: theme.colors.text.primary, + }), + subtitle: css({ + color: theme.colors.text.secondary, + paddingBottom: theme.spacing(2), + }), ctaContainer: css` padding: ${theme.spacing(4, 2)}; display: flex; diff --git a/public/app/features/alerting/unified/home/Home.tsx b/public/app/features/alerting/unified/home/Home.tsx index b164858a6b9..33753b070c1 100644 --- a/public/app/features/alerting/unified/home/Home.tsx +++ b/public/app/features/alerting/unified/home/Home.tsx @@ -1,50 +1,71 @@ import React, { useState } from 'react'; import { config } from '@grafana/runtime'; -import { Tab, TabContent, TabsBar } from '@grafana/ui'; +import { SceneApp, SceneAppPage } from '@grafana/scenes'; +import { usePageNav } from 'app/core/components/Page/usePageNav'; +import { PluginPageContext, PluginPageContextType } from 'app/features/plugins/components/PluginPageContext'; -import { AlertingPageWrapper } from '../components/AlertingPageWrapper'; +import { getOverviewScene, WelcomeHeader } from './GettingStarted'; +import { getGrafanaScenes } from './Insights'; -import GettingStarted, { WelcomeHeader } from './GettingStarted'; -import Insights from './Insights'; +let homeApp: SceneApp | undefined; -type HomeTabs = 'insights' | 'gettingStarted'; +export function getHomeApp(insightsEnabled: boolean) { + if (homeApp) { + return homeApp; + } + + if (insightsEnabled) { + homeApp = new SceneApp({ + pages: [ + new SceneAppPage({ + title: 'Alerting', + subTitle: , + url: '/alerting', + hideFromBreadcrumbs: true, + tabs: [ + new SceneAppPage({ + title: 'Grafana', + url: '/alerting/home/insights', + getScene: getGrafanaScenes, + }), + new SceneAppPage({ + title: 'Overview', + url: '/alerting/home/overview', + getScene: getOverviewScene, + }), + ], + }), + ], + }); + } else { + homeApp = new SceneApp({ + pages: [ + new SceneAppPage({ + title: 'Alerting', + subTitle: , + url: '/alerting', + hideFromBreadcrumbs: true, + getScene: getOverviewScene, + }), + ], + }); + } + + return homeApp; +} export default function Home() { - const [activeTab, setActiveTab] = useState('insights'); + const insightsEnabled = !!config.featureToggles.alertingInsights; + + const appScene = getHomeApp(insightsEnabled); + + const sectionNav = usePageNav('alerting')!; + const [pluginContext] = useState({ sectionNav }); - const alertingInsightsEnabled = config.featureToggles.alertingInsights; return ( - - {alertingInsightsEnabled && ( - <> - - - { - setActiveTab('insights'); - }} - /> - { - setActiveTab('gettingStarted'); - }} - /> - - - {activeTab === 'insights' && } - {activeTab === 'gettingStarted' && } - - - )} - - {!alertingInsightsEnabled && } - + + + ); } diff --git a/public/app/features/alerting/unified/home/Insights.tsx b/public/app/features/alerting/unified/home/Insights.tsx index abe83941c5f..8674486dcd3 100644 --- a/public/app/features/alerting/unified/home/Insights.tsx +++ b/public/app/features/alerting/unified/home/Insights.tsx @@ -1,16 +1,13 @@ -import { css } from '@emotion/css'; -import React from 'react'; - -import { GrafanaTheme2 } from '@grafana/data'; import { EmbeddedScene, + NestedScene, QueryVariable, + SceneFlexItem, SceneFlexLayout, SceneTimeRange, SceneVariableSet, VariableValueSelectors, } from '@grafana/scenes'; -import { useStyles2, CollapsableSection } from '@grafana/ui'; import { getFiringAlertsScene } from '../insights/grafana/FiringAlertsPercentage'; import { getFiringAlertsRateScene } from '../insights/grafana/FiringAlertsRate'; @@ -49,31 +46,50 @@ const grafanaCloudPromDs = { const THIS_WEEK_TIME_RANGE = new SceneTimeRange({ from: 'now-1w', to: 'now' }); const LAST_WEEK_TIME_RANGE = new SceneTimeRange({ from: 'now-2w', to: 'now-1w' }); -function getGrafanaScenes() { +export function getGrafanaScenes() { return new EmbeddedScene({ body: new SceneFlexLayout({ - wrap: 'wrap', + direction: 'column', children: [ - getMostFiredInstancesScene(THIS_WEEK_TIME_RANGE, ashDs, 'Top 10 firing instances this week'), - - getFiringAlertsRateScene(THIS_WEEK_TIME_RANGE, ashDs, 'Alerts firing per minute'), - - getFiringAlertsScene(THIS_WEEK_TIME_RANGE, ashDs, 'Firing alerts this week'), - - getFiringAlertsScene(LAST_WEEK_TIME_RANGE, ashDs, 'Firing alerts last week'), + new SceneFlexLayout({ + children: [ + getMostFiredInstancesScene(THIS_WEEK_TIME_RANGE, ashDs, 'Top 10 firing instances this week'), + getFiringAlertsRateScene(THIS_WEEK_TIME_RANGE, ashDs, 'Alerts firing per minute'), + ], + }), + new SceneFlexLayout({ + children: [ + getFiringAlertsScene(THIS_WEEK_TIME_RANGE, ashDs, 'Firing alerts this week'), + getFiringAlertsScene(LAST_WEEK_TIME_RANGE, ashDs, 'Firing alerts last week'), + ], + }), + new SceneFlexItem({ + ySizing: 'content', + body: getCloudScenes(), + }), + new SceneFlexItem({ + ySizing: 'content', + body: getMimirManagedRulesScenes(), + }), + new SceneFlexItem({ + ySizing: 'content', + body: getMimirManagedRulesPerGroupScenes(), + }), ], }), }); } function getCloudScenes() { - return new EmbeddedScene({ + return new NestedScene({ + title: 'Mimir alertmanager', + canCollapse: true, + isCollapsed: true, body: new SceneFlexLayout({ wrap: 'wrap', children: [ getAlertsByStateScene(THIS_WEEK_TIME_RANGE, cloudUsageDs, 'Alerts by State'), getNotificationsScene(THIS_WEEK_TIME_RANGE, cloudUsageDs, 'Notifications'), - getSilencesScene(LAST_WEEK_TIME_RANGE, cloudUsageDs, 'Silences'), getInvalidConfigScene(THIS_WEEK_TIME_RANGE, cloudUsageDs, 'Invalid configuration'), ], @@ -82,7 +98,10 @@ function getCloudScenes() { } function getMimirManagedRulesScenes() { - return new EmbeddedScene({ + return new NestedScene({ + title: 'Mimir-managed rules', + canCollapse: true, + isCollapsed: true, body: new SceneFlexLayout({ wrap: 'wrap', children: [ @@ -108,7 +127,10 @@ function getMimirManagedRulesPerGroupScenes() { query: 'label_values(grafanacloud_instance_rule_group_rules,rule_group)', }); - return new EmbeddedScene({ + return new NestedScene({ + title: 'Mimir-managed Rules - Per Rule Group', + canCollapse: true, + isCollapsed: true, body: new SceneFlexLayout({ wrap: 'wrap', children: [ @@ -124,37 +146,3 @@ function getMimirManagedRulesPerGroupScenes() { controls: [new VariableValueSelectors({})], }); } - -export default function Insights() { - const styles = useStyles2(getStyles); - const grafanaScenes = getGrafanaScenes(); - const cloudScenes = getCloudScenes(); - const mimirRulesScenes = getMimirManagedRulesScenes(); - const mimirRulesPerGroupScenes = getMimirManagedRulesPerGroupScenes(); - - return ( -
- - - - - - - - - - - - - - - -
- ); -} - -const getStyles = (theme: GrafanaTheme2) => ({ - container: css({ - padding: '10px 0 10px 0', - }), -}); diff --git a/public/app/features/alerting/unified/insights/grafana/FiringAlertsPercentage.tsx b/public/app/features/alerting/unified/insights/grafana/FiringAlertsPercentage.tsx index a59a0d96af4..b771e2de78a 100644 --- a/public/app/features/alerting/unified/insights/grafana/FiringAlertsPercentage.tsx +++ b/public/app/features/alerting/unified/insights/grafana/FiringAlertsPercentage.tsx @@ -61,8 +61,7 @@ export function getFiringAlertsScene(timeRange: SceneTimeRange, datasource: Data }); return new SceneFlexItem({ - width: 'calc(50% - 4px)', - height: 300, + minHeight: 300, body: PanelBuilders.stat().setTitle(panelTitle).setData(transformation).setUnit('percent').build(), }); } diff --git a/public/app/features/alerting/unified/insights/grafana/FiringAlertsRate.tsx b/public/app/features/alerting/unified/insights/grafana/FiringAlertsRate.tsx index b3c6dc58780..6765d283584 100644 --- a/public/app/features/alerting/unified/insights/grafana/FiringAlertsRate.tsx +++ b/public/app/features/alerting/unified/insights/grafana/FiringAlertsRate.tsx @@ -18,8 +18,7 @@ export function getFiringAlertsRateScene(timeRange: SceneTimeRange, datasource: }); return new SceneFlexItem({ - width: 'calc(50% - 4px)', - height: 300, + minHeight: 300, body: PanelBuilders.timeseries() .setTitle(panelTitle) .setData(query) diff --git a/public/app/features/alerting/unified/insights/grafana/MostFiredInstancesTable.tsx b/public/app/features/alerting/unified/insights/grafana/MostFiredInstancesTable.tsx index 86759ce47d8..10012787a4d 100644 --- a/public/app/features/alerting/unified/insights/grafana/MostFiredInstancesTable.tsx +++ b/public/app/features/alerting/unified/insights/grafana/MostFiredInstancesTable.tsx @@ -103,8 +103,7 @@ export function getMostFiredInstancesScene(timeRange: SceneTimeRange, datasource }); return new SceneFlexItem({ - width: 'calc(50% - 4px)', - height: 300, + minHeight: 300, body: PanelBuilders.table().setTitle(panelTitle).setData(transformation).build(), }); } diff --git a/public/app/features/alerting/unified/insights/grafana/MostFiredRulesTable.tsx b/public/app/features/alerting/unified/insights/grafana/MostFiredRulesTable.tsx index a4c5a8d2b1f..9789806304c 100644 --- a/public/app/features/alerting/unified/insights/grafana/MostFiredRulesTable.tsx +++ b/public/app/features/alerting/unified/insights/grafana/MostFiredRulesTable.tsx @@ -54,8 +54,7 @@ export function getMostFiredRulesScene(timeRange: SceneTimeRange, datasource: Da }); return new SceneFlexItem({ - width: 'calc(50% - 4px)', - height: 300, + minHeight: 300, body: PanelBuilders.table().setTitle(panelTitle).setData(transformation).build(), }); } diff --git a/public/app/features/alerting/unified/insights/grafana/MostFiringLabels.tsx b/public/app/features/alerting/unified/insights/grafana/MostFiringLabels.tsx index eb3b084ca7b..758a0f02653 100644 --- a/public/app/features/alerting/unified/insights/grafana/MostFiringLabels.tsx +++ b/public/app/features/alerting/unified/insights/grafana/MostFiringLabels.tsx @@ -49,8 +49,7 @@ export function getMostFiredLabelsScene(timeRange: SceneTimeRange, datasource: D }); return new SceneFlexItem({ - width: 'calc(50% - 8px)', - height: 300, + minHeight: 300, body: PanelBuilders.table().setTitle(panelTitle).setData(query).build(), }); } diff --git a/yarn.lock b/yarn.lock index ad7933f3faa..9d7883a41e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4010,9 +4010,9 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes@npm:^1.1.1": - version: 1.1.1 - resolution: "@grafana/scenes@npm:1.1.1" +"@grafana/scenes@npm:^1.3.1": + version: 1.3.1 + resolution: "@grafana/scenes@npm:1.3.1" dependencies: "@grafana/e2e-selectors": 10.0.2 react-grid-layout: 1.3.4 @@ -4024,7 +4024,7 @@ __metadata: "@grafana/runtime": 10.0.3 "@grafana/schema": 10.0.3 "@grafana/ui": 10.0.3 - checksum: 6405998a40e38f088443f5d4b1f5ea1f73e5bc0d08216e4aaccf8ff0b68ec4c3d691430857f357d3eed335dee0dc2e24c41c5c2f286fc7fdd32375382ad3eafe + checksum: fe348e4eaaa3604d0d1ec745b14ae1c0752ce1aa481e5f05a10cdf9392448386e600c2a94f2ae23af83f59daf34cd11fb7a336da863b8624b98c8d3c2732b3c3 languageName: node linkType: hard @@ -19702,7 +19702,7 @@ __metadata: "@grafana/lezer-traceql": 0.0.6 "@grafana/monaco-logql": ^0.0.7 "@grafana/runtime": "workspace:*" - "@grafana/scenes": ^1.1.1 + "@grafana/scenes": ^1.3.1 "@grafana/schema": "workspace:*" "@grafana/tsconfig": ^1.3.0-rc1 "@grafana/ui": "workspace:*"