Alerting: Add plugins extension point to alerting home page (#85725)

* Add basic extension point to alerting home page

* Remove home page scenes app. Improve plugins styles

* Remove unused code

* Fix home page rendering when no plugins registered

* Add row-based integrations component

* Add missing margins

* Rollback the Box component changes

* Remove unused import
This commit is contained in:
Konrad Lalik
2024-04-22 13:42:11 +02:00
committed by GitHub
parent 686c8013c3
commit 7caa30bc2e
4 changed files with 87 additions and 84 deletions

View File

@ -116,6 +116,7 @@ export type PluginExtensionEventHelpers<Context extends object = object> = {
// Extension Points available in core Grafana
export enum PluginExtensionPoints {
AlertInstanceAction = 'grafana/alerting/instance/action',
AlertingHomePage = 'grafana/alerting/home',
CommandPalette = 'grafana/commandpalette/action',
DashboardPanelMenu = 'grafana/dashboard/panel/menu',
DataSourceConfig = 'grafana/datasources/config',

View File

@ -3,23 +3,8 @@ import React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { EmbeddedScene, SceneFlexLayout, SceneFlexItem, SceneReactObject } from '@grafana/scenes';
import { useStyles2, useTheme2, Stack, Text, TextLink } from '@grafana/ui';
export const getOverviewScene = () => {
return new EmbeddedScene({
body: new SceneFlexLayout({
children: [
new SceneFlexItem({
body: new SceneReactObject({
component: GettingStarted,
}),
}),
],
}),
});
};
export default function GettingStarted() {
const theme = useTheme2();
const styles = useStyles2(getWelcomePageStyles);
@ -110,9 +95,7 @@ export function WelcomeHeader({ className }: { className?: string }) {
const styles = useStyles2(getWelcomeHeaderStyles);
return (
<div className={styles.welcomeHeaderWrapper}>
<div className={styles.subtitle}>Learn about problems in your systems moments after they occur</div>
<Stack gap={2} direction="column">
<ContentBox className={cx(styles.ctaContainer, className)}>
<WelcomeCTABox
title="Alert rules"
@ -135,18 +118,11 @@ export function WelcomeHeader({ className }: { className?: string }) {
hrefText="Manage notification policies"
/>
</ContentBox>
</div>
</Stack>
);
}
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(2),
display: 'flex',
@ -195,6 +171,7 @@ function WelcomeCTABox({ title, description, href, hrefText }: WelcomeCTABoxProp
const getWelcomeCTAButtonStyles = (theme: GrafanaTheme2) => ({
container: css({
color: theme.colors.text.primary,
flex: 1,
minWidth: '240px',
display: 'grid',

View File

@ -1,74 +1,54 @@
import React, { useState } from 'react';
import { config } from '@grafana/runtime';
import { SceneApp, SceneAppPage } from '@grafana/scenes';
import { usePageNav } from 'app/core/components/Page/usePageNav';
import { PluginPageContext, PluginPageContextType } from 'app/features/plugins/components/PluginPageContext';
import { Box, Stack, Tab, TabContent, TabsBar } from '@grafana/ui';
import { AlertingPageWrapper } from '../components/AlertingPageWrapper';
import { isLocalDevEnv, isOpenSourceEdition } from '../utils/misc';
import { getOverviewScene, WelcomeHeader } from './GettingStarted';
import GettingStarted, { WelcomeHeader } from './GettingStarted';
import { getInsightsScenes } from './Insights';
let homeApp: SceneApp | undefined;
export function getHomeApp(insightsEnabled: boolean) {
if (homeApp) {
return homeApp;
}
if (insightsEnabled) {
homeApp = new SceneApp({
pages: [
new SceneAppPage({
title: 'Alerting',
subTitle: <WelcomeHeader />,
url: '/alerting',
hideFromBreadcrumbs: true,
tabs: [
new SceneAppPage({
title: 'Insights',
url: '/alerting/home/insights',
getScene: getInsightsScenes,
}),
new SceneAppPage({
title: 'Get started',
url: '/alerting/home/overview',
getScene: getOverviewScene,
}),
],
}),
],
});
} else {
homeApp = new SceneApp({
pages: [
new SceneAppPage({
title: 'Alerting',
subTitle: <WelcomeHeader />,
url: '/alerting',
hideFromBreadcrumbs: true,
getScene: getOverviewScene,
}),
],
});
}
return homeApp;
}
import { PluginIntegrations } from './PluginIntegrations';
export default function Home() {
const insightsEnabled =
(!isOpenSourceEdition() || isLocalDevEnv()) && Boolean(config.featureToggles.alertingInsights);
const appScene = getHomeApp(insightsEnabled);
const sectionNav = usePageNav('alerting')!;
const [pluginContext] = useState<PluginPageContextType>({ sectionNav });
const [activeTab, setActiveTab] = useState<'insights' | 'overview'>(insightsEnabled ? 'insights' : 'overview');
const insightsScene = getInsightsScenes();
return (
<PluginPageContext.Provider value={pluginContext}>
<appScene.Component model={appScene} />
</PluginPageContext.Provider>
<AlertingPageWrapper
title="Alerting"
subTitle="Learn about problems in your systems moments after they occur"
navId="alerting"
>
<Stack gap={2} direction="column">
<WelcomeHeader />
<PluginIntegrations />
</Stack>
<Box marginTop={{ lg: 2, md: 0, xs: 0 }}>
<TabsBar>
{insightsEnabled && (
<Tab
key="insights"
label="Insights"
active={activeTab === 'insights'}
onChangeTab={() => setActiveTab('insights')}
/>
)}
<Tab
key="overview"
label="Get started"
active={activeTab === 'overview'}
onChangeTab={() => setActiveTab('overview')}
/>
</TabsBar>
<TabContent>
{activeTab === 'insights' && <insightsScene.Component model={insightsScene} />}
{activeTab === 'overview' && <GettingStarted />}
</TabContent>
</Box>
</AlertingPageWrapper>
);
}

View File

@ -0,0 +1,45 @@
import { css } from '@emotion/css';
import React from 'react';
import { PluginExtensionPoints } from '@grafana/data';
import { GrafanaTheme2 } from '@grafana/data/';
import { getPluginComponentExtensions } from '@grafana/runtime';
import { Stack, Text } from '@grafana/ui';
import { useStyles2 } from '@grafana/ui/';
export function PluginIntegrations() {
const styles = useStyles2(getStyles);
const { extensions } = getPluginComponentExtensions({
extensionPointId: PluginExtensionPoints.AlertingHomePage,
limitPerPlugin: 1,
});
if (extensions.length === 0) {
return null;
}
return (
<Stack direction="column" gap={2}>
<Text element="h3" variant="h4">
Speed up your alerts creation now by using one of our tailored apps
</Text>
<Stack gap={2} wrap="wrap" direction="row">
{extensions.map((extension) => (
<div key={extension.id} className={styles.box}>
<extension.component />
</div>
))}
</Stack>
</Stack>
);
}
const getStyles = (theme: GrafanaTheme2) => ({
box: css({
padding: theme.spacing(2),
flex: 1,
backgroundColor: theme.colors.background.secondary,
maxWidth: '460px',
}),
});