mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Migration: Alerting - notifications list (#22548)
* Handle empty list * Connect to redux * Finish migration * Remove comments * Remove old files * Remove console log * Remove old import * Forgot to add the new button * Fix href * Fix feedback
This commit is contained in:
parent
1f2a70117b
commit
8d56f87473
9
public/app/core/hooks/useNavModel.ts
Normal file
9
public/app/core/hooks/useNavModel.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { StoreState } from 'app/types/store';
|
||||
import { getNavModel } from '../selectors/navModel';
|
||||
import { NavModel } from '../core';
|
||||
|
||||
export const useNavModel = (id: string): NavModel => {
|
||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||
return getNavModel(navIndex, id);
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
import { IScope } from 'angular';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
|
||||
import { coreModule, NavModelSrv } from 'app/core/core';
|
||||
import { promiseToDigest } from '../../core/utils/promiseToDigest';
|
||||
|
||||
export class AlertNotificationsListCtrl {
|
||||
notifications: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope: IScope, navModelSrv: NavModelSrv) {
|
||||
this.loadNotifications();
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
|
||||
}
|
||||
|
||||
loadNotifications() {
|
||||
promiseToDigest(this.$scope)(
|
||||
getBackendSrv()
|
||||
.get(`/api/alert-notifications`)
|
||||
.then((result: any) => {
|
||||
this.notifications = result;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
deleteNotification(id: number) {
|
||||
promiseToDigest(this.$scope)(
|
||||
getBackendSrv()
|
||||
.delete(`/api/alert-notifications/${id}`)
|
||||
.then(() => {
|
||||
this.notifications = this.notifications.filter((notification: any) => {
|
||||
return notification.id !== id;
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.controller('AlertNotificationsListCtrl', AlertNotificationsListCtrl);
|
103
public/app/features/alerting/NotificationsListPage.tsx
Normal file
103
public/app/features/alerting/NotificationsListPage.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
import React, { useState, FC, useEffect } from 'react';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { useAsyncFn } from 'react-use';
|
||||
import { useNavModel } from 'app/core/hooks/useNavModel';
|
||||
import { HorizontalGroup, Button, LinkButton } from '@grafana/ui';
|
||||
import { AlertNotification } from 'app/types/alerting';
|
||||
|
||||
const deleteNotification = async (id: number) => {
|
||||
return await getBackendSrv().delete(`/api/alert-notifications/${id}`);
|
||||
};
|
||||
|
||||
const getNotifications = async () => {
|
||||
return await getBackendSrv().get(`/api/alert-notifications`);
|
||||
};
|
||||
|
||||
const NotificationsListPage: FC = () => {
|
||||
const navModel = useNavModel('channels');
|
||||
|
||||
const [notifications, setNotifications] = useState<AlertNotification[]>([]);
|
||||
const [state, fetchNotifications] = useAsyncFn(getNotifications);
|
||||
useEffect(() => {
|
||||
fetchNotifications().then(res => {
|
||||
setNotifications(res);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page.Contents>
|
||||
{state.error && <p>{state.error}</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);
|
||||
setNotifications(notifications.filter(notify => notify.id !== notification.id));
|
||||
fetchNotifications();
|
||||
}}
|
||||
/>
|
||||
</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;
|
@ -1,59 +0,0 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<div ng-if="ctrl.notifications.length">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
|
||||
<a href="alerting/notification/new" class="btn btn-primary">
|
||||
New channel
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="filter-table filter-table--hover">
|
||||
<thead>
|
||||
<th style="min-width: 200px">
|
||||
<strong>Name</strong>
|
||||
</th>
|
||||
<th style="min-width: 100px">Type</th>
|
||||
<th style="width: 1%"></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="notification in ctrl.notifications">
|
||||
<td class="link-td">
|
||||
<a href="alerting/notification/{{notification.id}}/edit">
|
||||
{{notification.name}}
|
||||
</a>
|
||||
</td>
|
||||
<td class="link-td">
|
||||
<a href="alerting/notification/{{notification.id}}/edit">
|
||||
{{notification.type}}
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span class="btn btn-secondary btn-small" ng-show="notification.isDefault == true">
|
||||
default
|
||||
</span>
|
||||
<a ng-click="ctrl.deleteNotification(notification.id)" class="btn btn-danger btn-small">
|
||||
<icon name="'times'" style="margin-top: 2px"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div ng-if="ctrl.notifications.length === 0">
|
||||
<empty-list-cta
|
||||
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'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer />
|
@ -7,7 +7,6 @@ import './panel/all';
|
||||
import './org/all';
|
||||
import './admin';
|
||||
import './alerting/NotificationsEditCtrl';
|
||||
import './alerting/NotificationsListCtrl';
|
||||
import './manage-dashboards';
|
||||
import './profile/all';
|
||||
import './datasources/settings/HttpSettingsCtrl';
|
||||
|
@ -436,9 +436,13 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati
|
||||
},
|
||||
})
|
||||
.when('/alerting/notifications', {
|
||||
templateUrl: 'public/app/features/alerting/partials/notifications_list.html',
|
||||
controller: 'AlertNotificationsListCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
template: '<react-container />',
|
||||
resolve: {
|
||||
component: () =>
|
||||
SafeDynamicImport(
|
||||
import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
||||
),
|
||||
},
|
||||
})
|
||||
.when('/alerting/notification/new', {
|
||||
templateUrl: 'public/app/features/alerting/partials/notification_edit.html',
|
||||
|
@ -38,3 +38,10 @@ export interface AlertRulesState {
|
||||
searchQuery: string;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export interface AlertNotification {
|
||||
isDefault: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
type: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user