mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: improve provisioning indicator for notification policies (#71160)
This commit is contained in:
parent
524f111ab3
commit
089305e399
@ -16,7 +16,6 @@ import { alertmanagerApi } from './api/alertmanagerApi';
|
||||
import { useGetContactPointsState } from './api/receiversApi';
|
||||
import { AlertmanagerPageWrapper } from './components/AlertingPageWrapper';
|
||||
import { GrafanaAlertmanagerDeliveryWarning } from './components/GrafanaAlertmanagerDeliveryWarning';
|
||||
import { ProvisionedResource, ProvisioningAlert } from './components/Provisioning';
|
||||
import { MuteTimingsTable } from './components/mute-timings/MuteTimingsTable';
|
||||
import {
|
||||
computeInheritedTree,
|
||||
@ -183,7 +182,7 @@ const AmRoutes = () => {
|
||||
}
|
||||
|
||||
const vanillaPrometheusAlertManager = isVanillaPrometheusAlertManagerDataSource(selectedAlertmanager);
|
||||
const readOnlyPolicies = vanillaPrometheusAlertManager || isProvisioned;
|
||||
const readOnlyPolicies = vanillaPrometheusAlertManager;
|
||||
const readOnlyMuteTimings = vanillaPrometheusAlertManager;
|
||||
|
||||
const numberOfMuteTimings = result?.alertmanager_config.mute_time_intervals?.length ?? 0;
|
||||
@ -227,7 +226,6 @@ const AmRoutes = () => {
|
||||
{policyTreeTabActive && (
|
||||
<>
|
||||
<GrafanaAlertmanagerDeliveryWarning currentAlertmanager={selectedAlertmanager} />
|
||||
{isProvisioned && <ProvisioningAlert resource={ProvisionedResource.RootNotificationPolicy} />}
|
||||
<Stack direction="column" gap={1}>
|
||||
{rootRoute && (
|
||||
<NotificationPoliciesFilter
|
||||
@ -244,6 +242,7 @@ const AmRoutes = () => {
|
||||
alertGroups={alertGroups ?? []}
|
||||
contactPointsState={contactPointsState.receivers}
|
||||
readOnly={readOnlyPolicies}
|
||||
provisioned={isProvisioned}
|
||||
alertManagerSourceName={selectedAlertmanager}
|
||||
onAddPolicy={openAddModal}
|
||||
onEditPolicy={openEditModal}
|
||||
|
@ -3,13 +3,14 @@ import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Stack } from '@grafana/experimental';
|
||||
import { Badge, Button, Dropdown, Icon, Menu, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Button, Dropdown, Icon, Menu, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Span } from '@grafana/ui/src/unstable';
|
||||
import ConditionalWrap from 'app/features/alerting/components/ConditionalWrap';
|
||||
import { GrafanaNotifierType } from 'app/types/alerting';
|
||||
|
||||
import { INTEGRATION_ICONS } from '../../types/contact-points';
|
||||
import { MetaText } from '../MetaText';
|
||||
import { ProvisioningBadge } from '../Provisioning';
|
||||
import { Spacer } from '../Spacer';
|
||||
import { Strong } from '../Strong';
|
||||
|
||||
@ -113,7 +114,7 @@ const ContactPointHeader = (props: ContactPointHeaderProps) => {
|
||||
) : (
|
||||
<MetaText>is not used</MetaText>
|
||||
)}
|
||||
{isProvisioned && <Badge color="purple" text="Provisioned" />}
|
||||
{isProvisioned && <ProvisioningBadge />}
|
||||
<Spacer />
|
||||
<ConditionalWrap
|
||||
shouldWrap={isProvisioned}
|
||||
|
@ -9,6 +9,7 @@ import { Stack } from '@grafana/experimental';
|
||||
import { Badge, Button, Dropdown, getTagColorsFromName, Icon, Menu, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Span } from '@grafana/ui/src/unstable';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import ConditionalWrap from 'app/features/alerting/components/ConditionalWrap';
|
||||
import { RouteWithID, Receiver, ObjectMatcher, AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { ReceiversState } from 'app/types';
|
||||
|
||||
@ -20,6 +21,7 @@ import { getInheritedProperties, InhertitableProperties } from '../../utils/noti
|
||||
import { HoverCard } from '../HoverCard';
|
||||
import { Label } from '../Label';
|
||||
import { MetaText } from '../MetaText';
|
||||
import { ProvisioningBadge } from '../Provisioning';
|
||||
import { Spacer } from '../Spacer';
|
||||
import { Strong } from '../Strong';
|
||||
|
||||
@ -31,6 +33,7 @@ interface PolicyComponentProps {
|
||||
alertGroups?: AlertmanagerGroup[];
|
||||
contactPointsState?: ReceiversState;
|
||||
readOnly?: boolean;
|
||||
provisioned?: boolean;
|
||||
inheritedProperties?: Partial<InhertitableProperties>;
|
||||
routesMatchingFilters?: RouteWithID[];
|
||||
// routeAlertGroupsMap?: Map<string, AlertmanagerGroup[]>;
|
||||
@ -50,6 +53,7 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
receivers = [],
|
||||
contactPointsState,
|
||||
readOnly = false,
|
||||
provisioned = false,
|
||||
alertGroups = [],
|
||||
alertManagerSourceName,
|
||||
currentRoute,
|
||||
@ -143,49 +147,57 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
<Spacer />
|
||||
{/* TODO maybe we should move errors to the gutter instead? */}
|
||||
{errors.length > 0 && <Errors errors={errors} />}
|
||||
{!readOnly && (
|
||||
{provisioned && <ProvisioningBadge />}
|
||||
{readOnly ? null : (
|
||||
<Stack direction="row" gap={0.5}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon="plus"
|
||||
size="sm"
|
||||
onClick={() => onAddPolicy(currentRoute)}
|
||||
type="button"
|
||||
>
|
||||
New nested policy
|
||||
</Button>
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
icon="edit"
|
||||
disabled={!isEditable}
|
||||
label="Edit"
|
||||
onClick={() => onEditPolicy(currentRoute, isDefaultPolicy)}
|
||||
/>
|
||||
{isDeletable && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
destructive
|
||||
icon="trash-alt"
|
||||
label="Delete"
|
||||
onClick={() => onDeletePolicy(currentRoute)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Button
|
||||
icon="ellipsis-h"
|
||||
variant="secondary"
|
||||
icon="plus"
|
||||
size="sm"
|
||||
onClick={() => onAddPolicy(currentRoute)}
|
||||
disabled={provisioned}
|
||||
type="button"
|
||||
aria-label="more-actions"
|
||||
data-testid="more-actions"
|
||||
/>
|
||||
</Dropdown>
|
||||
>
|
||||
New nested policy
|
||||
</Button>
|
||||
</ConditionalWrap>
|
||||
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
icon="edit"
|
||||
disabled={!isEditable}
|
||||
label="Edit"
|
||||
onClick={() => onEditPolicy(currentRoute, isDefaultPolicy)}
|
||||
/>
|
||||
{isDeletable && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
destructive
|
||||
icon="trash-alt"
|
||||
label="Delete"
|
||||
onClick={() => onDeletePolicy(currentRoute)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
icon="ellipsis-h"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
type="button"
|
||||
aria-label="more-actions"
|
||||
data-testid="more-actions"
|
||||
disabled={provisioned}
|
||||
/>
|
||||
</Dropdown>
|
||||
</ConditionalWrap>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
@ -270,7 +282,7 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
currentRoute={child}
|
||||
receivers={receivers}
|
||||
contactPointsState={contactPointsState}
|
||||
readOnly={readOnly}
|
||||
readOnly={readOnly || provisioned}
|
||||
inheritedProperties={childInheritedProperties}
|
||||
onAddPolicy={onAddPolicy}
|
||||
onEditPolicy={onEditPolicy}
|
||||
@ -288,6 +300,12 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const ProvisionedTooltip = (children: ReactNode) => (
|
||||
<Tooltip content="Provisioned items cannot be edited in the UI" placement="top">
|
||||
<span>{children}</span>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
const Errors: FC<{ errors: React.ReactNode[] }> = ({ errors }) => (
|
||||
<HoverCard
|
||||
arrow
|
||||
|
@ -5,7 +5,7 @@ import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Stack } from '@grafana/experimental';
|
||||
import { AsyncSelect, Badge, Field, InputControl, Label, useStyles2 } from '@grafana/ui';
|
||||
import { AsyncSelect, Field, InputControl, Label, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { AccessControlAction, useDispatch } from 'app/types';
|
||||
import { CombinedRuleGroup } from 'app/types/unified-alerting';
|
||||
@ -18,6 +18,7 @@ import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||
import { MINUTE } from '../../utils/rule-form';
|
||||
import { isGrafanaRulerRule } from '../../utils/rules';
|
||||
import { InfoIcon } from '../InfoIcon';
|
||||
import { ProvisioningBadge } from '../Provisioning';
|
||||
|
||||
import { Folder, RuleFolderPicker } from './RuleFolderPicker';
|
||||
import { checkForPathSeparator } from './util';
|
||||
@ -174,7 +175,7 @@ export function FolderAndGroup() {
|
||||
{option.isDisabled && (
|
||||
<>
|
||||
{' '}
|
||||
<Badge color="purple" text="Provisioned" />
|
||||
<ProvisioningBadge />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user