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. <!-- *Note*: If you want the issue to be auto-closed once the PR is merged, change "Related to" to "Closes" in the line above. If you have more than one GitHub issue that this PR closes, be sure to preface each issue link with a [closing keyword](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests#linking-a-pull-request-to-an-issue). This ensures that the issue(s) are auto-closed once the PR has been merged. --> ## 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 <innokenty.konstantinov@grafana.com>
This commit is contained in:
parent
fbd68b10f3
commit
a332011f1e
5 changed files with 155 additions and 42 deletions
|
|
@ -15,6 +15,7 @@ from apps.labels.utils import is_labels_feature_enabled
|
|||
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 @@ class FeaturesAPIView(APIView):
|
|||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SlackProps, SlackState> {
|
|||
slackChannelStore: { items: slackChannelItems },
|
||||
} = store;
|
||||
|
||||
const isUnifiedSlackInstalled = !currentOrganization.slack_team_identity.needs_reinstall;
|
||||
|
||||
return (
|
||||
<div className={cx('root')}>
|
||||
<Legend>Slack App settings</Legend>
|
||||
{currentOrganization.slack_team_identity.needs_reinstall && <UpgradeToUnifiedSlackBanner />}
|
||||
<InlineField label="Slack Workspace" grow disabled>
|
||||
<Input value={currentOrganization?.slack_team_identity?.cached_name} />
|
||||
</InlineField>
|
||||
|
|
@ -147,33 +154,58 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
/>
|
||||
<InlineField>
|
||||
<WithPermissionControlTooltip userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
<WithConfirm
|
||||
title="Remove Slack Integration for all of OnCall"
|
||||
description={
|
||||
<Alert severity="error" title="WARNING">
|
||||
<p>Are you sure to delete this Slack Integration?</p>
|
||||
<p>
|
||||
Removing the integration will also irreverisbly remove the following data for your OnCall plugin:
|
||||
</p>
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>default organization Slack channel</li>
|
||||
<li>default Slack channels for OnCall Integrations</li>
|
||||
<li>Slack channels & Slack user groups for OnCall Schedules</li>
|
||||
<li>linked Slack usernames for OnCall Users</li>
|
||||
</ul>
|
||||
<br />
|
||||
<p>
|
||||
If you would like to instead remove your linked Slack username, please head{' '}
|
||||
<PluginLink query={{ page: 'users/me' }}>here</PluginLink>.
|
||||
</p>
|
||||
</Alert>
|
||||
}
|
||||
confirmationText="DELETE"
|
||||
>
|
||||
<Button variant="destructive" onClick={() => this.removeSlackIntegration()}>
|
||||
Disconnect Slack App
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
{isUnifiedSlackInstalled ? (
|
||||
<WithConfirm
|
||||
title="Remove IRM Slack integration"
|
||||
description={
|
||||
<Alert severity="error" title="WARNING">
|
||||
<p>Are you sure to delete this Slack Integration? It will affect both OnCall & Incident.</p>
|
||||
<p>Removing the integration will irreverisbly remove the following data for IRM;</p>
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>OnCall default Slack channel</li>
|
||||
<li>Slack channels for OnCall escalation policies</li>
|
||||
<li>Slack channels & Slack user groups for OnCall Schedules</li>
|
||||
<li>linked Slack usernames for OnCall Users</li>
|
||||
<li>Incident hooks</li>
|
||||
</ul>
|
||||
<br />
|
||||
</Alert>
|
||||
}
|
||||
confirmationText="DELETE"
|
||||
>
|
||||
<Button variant="destructive" onClick={() => this.removeSlackIntegration()}>
|
||||
Disconnect Slack App
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
) : (
|
||||
<WithConfirm
|
||||
title="Remove Slack Integration for all of OnCall"
|
||||
description={
|
||||
<Alert severity="error" title="WARNING">
|
||||
<p>Are you sure to delete this Slack Integration?</p>
|
||||
<p>
|
||||
Removing the integration will also irreverisbly remove the following data for your OnCall plugin:
|
||||
</p>
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>default organization Slack channel</li>
|
||||
<li>default Slack channels for OnCall Integrations</li>
|
||||
<li>Slack channels & Slack user groups for OnCall Schedules</li>
|
||||
<li>linked Slack usernames for OnCall Users</li>
|
||||
</ul>
|
||||
<br />
|
||||
<p>
|
||||
If you would like to instead remove your linked Slack username, please head{' '}
|
||||
<PluginLink query={{ page: 'users/me' }}>here</PluginLink>.
|
||||
</p>
|
||||
</Alert>
|
||||
}
|
||||
confirmationText="DELETE"
|
||||
>
|
||||
<Button variant="destructive" onClick={() => this.removeSlackIntegration()}>
|
||||
Disconnect Slack App
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
)}
|
||||
</WithPermissionControlTooltip>
|
||||
</InlineField>
|
||||
<Legend>Additional settings</Legend>
|
||||
|
|
@ -201,19 +233,20 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
</WithPermissionControlTooltip>
|
||||
</HorizontalGroup>
|
||||
</InlineField>
|
||||
{currentOrganization.slack_team_identity.needs_reinstall && (
|
||||
<>
|
||||
<Legend>Unified Slack App</Legend>
|
||||
<InlineField>
|
||||
<WithPermissionControlTooltip userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
<Button onClick={this.handleOpenSlackInstructions}>
|
||||
<HorizontalGroup spacing="xs" align="center">
|
||||
<Icon name="external-link-alt" className={cx('external-link-style')} /> Reinstall Slack App
|
||||
</HorizontalGroup>
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</InlineField>
|
||||
</>
|
||||
{isUnifiedSlackInstalled && (
|
||||
<div className={styles.linkToIncidentWrapper}>
|
||||
<PluginBridge plugin={SupportedPlugin.Incident}>
|
||||
<Text type="secondary">
|
||||
<a
|
||||
href={`/a/${SupportedPlugin.Incident}/integrations/grate.irm.slack`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Text type="link">Open Slack Incident settings</Text>
|
||||
</a>
|
||||
</Text>
|
||||
</PluginBridge>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -251,6 +284,7 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
const { store } = this.props;
|
||||
const { showENVVariablesButton } = this.state;
|
||||
const isLiveSettingAvailable = store.hasFeature(AppFeature.LiveSettings) && showENVVariablesButton;
|
||||
const isUnifiedSlackEnabled = store.hasFeature(AppFeature.UnifiedSlack);
|
||||
|
||||
return (
|
||||
<VerticalGroup spacing="lg">
|
||||
|
|
@ -261,7 +295,9 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
<SlackNewIcon />
|
||||
</div>
|
||||
<Text className={cx('infoblock-text')}>
|
||||
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.'}
|
||||
</Text>
|
||||
<Text className={cx('infoblock-text')}>
|
||||
After a basic workspace connection your team members need to connect their personal Slack accounts in
|
||||
|
|
@ -305,4 +341,61 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
};
|
||||
}
|
||||
|
||||
const UpgradeToUnifiedSlackBanner = observer(() => {
|
||||
const {
|
||||
slackStore: { installSlackIntegration },
|
||||
} = useStore();
|
||||
const { modalProps, openModal } = useConfirmModal();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmModal {...modalProps} />
|
||||
<Alert
|
||||
className={styles.upgradeSlackAlert}
|
||||
severity="success"
|
||||
title="Upgrade to Grafana IRM unified Slack app"
|
||||
buttonContent={<div>Upgrade</div>}
|
||||
>
|
||||
We've rebranded the OnCall Slack app as the Grafana IRM Slack app, now with incident management features.
|
||||
<p>Click "Upgrade" to reviewn and approve the new permissions and complete the process.</p>
|
||||
<p>For more details, check our documentation.</p>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className={styles.upgradeSlackBtn}
|
||||
onClick={() =>
|
||||
openModal({
|
||||
confirmText: 'Confirm',
|
||||
onConfirm: installSlackIntegration,
|
||||
confirmButtonVariant: 'primary',
|
||||
title: `Upgrade to Grafana IRM Slack app`,
|
||||
description: (
|
||||
<div>
|
||||
<p>
|
||||
You will be redirected to Slack to approve additional permissions for the Grafana IRM Slack app.{' '}
|
||||
</p>
|
||||
<p>
|
||||
These permissions are necessary for incident management. You can view the detailed list of new
|
||||
permissions here.[LINK]
|
||||
</p>
|
||||
<p>After the upgrade, you'll be able to manage incidents in Slack using the Grafana IRM Slack app.</p>
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>Your OnCall Slack configuration will remain unchanged. </li>
|
||||
<li>
|
||||
Your Incident Slack integration will be upgraded to use the Grafana IRM Slack app. Please refer to
|
||||
the documentation for more details.[LINK]
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
),
|
||||
confirmVariant: 'secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
Upgrade
|
||||
</Button>
|
||||
</Alert>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export const SlackSettings = withMobXProviderContext(_SlackSettings);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export enum AppFeature {
|
||||
Slack = 'slack',
|
||||
UnifiedSlack = 'unified_slack',
|
||||
Telegram = 'telegram',
|
||||
LiveSettings = 'live_settings',
|
||||
CloudNotifications = 'grafana_cloud_notifications',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue