grafana/public/app/features/alerting/NotificationsListPage.tsx
Ashley Harrison 1261345b81
Chore: Upgrade to react 18 (#64428)
* update react 18 related deps

* fix some types

* make sure we're on react-router-dom >= 5.3.3

* Use new root API

* Remove StrictMode for now - react 18 double rendering causes issues

* fix + ignore some @grafana/ui types

* fix some more types

* use renderHook from @testing-library/react in almost all cases

* fix storybook types

* rewrite useDashboardSave to not use useEffect

* make props optional

* only render if props are provided

* add correct type for useCallback

* make resourcepicker tests more robust

* fix ModalManager rendering

* fix some more unit tests

* store the click coordinates in a ref as setState is NOT synchronous

* fix remaining e2e tests

* rewrite dashboardpage tests to avoid act warnings

* undo lint ignores

* fix ExpanderCell types

* set SymbolCell type correctly

* fix QueryAndExpressionsStep

* looks like the types were actually wrong instead :D

* undo this for now...

* remove spinner waits

* more robust tests

* rewrite errorboundary test to not explicitly count the number of renders

* make urlParam expect async

* increase timeout in waitFor

* revert ExplorePage test changes

* Update public/app/features/dashboard/containers/DashboardPage.test.tsx

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* skip fakeTimer test, ignore table types for now + other review comments

* update package peerDeps

* small tweak to resourcepicker test

* update lockfile...

* increase timeout in sharepublicdashboard tests

* ensure ExplorePaneContainer passes correct queries to initializeExplore

* fix LokiContextUI test

* fix unit tests

* make importDashboard flow more consistent

* wait for dashboard name before continuing

* more test fixes

* readd dashboard name to variable e2e tests

* wait for switches to be enabled before clicking

* fix modal rendering

* don't use @testing-library/dom directly

* quick fix for rendering of panels in firefox

* make PromQueryField test more robust

* don't wait for chartData - in react 18 this can happen before the wait code even gets executed

---------

Co-authored-by: kay delaney <kay@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
2023-04-11 10:51:54 +01:00

125 lines
4.4 KiB
TypeScript

import React, { useState, FC, useEffect } from 'react';
import { useAsyncFn } from 'react-use';
import { getBackendSrv } from '@grafana/runtime';
import { HorizontalGroup, Button, LinkButton } from '@grafana/ui';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { Page } from 'app/core/components/Page/Page';
import { appEvents } from 'app/core/core';
import { useNavModel } from 'app/core/hooks/useNavModel';
import { AlertNotification } from 'app/types/alerting';
import { ShowConfirmModalEvent } from '../../types/events';
const NotificationsListPage: FC = () => {
const navModel = useNavModel('channels');
const [notifications, setNotifications] = useState<AlertNotification[]>([]);
const getNotifications = async () => {
return await getBackendSrv().get(`/api/alert-notifications`);
};
const [state, fetchNotifications] = useAsyncFn(getNotifications);
useEffect(() => {
fetchNotifications().then((res) => {
setNotifications(res);
});
}, [fetchNotifications]);
const deleteNotification = (id: number) => {
appEvents.publish(
new ShowConfirmModalEvent({
title: 'Delete',
text: 'Do you want to delete this notification channel?',
text2: `Deleting this notification channel will not delete from alerts any references to it`,
icon: 'trash-alt',
confirmText: 'Delete',
yesText: 'Delete',
onConfirm: async () => {
deleteNotificationConfirmed(id);
},
})
);
};
const deleteNotificationConfirmed = async (id: number) => {
await getBackendSrv().delete(`/api/alert-notifications/${id}`);
const notifications = await fetchNotifications();
setNotifications(notifications);
};
return (
<Page navModel={navModel}>
<Page.Contents>
{state.error && <p>{state.error.message}</p>}
{!!notifications.length && (
<>
<div className="page-action-bar">
<div className="page-action-bar__spacer" />
<LinkButton icon="channel-add" href="alerting/notification/new">
New channel
</LinkButton>
</div>
<table className="filter-table filter-table--hover">
<thead>
<tr>
<th style={{ minWidth: '200px' }}>
<strong>Name</strong>
</th>
<th style={{ minWidth: '100px' }}>Type</th>
<th style={{ width: '1%' }}></th>
</tr>
</thead>
<tbody>
{notifications.map((notification) => (
<tr key={notification.id}>
<td className="link-td">
<a href={`alerting/notification/${notification.id}/edit`}>{notification.name}</a>
</td>
<td className="link-td">
<a href={`alerting/notification/${notification.id}/edit`}>{notification.type}</a>
</td>
<td className="text-right">
<HorizontalGroup justify="flex-end">
{notification.isDefault && (
<Button disabled variant="secondary" size="sm">
default
</Button>
)}
<Button
variant="destructive"
icon="times"
size="sm"
onClick={() => {
deleteNotification(notification.id);
}}
/>
</HorizontalGroup>
</td>
</tr>
))}
</tbody>
</table>
</>
)}
{!(notifications.length || state.loading) && (
<EmptyListCTA
title="There are no notification channels defined yet"
buttonIcon="channel-add"
buttonLink="alerting/notification/new"
buttonTitle="Add channel"
proTip="You can include images in your alert notifications."
proTipLink="http://docs.grafana.org/alerting/notifications/"
proTipLinkTitle="Learn more"
proTipTarget="_blank"
/>
)}
</Page.Contents>
</Page>
);
};
export default NotificationsListPage;