Alerting: Show repeat interval in timing options meta (#89414)

This commit is contained in:
Gilles De Mey 2024-07-03 18:56:30 +02:00 committed by GitHub
parent c6663ce6be
commit 3ca4fb1a8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 141 additions and 32 deletions

View File

@ -1835,10 +1835,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"], [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"], [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"], [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"], [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "18"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "19"]
], ],
"public/app/features/alerting/unified/components/notification-policies/PromDurationDocs.tsx:5381": [ "public/app/features/alerting/unified/components/notification-policies/PromDurationDocs.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"], [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],

View File

@ -1,6 +1,6 @@
import { render, renderHook, screen, within } from '@testing-library/react'; import { render, renderHook, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import { noop } from 'lodash'; import { first, noop } from 'lodash';
import { Router } from 'react-router-dom'; import { Router } from 'react-router-dom';
import { config, locationService } from '@grafana/runtime'; import { config, locationService } from '@grafana/runtime';
@ -21,6 +21,7 @@ import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
import { import {
AUTOGENERATED_ROOT_LABEL_NAME, AUTOGENERATED_ROOT_LABEL_NAME,
Policy, Policy,
TimingOptionsMeta,
isAutoGeneratedRootAndSimplifiedEnabled, isAutoGeneratedRootAndSimplifiedEnabled,
useCreateDropdownMenuActions, useCreateDropdownMenuActions,
} from './Policy'; } from './Policy';
@ -104,7 +105,7 @@ describe('Policy', () => {
// for timing options // for timing options
expect(within(defaultPolicy).getByTestId('timing-options')).toHaveTextContent( expect(within(defaultPolicy).getByTestId('timing-options')).toHaveTextContent(
'Wait30s to group instances,5m before sending updates' 'Wait 30s to group instances · Wait 5m before sending updates · Repeated every 4h'
); );
// should have custom policies // should have custom policies
@ -485,3 +486,29 @@ describe('useCreateDropdownMenuActions', () => {
}); });
}); });
}); });
describe('TimingOptionsMeta', () => {
it('should render nothing without options', () => {
render(<TimingOptionsMeta timingOptions={{}} />);
expect(screen.queryByText(/wait/i)).not.toBeInTheDocument();
});
it('should render only repeat interval', () => {
render(<TimingOptionsMeta timingOptions={{ repeat_interval: '5h' }} />);
expect(screen.getByText(/repeated every/i)).toBeInTheDocument();
expect(screen.getByText('5h')).toBeInTheDocument();
});
it('should render all options', () => {
render(<TimingOptionsMeta timingOptions={{ group_wait: '30s', group_interval: '5m', repeat_interval: '4h' }} />);
expect(
first(
screen.getAllByText(
(_, element) =>
element?.textContent === 'Wait 30s to group instances · Wait 5m before sending updates · Repeated every 4h',
{ collapseWhitespace: false, trim: false, exact: true }
)
)
).toBeInTheDocument();
});
});

View File

@ -21,6 +21,7 @@ import {
getTagColorsFromName, getTagColorsFromName,
useStyles2, useStyles2,
} from '@grafana/ui'; } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import ConditionalWrap from 'app/features/alerting/unified/components/ConditionalWrap'; import ConditionalWrap from 'app/features/alerting/unified/components/ConditionalWrap';
import { import {
AlertmanagerGroup, AlertmanagerGroup,
@ -720,40 +721,84 @@ const MuteTimings: FC<{ timings: string[]; alertManagerSourceName: string }> = (
); );
}; };
const TimingOptionsMeta: FC<{ timingOptions: TimingOptions }> = ({ timingOptions }) => { interface TimingOptionsMetaProps {
timingOptions: TimingOptions;
}
export const TimingOptionsMeta = ({ timingOptions }: TimingOptionsMetaProps) => {
const groupWait = timingOptions.group_wait; const groupWait = timingOptions.group_wait;
const groupInterval = timingOptions.group_interval; const groupInterval = timingOptions.group_interval;
const repeatInterval = timingOptions.repeat_interval;
// we don't have any timing options to show we're inheriting everything from the parent // we don't have any timing options to show we're inheriting everything from the parent
// and those show up in a separate "inherited properties" component // and those show up in a separate "inherited properties" component
if (!groupWait && !groupInterval) { if (!groupWait && !groupInterval && !repeatInterval) {
return null; return null;
} }
const metaOptions: ReactNode[] = [];
if (groupWait) {
metaOptions.push(
<Tooltip
placement="top"
content={t(
'alerting.policies.metadata.timingOptions.groupWait.description',
'How long to initially wait to send a notification for a group of alert instances.'
)}
>
<span>
<Trans i18nKey="alerting.policies.metadata.timingOptions.groupWait.label">
Wait <PrimaryText content={groupWait} /> to group instances
</Trans>
</span>
</Tooltip>
);
}
if (groupInterval) {
metaOptions.push(
<Tooltip
placement="top"
content={t(
'alerting.policies.metadata.timingOptions.groupInterval.description',
'How long to wait before sending a notification about new alerts that are added to a group of alerts for which an initial notification has already been sent.'
)}
>
<span>
<Trans i18nKey="alerting.policies.metadata.timingOptions.groupInterval.label">
Wait <PrimaryText content={groupInterval} /> before sending updates
</Trans>
</span>
</Tooltip>
);
}
if (repeatInterval) {
metaOptions.push(
<Tooltip
placement="top"
content={t(
'alerting.policies.metadata.timingOptions.repeatInterval.description',
'How often notifications are sent if the group of alerts has not changed since the last notification.'
)}
>
<span>
<Trans i18nKey="alerting.policies.metadata.timingOptions.repeatInterval.label">
Repeated every <PrimaryText content={repeatInterval} />
</Trans>
</span>
</Tooltip>
);
}
return ( return (
<MetaText icon="hourglass" data-testid="timing-options"> <MetaText icon="hourglass" data-testid="timing-options">
<span>Wait</span> {metaOptions.map((meta, index) => (
{groupWait && ( <span key={uniqueId()}>
<Tooltip {meta}
placement="top" {index < metaOptions.length - 1 && ' · '}
content="How long to initially wait to send a notification for a group of alert instances."
>
<span>
<Text color="primary">{groupWait}</Text> to group instances
{groupWait && groupInterval && ','}
</span> </span>
</Tooltip> ))}
)}
{groupInterval && (
<Tooltip
placement="top"
content="How long to wait before sending a notification about new alerts that are added to a group of alerts for which an initial notification has already been sent."
>
<span>
<Text color="primary">{groupInterval}</Text> before sending updates
</span>
</Tooltip>
)}
</MetaText> </MetaText>
); );
}; };
@ -976,4 +1021,8 @@ const getStyles = (theme: GrafanaTheme2) => ({
}), }),
}); });
// This is a convencience component to deal with I18n shenanigans
// see https://github.com/grafana/grafana/blob/main/contribute/internationalization.md#jsx
const PrimaryText = ({ content }: { content: string }) => <Text color="primary">{content}</Text>;
export { Policy }; export { Policy };

View File

@ -61,6 +61,24 @@
"parse-mode-warning-body": "If you use a <1>parse_mode</1> option other than <3>None</3>, truncation may result in an invalid message, causing the notification to fail. For longer messages, we recommend using an alternative contact method.", "parse-mode-warning-body": "If you use a <1>parse_mode</1> option other than <3>None</3>, truncation may result in an invalid message, causing the notification to fail. For longer messages, we recommend using an alternative contact method.",
"parse-mode-warning-title": "Telegram messages are limited to 4096 UTF-8 characters." "parse-mode-warning-title": "Telegram messages are limited to 4096 UTF-8 characters."
} }
},
"policies": {
"metadata": {
"timingOptions": {
"groupInterval": {
"description": "How long to wait before sending a notification about new alerts that are added to a group of alerts for which an initial notification has already been sent.",
"label": "Wait <1></1> before sending updates"
},
"groupWait": {
"description": "How long to initially wait to send a notification for a group of alert instances.",
"label": "Wait <1></1> to group instances"
},
"repeatInterval": {
"description": "How often notifications are sent if the group of alerts has not changed since the last notification.",
"label": "Repeated every <1></1>"
}
}
}
} }
}, },
"annotations": { "annotations": {
@ -1638,7 +1656,7 @@
"restore-modal": { "restore-modal": {
"restore-button": "Restore", "restore-button": "Restore",
"restore-loading": "Restoring...", "restore-loading": "Restoring...",
"text_one": "This action will restore {{numberOfDashboards}} dashboard.", "text_one": "This action will restore {{numberOfDashboards}} dashboards.",
"text_other": "This action will restore {{numberOfDashboards}} dashboards.", "text_other": "This action will restore {{numberOfDashboards}} dashboards.",
"title": "Restore Dashboards" "title": "Restore Dashboards"
} }

View File

@ -61,6 +61,24 @@
"parse-mode-warning-body": "Ĩƒ yőū ūşę ä <1>päřşę_mőđę</1> őpŧįőʼn őŧĥęř ŧĥäʼn <3>Ńőʼnę</3>, ŧřūʼnčäŧįőʼn mäy řęşūľŧ įʼn äʼn įʼnväľįđ męşşäģę, čäūşįʼnģ ŧĥę ʼnőŧįƒįčäŧįőʼn ŧő ƒäįľ. Főř ľőʼnģęř męşşäģęş, ŵę řęčőmmęʼnđ ūşįʼnģ äʼn äľŧęřʼnäŧįvę čőʼnŧäčŧ męŧĥőđ.", "parse-mode-warning-body": "Ĩƒ yőū ūşę ä <1>päřşę_mőđę</1> őpŧįőʼn őŧĥęř ŧĥäʼn <3>Ńőʼnę</3>, ŧřūʼnčäŧįőʼn mäy řęşūľŧ įʼn äʼn įʼnväľįđ męşşäģę, čäūşįʼnģ ŧĥę ʼnőŧįƒįčäŧįőʼn ŧő ƒäįľ. Főř ľőʼnģęř męşşäģęş, ŵę řęčőmmęʼnđ ūşįʼnģ äʼn äľŧęřʼnäŧįvę čőʼnŧäčŧ męŧĥőđ.",
"parse-mode-warning-title": "Ŧęľęģřäm męşşäģęş äřę ľįmįŧęđ ŧő 4096 ŮŦF-8 čĥäřäčŧęřş." "parse-mode-warning-title": "Ŧęľęģřäm męşşäģęş äřę ľįmįŧęđ ŧő 4096 ŮŦF-8 čĥäřäčŧęřş."
} }
},
"policies": {
"metadata": {
"timingOptions": {
"groupInterval": {
"description": "Ħőŵ ľőʼnģ ŧő ŵäįŧ þęƒőřę şęʼnđįʼnģ ä ʼnőŧįƒįčäŧįőʼn äþőūŧ ʼnęŵ äľęřŧş ŧĥäŧ äřę äđđęđ ŧő ä ģřőūp őƒ äľęřŧş ƒőř ŵĥįčĥ äʼn įʼnįŧįäľ ʼnőŧįƒįčäŧįőʼn ĥäş äľřęäđy þęęʼn şęʼnŧ.",
"label": "Ŵäįŧ <1></1> þęƒőřę şęʼnđįʼnģ ūpđäŧęş"
},
"groupWait": {
"description": "Ħőŵ ľőʼnģ ŧő įʼnįŧįäľľy ŵäįŧ ŧő şęʼnđ ä ʼnőŧįƒįčäŧįőʼn ƒőř ä ģřőūp őƒ äľęřŧ įʼnşŧäʼnčęş.",
"label": "Ŵäįŧ <1></1> ŧő ģřőūp įʼnşŧäʼnčęş"
},
"repeatInterval": {
"description": "Ħőŵ őƒŧęʼn ʼnőŧįƒįčäŧįőʼnş äřę şęʼnŧ įƒ ŧĥę ģřőūp őƒ äľęřŧş ĥäş ʼnőŧ čĥäʼnģęđ şįʼnčę ŧĥę ľäşŧ ʼnőŧįƒįčäŧįőʼn.",
"label": "Ŗępęäŧęđ ęvęřy <1></1>"
}
}
}
} }
}, },
"annotations": { "annotations": {
@ -1638,7 +1656,7 @@
"restore-modal": { "restore-modal": {
"restore-button": "Ŗęşŧőřę", "restore-button": "Ŗęşŧőřę",
"restore-loading": "Ŗęşŧőřįʼnģ...", "restore-loading": "Ŗęşŧőřįʼnģ...",
"text_one": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđ.", "text_one": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđş.",
"text_other": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđş.", "text_other": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđş.",
"title": "Ŗęşŧőřę Đäşĥþőäřđş" "title": "Ŗęşŧőřę Đäşĥþőäřđş"
} }