Polish unified slack ui (#4819)
# What this PR does polish ui of unified slack: - [x] New deprecation banner - [x] Move install/uninstall button to the top right corner - [x] New texts in migrate modal - [x] New text and layout in uninstall modal. ## Which issue(s) this PR closes Related to https://github.com/grafana/oncall-gateway/issues/299 <!-- *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 - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] 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.
This commit is contained in:
parent
a1c67cdfe7
commit
854dfd56a0
4 changed files with 150 additions and 117 deletions
|
|
@ -36,6 +36,10 @@
|
|||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.u-margin-left-xs {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.u-margin-bottom-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
@ -44,6 +48,10 @@
|
|||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.u-margin-bottom-xxs {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.u-margin-top-xs {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export const WithConfirm: React.FC<WithConfirmProps> = ({
|
|||
children,
|
||||
disabled,
|
||||
skip = false,
|
||||
modalClass,
|
||||
}) => {
|
||||
const [showConfirmation, setShowConfirmation] = useState<boolean>(false);
|
||||
|
||||
|
|
@ -57,6 +58,7 @@ export const WithConfirm: React.FC<WithConfirmProps> = ({
|
|||
onDismiss={() => {
|
||||
setShowConfirmation(false);
|
||||
}}
|
||||
modalClass={modalClass}
|
||||
/>
|
||||
)}
|
||||
{React.cloneElement(children, {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
.slack-infoblock {
|
||||
text-align: center;
|
||||
width: 725px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.external-link-style {
|
||||
|
|
@ -33,10 +33,9 @@
|
|||
.infoblock-text {
|
||||
margin-left: 48px;
|
||||
margin-right: 48px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.infoblock-icon {
|
||||
.marginTop {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
|
|
@ -47,10 +46,18 @@
|
|||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.upgradeSlackAlert svg {
|
||||
display: none;
|
||||
.upgradeSlackAlertText {
|
||||
margin-right: 110px;
|
||||
|
||||
a {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.linkToIncidentWrapper {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.confirmUninstallModal input {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import {
|
|||
Alert,
|
||||
HorizontalGroup,
|
||||
LoadingPlaceholder,
|
||||
VerticalGroup,
|
||||
Icon,
|
||||
Button,
|
||||
InlineField,
|
||||
Input,
|
||||
Legend,
|
||||
ConfirmModal,
|
||||
Stack,
|
||||
} from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observer } from 'mobx-react';
|
||||
|
|
@ -31,7 +31,7 @@ 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 { DOCS_ROOT, DOCS_SLACK_SETUP, getPluginId } from 'utils/consts';
|
||||
import { useConfirmModal } from 'utils/hooks';
|
||||
import { showApiError } from 'utils/utils';
|
||||
|
||||
|
|
@ -122,9 +122,74 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
|
||||
const isUnifiedSlackInstalled = !currentOrganization.slack_team_identity.needs_reinstall;
|
||||
|
||||
const uninstallSlackButton = (
|
||||
<WithPermissionControlTooltip userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
{isUnifiedSlackInstalled ? (
|
||||
<WithConfirm
|
||||
title="Uninstall IRM Slack integration"
|
||||
modalClass={styles.confirmUninstallModal}
|
||||
description={
|
||||
<div>
|
||||
<Alert severity="error" title="">
|
||||
Are you sure you want to remove this integration from OnCall and Incident?
|
||||
</Alert>
|
||||
<p>
|
||||
This action will uninstall the IRM Slack integration from OnCall and Incident. The following IRM data
|
||||
will be permanently deleted:
|
||||
</p>
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>OnCall default Slack channel</li>
|
||||
<li>Slack channels for OnCall escalation policies</li>
|
||||
<li>Slack channels and user groups for OnCall schedules</li>
|
||||
<li>Linked Slack profiles for OnCall users</li>
|
||||
<li>Incident announcement and automatic Slack channel creation</li>
|
||||
</ul>
|
||||
<br />
|
||||
</div>
|
||||
}
|
||||
confirmationText="UNINSTALL"
|
||||
confirmText="Uninstall"
|
||||
>
|
||||
<Button variant="destructive" fill="outline" onClick={() => this.removeSlackIntegration()}>
|
||||
Uninstall
|
||||
</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" fill="outline" onClick={() => this.removeSlackIntegration()}>
|
||||
Uninstall
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
)}
|
||||
</WithPermissionControlTooltip>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={cx('root')}>
|
||||
<Legend>Slack App settings</Legend>
|
||||
<Stack>
|
||||
<Legend>Slack OnCall settings</Legend>
|
||||
{uninstallSlackButton}
|
||||
</Stack>
|
||||
{currentOrganization.slack_team_identity.needs_reinstall && <UpgradeToUnifiedSlackBanner />}
|
||||
<InlineField label="Slack Workspace" grow disabled>
|
||||
<Input value={currentOrganization?.slack_team_identity?.cached_name} />
|
||||
|
|
@ -152,62 +217,6 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
severity="info"
|
||||
title="Tip: Create a separate channel for OnCall Slack App notifications (catch-all). Avoid using #general, etc."
|
||||
/>
|
||||
<InlineField>
|
||||
<WithPermissionControlTooltip userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
{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>
|
||||
<InlineField
|
||||
label="Timeout for acknowledged alerts"
|
||||
|
|
@ -287,56 +296,53 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
const isUnifiedSlackEnabled = store.hasFeature(AppFeature.UnifiedSlack);
|
||||
|
||||
return (
|
||||
<VerticalGroup spacing="lg">
|
||||
<Text.Title level={2}>Connect Slack workspace</Text.Title>
|
||||
<Stack gap={4} direction="column">
|
||||
<Stack justifyContent={'space-between'}>
|
||||
<Text.Title level={2}>Slack</Text.Title>
|
||||
{isLiveSettingAvailable ? (
|
||||
<PluginLink query={{ page: 'live-settings' }}>
|
||||
<Button variant="primary">Setup ENV Variables</Button>
|
||||
</PluginLink>
|
||||
) : (
|
||||
<Stack grow={0}>
|
||||
<Button onClick={this.handleOpenSlackInstructions}>Install integration</Button>
|
||||
{store.hasFeature(AppFeature.LiveSettings) && (
|
||||
<PluginLink query={{ page: 'live-settings' }}>
|
||||
<Button variant="secondary">See ENV Variables</Button>
|
||||
</PluginLink>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
<Block bordered withBackground className={cx('slack-infoblock')}>
|
||||
<VerticalGroup align="center">
|
||||
<div className={cx('infoblock-icon')}>
|
||||
<Stack direction="column" alignItems="center" gap={0}>
|
||||
<div className={cx('marginTop')}>
|
||||
<SlackNewIcon />
|
||||
</div>
|
||||
<Text className={cx('infoblock-text')}>
|
||||
<Text className={cx(['infoblock-text', 'marginTop'])}>
|
||||
{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
|
||||
order to be allowed to manage alert groups.
|
||||
Once the workspace is connected, team members need to link their Slack accounts to their IRM users to
|
||||
start using the app.
|
||||
</Text>
|
||||
{isLiveSettingAvailable && (
|
||||
<Text type="secondary" className={cx('infoblock-text')}>
|
||||
<Text type="secondary" className={cx('infoblock-text', 'marginTop')}>
|
||||
For bot creating instructions and additional information please read{' '}
|
||||
<a href={DOCS_SLACK_SETUP} target="_blank" rel="noreferrer">
|
||||
<Text type="link">our documentation</Text>
|
||||
</a>
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<img
|
||||
style={{ height: '350px', display: 'block', margin: '0 auto' }}
|
||||
src={`public/plugins/${getPluginId()}/assets/img/slack_instructions.png`}
|
||||
/>
|
||||
</VerticalGroup>
|
||||
</Stack>
|
||||
</Block>
|
||||
{isLiveSettingAvailable ? (
|
||||
<PluginLink query={{ page: 'live-settings' }}>
|
||||
<Button variant="primary">Setup ENV Variables</Button>
|
||||
</PluginLink>
|
||||
) : (
|
||||
<HorizontalGroup>
|
||||
<Button onClick={this.handleOpenSlackInstructions}>
|
||||
<HorizontalGroup spacing="xs" align="center">
|
||||
<Icon name="external-link-alt" className={cx('external-link-style')} /> Open Slack connection page
|
||||
</HorizontalGroup>
|
||||
</Button>
|
||||
{store.hasFeature(AppFeature.LiveSettings) && (
|
||||
<PluginLink query={{ page: 'live-settings' }}>
|
||||
<Button variant="secondary">See ENV Variables</Button>
|
||||
</PluginLink>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
)}
|
||||
</VerticalGroup>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -350,48 +356,58 @@ const UpgradeToUnifiedSlackBanner = observer(() => {
|
|||
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>
|
||||
<Alert severity="warning" title="This integration is outdated" buttonContent="Migrate">
|
||||
<div className={styles.upgradeSlackAlertText}>
|
||||
The OnCall Slack app is now a Grafana IRM app with new incident management features. Migrate now to access the
|
||||
enhanced capabilities.{' '}
|
||||
<a href={`${DOCS_ROOT}`} target="_blank" rel="noreferrer">
|
||||
{/* TODO: update link to docs */}
|
||||
Learn more
|
||||
</a>
|
||||
</div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className={styles.upgradeSlackBtn}
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
openModal({
|
||||
confirmText: 'Confirm',
|
||||
confirmText: 'Migrate',
|
||||
onConfirm: installSlackIntegration,
|
||||
confirmButtonVariant: 'primary',
|
||||
title: `Upgrade to Grafana IRM Slack app`,
|
||||
title: `Migrate to Grafana IRM Slack integration`,
|
||||
description: (
|
||||
<div>
|
||||
<p>
|
||||
You will be redirected to Slack to approve additional permissions for the Grafana IRM Slack app.{' '}
|
||||
You will be redirected to Slack to approve additional permissions for the Grafana IRM Slack app. New
|
||||
permissions are necessary for incident management features.
|
||||
</p>
|
||||
<p>After the migration, you can use OnCall and Incident features in a single app:</p>
|
||||
<p>
|
||||
These permissions are necessary for incident management. You can view the detailed list of new
|
||||
permissions here.[LINK]
|
||||
<ul style={{ marginLeft: '20px' }}>
|
||||
<li>The OnCall Slack configuration will remain intact.</li>
|
||||
<li>
|
||||
The Incident Slack integration will be upgraded to Grafana IRM Slack. Announcement and Create
|
||||
Slack Channel hooks will be migrated, active incident can still be managed.
|
||||
</li>
|
||||
</ul>
|
||||
</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>
|
||||
<a
|
||||
href={`${DOCS_ROOT}`} // TODO: update link to docs
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={styles.marginTop}
|
||||
>
|
||||
<Text type="link">
|
||||
<span>Learn more in the docs</span>
|
||||
<Icon name="external-link-alt" className="u-margin-left-xs u-margin-bottom-xxs" />
|
||||
</Text>
|
||||
</a>
|
||||
</div>
|
||||
),
|
||||
confirmVariant: 'secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
Upgrade
|
||||
Migrate
|
||||
</Button>
|
||||
</Alert>
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue