When removing Slack ChatOps integration, warn the user of the implications (#1192)
# What this PR does - When removing Slack ChatOps integration, warn the user of the implications of doing so + make them confirm the deletion by having to type `DELETE`:  - remove `grafana-plugin/src/containers/SlackIntegrationButton/SlackIntegrationButton.tsx` component as it is not referenced anywhere + remove `grafana-plugin/src/img/slack_workspace_choose_attention.png` as this was only referenced in `SlackIntegrationButton.tsx` ## Which issue(s) this PR fixes https://github.com/grafana/oncall-private/issues/1588 ## Checklist - [ ] Tests updated (N/A) - [ ] Documentation added (N/A) - [x] `CHANGELOG.md` updated
This commit is contained in:
parent
46b39b2c87
commit
3bc593cdb2
5 changed files with 40 additions and 119 deletions
|
|
@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Changed
|
||||
|
||||
- Allow users with `viewer` role to fetch cloud connection status using the internal API ([#1181](https://github.com/grafana/oncall/pull/1181))
|
||||
- When removing the Slack ChatOps integration, make it more explicit to the user what the implications of doing so are
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
import React, { ReactElement, useCallback, useState } from 'react';
|
||||
|
||||
import { ConfirmModal } from '@grafana/ui';
|
||||
import { ConfirmModal, ConfirmModalProps } from '@grafana/ui';
|
||||
|
||||
interface WithConfirmProps {
|
||||
type WithConfirmProps = Partial<ConfirmModalProps> & {
|
||||
children: ReactElement;
|
||||
title?: string;
|
||||
body?: React.ReactNode;
|
||||
confirmText?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const WithConfirm = (props: WithConfirmProps) => {
|
||||
const { children, title = 'Are you sure to delete?', body, confirmText = 'Delete', disabled } = props;
|
||||
};
|
||||
|
||||
const WithConfirm: React.FC<WithConfirmProps> = ({
|
||||
title = 'Are you sure to delete?',
|
||||
confirmText = 'Delete',
|
||||
body,
|
||||
description,
|
||||
confirmationText,
|
||||
children,
|
||||
disabled,
|
||||
}) => {
|
||||
const [showConfirmation, setShowConfirmation] = useState<boolean>(false);
|
||||
|
||||
const onClickCallback = useCallback((event) => {
|
||||
|
|
@ -39,6 +42,8 @@ const WithConfirm = (props: WithConfirmProps) => {
|
|||
dismissText="Cancel"
|
||||
onConfirm={onConfirmCallback}
|
||||
body={body}
|
||||
description={description}
|
||||
confirmationText={confirmationText}
|
||||
onDismiss={() => {
|
||||
setShowConfirmation(false);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,97 +0,0 @@
|
|||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { Button, Modal } from '@grafana/ui';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import WithConfirm from 'components/WithConfirm/WithConfirm';
|
||||
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { UserActions } from 'utils/authorization';
|
||||
|
||||
const SlackIntegrationButton = observer((props: { className: string; disabled?: boolean }) => {
|
||||
const { className, disabled } = props;
|
||||
|
||||
const [showModal, setShowModal] = useState<boolean>(false);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const onInstallModalCallback = useCallback(() => {
|
||||
setShowModal(true);
|
||||
}, []);
|
||||
|
||||
const onInstallModalHideCallback = useCallback(() => {
|
||||
setShowModal(false);
|
||||
}, []);
|
||||
|
||||
const onRemoveClickCallback = useCallback(() => {
|
||||
store.slackStore.removeSlackIntegration().then(() => {
|
||||
store.teamStore.loadCurrentTeam();
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onInstallClickCallback = useCallback(() => {
|
||||
store.slackStore.installSlackIntegration();
|
||||
}, []);
|
||||
|
||||
if (store.teamStore.currentTeam?.slack_team_identity) {
|
||||
return (
|
||||
<WithPermissionControl userAction={UserActions.IntegrationsWrite}>
|
||||
<WithConfirm title="Are you sure to delete this Slack Integration?">
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="md"
|
||||
icon="slack"
|
||||
className={className}
|
||||
disabled={disabled}
|
||||
onClick={onRemoveClickCallback}
|
||||
>
|
||||
Remove Slack Integration ({store.teamStore.currentTeam.slack_team_identity?.cached_name})
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
</WithPermissionControl>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WithPermissionControl userAction={UserActions.IntegrationsWrite}>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="primary"
|
||||
icon="slack"
|
||||
className={className}
|
||||
disabled={disabled}
|
||||
onClick={onInstallModalCallback}
|
||||
>
|
||||
Connect Slack
|
||||
</Button>
|
||||
</WithPermissionControl>
|
||||
{showModal && <SlackModal onHide={onInstallModalHideCallback} onConfirm={onInstallClickCallback} />}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
interface SlackModalProps {
|
||||
onHide: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
const SlackModal = (props: SlackModalProps) => {
|
||||
const { onHide, onConfirm } = props;
|
||||
|
||||
return (
|
||||
<Modal title="Slack connection" closeOnEscape isOpen onDismiss={onHide}>
|
||||
<div style={{ textAlign: 'left' }}>
|
||||
You can view your Slack Workspace at the top-right corner after you are redirected. It should be a Workspace
|
||||
with App Bot installed:
|
||||
</div>
|
||||
<img
|
||||
style={{ height: '350px', display: 'block', margin: '0 auto' }}
|
||||
src="public/plugins/grafana-oncall-app/img/slack_workspace_choose_attention.png"
|
||||
/>
|
||||
<Button onClick={onConfirm}>I'll check! Proceed to Slack...</Button>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SlackIntegrationButton;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 42 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import { Field, HorizontalGroup, LoadingPlaceholder, VerticalGroup, Icon, Button } from '@grafana/ui';
|
||||
import { Alert, Field, HorizontalGroup, LoadingPlaceholder, VerticalGroup, Icon, Button } from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
|
|
@ -124,8 +124,30 @@ class SlackSettings extends Component<SlackProps, SlackState> {
|
|||
</WithPermissionControl>
|
||||
</Field>
|
||||
</HorizontalGroup>
|
||||
<WithPermissionControl userAction={UserActions.ChatOpsWrite}>
|
||||
<WithConfirm title="Are you sure to delete this Slack Integration?">
|
||||
<WithPermissionControl 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" size="sm" onClick={() => this.removeSlackIntegration()}>
|
||||
Disconnect
|
||||
</Button>
|
||||
|
|
@ -189,16 +211,6 @@ class SlackSettings extends Component<SlackProps, SlackState> {
|
|||
);
|
||||
};
|
||||
|
||||
renderActionButtons = () => {
|
||||
<WithPermissionControl userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
<WithConfirm title="Are you sure to delete this Slack Integration?">
|
||||
<Button variant="destructive" size="sm" onClick={() => this.removeSlackIntegration()}>
|
||||
Disconnect
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
</WithPermissionControl>;
|
||||
};
|
||||
|
||||
removeSlackIntegration = () => {
|
||||
const { store } = this.props;
|
||||
store.slackStore.removeSlackIntegration().then(() => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue