mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Separate overlapping legacy and UA alerting routes (#76517)
* Separate overlapping legacy and UA alerting routes api/alert-notifiers, alerting/list, and alerting/notifications existed in both legacy and UA. Rename legacy route paths and nav ids to be independent of UA ones.
This commit is contained in:
parent
935ecdd809
commit
c18da48e50
@ -239,17 +239,18 @@ func (hs *HTTPServer) GetAlert(c *contextmodel.ReqContext) response.Response {
|
|||||||
return response.JSON(http.StatusOK, &res)
|
return response.JSON(http.StatusOK, &res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) GetAlertNotifiers(ngalertEnabled bool) func(*contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) GetLegacyAlertNotifiers() func(*contextmodel.ReqContext) response.Response {
|
||||||
return func(_ *contextmodel.ReqContext) response.Response {
|
return func(_ *contextmodel.ReqContext) response.Response {
|
||||||
if ngalertEnabled {
|
|
||||||
return response.JSON(http.StatusOK, channels_config.GetAvailableNotifiers())
|
|
||||||
}
|
|
||||||
// TODO(codesome): This wont be required in 8.0 since ngalert
|
|
||||||
// will be enabled by default with no disabling. This is to be removed later.
|
|
||||||
return response.JSON(http.StatusOK, alerting.GetNotifiers())
|
return response.JSON(http.StatusOK, alerting.GetNotifiers())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hs *HTTPServer) GetAlertNotifiers() func(*contextmodel.ReqContext) response.Response {
|
||||||
|
return func(_ *contextmodel.ReqContext) response.Response {
|
||||||
|
return response.JSON(http.StatusOK, channels_config.GetAvailableNotifiers())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// swagger:route GET /alert-notifications/lookup legacy_alerts_notification_channels getAlertNotificationLookup
|
// swagger:route GET /alert-notifications/lookup legacy_alerts_notification_channels getAlertNotificationLookup
|
||||||
//
|
//
|
||||||
// Get all notification channels (lookup).
|
// Get all notification channels (lookup).
|
||||||
|
@ -47,7 +47,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/web"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var plog = log.New("api")
|
var plog = log.New("api")
|
||||||
@ -514,15 +513,14 @@ func (hs *HTTPServer) registerRoutes() {
|
|||||||
alertsRoute.Get("/states-for-dashboard", routing.Wrap(hs.GetAlertStatesForDashboard))
|
alertsRoute.Get("/states-for-dashboard", routing.Wrap(hs.GetAlertStatesForDashboard))
|
||||||
}, requestmeta.SetOwner(requestmeta.TeamAlerting))
|
}, requestmeta.SetOwner(requestmeta.TeamAlerting))
|
||||||
|
|
||||||
var notifiersAuthHandler web.Handler
|
// Unified Alerting
|
||||||
if hs.Cfg.UnifiedAlerting.IsEnabled() {
|
apiRoute.Get("/alert-notifiers", reqSignedIn, requestmeta.SetOwner(requestmeta.TeamAlerting), routing.Wrap(
|
||||||
notifiersAuthHandler = reqSignedIn
|
hs.GetAlertNotifiers()),
|
||||||
} else {
|
)
|
||||||
notifiersAuthHandler = reqEditorRole
|
|
||||||
}
|
|
||||||
|
|
||||||
apiRoute.Get("/alert-notifiers", notifiersAuthHandler, requestmeta.SetOwner(requestmeta.TeamAlerting), routing.Wrap(
|
// Legacy
|
||||||
hs.GetAlertNotifiers(hs.Cfg.UnifiedAlerting.IsEnabled())),
|
apiRoute.Get("/alert-notifiers-legacy", reqEditorRole, requestmeta.SetOwner(requestmeta.TeamAlerting), routing.Wrap(
|
||||||
|
hs.GetLegacyAlertNotifiers()),
|
||||||
)
|
)
|
||||||
|
|
||||||
apiRoute.Group("/alert-notifications", func(alertNotifications routing.RouteRegister) {
|
apiRoute.Group("/alert-notifications", func(alertNotifications routing.RouteRegister) {
|
||||||
|
@ -394,12 +394,12 @@ func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext) []*navt
|
|||||||
func (s *ServiceImpl) buildLegacyAlertNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
func (s *ServiceImpl) buildLegacyAlertNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
||||||
var alertChildNavs []*navtree.NavLink
|
var alertChildNavs []*navtree.NavLink
|
||||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
||||||
Text: "Alert rules", Id: "alert-list", Url: s.cfg.AppSubURL + "/alerting/list", Icon: "list-ul",
|
Text: "Alert rules", Id: "alert-list-legacy", Url: s.cfg.AppSubURL + "/alerting-legacy/list", Icon: "list-ul",
|
||||||
})
|
})
|
||||||
|
|
||||||
if c.SignedInUser.HasRole(roletype.RoleEditor) {
|
if c.SignedInUser.HasRole(roletype.RoleEditor) {
|
||||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
||||||
Text: "Notification channels", Id: "channels", Url: s.cfg.AppSubURL + "/alerting/notifications",
|
Text: "Notification channels", Id: "channels", Url: s.cfg.AppSubURL + "/alerting-legacy/notifications",
|
||||||
Icon: "comment-alt-share",
|
Icon: "comment-alt-share",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ func (s *ServiceImpl) buildLegacyAlertNavLinks(c *contextmodel.ReqContext) *navt
|
|||||||
Icon: "bell",
|
Icon: "bell",
|
||||||
Children: alertChildNavs,
|
Children: alertChildNavs,
|
||||||
SortWeight: navtree.WeightAlerting,
|
SortWeight: navtree.WeightAlerting,
|
||||||
Url: s.cfg.AppSubURL + "/alerting",
|
Url: s.cfg.AppSubURL + "/alerting-legacy",
|
||||||
}
|
}
|
||||||
|
|
||||||
return &alertNav
|
return &alertNav
|
||||||
|
@ -61,6 +61,8 @@ export function getNavTitle(navId: string | undefined) {
|
|||||||
return t('nav.alerting-home.title', 'Home');
|
return t('nav.alerting-home.title', 'Home');
|
||||||
case 'alert-list':
|
case 'alert-list':
|
||||||
return t('nav.alerting-list.title', 'Alert rules');
|
return t('nav.alerting-list.title', 'Alert rules');
|
||||||
|
case 'alert-list-legacy':
|
||||||
|
return t('nav.alert-list-legacy.title', 'Alert rules');
|
||||||
case 'receivers':
|
case 'receivers':
|
||||||
return t('nav.alerting-receivers.title', 'Contact points');
|
return t('nav.alerting-receivers.title', 'Contact points');
|
||||||
case 'am-routes':
|
case 'am-routes':
|
||||||
|
@ -95,7 +95,7 @@ export class AlertRuleListUnconnected extends PureComponent<Props> {
|
|||||||
const { alertRules, search, isLoading } = this.props;
|
const { alertRules, search, isLoading } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page navId="alert-list">
|
<Page navId="alert-list-legacy">
|
||||||
<Page.Contents isLoading={isLoading}>
|
<Page.Contents isLoading={isLoading}>
|
||||||
<div className="page-action-bar">
|
<div className="page-action-bar">
|
||||||
<div className="gf-form gf-form--grow">
|
<div className="gf-form gf-form--grow">
|
||||||
@ -117,7 +117,7 @@ export class AlertRuleListUnconnected extends PureComponent<Props> {
|
|||||||
</div>
|
</div>
|
||||||
<div className="page-action-bar__spacer" />
|
<div className="page-action-bar__spacer" />
|
||||||
{config.unifiedAlertingEnabled && (
|
{config.unifiedAlertingEnabled && (
|
||||||
<LinkButton variant="primary" href="alerting/ng/new">
|
<LinkButton variant="primary" href="alerting-legacy/ng/new">
|
||||||
Add NG Alert
|
Add NG Alert
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
)}
|
)}
|
||||||
|
@ -57,7 +57,7 @@ const NotificationsListPage: FC = () => {
|
|||||||
<>
|
<>
|
||||||
<div className="page-action-bar">
|
<div className="page-action-bar">
|
||||||
<div className="page-action-bar__spacer" />
|
<div className="page-action-bar__spacer" />
|
||||||
<LinkButton icon="channel-add" href="alerting/notification/new">
|
<LinkButton icon="channel-add" href="alerting-legacy/notification/new">
|
||||||
New channel
|
New channel
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
</div>
|
</div>
|
||||||
@ -75,10 +75,10 @@ const NotificationsListPage: FC = () => {
|
|||||||
{notifications.map((notification) => (
|
{notifications.map((notification) => (
|
||||||
<tr key={notification.id}>
|
<tr key={notification.id}>
|
||||||
<td className="link-td">
|
<td className="link-td">
|
||||||
<a href={`alerting/notification/${notification.id}/edit`}>{notification.name}</a>
|
<a href={`alerting-legacy/notification/${notification.id}/edit`}>{notification.name}</a>
|
||||||
</td>
|
</td>
|
||||||
<td className="link-td">
|
<td className="link-td">
|
||||||
<a href={`alerting/notification/${notification.id}/edit`}>{notification.type}</a>
|
<a href={`alerting-legacy/notification/${notification.id}/edit`}>{notification.type}</a>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<HorizontalGroup justify="flex-end">
|
<HorizontalGroup justify="flex-end">
|
||||||
@ -108,7 +108,7 @@ const NotificationsListPage: FC = () => {
|
|||||||
<EmptyListCTA
|
<EmptyListCTA
|
||||||
title="There are no notification channels defined yet"
|
title="There are no notification channels defined yet"
|
||||||
buttonIcon="channel-add"
|
buttonIcon="channel-add"
|
||||||
buttonLink="alerting/notification/new"
|
buttonLink="alerting-legacy/notification/new"
|
||||||
buttonTitle="Add channel"
|
buttonTitle="Add channel"
|
||||||
proTip="You can include images in your alert notifications."
|
proTip="You can include images in your alert notifications."
|
||||||
proTipLink="http://docs.grafana.org/alerting/notifications/"
|
proTipLink="http://docs.grafana.org/alerting/notifications/"
|
||||||
|
@ -106,7 +106,7 @@ export const NotificationChannelForm = ({
|
|||||||
<Button type="button" variant="secondary" onClick={() => onTestChannel(getValues())}>
|
<Button type="button" variant="secondary" onClick={() => onTestChannel(getValues())}>
|
||||||
Test
|
Test
|
||||||
</Button>
|
</Button>
|
||||||
<a href={`${config.appSubUrl}/alerting/notifications`}>
|
<a href={`${config.appSubUrl}/alerting-legacy/notifications`}>
|
||||||
<Button type="button" variant="secondary">
|
<Button type="button" variant="secondary">
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { uniq } from 'lodash';
|
import { uniq } from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Redirect, RouteComponentProps } from 'react-router-dom';
|
||||||
|
|
||||||
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
||||||
import { NavLandingPage } from 'app/core/components/NavLandingPage/NavLandingPage';
|
import { NavLandingPage } from 'app/core/components/NavLandingPage/NavLandingPage';
|
||||||
@ -14,73 +15,79 @@ const commonRoutes: RouteDescriptor[] = [];
|
|||||||
const legacyRoutes: RouteDescriptor[] = [
|
const legacyRoutes: RouteDescriptor[] = [
|
||||||
...commonRoutes,
|
...commonRoutes,
|
||||||
{
|
{
|
||||||
path: '/alerting',
|
path: '/alerting-legacy',
|
||||||
component: () => <NavLandingPage navId="alerting-legacy" />,
|
component: () => <NavLandingPage navId="alerting-legacy" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/list',
|
path: '/alerting-legacy/list',
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "AlertRuleListIndex" */ 'app/features/alerting/AlertRuleList')
|
() => import(/* webpackChunkName: "AlertRuleListLegacyIndex" */ 'app/features/alerting/AlertRuleList')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/ng/list',
|
path: '/alerting-legacy/ng/list',
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "AlertRuleList" */ 'app/features/alerting/AlertRuleList')
|
() => import(/* webpackChunkName: "AlertRuleListLegacy" */ 'app/features/alerting/AlertRuleList')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications',
|
path: '/alerting-legacy/notifications',
|
||||||
roles: config.unifiedAlertingEnabled ? () => ['Editor', 'Admin'] : undefined,
|
roles: config.unifiedAlertingEnabled ? () => ['Editor', 'Admin'] : undefined,
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/templates/new',
|
path: '/alerting-legacy/notifications/templates/new',
|
||||||
roles: () => ['Editor', 'Admin'],
|
roles: () => ['Editor', 'Admin'],
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/templates/:id/edit',
|
path: '/alerting-legacy/notifications/templates/:id/edit',
|
||||||
roles: () => ['Editor', 'Admin'],
|
roles: () => ['Editor', 'Admin'],
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/receivers/new',
|
path: '/alerting-legacy/notifications/receivers/new',
|
||||||
roles: () => ['Editor', 'Admin'],
|
roles: () => ['Editor', 'Admin'],
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/receivers/:id/edit',
|
path: '/alerting-legacy/notifications/receivers/:id/edit',
|
||||||
roles: () => ['Editor', 'Admin'],
|
roles: () => ['Editor', 'Admin'],
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notifications/global-config',
|
path: '/alerting-legacy/notifications/global-config',
|
||||||
roles: () => ['Admin', 'Editor'],
|
roles: () => ['Admin', 'Editor'],
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NotificationsListPage" */ 'app/features/alerting/NotificationsListPage')
|
() => import(/* webpackChunkName: "NotificationsListLegacyPage" */ 'app/features/alerting/NotificationsListPage')
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notification/new',
|
path: '/alerting-legacy/notification/new',
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "NewNotificationChannel" */ 'app/features/alerting/NewNotificationChannelPage')
|
() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "NewNotificationChannelLegacy" */ 'app/features/alerting/NewNotificationChannelPage'
|
||||||
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/alerting/notification/:id/edit',
|
path: '/alerting-legacy/notification/:id/edit',
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "EditNotificationChannel"*/ 'app/features/alerting/EditNotificationChannelPage')
|
() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "EditNotificationChannelLegacy"*/ 'app/features/alerting/EditNotificationChannelPage'
|
||||||
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -295,7 +302,32 @@ export function getAlertingRoutes(cfg = config): RouteDescriptor[] {
|
|||||||
if (cfg.unifiedAlertingEnabled) {
|
if (cfg.unifiedAlertingEnabled) {
|
||||||
return unifiedRoutes;
|
return unifiedRoutes;
|
||||||
} else if (cfg.alertingEnabled) {
|
} else if (cfg.alertingEnabled) {
|
||||||
return legacyRoutes;
|
// Redirect old overlapping legacy routes to new separate ones to minimize unintended 404s.
|
||||||
|
const redirects = [
|
||||||
|
{
|
||||||
|
path: '/alerting',
|
||||||
|
component: () => <Redirect to={'/alerting-legacy'} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/list',
|
||||||
|
component: () => <Redirect to={'/alerting-legacy/list'} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/notifications',
|
||||||
|
component: () => <Redirect to={'/alerting-legacy/notifications'} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/notification/new',
|
||||||
|
component: () => <Redirect to={'/alerting-legacy/notification/new'} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/alerting/notification/:id/edit',
|
||||||
|
component: (props: RouteComponentProps<{ id: string }>) => (
|
||||||
|
<Redirect to={'/alerting-legacy/notification/:id/edit'.replace(':id', props.match.params.id)} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return [...legacyRoutes, ...redirects];
|
||||||
}
|
}
|
||||||
|
|
||||||
const uniquePaths = uniq([...legacyRoutes, ...unifiedRoutes].map((route) => route.path));
|
const uniquePaths = uniq([...legacyRoutes, ...unifiedRoutes].map((route) => route.path));
|
||||||
|
@ -26,7 +26,7 @@ export function createNotificationChannel(data: any): ThunkResult<Promise<void>>
|
|||||||
try {
|
try {
|
||||||
await getBackendSrv().post(`/api/alert-notifications`, data);
|
await getBackendSrv().post(`/api/alert-notifications`, data);
|
||||||
dispatch(notifyApp(createSuccessNotification('Notification created')));
|
dispatch(notifyApp(createSuccessNotification('Notification created')));
|
||||||
locationService.push('/alerting/notifications');
|
locationService.push('/alerting-legacy/notifications');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isFetchError(error)) {
|
if (isFetchError(error)) {
|
||||||
dispatch(notifyApp(createErrorNotification(error.data.error)));
|
dispatch(notifyApp(createErrorNotification(error.data.error)));
|
||||||
@ -57,7 +57,7 @@ export function testNotificationChannel(data: any): ThunkResult<void> {
|
|||||||
|
|
||||||
export function loadNotificationTypes(): ThunkResult<void> {
|
export function loadNotificationTypes(): ThunkResult<void> {
|
||||||
return async (dispatch) => {
|
return async (dispatch) => {
|
||||||
const alertNotifiers: NotifierDTO[] = await getBackendSrv().get(`/api/alert-notifiers`);
|
const alertNotifiers: NotifierDTO[] = await getBackendSrv().get(`/api/alert-notifiers-legacy`);
|
||||||
|
|
||||||
const notificationTypes = alertNotifiers.sort((o1, o2) => {
|
const notificationTypes = alertNotifiers.sort((o1, o2) => {
|
||||||
if (o1.name > o2.name) {
|
if (o1.name > o2.name) {
|
||||||
|
@ -671,6 +671,9 @@
|
|||||||
"subtitle": "Serverweite Einstellungen und Zugriff auf Ressourcen wie Organisationen, Benutzer und Lizenzen verwalten",
|
"subtitle": "Serverweite Einstellungen und Zugriff auf Ressourcen wie Organisationen, Benutzer und Lizenzen verwalten",
|
||||||
"title": "Server-Administrator"
|
"title": "Server-Administrator"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "Informiere dich über Probleme in deinen Systemen kurz nach deren Auftreten",
|
"subtitle": "Informiere dich über Probleme in deinen Systemen kurz nach deren Auftreten",
|
||||||
"title": "Meldungen"
|
"title": "Meldungen"
|
||||||
|
@ -671,6 +671,9 @@
|
|||||||
"subtitle": "Manage server-wide settings and access to resources such as organizations, users, and licenses",
|
"subtitle": "Manage server-wide settings and access to resources such as organizations, users, and licenses",
|
||||||
"title": "Server admin"
|
"title": "Server admin"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": "Alert rules"
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "Learn about problems in your systems moments after they occur",
|
"subtitle": "Learn about problems in your systems moments after they occur",
|
||||||
"title": "Alerting"
|
"title": "Alerting"
|
||||||
|
@ -677,6 +677,9 @@
|
|||||||
"subtitle": "Administrar la configuración de todo el servidor y el acceso a recursos como organizaciones, usuarios y licencias",
|
"subtitle": "Administrar la configuración de todo el servidor y el acceso a recursos como organizaciones, usuarios y licencias",
|
||||||
"title": "Administrador del servidor"
|
"title": "Administrador del servidor"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "Conozca los problemas de sus sistemas justo después de que se produzcan",
|
"subtitle": "Conozca los problemas de sus sistemas justo después de que se produzcan",
|
||||||
"title": "Alertas"
|
"title": "Alertas"
|
||||||
|
@ -677,6 +677,9 @@
|
|||||||
"subtitle": "Gérer les paramètres à l'échelle du serveur et l'accès aux ressources telles que les organisations, les utilisateurs et les licences",
|
"subtitle": "Gérer les paramètres à l'échelle du serveur et l'accès aux ressources telles que les organisations, les utilisateurs et les licences",
|
||||||
"title": "Administrateur de serveur"
|
"title": "Administrateur de serveur"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "En savoir plus sur les problèmes dans vos systèmes quelques instants après qu'ils se produisent",
|
"subtitle": "En savoir plus sur les problèmes dans vos systèmes quelques instants après qu'ils se produisent",
|
||||||
"title": "Alertes"
|
"title": "Alertes"
|
||||||
|
@ -671,6 +671,9 @@
|
|||||||
"subtitle": "Mäʼnäģę şęřvęř-ŵįđę şęŧŧįʼnģş äʼnđ äččęşş ŧő řęşőūřčęş şūčĥ äş őřģäʼnįžäŧįőʼnş, ūşęřş, äʼnđ ľįčęʼnşęş",
|
"subtitle": "Mäʼnäģę şęřvęř-ŵįđę şęŧŧįʼnģş äʼnđ äččęşş ŧő řęşőūřčęş şūčĥ äş őřģäʼnįžäŧįőʼnş, ūşęřş, äʼnđ ľįčęʼnşęş",
|
||||||
"title": "Ŝęřvęř äđmįʼn"
|
"title": "Ŝęřvęř äđmįʼn"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": "Åľęřŧ řūľęş"
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "Ŀęäřʼn äþőūŧ přőþľęmş įʼn yőūř şyşŧęmş mőmęʼnŧş äƒŧęř ŧĥęy őččūř",
|
"subtitle": "Ŀęäřʼn äþőūŧ přőþľęmş įʼn yőūř şyşŧęmş mőmęʼnŧş äƒŧęř ŧĥęy őččūř",
|
||||||
"title": "Åľęřŧįʼnģ"
|
"title": "Åľęřŧįʼnģ"
|
||||||
|
@ -665,6 +665,9 @@
|
|||||||
"subtitle": "管理整个服务器范围的设置,以及对组织、用户和许可证等资源的访问权限",
|
"subtitle": "管理整个服务器范围的设置,以及对组织、用户和许可证等资源的访问权限",
|
||||||
"title": "服务器管理员"
|
"title": "服务器管理员"
|
||||||
},
|
},
|
||||||
|
"alert-list-legacy": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"alerting": {
|
"alerting": {
|
||||||
"subtitle": "在系统发生问题后立即获悉",
|
"subtitle": "在系统发生问题后立即获悉",
|
||||||
"title": "警报"
|
"title": "警报"
|
||||||
|
Loading…
Reference in New Issue
Block a user