Skip to content

Commit 5975b9d

Browse files
iskhakovUkochka
andauthoredMay 31, 2023
Change integrations page wording and add more guidance (#1986)
# What this PR does ## Which issue(s) this PR fixes ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Yulia Shanyrova <[email protected]>
1 parent f299fb9 commit 5975b9d

File tree

11 files changed

+97
-27
lines changed

11 files changed

+97
-27
lines changed
 

‎engine/apps/alerts/integration_options_mixin.py

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ def __init__(self, *args, **kwargs):
4949
integration_config.slug: integration_config.short_description for integration_config in _config
5050
}
5151
INTEGRATION_FEATURED = [integration_config.slug for integration_config in _config if integration_config.is_featured]
52+
INTEGRATION_FEATURED_TAG_NAME = {
53+
integration_config.slug: integration_config.featured_tag_name
54+
for integration_config in _config
55+
if hasattr(integration_config, "featured_tag_name")
56+
}
5257

5358
# The following attributes dynamically generated and used by apps.alerts.incident_appearance.renderers, templaters
5459
# e.g. INTEGRATION_TO_DEFAULT_SLACK_TITLE_TEMPLATE, INTEGRATION_TO_DEFAULT_SLACK_MESSAGE_TEMPLATE, etc...

‎engine/apps/api/views/alert_receive_channel.py

+3
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ def integration_options(self, request):
198198
"display_name": integration_title,
199199
"short_description": AlertReceiveChannel.INTEGRATION_SHORT_DESCRIPTION[integration_id],
200200
"featured": integration_id in AlertReceiveChannel.INTEGRATION_FEATURED,
201+
"featured_tag_name": AlertReceiveChannel.INTEGRATION_FEATURED_TAG_NAME[integration_id]
202+
if integration_id in AlertReceiveChannel.INTEGRATION_FEATURED_TAG_NAME
203+
else None,
201204
}
202205
# if integration is featured we show it in the beginning
203206
if choice["featured"]:

‎engine/config_integrations/grafana_alerting.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
description = None
99
is_displayed_on_web = True
1010
is_featured = True
11+
featured_tag_name = "Quick Connect"
1112
is_able_to_autoresolve = True
1213
is_demo_alert_enabled = True
1314

‎engine/config_integrations/webhook.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
enabled = True
33
title = "Webhook"
44
slug = "webhook"
5-
short_description = None
5+
short_description = "If your monitoring system isn't listed, choose Webhook for generic templates, and feel free to modify them as needed."
66
description = None
7-
is_featured = False
7+
is_featured = True
8+
featured_tag_name = "Generic"
89
is_displayed_on_web = True
910
is_able_to_autoresolve = True
1011
is_demo_alert_enabled = True

‎grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ const CollapsedIntegrationRouteDisplay: React.FC<CollapsedIntegrationRouteDispla
5555
alertReceiveChannelStore.channelFilterIds[alertReceiveChannelId],
5656
routeIndex
5757
)}
58-
tooltipTitle={undefined}
58+
tooltipTitle={IntegrationHelper.getRouteConditionTooltipWording(
59+
alertReceiveChannelStore.channelFilterIds[alertReceiveChannelId],
60+
routeIndex
61+
)}
5962
tooltipContent={undefined}
6063
/>
6164
{routeWording === 'Default' && (
@@ -93,7 +96,7 @@ const CollapsedIntegrationRouteDisplay: React.FC<CollapsedIntegrationRouteDispla
9396

9497
<HorizontalGroup>
9598
<Icon name="list-ui-alt" />
96-
<Text type="secondary">Escalate to</Text>
99+
<Text type="secondary">Trigger escalation chain:</Text>
97100

98101
{escalationChain?.name && (
99102
<PluginLink
@@ -112,9 +115,7 @@ const CollapsedIntegrationRouteDisplay: React.FC<CollapsedIntegrationRouteDispla
112115
<div className={cx('icon-exclamation')}>
113116
<Icon name="exclamation-triangle" />
114117
</div>
115-
<Text type="primary" strong>
116-
No Escalation chain
117-
</Text>
118+
<Text type="primary">No Escalation chain selected</Text>
118119
</HorizontalGroup>
119120
)}
120121
</HorizontalGroup>

‎grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx

+18-4
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ const ExpandedIntegrationRouteDisplay: React.FC<ExpandedIntegrationRouteDisplayP
113113
<TooltipBadge
114114
borderType="success"
115115
text={IntegrationHelper.getRouteConditionWording(channelFilterIds, routeIndex)}
116-
tooltipTitle={undefined}
116+
tooltipTitle={IntegrationHelper.getRouteConditionTooltipWording(channelFilterIds, routeIndex)}
117117
tooltipContent={undefined}
118118
/>
119119
</HorizontalGroup>
@@ -129,6 +129,16 @@ const ExpandedIntegrationRouteDisplay: React.FC<ExpandedIntegrationRouteDisplayP
129129
}
130130
content={
131131
<VerticalGroup spacing="xs">
132+
{routeIndex !== channelFiltersTotal.length - 1 && (
133+
<IntegrationBlockItem>
134+
<VerticalGroup>
135+
<Text type="secondary">
136+
If the Routing Template is True, group the alerts using the Grouping Template, publish them to
137+
messengers, and trigger the escalation chain.
138+
</Text>
139+
</VerticalGroup>
140+
</IntegrationBlockItem>
141+
)}
132142
{/* Show Routing Template only for If/Else Routes, not for Default */}
133143
{!isDefault && (
134144
<IntegrationBlockItem>
@@ -206,9 +216,13 @@ const ExpandedIntegrationRouteDisplay: React.FC<ExpandedIntegrationRouteDisplayP
206216
></Select>
207217
</WithPermissionControlTooltip>
208218

209-
<Tooltip content={'Reload escalation chains list'} placement={'top'}>
210-
<Button variant={'secondary'} icon={'sync'} size={'md'} onClick={onEscalationChainsRefresh} />
211-
</Tooltip>
219+
<Button
220+
variant={'secondary'}
221+
tooltip={'Refresh Escalation Chains'}
222+
icon={'sync'}
223+
size={'md'}
224+
onClick={onEscalationChainsRefresh}
225+
/>
212226

213227
<PluginLink className={cx('hover-button')} target="_blank" query={escalationChainRedirectObj}>
214228
<Tooltip

‎grafana-plugin/src/containers/IntegrationForm/IntegrationForm2.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ const IntegrationForm2 = observer((props: IntegrationFormProps) => {
100100
<Drawer scrollableContent title="New Integration" onClose={onHide} closeOnMaskClick={false} width="640px">
101101
<div className={cx('content')}>
102102
<VerticalGroup>
103+
<Text type="secondary">
104+
Integration receives alerts on an unique API URL, interprets them using set of templates tailored for
105+
monitoring system and starts escalations.
106+
</Text>
103107
<div className={cx('search-integration')}>
104108
<Input
105109
autoFocus
@@ -129,7 +133,9 @@ const IntegrationForm2 = observer((props: IntegrationFormProps) => {
129133
<Text strong data-testid="integration-display-name">
130134
{alertReceiveChannelChoice.display_name}
131135
</Text>
132-
{alertReceiveChannelChoice.featured && <Tag name="Quick connect" colorIndex={5} />}
136+
{alertReceiveChannelChoice.featured && alertReceiveChannelChoice.featured_tag_name && (
137+
<Tag name={alertReceiveChannelChoice.featured_tag_name} colorIndex={5} />
138+
)}
133139
</HorizontalGroup>
134140
<Text type="secondary" size="small">
135141
{alertReceiveChannelChoice.short_description}

‎grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface AlertReceiveChannelOption {
1313
value: number;
1414
featured: boolean;
1515
short_description: string;
16+
featured_tag_name: string;
1617
}
1718

1819
export interface AlertReceiveChannelCounters {
@@ -43,6 +44,7 @@ export interface AlertReceiveChannel {
4344
heartbeat: Heartbeat | null;
4445
is_available_for_integration_heartbeat: boolean;
4546
routes_count: number;
47+
connected_escalations_chains_count: number;
4648
allow_delete: boolean;
4749
deleted?: boolean;
4850
}

‎grafana-plugin/src/pages/integration_2/Integration2.helper.ts

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ const IntegrationHelper = {
4646
return routeIndex ? 'Else' : 'If';
4747
},
4848

49+
getRouteConditionTooltipWording(channelFilters: Array<ChannelFilter['id']>, routeIndex: number) {
50+
const totalCount = Object.keys(channelFilters).length;
51+
52+
if (routeIndex === totalCount - 1) {
53+
return 'If the alert payload does not match to the previous routes, it will be directed to this default route.';
54+
}
55+
return 'If the alert payload evaluates the route template as True, it will be directed to this route. It will not be evaluated against the subsequent routes.';
56+
},
57+
4958
getMaintenanceText(maintenanceUntill: number, mode: number = undefined) {
5059
const date = dayjs(new Date(maintenanceUntill * 1000));
5160
const now = dayjs();

‎grafana-plugin/src/pages/integration_2/Integration2.tsx

+25-11
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
207207
<IntegrationHeader
208208
alertReceiveChannel={alertReceiveChannel}
209209
alertReceiveChannelCounter={alertReceiveChannelCounter}
210-
channelFilterIds={channelFilterIds}
211210
integration={integration}
212211
/>
213212
</div>
@@ -255,7 +254,10 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
255254

256255
<div className={cx('templates__content')}>
257256
<div className={cx('templates__container')}>
258-
<div className={cx('templates__item', 'templates__item--large')}>
257+
<div
258+
className={cx('templates__item', 'templates__item--large')}
259+
onClick={() => this.setState({ isTemplateSettingsOpen: true })}
260+
>
259261
<Text type="secondary" className={cx('templates__item-text')}>
260262
Grouping:
261263
</Text>
@@ -264,7 +266,10 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
264266
</Text>
265267
</div>
266268

267-
<div className={cx('templates__item', 'templates__item--large')}>
269+
<div
270+
className={cx('templates__item', 'templates__item--large')}
271+
onClick={() => this.setState({ isTemplateSettingsOpen: true })}
272+
>
268273
<Text type="secondary" className={cx('templates__item-text')}>
269274
Autoresolve:
270275
</Text>
@@ -273,7 +278,10 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
273278
</Text>
274279
</div>
275280

276-
<div className={cx('templates__item', 'templates__item--small')}>
281+
<div
282+
className={cx('templates__item', 'templates__item--small')}
283+
onClick={() => this.setState({ isTemplateSettingsOpen: true })}
284+
>
277285
<Text type="secondary" className={cx('templates__item-text')}>
278286
Visualisation:
279287
</Text>
@@ -968,14 +976,12 @@ interface IntegrationHeaderProps {
968976
alertReceiveChannelCounter: AlertReceiveChannelCounters;
969977
alertReceiveChannel: AlertReceiveChannel;
970978
integration: SelectOption;
971-
channelFilterIds: string[];
972979
}
973980

974981
const IntegrationHeader: React.FC<IntegrationHeaderProps> = ({
975982
integration,
976983
alertReceiveChannelCounter,
977984
alertReceiveChannel,
978-
channelFilterIds,
979985
}) => {
980986
const { grafanaTeamStore, heartbeatStore, alertReceiveChannelStore } = useStore();
981987

@@ -989,8 +995,8 @@ const IntegrationHeader: React.FC<IntegrationHeaderProps> = ({
989995
>
990996
<TooltipBadge
991997
borderType="primary"
992-
tooltipTitle={getAlertReceiveChannelCounterTooltip()}
993-
tooltipContent={undefined}
998+
tooltipTitle={undefined}
999+
tooltipContent={getAlertReceiveChannelCounterTooltip()}
9941000
text={alertReceiveChannelCounter?.alerts_count + '/' + alertReceiveChannelCounter?.alert_groups_count}
9951001
/>
9961002
</PluginLink>
@@ -999,9 +1005,17 @@ const IntegrationHeader: React.FC<IntegrationHeaderProps> = ({
9991005
<TooltipBadge
10001006
borderType="success"
10011007
icon="link"
1002-
text={channelFilterIds.length}
1003-
tooltipTitle={`${channelFilterIds.length} Routes`}
1004-
tooltipContent={undefined}
1008+
text={`${alertReceiveChannel.connected_escalations_chains_count}/${alertReceiveChannel.routes_count}`}
1009+
tooltipTitle=""
1010+
tooltipContent={
1011+
alertReceiveChannel.connected_escalations_chains_count +
1012+
' connected escalation chain' +
1013+
(alertReceiveChannel.connected_escalations_chains_count === 1 ? '' : 's') +
1014+
' in ' +
1015+
alertReceiveChannel.routes_count +
1016+
' route' +
1017+
(alertReceiveChannel.routes_count === 1 ? '' : 's')
1018+
}
10051019
/>
10061020

10071021
{alertReceiveChannel.maintenance_till && (

‎grafana-plugin/src/pages/integrations_2/Integrations2.tsx

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22

3-
import { HorizontalGroup, Button, IconButton } from '@grafana/ui';
3+
import { HorizontalGroup, Button, IconButton, VerticalGroup } from '@grafana/ui';
44
import cn from 'classnames/bind';
55
import { debounce } from 'lodash-es';
66
import { observer } from 'mobx-react';
@@ -165,7 +165,12 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
165165
<div className={cx('root')}>
166166
<div className={cx('title')}>
167167
<HorizontalGroup justify="space-between">
168-
<Text.Title level={3}>Integrations 2</Text.Title>
168+
<VerticalGroup>
169+
<Text.Title level={3}>Integrations 2</Text.Title>
170+
<Text type="secondary">
171+
Receive alerts, group and interpret using templates and route to escalations
172+
</Text>
173+
</VerticalGroup>
169174
<WithPermissionControlTooltip userAction={UserActions.IntegrationsWrite}>
170175
<Button
171176
onClick={() => {
@@ -257,6 +262,7 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
257262
renderIntegrationStatus(item: AlertReceiveChannel, alertReceiveChannelStore) {
258263
const alertReceiveChannelCounter = alertReceiveChannelStore.counters[item.id];
259264
let routesCounter = item.routes_count;
265+
let connectedEscalationsChainsCount = item.connected_escalations_chains_count;
260266

261267
return (
262268
<HorizontalGroup spacing="xs">
@@ -282,9 +288,17 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
282288
<TooltipBadge
283289
borderType="success"
284290
icon="link"
285-
text={routesCounter}
291+
text={`${connectedEscalationsChainsCount}/${routesCounter}`}
286292
tooltipTitle=""
287-
tooltipContent={`${routesCounter} routes`}
293+
tooltipContent={
294+
connectedEscalationsChainsCount +
295+
' connected escalation chain' +
296+
(connectedEscalationsChainsCount === 1 ? '' : 's') +
297+
' in ' +
298+
routesCounter +
299+
' route' +
300+
(routesCounter === 1 ? '' : 's')
301+
}
288302
/>
289303
)}
290304
</HorizontalGroup>

0 commit comments

Comments
 (0)
Please sign in to comment.