From 5a07db851d648c2995bd45647e014b2dc353a0ae Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Tue, 30 May 2023 14:53:48 -0400 Subject: [PATCH 01/12] add description to "Default channel for Slack notifications" UI dropdown (#2051) # What this PR does Screenshot 2023-05-30 at 07 53 20 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated (N/A) - [ ] Documentation added (or `pr:no public docs` PR label added if not required) (N/A) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- CHANGELOG.md | 1 + .../tabs/ChatOps/tabs/SlackSettings/SlackSettings.tsx | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09bf18d2..501aaa82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Helm chart: configuration of `uwsgi` using environment variables by @alexintech ([#2045](https://github.com/grafana/oncall/pull/2045)) - Much expanded/improved docs for mobile app ([2026](https://github.com/grafana/oncall/pull/2026>)) - Enable by-day selection when defining monthly and hourly rotations ([2037](https://github.com/grafana/oncall/pull/2037)) +- Add description to "Default channel for Slack notifications" UI dropdown by @joeyorlando ([2051](https://github.com/grafana/oncall/pull/2051)) ### Fixed diff --git a/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.tsx b/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.tsx index 3bad354e..1f3950b9 100644 --- a/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.tsx +++ b/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.tsx @@ -109,7 +109,10 @@ class SlackSettings extends Component { {store.teamStore.currentTeam.slack_team_identity?.cached_name} - + Date: Wed, 31 May 2023 08:00:43 +0300 Subject: [PATCH 02/12] Edit critical to be Important to align with the rest of app convention (#2063) # What this PR does - Edits the send important notification button to be send critical notification button to align with the app conventions ## Which issue(s) this PR fixes Ref #2043 --- .../src/containers/MobileAppConnection/MobileAppConnection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx b/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx index 943dca59..0bb60fd9 100644 --- a/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx +++ b/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx @@ -215,7 +215,7 @@ const MobileAppConnection = observer(({ userPk }: Props) => { onClick={() => onSendTestNotification(true)} disabled={isAttemptingTestNotification} > - Send Critical Test Push notification + Send Important Test Push notification From b93413c032ab0b20ca53425484a52bbfcf1901c1 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Wed, 31 May 2023 10:40:02 +0300 Subject: [PATCH 03/12] Rares/templates tweaks 3 (#2052) # What this PR does - Added option to expand tree view on main block click - Fixed showing contact policy for grafana alerting --- .../IntegrationCollapsibleTreeView.tsx | 8 ++-- .../Integrations/IntegrationBlock.tsx | 13 +++++- .../src/containers/AlertRules/AlertRules.tsx | 1 + .../CollapsedIntegrationRouteDisplay.tsx | 4 +- .../ExpandedIntegrationRouteDisplay.tsx | 13 ++++-- .../integration_2/Integration2.module.scss | 9 +++- .../src/pages/integration_2/Integration2.tsx | 43 +++++++++++++------ grafana-plugin/src/utils/consts.ts | 2 +- 8 files changed, 67 insertions(+), 26 deletions(-) diff --git a/grafana-plugin/src/components/IntegrationCollapsibleTreeView/IntegrationCollapsibleTreeView.tsx b/grafana-plugin/src/components/IntegrationCollapsibleTreeView/IntegrationCollapsibleTreeView.tsx index 4c212a8b..a57708d0 100644 --- a/grafana-plugin/src/components/IntegrationCollapsibleTreeView/IntegrationCollapsibleTreeView.tsx +++ b/grafana-plugin/src/components/IntegrationCollapsibleTreeView/IntegrationCollapsibleTreeView.tsx @@ -11,8 +11,8 @@ const cx = cn.bind(styles); export interface IntegrationCollapsibleItem { customIcon?: IconName; canHoverIcon: boolean; - expandedView: React.ReactNode; - collapsedView: React.ReactNode; + collapsedView: (toggle?: () => void) => React.ReactNode; // needs toggle param for toggling on click + expandedView: () => React.ReactNode; // for consistency, this is also a function isCollapsible: boolean; isExpanded?: boolean; onStateChange?(): void; @@ -116,10 +116,10 @@ const IntegrationCollapsibleTreeItem: React.FC<{ )}
- {item.expandedView} + {item.expandedView?.()}
- {item.collapsedView} + {item.collapsedView?.(onClick)}
); diff --git a/grafana-plugin/src/components/Integrations/IntegrationBlock.tsx b/grafana-plugin/src/components/Integrations/IntegrationBlock.tsx index cda84f2f..0e283d44 100644 --- a/grafana-plugin/src/components/Integrations/IntegrationBlock.tsx +++ b/grafana-plugin/src/components/Integrations/IntegrationBlock.tsx @@ -1,6 +1,7 @@ import React from 'react'; import cn from 'classnames/bind'; +import { noop } from 'lodash-es'; import Block from 'components/GBlock/Block'; @@ -13,13 +14,20 @@ interface IntegrationBlockProps { hasCollapsedBorder: boolean; heading: React.ReactNode; content: React.ReactNode; + toggle?: () => void; } -const IntegrationBlock: React.FC = ({ heading, content, hasCollapsedBorder, className }) => { +const IntegrationBlock: React.FC = ({ + heading, + content, + hasCollapsedBorder, + className, + toggle = noop, +}) => { return (
{heading && ( - + {heading} )} @@ -28,6 +36,7 @@ const IntegrationBlock: React.FC = ({ heading, content, h className={cx('integrationBlock__content', { 'integrationBlock__content--collapsedBorder': hasCollapsedBorder, })} + onClick={toggle} > {content}
diff --git a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx index 1909db48..4bb4a088 100644 --- a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx +++ b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx @@ -292,6 +292,7 @@ class AlertRules extends React.Component { )} + {alertReceiveChannel.description && (
void; } const CollapsedIntegrationRouteDisplay: React.FC = observer( - ({ channelFilterId, alertReceiveChannelId, routeIndex }) => { + ({ channelFilterId, alertReceiveChannelId, routeIndex, toggle }) => { const { escalationChainStore, alertReceiveChannelStore } = useStore(); const [routeIdForDeletion, setRouteIdForDeletion] = useState(undefined); @@ -44,6 +45,7 @@ const CollapsedIntegrationRouteDisplay: React.FC
diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index cc6437bd..788e19f9 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -336,18 +336,25 @@ export const RouteButtonsDisplay: React.FC = ({ {!channelFilter.is_default && ( -
+ + {alertReceiveChannel.description && ( +
+
} + severity="info" + /> +
+ )} customIcon: 'plug', canHoverIcon: false, collapsedView: null, - expandedView: , + expandedView: () => , }, { customIcon: 'layer-group', isExpanded: false, isCollapsible: false, canHoverIcon: false, - expandedView: ( + expandedView: () => ( isCollapsible: false, collapsedView: null, canHoverIcon: false, - expandedView: ( + expandedView: () => (
@@ -420,14 +433,15 @@ class Integration2 extends React.Component this.setState((prevState) => ({ newRoutes: prevState.newRoutes.filter((r) => r !== channelFilterId) })); } }, - collapsedView: ( + collapsedView: (toggle) => ( ), - expandedView: ( + expandedView: () => ( = ({ id const { alertReceiveChannelStore } = useStore(); const alertReceiveChannelCounter = alertReceiveChannelStore.counters[id]; const alertReceiveChannel = alertReceiveChannelStore.items[id]; - const isAlertManager = alertReceiveChannel.integration === DATASOURCE_ALERTING; + const isGrafanaDatasource = alertReceiveChannel.integration === DATASOURCE_GRAFANA; const hasAlerts = !!alertReceiveChannelCounter?.alerts_count; return ( = ({ id
} - content={isAlertManager || !hasAlerts ? renderContent() : null} + content={isGrafanaDatasource || !hasAlerts ? renderContent() : null} /> ); @@ -930,14 +945,14 @@ const HowToConnectComponent: React.FC<{ id: AlertReceiveChannel['id'] }> = ({ id )} - {isAlertManager && ( + {isGrafanaDatasource && ( - + Contact Point and - + Notification Policy created in Grafana Alerting @@ -974,8 +989,8 @@ const IntegrationHeader: React.FC = ({ > diff --git a/grafana-plugin/src/utils/consts.ts b/grafana-plugin/src/utils/consts.ts index 386ced4b..b7dba9fc 100644 --- a/grafana-plugin/src/utils/consts.ts +++ b/grafana-plugin/src/utils/consts.ts @@ -34,4 +34,4 @@ export const DOCS_TELEGRAM_SETUP = 'https://grafana.com/docs/oncall/latest/chat- // Make sure if you chage max-width here you also change it in responsive.css export const TABLE_COLUMN_MAX_WIDTH = 1500; -export const DATASOURCE_ALERTING = 'alertmanager'; +export const DATASOURCE_GRAFANA = 'grafana'; From 528529de232384d744510b70ba0003ef24308c84 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Wed, 31 May 2023 16:22:58 +0800 Subject: [PATCH 04/12] Fix 500 on templates when slack or tg integration is disabled (#2064) # What this PR does Continue the work, started in https://github.com/grafana/oncall/pull/2061. Check if slack or telegram integration is enabled to include related templates in the response ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/1889 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated --- CHANGELOG.md | 6 ++ .../api/serializers/alert_receive_channel.py | 85 +++++++++---------- .../test_alert_receive_channel_template.py | 42 +++++++++ 3 files changed, 87 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 501aaa82..40232600 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fix templates when slack or telegram is disabled ([#2064](https://github.com/grafana/oncall/pull/2064)) + ## v1.2.33 (2023-05-30) ### Fixed diff --git a/engine/apps/api/serializers/alert_receive_channel.py b/engine/apps/api/serializers/alert_receive_channel.py index d3d0d91d..7d070d4f 100644 --- a/engine/apps/api/serializers/alert_receive_channel.py +++ b/engine/apps/api/serializers/alert_receive_channel.py @@ -216,23 +216,6 @@ class FilterAlertReceiveChannelSerializer(serializers.ModelSerializer): class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.ModelSerializer): id = serializers.CharField(read_only=True, source="public_primary_key") - CORE_TEMPLATE_NAMES = [ - "slack_title_template", - "slack_message_template", - "slack_image_url_template", - "web_title_template", - "web_message_template", - "web_image_url_template", - "telegram_title_template", - "telegram_message_template", - "telegram_image_url_template", - "sms_title_template", - "phone_call_title_template", - "source_link_template", - "grouping_id_template", - "resolve_condition_template", - "acknowledge_condition_template", - ] payload_example = SerializerMethodField() is_based_on_alertmanager = SerializerMethodField() @@ -325,9 +308,7 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode """Update core templates if needed.""" errors = {} - core_template_names = self.CORE_TEMPLATE_NAMES - - for field_name in core_template_names: + for field_name in self.core_templates_names: value = data.get(field_name) validator = jinja_template_env.from_string if value is not None: @@ -343,7 +324,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode def to_representation(self, obj): ret = super().to_representation(obj) - ret = self._get_templates_to_show(ret) core_templates = self._get_core_templates(obj) ret.update(core_templates) @@ -354,29 +334,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode return ret - def _get_templates_to_show(self, response_data): - """ - For On-prem installations with disabled features it is needed to disable corresponding templates - """ - slack_integration_required_templates = [ - "slack_title_template", - "slack_message_template", - "slack_image_url_template", - ] - telegram_integration_required_templates = [ - "telegram_title_template", - "telegram_message_template", - "telegram_image_url_template", - ] - if not settings.FEATURE_SLACK_INTEGRATION_ENABLED: - for st in slack_integration_required_templates: - response_data.pop(st) - if not settings.FEATURE_TELEGRAM_INTEGRATION_ENABLED: - for tt in telegram_integration_required_templates: - response_data.pop(tt) - - return response_data - def _get_messaging_backend_templates(self, obj): """Return additional messaging backend templates if any.""" templates = {} @@ -399,8 +356,7 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode def _get_core_templates(self, obj): core_templates = {} - core_template_names = self.CORE_TEMPLATE_NAMES - for template_name in core_template_names: + for template_name in self.core_templates_names: template_value = getattr(obj, template_name) defaults = getattr(obj, f"INTEGRATION_TO_DEFAULT_{template_name.upper()}", {}) default_template_value = defaults.get(obj.integration) @@ -408,3 +364,40 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode core_templates[f"{template_name}_is_default"] = not bool(template_value) return core_templates + + @property + def core_templates_names(self): + """ + core_templates_names returns names of templates introduced before messaging backends system with respect to + enabled integrations. + """ + core_templates = [ + "web_title_template", + "web_message_template", + "web_image_url_template", + "sms_title_template", + "phone_call_title_template", + "source_link_template", + "grouping_id_template", + "resolve_condition_template", + "acknowledge_condition_template", + ] + + slack_integration_required_templates = [ + "slack_title_template", + "slack_message_template", + "slack_image_url_template", + ] + telegram_integration_required_templates = [ + "telegram_title_template", + "telegram_message_template", + "telegram_image_url_template", + ] + + apppend = [] + + if settings.FEATURE_SLACK_INTEGRATION_ENABLED: + core_templates += slack_integration_required_templates + if settings.FEATURE_TELEGRAM_INTEGRATION_ENABLED: + core_templates += telegram_integration_required_templates + return apppend + core_templates diff --git a/engine/apps/api/tests/test_alert_receive_channel_template.py b/engine/apps/api/tests/test_alert_receive_channel_template.py index 4c134855..728add84 100644 --- a/engine/apps/api/tests/test_alert_receive_channel_template.py +++ b/engine/apps/api/tests/test_alert_receive_channel_template.py @@ -1,6 +1,7 @@ from unittest.mock import patch import pytest +from django.test.utils import override_settings from django.urls import reverse from rest_framework import status from rest_framework.response import Response @@ -381,3 +382,44 @@ def test_update_alert_receive_channel_templates( assert updated_templates_data[template_name] is False else: assert updated_templates_data[template_name] == template_update_func(prev_template_value) + + +@override_settings(FEATURE_TELEGRAM_INTEGRATION_ENABLED=False) +@override_settings(FEATURE_SLACK_INTEGRATION_ENABLED=False) +@pytest.mark.django_db +def test_update_alert_receive_channel_backend_template_hide_disabled_integration_templates( + make_organization_and_user_with_plugin_token, + make_user_auth_headers, + make_alert_receive_channel, +): + slack_integration_required_templates = [ + "slack_title_template", + "slack_message_template", + "slack_image_url_template", + ] + telegram_integration_required_templates = [ + "telegram_title_template", + "telegram_message_template", + "telegram_image_url_template", + ] + + organization, user, token = make_organization_and_user_with_plugin_token() + alert_receive_channel = make_alert_receive_channel( + organization, + messaging_backends_templates={"TESTONLY": {"title": "the-title", "message": "the-message", "image_url": "url"}}, + ) + client = APIClient() + + url = reverse( + "api-internal:alert_receive_channel_template-detail", kwargs={"pk": alert_receive_channel.public_primary_key} + ) + + response = client.get(url, format="json", **make_user_auth_headers(user, token)) + assert response.status_code == status.HTTP_200_OK + templates_data = response.json() + + for st in slack_integration_required_templates: + assert st not in templates_data + + for tt in telegram_integration_required_templates: + assert tt not in templates_data From 76a37bd90b81b4291622f4078c1ac2c561e76d94 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Wed, 31 May 2023 12:27:39 +0300 Subject: [PATCH 05/12] Templates&grouping changes (#2066) # What this PR does - removed msteams usage from public - removed check for chatops --- .../ExpandedIntegrationRouteDisplay.tsx | 19 +++++-------- .../integration_2/Integration2.config.ts | 27 ++++--------------- 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index 788e19f9..4c6bf8ee 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -32,7 +32,6 @@ import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'; import { MONACO_INPUT_HEIGHT_SMALL, MONACO_OPTIONS } from 'pages/integration_2/Integration2.config'; import IntegrationHelper from 'pages/integration_2/Integration2.helper'; -import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization'; @@ -58,7 +57,6 @@ const ExpandedIntegrationRouteDisplay: React.FC 0; const [{ isEscalationCollapsed, isRefreshingEscalationChains, routeIdForDeletion }, setState] = useReducer( (state: ExpandedIntegrationRouteDisplayState, newState: Partial) => ({ @@ -170,14 +165,12 @@ const ExpandedIntegrationRouteDisplay: React.FC )} - {(isSlackInstalled || isTelegramInstalled) && ( - - - Publish to ChatOps - - - - )} + + + Publish to ChatOps + + + diff --git a/grafana-plugin/src/pages/integration_2/Integration2.config.ts b/grafana-plugin/src/pages/integration_2/Integration2.config.ts index b800973a..4c4ded1f 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.config.ts +++ b/grafana-plugin/src/pages/integration_2/Integration2.config.ts @@ -1,3 +1,8 @@ +/* + [oncall-private] + Any change to this file needs to be done in the oncall-private also +*/ + import { KeyValuePair } from 'utils'; export const TEXTAREA_ROWS_COUNT = 4; @@ -45,10 +50,6 @@ const TemplateOptions = { TelegramTitle: new KeyValuePair('telegram_title_template', 'Title'), TelegramMessage: new KeyValuePair('telegram_message_template', 'Message'), TelegramImage: new KeyValuePair('telegram_image_url_template', 'Image'), - /*Should it be in Oncallprivate repo? (All MsTeams)*/ - MSTeamsTitle: new KeyValuePair('MSTeams Title', 'Title'), - MSTeamsMessage: new KeyValuePair('MSTeams Message', 'Message'), - MSTeamsImage: new KeyValuePair('MSTeams Image', 'Image'), Email: new KeyValuePair('Email', 'Email'), Slack: new KeyValuePair('Slack', 'Slack'), @@ -105,24 +106,6 @@ export const INTEGRATION_TEMPLATES_LIST = [ }, ], }, - { - label: TemplateOptions.MSTeams.value, - value: TemplateOptions.MSTeams.key, - children: [ - { - label: TemplateOptions.MSTeamsTitle.value, - value: TemplateOptions.MSTeamsTitle.key, - }, - { - label: TemplateOptions.MSTeamsMessage.value, - value: TemplateOptions.MSTeamsMessage.key, - }, - { - label: TemplateOptions.MSTeamsImage.value, - value: TemplateOptions.MSTeamsImage.key, - }, - ], - }, { label: TemplateOptions.Telegram.value, value: TemplateOptions.Telegram.key, From 83b328a0f60c5be215b75462eb58b99827ce86ac Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Wed, 31 May 2023 12:39:23 +0300 Subject: [PATCH 06/12] Dieter/mobile app docs tweaks (#2055) # What this PR does Better docs for mobile app push notifications and shift pages ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [x] 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) --- .../on-call-status-and-shifts/index.md | 7 ++++-- .../mobile-app/push-notifications/index.md | 23 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/docs/sources/mobile-app/on-call-status-and-shifts/index.md b/docs/sources/mobile-app/on-call-status-and-shifts/index.md index 2736c9cf..359f5f2f 100644 --- a/docs/sources/mobile-app/on-call-status-and-shifts/index.md +++ b/docs/sources/mobile-app/on-call-status-and-shifts/index.md @@ -13,6 +13,9 @@ weight: 500 # On-call status and shifts On the **Feed** page, your avatar on top of the screen indicates whether you are oncall, will be on call soon, or not. -Tap on it to open the **upcoming shifts** view. This view presents your current, and next upcoming shifts (if any), up to 1 month into the future. +Tap it to open the **upcoming shifts** view. This view displays: - +- your current shift (if any), per schedule. +- your next upcoming shift (if any), per schedule. This only looks up to 31 days into the future. + + diff --git a/docs/sources/mobile-app/push-notifications/index.md b/docs/sources/mobile-app/push-notifications/index.md index efdddd78..e5f569f9 100644 --- a/docs/sources/mobile-app/push-notifications/index.md +++ b/docs/sources/mobile-app/push-notifications/index.md @@ -25,7 +25,7 @@ To receive push notifications from the Grafana OnCall mobile app, you must add t In the **Settings** tab of the mobile app, tap on **Notification policies** to review, reorder, remove, add or change steps. Alternatively, you can do the same on desktop. From Grafana OnCall, navigate to the **Users** page, click **View my profile** and navigate to the **User Info** tab. - + ## Configuration @@ -33,20 +33,31 @@ Use the **Push notifications** section in the **Settings** tab to configure push You can always confirm how a notification is presented by going to Grafana OnCall on your desktop, navigate to the **Users** page, click **View my profile** and navigate to the **Mobile App connection** tab. -Here you can send a test notification of default or important priority. +Here you can send a test notification of default or important priority. We recommend doing this to try out +correct configuration of **Do Not Disturb** and **Volume** overrides. ### Android On Android, we leverage the "Notification channels" system feature. Each type of notification (**important**, **default**, and **on-call shifts**) registers a channel. -In this channel, you may configure the sound style, optional Do Not Disturb override, vibration, and so on. +In this channel, you may configure the sound style, vibration, and so on. **Customize notifications** takes you to this system menu, while hitting the **back** button or swiping left (if enabled) takes you back to the application. +>**Note**: You can explore included sounds and recommendations via the **Sound Library** button, but to change the sound, go to **Customize notifications**. + +#### Override Do Not Disturb + +- On most Android versions, the **Override Do Not Disturb** option is available in the channel options described above. +- On some Samsung devices, you can add the Grafana Oncall app under (System) Settings > Notifications > Do not disturb > App notifications. +- If your device does something different, you may need to search for this setting for notifications via the (System) Settings app. + Do not confuse this with the **Override Do Not Disturb** application permission, needed for **Volume Overrides** (see below). + +#### Override Volume + **Volume Override** can optionally be configured in the mobile app itself. Confusingly, this requires you to provide the **Override Do Not Disturb** permission to the application, in the system configuration. -The app will prompt for this if applicable. - ->**Note**: You can explore included sounds and recommendations via the **Sound Library** button, but to change the sound, go to **Customize notifications**. +The app will prompt for this if applicable. Note that this is a different setting than the **Do Not Disturb** override needed for +notifications triggered by the application, which is described above. From f299fb98143ba914cd41b35f2eaa053616e3985e Mon Sep 17 00:00:00 2001 From: Yulia Shanyrova Date: Wed, 31 May 2023 11:40:21 +0200 Subject: [PATCH 07/12] bug fixes (#2067) ## Which issue(s) this PR fixes - Wrong field name in validation (Verbal name is required, but should be Name is required) - For messenger templates we need to keep \n in the beginning of the result -Save and Open in slack button should not close drawer - If user edit templates, button Cancel should return to templates drawer - Cheatsheet should have a scroll, not main drawer - narrow screen issues in cheatsheet - How integration works should have the dynamic integration name (first red mark). Alerting Contact point and notification policy should be mentioned only for Grafana Alerting https://files.slack.com/files-pri/T02S4RCS0-F0592BHP42G/screenshot_2023-05-23_at_11.45.29_am.png - Cheatsheet title doesn't match to template - Image is not rendered in Result of Edit Template https://files.slack.com/files-tmb/T02S4RCS0-F058TEPD214-27c1136ad2/screenshot_2023-05-23_at_1.02.47_pm_720.png - Add description to the Result of conditional template: if True Selected alert will resolve alert group else Selected alert will not resolve alert group. And change the icon from Warning to X - Opening cheatsheet resets the non-saved template](https://github.com/grafana/oncall-private/issues/1824#issuecomment-1560348999) --- .../CheatSheet/CheatSheet.module.css | 6 +++++ .../IntegrationForm/IntegrationForm2.tsx | 8 +++---- .../IntegrationTemplate.module.css | 4 ++++ .../IntegrationTemplate.tsx | 12 +++++++--- .../TemplatePreview.module.css | 5 ++++ .../TemplatePreview/TemplatePreview.tsx | 21 ++++++++++------ .../TemplatesAlertGroupsList.module.css | 9 +++++++ .../TemplatesAlertGroupsList.tsx | 24 ++++++++++++------- .../src/pages/integration_2/Integration2.tsx | 2 +- 9 files changed, 68 insertions(+), 23 deletions(-) diff --git a/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css b/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css index 2915452c..db596036 100644 --- a/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css +++ b/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css @@ -6,6 +6,12 @@ min-width: min-content; } +.cheatsheet-container > div { + height: 100%; + max-height: 100%; + overflow-y: scroll; +} + .cheatsheet-item { margin-bottom: 24px; } diff --git a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm2.tsx b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm2.tsx index d565ee50..0065de03 100644 --- a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm2.tsx +++ b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm2.tsx @@ -152,7 +152,7 @@ const IntegrationForm2 = observer((props: IntegrationFormProps) => {
- {isTableView && ( + {isTableView && selectedOption && ( {
  • Unique URL endpoint for receiving alerts
  • - Templates to interpret alerts, tailored for Grafana Alerting{' '} + Templates to interpret alerts, tailored for {selectedOption.display_name}{' '}
  • -
  • Grafana Alerting contact point
  • -
  • Grafana Alerting notification
  • +
  • {selectedOption.display_name} contact point
  • +
  • {selectedOption.display_name} notification
What you’ll need to do next:
    diff --git a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.module.css b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.module.css index 17f7b2a2..e7a7639c 100644 --- a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.module.css +++ b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.module.css @@ -4,10 +4,14 @@ .container-wrapper { padding: 8px; + height: 100%; + max-height: 100%; } .container { display: flex; + height: 100%; + max-height: 100%; width: 100%; border: var(--border-strong); padding: 0 16px; diff --git a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx index 2d9afecc..55c36495 100644 --- a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx +++ b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx @@ -55,6 +55,12 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => { LocationHelper.update(locationParams, 'partial'); }, []); + const getCodeEditorHeight = () => { + const mainDiv = document.getElementById('content-container-id'); + const height = mainDiv?.getBoundingClientRect().height - 59; + return `${height}px`; + }; + const onShowCheatSheet = useCallback(() => { setIsCheatSheetVisible(true); }, []); @@ -166,7 +172,7 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => { width={'95%'} >
    -
    +
    { <>
    - + Template editor
    diff --git a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.module.css b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.module.css index 5f2ecb4a..41af313f 100644 --- a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.module.css +++ b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.module.css @@ -13,3 +13,8 @@ .message code { white-space: break-spaces; } + +.image-result img { + max-width: 100%; + max-height: 100%; +} diff --git a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx index f2172173..e268ef25 100644 --- a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx +++ b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx @@ -60,7 +60,6 @@ const TemplatePreview = observer((props: TemplatePreviewProps) => { }, 1000); useEffect(handleTemplateBodyChange, [templateBody, payload]); - // onResult(result); return result ? ( <> @@ -93,12 +92,20 @@ const TemplatePreview = observer((props: TemplatePreviewProps) => { )} ) : ( -
    + <> + {templateName.includes('image') ? ( +
    + +
    + ) : ( +
    ') || ''), + }} + /> + )} + )} ) : ( diff --git a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.module.css b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.module.css index 29df3d90..e66b1ba4 100644 --- a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.module.css +++ b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.module.css @@ -27,6 +27,15 @@ padding-left: 0; } +.alert-groups-list-item { + cursor: pointer; + margin-bottom: 8px; +} + +.alert-groups-list-item:hover { + background-color: var(--background-secondary); +} + .alert-groups-editor { width: 100%; } diff --git a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx index 26cc233b..b58d1988 100644 --- a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx +++ b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx @@ -37,6 +37,12 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { .then((result) => setAlertGroupsList(result.slice(0, 30))); }, []); + const getCodeEditorHeight = () => { + const mainDiv = document.getElementById('content-container-id'); + const height = mainDiv?.getBoundingClientRect().height - 59; + return `${height}px`; + }; + const getChangeHandler = () => { return debounce((value: string) => { onEditPayload(value); @@ -65,7 +71,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { }; return ( -
    +
    {selectedAlertPayload ? ( <> {isEditMode ? ( @@ -83,7 +89,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { { value={JSON.stringify(selectedAlertPayload, null, 4)} data={undefined} disabled - height={'85vh'} + height={getCodeEditorHeight()} onChange={getChangeHandler()} showLineNumbers useAutoCompleteList={false} @@ -147,7 +153,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { data={templates} monacoOptions={MONACO_PAYLOAD_OPTIONS} showLineNumbers={false} - height={'85vh'} + height={getCodeEditorHeight()} onChange={getChangeHandler()} />
    @@ -175,10 +181,12 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { <> {alertGroupsList.map((alertGroup) => { return ( -
    - +
    getAlertGroupPayload(alertGroup.pk)} + className={cx('alert-groups-list-item')} + > + {getAlertGroupName(alertGroup)}
    ); })} diff --git a/grafana-plugin/src/pages/integration_2/Integration2.tsx b/grafana-plugin/src/pages/integration_2/Integration2.tsx index c09110c7..17c2b7d5 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.tsx +++ b/grafana-plugin/src/pages/integration_2/Integration2.tsx @@ -1059,7 +1059,7 @@ const IntegrationHeader: React.FC = ({ if ( !alertReceiveChannel.is_available_for_integration_heartbeat || - alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal === null + !alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal ) { return null; } From 5975b9dd8ca5aac2fd9c841c01c2d5d23ca24302 Mon Sep 17 00:00:00 2001 From: Ildar Iskhakov Date: Wed, 31 May 2023 19:26:36 +0800 Subject: [PATCH 08/12] 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 --- .../apps/alerts/integration_options_mixin.py | 5 +++ .../apps/api/views/alert_receive_channel.py | 3 ++ .../config_integrations/grafana_alerting.py | 1 + engine/config_integrations/webhook.py | 5 +-- .../CollapsedIntegrationRouteDisplay.tsx | 11 +++--- .../ExpandedIntegrationRouteDisplay.tsx | 22 +++++++++--- .../IntegrationForm/IntegrationForm2.tsx | 8 ++++- .../alert_receive_channel.types.ts | 2 ++ .../integration_2/Integration2.helper.ts | 9 +++++ .../src/pages/integration_2/Integration2.tsx | 36 +++++++++++++------ .../pages/integrations_2/Integrations2.tsx | 22 +++++++++--- 11 files changed, 97 insertions(+), 27 deletions(-) diff --git a/engine/apps/alerts/integration_options_mixin.py b/engine/apps/alerts/integration_options_mixin.py index a747d899..0594e0f6 100644 --- a/engine/apps/alerts/integration_options_mixin.py +++ b/engine/apps/alerts/integration_options_mixin.py @@ -49,6 +49,11 @@ class IntegrationOptionsMixin: integration_config.slug: integration_config.short_description for integration_config in _config } INTEGRATION_FEATURED = [integration_config.slug for integration_config in _config if integration_config.is_featured] + INTEGRATION_FEATURED_TAG_NAME = { + integration_config.slug: integration_config.featured_tag_name + for integration_config in _config + if hasattr(integration_config, "featured_tag_name") + } # The following attributes dynamically generated and used by apps.alerts.incident_appearance.renderers, templaters # e.g. INTEGRATION_TO_DEFAULT_SLACK_TITLE_TEMPLATE, INTEGRATION_TO_DEFAULT_SLACK_MESSAGE_TEMPLATE, etc... diff --git a/engine/apps/api/views/alert_receive_channel.py b/engine/apps/api/views/alert_receive_channel.py index 95cb3120..cd4e2552 100644 --- a/engine/apps/api/views/alert_receive_channel.py +++ b/engine/apps/api/views/alert_receive_channel.py @@ -198,6 +198,9 @@ class AlertReceiveChannelView( "display_name": integration_title, "short_description": AlertReceiveChannel.INTEGRATION_SHORT_DESCRIPTION[integration_id], "featured": integration_id in AlertReceiveChannel.INTEGRATION_FEATURED, + "featured_tag_name": AlertReceiveChannel.INTEGRATION_FEATURED_TAG_NAME[integration_id] + if integration_id in AlertReceiveChannel.INTEGRATION_FEATURED_TAG_NAME + else None, } # if integration is featured we show it in the beginning if choice["featured"]: diff --git a/engine/config_integrations/grafana_alerting.py b/engine/config_integrations/grafana_alerting.py index 0b72ff20..5b0deb0c 100644 --- a/engine/config_integrations/grafana_alerting.py +++ b/engine/config_integrations/grafana_alerting.py @@ -8,6 +8,7 @@ short_description = ( description = None is_displayed_on_web = True is_featured = True +featured_tag_name = "Quick Connect" is_able_to_autoresolve = True is_demo_alert_enabled = True diff --git a/engine/config_integrations/webhook.py b/engine/config_integrations/webhook.py index 823bc837..0041c8c1 100644 --- a/engine/config_integrations/webhook.py +++ b/engine/config_integrations/webhook.py @@ -2,9 +2,10 @@ enabled = True title = "Webhook" slug = "webhook" -short_description = None +short_description = "If your monitoring system isn't listed, choose Webhook for generic templates, and feel free to modify them as needed." description = None -is_featured = False +is_featured = True +featured_tag_name = "Generic" is_displayed_on_web = True is_able_to_autoresolve = True is_demo_alert_enabled = True diff --git a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx index 383be9b6..8a3504ac 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.tsx @@ -55,7 +55,10 @@ const CollapsedIntegrationRouteDisplay: React.FC {routeWording === 'Default' && ( @@ -93,7 +96,7 @@ const CollapsedIntegrationRouteDisplay: React.FC - Escalate to + Trigger escalation chain: {escalationChain?.name && (
    - - No Escalation chain - + No Escalation chain selected )} diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index 4c6bf8ee..cf24abe8 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -113,7 +113,7 @@ const ExpandedIntegrationRouteDisplay: React.FC @@ -129,6 +129,16 @@ const ExpandedIntegrationRouteDisplay: React.FC + {routeIndex !== channelFiltersTotal.length - 1 && ( + + + + If the Routing Template is True, group the alerts using the Grouping Template, publish them to + messengers, and trigger the escalation chain. + + + + )} {/* Show Routing Template only for If/Else Routes, not for Default */} {!isDefault && ( @@ -206,9 +216,13 @@ const ExpandedIntegrationRouteDisplay: React.FC - -