mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Routing: Hoist alerting receivers routes (#94309)
* Separate receivers components * Update exports * Remove type assertion * Add back test * Format * Update test * Fix test import
This commit is contained in:
parent
a3764ebeba
commit
be7b293b79
@ -3,10 +3,7 @@ import { config } from 'app/core/config';
|
|||||||
import { GrafanaRouteComponent, RouteDescriptor } from 'app/core/navigation/types';
|
import { GrafanaRouteComponent, RouteDescriptor } from 'app/core/navigation/types';
|
||||||
import { AccessControlAction } from 'app/types';
|
import { AccessControlAction } from 'app/types';
|
||||||
|
|
||||||
import {
|
import { PERMISSIONS_CONTACT_POINTS } from './unified/components/contact-points/permissions';
|
||||||
PERMISSIONS_CONTACT_POINTS,
|
|
||||||
PERMISSIONS_CONTACT_POINTS_MODIFY,
|
|
||||||
} from './unified/components/contact-points/permissions';
|
|
||||||
import { evaluateAccess } from './unified/utils/access-control';
|
import { evaluateAccess } from './unified/utils/access-control';
|
||||||
|
|
||||||
export function getAlertingRoutes(cfg = config): RouteDescriptor[] {
|
export function getAlertingRoutes(cfg = config): RouteDescriptor[] {
|
||||||
@ -104,7 +101,43 @@ export function getAlertingRoutes(cfg = config): RouteDescriptor[] {
|
|||||||
...PERMISSIONS_CONTACT_POINTS,
|
...PERMISSIONS_CONTACT_POINTS,
|
||||||
]),
|
]),
|
||||||
component: importAlertingComponent(
|
component: importAlertingComponent(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "ContactPoints" */ 'app/features/alerting/unified/components/contact-points/ContactPoints'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/notifications/receivers/new',
|
||||||
|
roles: evaluateAccess([
|
||||||
|
AccessControlAction.AlertingNotificationsRead,
|
||||||
|
AccessControlAction.AlertingNotificationsExternalRead,
|
||||||
|
...PERMISSIONS_CONTACT_POINTS,
|
||||||
|
]),
|
||||||
|
component: importAlertingComponent(
|
||||||
|
() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "NewReceiverView" */ 'app/features/alerting/unified/components/receivers/NewReceiverView'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/notifications/receivers/:name/edit',
|
||||||
|
roles: evaluateAccess([
|
||||||
|
AccessControlAction.AlertingNotificationsWrite,
|
||||||
|
AccessControlAction.AlertingNotificationsExternalWrite,
|
||||||
|
AccessControlAction.AlertingNotificationsRead,
|
||||||
|
AccessControlAction.AlertingNotificationsExternalRead,
|
||||||
|
// We check any contact point permission here because a user without edit permissions
|
||||||
|
// still has to be able to visit the "edit" page, because we don't have a separate view for edit vs view
|
||||||
|
// (we just disable the form instead)
|
||||||
|
...PERMISSIONS_CONTACT_POINTS,
|
||||||
|
]),
|
||||||
|
component: importAlertingComponent(
|
||||||
|
() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "EditContactPoint" */ 'app/features/alerting/unified/components/contact-points/EditContactPoint'
|
||||||
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,60 +151,16 @@ export function getAlertingRoutes(cfg = config): RouteDescriptor[] {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/:type/new',
|
path: '/alerting/notifications/global-config',
|
||||||
roles: evaluateAccess([
|
|
||||||
AccessControlAction.AlertingNotificationsWrite,
|
|
||||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
|
||||||
...PERMISSIONS_CONTACT_POINTS_MODIFY,
|
|
||||||
]),
|
|
||||||
component: importAlertingComponent(
|
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/alerting/notifications/receivers/:id/edit',
|
|
||||||
roles: evaluateAccess([
|
|
||||||
AccessControlAction.AlertingNotificationsWrite,
|
|
||||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
|
||||||
AccessControlAction.AlertingNotificationsRead,
|
|
||||||
AccessControlAction.AlertingNotificationsExternalRead,
|
|
||||||
// We check any contact point permission here because a user without edit permissions
|
|
||||||
// still has to be able to visit the "edit" page, because we don't have a separate view for edit vs view
|
|
||||||
// (we just disable the form instead)
|
|
||||||
...PERMISSIONS_CONTACT_POINTS,
|
|
||||||
]),
|
|
||||||
component: importAlertingComponent(
|
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/alerting/notifications/:type/:id/edit',
|
|
||||||
roles: evaluateAccess([
|
roles: evaluateAccess([
|
||||||
AccessControlAction.AlertingNotificationsWrite,
|
AccessControlAction.AlertingNotificationsWrite,
|
||||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
AccessControlAction.AlertingNotificationsExternalWrite,
|
||||||
]),
|
]),
|
||||||
component: importAlertingComponent(
|
component: importAlertingComponent(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
() =>
|
||||||
),
|
import(
|
||||||
},
|
/* webpackChunkName: "GlobalConfig" */ 'app/features/alerting/unified/components/contact-points/components/GlobalConfig'
|
||||||
{
|
)
|
||||||
path: '/alerting/notifications/:type/:id/duplicate',
|
|
||||||
roles: evaluateAccess([
|
|
||||||
AccessControlAction.AlertingNotificationsWrite,
|
|
||||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
|
||||||
]),
|
|
||||||
component: importAlertingComponent(
|
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/alerting/notifications/:type',
|
|
||||||
roles: evaluateAccess([
|
|
||||||
AccessControlAction.AlertingNotificationsWrite,
|
|
||||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
|
||||||
]),
|
|
||||||
component: importAlertingComponent(
|
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/unified/Receivers')
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Route, Routes } from 'react-router-dom-v5-compat';
|
||||||
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
||||||
import { render, screen, waitFor, userEvent } from 'test/test-utils';
|
import { render, screen, waitFor, userEvent } from 'test/test-utils';
|
||||||
|
|
||||||
@ -11,9 +12,10 @@ import { grantUserPermissions } from 'app/features/alerting/unified/mocks';
|
|||||||
import { setupDataSources } from 'app/features/alerting/unified/testSetup/datasources';
|
import { setupDataSources } from 'app/features/alerting/unified/testSetup/datasources';
|
||||||
import { AccessControlAction } from 'app/types';
|
import { AccessControlAction } from 'app/types';
|
||||||
|
|
||||||
import ContactPoints from './Receivers';
|
|
||||||
|
|
||||||
import 'core-js/stable/structured-clone';
|
import 'core-js/stable/structured-clone';
|
||||||
|
import ContactPoints from './components/contact-points/ContactPoints';
|
||||||
|
import EditContactPoint from './components/contact-points/EditContactPoint';
|
||||||
|
import NewReceiverView from './components/receivers/NewReceiverView';
|
||||||
|
|
||||||
const server = setupMswServer();
|
const server = setupMswServer();
|
||||||
|
|
||||||
@ -28,6 +30,21 @@ const saveContactPoint = async () => {
|
|||||||
return user.click(await screen.findByRole('button', { name: /save contact point/i }));
|
return user.click(await screen.findByRole('button', { name: /save contact point/i }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setup = (location: string) => {
|
||||||
|
return render(
|
||||||
|
<Routes>
|
||||||
|
<Route path="/alerting/notifications" element={<ContactPoints />} />
|
||||||
|
<Route path="/alerting/notifications/receivers/new" element={<NewReceiverView />} />
|
||||||
|
<Route path="/alerting/notifications/receivers/:name/edit" element={<EditContactPoint />} />
|
||||||
|
</Routes>,
|
||||||
|
{
|
||||||
|
historyOptions: {
|
||||||
|
initialEntries: [location],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
grantUserPermissions([
|
grantUserPermissions([
|
||||||
AccessControlAction.AlertingNotificationsRead,
|
AccessControlAction.AlertingNotificationsRead,
|
||||||
@ -41,18 +58,7 @@ beforeEach(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can save a contact point with a select dropdown', async () => {
|
it('can save a contact point with a select dropdown', async () => {
|
||||||
const user = userEvent.setup();
|
const { user } = setup(`/alerting/notifications/receivers/new?alertmanager=${PROVISIONED_MIMIR_ALERTMANAGER_UID}`);
|
||||||
|
|
||||||
render(<ContactPoints />, {
|
|
||||||
historyOptions: {
|
|
||||||
initialEntries: [
|
|
||||||
{
|
|
||||||
pathname: `/alerting/notifications/receivers/new`,
|
|
||||||
search: `?alertmanager=${PROVISIONED_MIMIR_ALERTMANAGER_UID}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fill out contact point name
|
// Fill out contact point name
|
||||||
const contactPointName = await screen.findByPlaceholderText(/name/i);
|
const contactPointName = await screen.findByPlaceholderText(/name/i);
|
||||||
@ -75,16 +81,7 @@ it('can save a contact point with a select dropdown', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can save existing Telegram contact point', async () => {
|
it('can save existing Telegram contact point', async () => {
|
||||||
render(<ContactPoints />, {
|
setup(`/alerting/notifications/receivers/Telegram/edit?alertmanager=${PROVISIONED_MIMIR_ALERTMANAGER_UID}`);
|
||||||
historyOptions: {
|
|
||||||
initialEntries: [
|
|
||||||
{
|
|
||||||
pathname: `/alerting/notifications/receivers/Telegram/edit`,
|
|
||||||
search: `?alertmanager=${PROVISIONED_MIMIR_ALERTMANAGER_UID}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Here, we're implicitly testing that our parsing of an existing Telegram integration works correctly
|
// Here, we're implicitly testing that our parsing of an existing Telegram integration works correctly
|
||||||
// Our mock server will reject a request if we've sent the Chat ID as `0`,
|
// Our mock server will reject a request if we've sent the Chat ID as `0`,
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import { Route, Switch } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { withErrorBoundary } from '@grafana/ui';
|
|
||||||
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
|
||||||
|
|
||||||
import { AlertmanagerPageWrapper } from './components/AlertingPageWrapper';
|
|
||||||
|
|
||||||
const ContactPointsV2 = SafeDynamicImport(() => import('./components/contact-points/ContactPoints'));
|
|
||||||
const EditContactPoint = SafeDynamicImport(() => import('./components/contact-points/EditContactPoint'));
|
|
||||||
const NewReceiverView = SafeDynamicImport(() => import('./components/receivers/NewReceiverView'));
|
|
||||||
const GlobalConfig = SafeDynamicImport(() => import('./components/contact-points/components/GlobalConfig'));
|
|
||||||
|
|
||||||
const ContactPoints = (): JSX.Element => (
|
|
||||||
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
|
||||||
<Switch>
|
|
||||||
<Route exact={true} path="/alerting/notifications" component={ContactPointsV2} />
|
|
||||||
<Route exact={true} path="/alerting/notifications/receivers/new" component={NewReceiverView} />
|
|
||||||
<Route exact={true} path="/alerting/notifications/receivers/:name/edit" component={EditContactPoint} />
|
|
||||||
<Route exact={true} path="/alerting/notifications/global-config" component={GlobalConfig} />
|
|
||||||
</Switch>
|
|
||||||
</AlertmanagerPageWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default withErrorBoundary(ContactPoints, { style: 'page' });
|
|
@ -19,7 +19,7 @@ import { setupDataSources } from '../../testSetup/datasources';
|
|||||||
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||||
|
|
||||||
import { ContactPoint } from './ContactPoint';
|
import { ContactPoint } from './ContactPoint';
|
||||||
import ContactPointsPageContents from './ContactPoints';
|
import { ContactPointsPageContents } from './ContactPoints';
|
||||||
import setupMimirFlavoredServer, { MIMIR_DATASOURCE_UID } from './__mocks__/mimirFlavoredServer';
|
import setupMimirFlavoredServer, { MIMIR_DATASOURCE_UID } from './__mocks__/mimirFlavoredServer';
|
||||||
import setupVanillaAlertmanagerFlavoredServer, {
|
import setupVanillaAlertmanagerFlavoredServer, {
|
||||||
VANILLA_ALERTMANAGER_DATASOURCE_UID,
|
VANILLA_ALERTMANAGER_DATASOURCE_UID,
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
TabContent,
|
TabContent,
|
||||||
TabsBar,
|
TabsBar,
|
||||||
Text,
|
Text,
|
||||||
|
withErrorBoundary,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
import { t, Trans } from 'app/core/internationalization';
|
import { t, Trans } from 'app/core/internationalization';
|
||||||
@ -24,6 +25,7 @@ import { usePagination } from '../../hooks/usePagination';
|
|||||||
import { useURLSearchParams } from '../../hooks/useURLSearchParams';
|
import { useURLSearchParams } from '../../hooks/useURLSearchParams';
|
||||||
import { useAlertmanager } from '../../state/AlertmanagerContext';
|
import { useAlertmanager } from '../../state/AlertmanagerContext';
|
||||||
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||||
|
import { AlertmanagerPageWrapper } from '../AlertingPageWrapper';
|
||||||
import { GrafanaAlertmanagerDeliveryWarning } from '../GrafanaAlertmanagerDeliveryWarning';
|
import { GrafanaAlertmanagerDeliveryWarning } from '../GrafanaAlertmanagerDeliveryWarning';
|
||||||
|
|
||||||
import { ContactPoint } from './ContactPoint';
|
import { ContactPoint } from './ContactPoint';
|
||||||
@ -179,7 +181,7 @@ const useTabQueryParam = () => {
|
|||||||
return [param, setParam] as const;
|
return [param, setParam] as const;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ContactPointsPageContents = () => {
|
export const ContactPointsPageContents = () => {
|
||||||
const { selectedAlertmanager } = useAlertmanager();
|
const { selectedAlertmanager } = useAlertmanager();
|
||||||
const [activeTab, setActiveTab] = useTabQueryParam();
|
const [activeTab, setActiveTab] = useTabQueryParam();
|
||||||
|
|
||||||
@ -242,4 +244,12 @@ const ContactPointsList = ({ contactPoints, search, pageSize = DEFAULT_PAGE_SIZE
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ContactPointsPageContents;
|
function ContactPointsPage() {
|
||||||
|
return (
|
||||||
|
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
||||||
|
<ContactPointsPageContents />
|
||||||
|
</AlertmanagerPageWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(ContactPointsPage, { style: 'page' });
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { RouteChildrenProps } from 'react-router-dom';
|
import { useParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { Alert, LoadingPlaceholder } from '@grafana/ui';
|
import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui';
|
||||||
import { useGetContactPoint } from 'app/features/alerting/unified/components/contact-points/useContactPoints';
|
import { useGetContactPoint } from 'app/features/alerting/unified/components/contact-points/useContactPoints';
|
||||||
import { stringifyErrorLike } from 'app/features/alerting/unified/utils/misc';
|
import { stringifyErrorLike } from 'app/features/alerting/unified/utils/misc';
|
||||||
|
|
||||||
import { useAlertmanager } from '../../state/AlertmanagerContext';
|
import { useAlertmanager } from '../../state/AlertmanagerContext';
|
||||||
|
import { AlertmanagerPageWrapper } from '../AlertingPageWrapper';
|
||||||
import { EditReceiverView } from '../receivers/EditReceiverView';
|
import { EditReceiverView } from '../receivers/EditReceiverView';
|
||||||
|
|
||||||
type Props = RouteChildrenProps<{ name: string }>;
|
const EditContactPoint = () => {
|
||||||
|
|
||||||
const EditContactPoint = ({ match }: Props) => {
|
|
||||||
const { selectedAlertmanager } = useAlertmanager();
|
const { selectedAlertmanager } = useAlertmanager();
|
||||||
|
const { name = '' } = useParams();
|
||||||
|
|
||||||
const contactPointName = decodeURIComponent(match?.params.name!);
|
const contactPointName = decodeURIComponent(name);
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
@ -42,4 +42,12 @@ const EditContactPoint = ({ match }: Props) => {
|
|||||||
return <EditReceiverView alertmanagerName={selectedAlertmanager!} contactPoint={contactPoint} />;
|
return <EditReceiverView alertmanagerName={selectedAlertmanager!} contactPoint={contactPoint} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditContactPoint;
|
function EditContactPointPage() {
|
||||||
|
return (
|
||||||
|
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
||||||
|
<EditContactPoint />
|
||||||
|
</AlertmanagerPageWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(EditContactPointPage, { style: 'page' });
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Alert } from '@grafana/ui';
|
import { Alert, withErrorBoundary } from '@grafana/ui';
|
||||||
|
|
||||||
import { useAlertmanagerConfig } from '../../../hooks/useAlertmanagerConfig';
|
import { useAlertmanagerConfig } from '../../../hooks/useAlertmanagerConfig';
|
||||||
import { useAlertmanager } from '../../../state/AlertmanagerContext';
|
import { useAlertmanager } from '../../../state/AlertmanagerContext';
|
||||||
|
import { AlertmanagerPageWrapper } from '../../AlertingPageWrapper';
|
||||||
import { GlobalConfigForm } from '../../receivers/GlobalConfigForm';
|
import { GlobalConfigForm } from '../../receivers/GlobalConfigForm';
|
||||||
|
|
||||||
const NewMessageTemplate = () => {
|
const NewMessageTemplate = () => {
|
||||||
@ -27,4 +28,12 @@ const NewMessageTemplate = () => {
|
|||||||
return <GlobalConfigForm config={data} alertManagerSourceName={selectedAlertmanager!} />;
|
return <GlobalConfigForm config={data} alertManagerSourceName={selectedAlertmanager!} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NewMessageTemplate;
|
function NewMessageTemplatePage() {
|
||||||
|
return (
|
||||||
|
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
||||||
|
<NewMessageTemplate />
|
||||||
|
</AlertmanagerPageWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(NewMessageTemplatePage, { style: 'page' });
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import { withErrorBoundary } from '@grafana/ui';
|
||||||
import { useAlertmanager } from 'app/features/alerting/unified/state/AlertmanagerContext';
|
import { useAlertmanager } from 'app/features/alerting/unified/state/AlertmanagerContext';
|
||||||
|
|
||||||
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||||
|
import { AlertmanagerPageWrapper } from '../AlertingPageWrapper';
|
||||||
|
|
||||||
import { CloudReceiverForm } from './form/CloudReceiverForm';
|
import { CloudReceiverForm } from './form/CloudReceiverForm';
|
||||||
import { GrafanaReceiverForm } from './form/GrafanaReceiverForm';
|
import { GrafanaReceiverForm } from './form/GrafanaReceiverForm';
|
||||||
@ -14,4 +16,12 @@ const NewReceiverView = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NewReceiverView;
|
function NewReceiverViewPage() {
|
||||||
|
return (
|
||||||
|
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
||||||
|
<NewReceiverView />
|
||||||
|
</AlertmanagerPageWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(NewReceiverViewPage, { style: 'page' });
|
||||||
|
Loading…
Reference in New Issue
Block a user