From a332011f1e8beaa370a8f29e168a7661322381c1 Mon Sep 17 00:00:00 2001 From: Dominik Broj Date: Thu, 8 Aug 2024 16:16:19 +0200 Subject: [PATCH] adjust to unified slack (#4776) # What this PR does Introduce OnCall UI for Unified Slack migration. It's mostly banners and text adjustments. Changes are behind feature flag. ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. --------- Co-authored-by: Innokentii Konstantinov --- engine/apps/api/views/features.py | 4 + grafana-plugin/src/models/slack/slack.ts | 2 +- .../SlackSettings/SlackSettings.module.css | 15 ++ .../tabs/SlackSettings/SlackSettings.tsx | 175 ++++++++++++++---- grafana-plugin/src/state/features.ts | 1 + 5 files changed, 155 insertions(+), 42 deletions(-) diff --git a/engine/apps/api/views/features.py b/engine/apps/api/views/features.py index acd98de81d..7e35597aaf 100644 --- a/engine/apps/api/views/features.py +++ b/engine/apps/api/views/features.py @@ -15,6 +15,7 @@ class Feature(enum.StrEnum): MSTEAMS = "msteams" SLACK = "slack" + UNIFIED_SLACK = "unified_slack" TELEGRAM = "telegram" LIVE_SETTINGS = "live_settings" GRAFANA_CLOUD_NOTIFICATIONS = "grafana_cloud_notifications" @@ -46,6 +47,9 @@ def _get_enabled_features(self, request): if settings.FEATURE_SLACK_INTEGRATION_ENABLED: enabled_features.append(Feature.SLACK) + if settings.UNIFIED_SLACK_APP_ENABLED: + enabled_features.append(Feature.UNIFIED_SLACK) + if settings.FEATURE_TELEGRAM_INTEGRATION_ENABLED: enabled_features.append(Feature.TELEGRAM) diff --git a/grafana-plugin/src/models/slack/slack.ts b/grafana-plugin/src/models/slack/slack.ts index fb665b9767..6a4b6ce82d 100644 --- a/grafana-plugin/src/models/slack/slack.ts +++ b/grafana-plugin/src/models/slack/slack.ts @@ -82,10 +82,10 @@ export class SlackStore extends BaseStore { window.location = url_for_redirect; } + @action.bound async installSlackIntegration() { try { const response = await makeRequestRaw('/login/slack-install-free/', {}); - if (response.status === 201) { this.rootStore.organizationStore.loadCurrentOrganization(); } else if (response.status === 200) { diff --git a/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.module.css b/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.module.css index 49111eb0ad..ab38f543e3 100644 --- a/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.module.css +++ b/grafana-plugin/src/pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings.module.css @@ -39,3 +39,18 @@ .infoblock-icon { margin-top: 24px; } + +.upgradeSlackBtn { + position: absolute; + right: 20px; + top: 50%; + transform: translateY(-50%); +} + +.upgradeSlackAlert svg { + display: none; +} + +.linkToIncidentWrapper { + margin-top: 16px; +} 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 462824dd95..213f3b6bc7 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 @@ -10,11 +10,13 @@ import { InlineField, Input, Legend, + ConfirmModal, } from '@grafana/ui'; import cn from 'classnames/bind'; import { observer } from 'mobx-react'; import { Block } from 'components/GBlock/Block'; +import { PluginBridge, SupportedPlugin } from 'components/PluginBridge/PluginBridge'; import { PluginLink } from 'components/PluginLink/PluginLink'; import { Text } from 'components/Text/Text'; import { WithConfirm } from 'components/WithConfirm/WithConfirm'; @@ -26,9 +28,11 @@ import { PRIVATE_CHANNEL_NAME } from 'models/slack_channel/slack_channel.config' import { SlackChannel } from 'models/slack_channel/slack_channel.types'; import { AppFeature } from 'state/features'; import { WithStoreProps } from 'state/types'; +import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; import { UserActions } from 'utils/authorization/authorization'; import { DOCS_SLACK_SETUP, getPluginId } from 'utils/consts'; +import { useConfirmModal } from 'utils/hooks'; import { showApiError } from 'utils/utils'; import styles from './SlackSettings.module.css'; @@ -116,9 +120,12 @@ class _SlackSettings extends Component { slackChannelStore: { items: slackChannelItems }, } = store; + const isUnifiedSlackInstalled = !currentOrganization.slack_team_identity.needs_reinstall; + return (
Slack App settings + {currentOrganization.slack_team_identity.needs_reinstall && } @@ -147,33 +154,58 @@ class _SlackSettings extends Component { /> - -

Are you sure to delete this Slack Integration?

-

- Removing the integration will also irreverisbly remove the following data for your OnCall plugin: -

-
    -
  • default organization Slack channel
  • -
  • default Slack channels for OnCall Integrations
  • -
  • Slack channels & Slack user groups for OnCall Schedules
  • -
  • linked Slack usernames for OnCall Users
  • -
-
-

- If you would like to instead remove your linked Slack username, please head{' '} - here. -

- - } - confirmationText="DELETE" - > - -
+ {isUnifiedSlackInstalled ? ( + +

Are you sure to delete this Slack Integration? It will affect both OnCall & Incident.

+

Removing the integration will irreverisbly remove the following data for IRM;

+
    +
  • OnCall default Slack channel
  • +
  • Slack channels for OnCall escalation policies
  • +
  • Slack channels & Slack user groups for OnCall Schedules
  • +
  • linked Slack usernames for OnCall Users
  • +
  • Incident hooks
  • +
+
+ + } + confirmationText="DELETE" + > + +
+ ) : ( + +

Are you sure to delete this Slack Integration?

+

+ Removing the integration will also irreverisbly remove the following data for your OnCall plugin: +

+
    +
  • default organization Slack channel
  • +
  • default Slack channels for OnCall Integrations
  • +
  • Slack channels & Slack user groups for OnCall Schedules
  • +
  • linked Slack usernames for OnCall Users
  • +
+
+

+ If you would like to instead remove your linked Slack username, please head{' '} + here. +

+ + } + confirmationText="DELETE" + > + +
+ )}
Additional settings @@ -201,19 +233,20 @@ class _SlackSettings extends Component { - {currentOrganization.slack_team_identity.needs_reinstall && ( - <> - Unified Slack App - - - - - - + {isUnifiedSlackInstalled && ( + )}
); @@ -251,6 +284,7 @@ class _SlackSettings extends Component { const { store } = this.props; const { showENVVariablesButton } = this.state; const isLiveSettingAvailable = store.hasFeature(AppFeature.LiveSettings) && showENVVariablesButton; + const isUnifiedSlackEnabled = store.hasFeature(AppFeature.UnifiedSlack); return ( @@ -261,7 +295,9 @@ class _SlackSettings extends Component { - Connecting Slack App will allow you to manage alert groups in your team Slack workspace. + {isUnifiedSlackEnabled + ? 'Connecting Slack App will allow you to manage alert groups and incidents in your team Slack workspace.' + : 'Connecting Slack App will allow you to manage alert groups in your team Slack workspace.'} After a basic workspace connection your team members need to connect their personal Slack accounts in @@ -305,4 +341,61 @@ class _SlackSettings extends Component { }; } +const UpgradeToUnifiedSlackBanner = observer(() => { + const { + slackStore: { installSlackIntegration }, + } = useStore(); + const { modalProps, openModal } = useConfirmModal(); + + return ( + <> + + Upgrade} + > + We've rebranded the OnCall Slack app as the Grafana IRM Slack app, now with incident management features. +

Click "Upgrade" to reviewn and approve the new permissions and complete the process.

+

For more details, check our documentation.

+ +
+ + ); +}); + export const SlackSettings = withMobXProviderContext(_SlackSettings); diff --git a/grafana-plugin/src/state/features.ts b/grafana-plugin/src/state/features.ts index a5c5af265e..b36b0a1de8 100644 --- a/grafana-plugin/src/state/features.ts +++ b/grafana-plugin/src/state/features.ts @@ -1,5 +1,6 @@ export enum AppFeature { Slack = 'slack', + UnifiedSlack = 'unified_slack', Telegram = 'telegram', LiveSettings = 'live_settings', CloudNotifications = 'grafana_cloud_notifications',