From d182e71f62c77be489aa50865f4320fccac4b771 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Thu, 2 Mar 2023 17:32:59 +0200 Subject: [PATCH] =?UTF-8?q?fix=20for=20#1273,=20added=20component=20for=20?= =?UTF-8?q?showing=20permission=20restricted=20acce=E2=80=A6=20(#1422)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What this PR does - Removed unused code - Added another component for displaying Error Messages based on permissions access (so that we do not duplicate this code everywhere it's needed) - Fix for #1273 ## Which issue(s) this PR fixes - #1273 ## Checklist - [ ] Tests updated - [ ] Documentation added - [ ] `CHANGELOG.md` updated --- CHANGELOG.md | 6 ++ .../AlertTemplates/AlertTemplatesForm.tsx | 10 +-- .../NewScheduleSelector.tsx | 6 +- .../components/Policy/EscalationPolicy.tsx | 62 ++++++++++++------- .../components/Policy/NotificationPolicy.tsx | 22 +++---- .../src/containers/AlertRules/AlertRules.tsx | 50 +++++++-------- .../parts/connectors/SlackConnector.tsx | 18 +++--- .../parts/connectors/TelegramConnector.tsx | 10 +-- .../ApiTokenSettings/ApiTokenSettings.tsx | 10 +-- .../AttachIncidentForm/AttachIncidentForm.tsx | 6 +- .../EscalationChainSteps.tsx | 6 +- .../EscalationVariants/EscalationVariants.tsx | 10 +-- .../GrafanaTeamSelect/GrafanaTeamSelect.tsx | 6 +- .../HeartbeatModal/HeartbeatForm.tsx | 10 +-- .../IntegrationSettings/parts/Autoresolve.tsx | 6 +- .../MaintenanceForm/MaintenanceForm.tsx | 6 +- .../MobileAppConnection.tsx | 16 ++--- .../OutgoingWebhookForm.tsx | 6 +- .../PersonalNotificationSettings.tsx | 6 +- .../src/containers/Rotations/Rotations.tsx | 6 +- .../Rotations/ScheduleOverrides.tsx | 6 +- .../containers/ScheduleForm/ScheduleForm.tsx | 6 +- .../TelegramIntegrationButton.tsx | 6 +- .../parts/connectors/ICalConnector.tsx | 10 +-- .../CloudPhoneSettings/CloudPhoneSettings.tsx | 16 ++--- .../PhoneVerification/PhoneVerification.tsx | 18 +++--- .../parts/tabs/TelegramInfo/TelegramInfo.tsx | 9 ++- .../WithPermissionControlDisplay.tsx | 28 +++++++++ ...> WithPermissionControlTooltip.module.css} | 0 ...l.tsx => WithPermissionControlTooltip.tsx} | 6 +- .../WithPermissionControl.tsx | 30 --------- .../escalation-chains/EscalationChains.tsx | 18 +++--- .../src/pages/incident/Incident.helpers.tsx | 22 +++---- .../src/pages/incident/Incident.tsx | 10 +-- .../src/pages/incident/parts/PagedUsers.tsx | 6 +- .../src/pages/incidents/Incidents.tsx | 22 +++---- .../incidents/parts/IncidentDropdown.tsx | 34 +++++----- .../incidents/parts/SilenceButtonCascader.tsx | 6 +- .../pages/incidents/parts/SilenceSelect.tsx | 6 +- .../src/pages/integrations/Integrations.tsx | 10 +-- .../src/pages/maintenance/Maintenance.tsx | 10 +-- .../outgoing_webhooks/OutgoingWebhooks.tsx | 14 ++--- grafana-plugin/src/pages/routes.tsx | 5 -- .../src/pages/schedules/Schedules.tsx | 14 ++--- .../tabs/SlackSettings/SlackSettings.tsx | 22 +++---- .../tabs/LiveSettings/LiveSettingsPage.tsx | 6 +- .../tabs/MainSettings/MainSettings.tsx | 6 +- grafana-plugin/src/pages/test/Test.module.css | 3 - grafana-plugin/src/pages/test/Test.tsx | 28 --------- grafana-plugin/src/pages/users/Users.tsx | 6 +- .../src/plugin/GrafanaPluginRootPage.tsx | 4 -- 51 files changed, 325 insertions(+), 340 deletions(-) create mode 100644 grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlDisplay.tsx rename grafana-plugin/src/containers/WithPermissionControl/{WithPermissionControl.module.css => WithPermissionControlTooltip.module.css} (100%) rename grafana-plugin/src/containers/WithPermissionControl/{WithPermissionControl.tsx => WithPermissionControlTooltip.tsx} (85%) delete mode 100644 grafana-plugin/src/containers/WithPermissionControl2/WithPermissionControl.tsx delete mode 100644 grafana-plugin/src/pages/test/Test.module.css delete mode 100644 grafana-plugin/src/pages/test/Test.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8488525f..ce4e3096ed 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 + +- Show permission error for accessing Telegram as Viewer ([1273](https://github.com/grafana/oncall/issues/1273)) + ## v1.1.32 (2023-03-01) ### Fixed diff --git a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx index ec175eec23..9cef300f08 100644 --- a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx +++ b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx @@ -13,7 +13,7 @@ import MonacoJinja2Editor from 'components/MonacoJinja2Editor/MonacoJinja2Editor import SourceCode from 'components/SourceCode/SourceCode'; import Text from 'components/Text/Text'; import TemplatePreview from 'containers/TemplatePreview/TemplatePreview'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; import { Alert } from 'models/alertgroup/alertgroup.types'; import { makeRequest } from 'network'; @@ -153,11 +153,11 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => { There are no alerts from this monitoring yet. {demoAlertEnabled ? ( - + - + ) : null} ); @@ -240,11 +240,11 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => { ))} - + - + diff --git a/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx b/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx index b9beecb335..b1c76f5983 100644 --- a/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx +++ b/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx @@ -6,7 +6,7 @@ import cn from 'classnames/bind'; import Block from 'components/GBlock/Block'; import Text from 'components/Text/Text'; import ScheduleForm from 'containers/ScheduleForm/ScheduleForm'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Schedule, ScheduleType } from 'models/schedule/schedule.types'; import { UserActions } from 'utils/authorization'; @@ -49,11 +49,11 @@ const NewScheduleSelector: FC = (props) => { Configure rotations and shifts directly in Grafana On-Call - + - + diff --git a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx index 3f01158e5d..027f9edcbd 100644 --- a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx @@ -12,7 +12,7 @@ import TimeRange from 'components/TimeRange/TimeRange'; import Timeline from 'components/Timeline/Timeline'; import GSelect from 'containers/GSelect/GSelect'; import UserTooltip from 'containers/UserTooltip/UserTooltip'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { prepareEscalationPolicy } from 'models/escalation_policy/escalation_policy.helpers'; import { EscalationPolicy as EscalationPolicyType, @@ -53,14 +53,14 @@ export class EscalationPolicy extends React.Component - + - + {escalationOption && reactStringReplace(escalationOption.display_name, /\{\{([^}]+)\}\}/g, this.replacePlaceholder)} {this._renderNote()} {is_final ? null : ( - + - + )} ); @@ -134,7 +134,11 @@ export class EscalationPolicy extends React.Component + } /> - + ); } @@ -157,7 +161,7 @@ export class EscalationPolicy extends React.Component + - + ); } @@ -215,7 +219,11 @@ export class EscalationPolicy extends React.Component + - + ); } @@ -237,7 +245,7 @@ export class EscalationPolicy extends React.Component - + ); } @@ -263,7 +271,11 @@ export class EscalationPolicy extends React.Component + - + ); } @@ -285,7 +297,11 @@ export class EscalationPolicy extends React.Component + - + ); } @@ -304,7 +320,7 @@ export class EscalationPolicy extends React.Component + - + ); } diff --git a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx index b51c0d90b1..bc97f132d6 100644 --- a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx @@ -7,7 +7,7 @@ import { SortableElement } from 'react-sortable-hoc'; import PluginLink from 'components/PluginLink/PluginLink'; import Timeline from 'components/Timeline/Timeline'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Channel } from 'models/channel'; import { NotificationPolicyType, prepareNotificationPolicy } from 'models/notification_policy'; import { NotifyBy } from 'models/notify_by'; @@ -51,26 +51,26 @@ export class NotificationPolicy extends React.Component
- + - - + + - + ); } @@ -185,7 +185,7 @@ export class NotificationPolicy extends React.Component + { }))} value={null} /> - + ); diff --git a/grafana-plugin/src/containers/EscalationVariants/EscalationVariants.tsx b/grafana-plugin/src/containers/EscalationVariants/EscalationVariants.tsx index bc5be6b5b0..f4f5e46ff7 100644 --- a/grafana-plugin/src/containers/EscalationVariants/EscalationVariants.tsx +++ b/grafana-plugin/src/containers/EscalationVariants/EscalationVariants.tsx @@ -9,7 +9,7 @@ import { observer } from 'mobx-react'; import Avatar from 'components/Avatar/Avatar'; import Text from 'components/Text/Text'; import UserWarning from 'containers/UserWarningModal/UserWarning'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { getTzOffsetString } from 'models/timezone/timezone.helpers'; import { User } from 'models/user/user.types'; import { UserActions } from 'utils/authorization'; @@ -125,7 +125,7 @@ const EscalationVariants = observer( )}
- + Add responders - - + + - +
{showEscalationVariants && ( diff --git a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx index 7d3f25a46c..fd786b31bf 100644 --- a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx +++ b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import ReactDOM from 'react-dom'; import GSelect from 'containers/GSelect/GSelect'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { GrafanaTeam } from 'models/grafana_team/grafana_team.types'; import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers'; import { useStore } from 'state/useStore'; @@ -44,11 +44,11 @@ const GrafanaTeamSelect = observer(() => { - + Edit teams - +

OnCall will issue an incident if no alert is received every - + - + {autoresolveSelected && ( <> diff --git a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.tsx b/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.tsx index 67a04b5467..37619b42e5 100644 --- a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.tsx +++ b/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import GForm from 'components/GForm/GForm'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; import { MaintenanceType } from 'models/maintenance/maintenance.types'; import { useStore } from 'state/useStore'; @@ -65,11 +65,11 @@ const MaintenanceForm = observer((props: MaintenanceFormProps) => {

- + - +
diff --git a/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx b/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx index a7335139d1..06f07aaa7b 100644 --- a/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx +++ b/grafana-plugin/src/containers/MobileAppConnection/MobileAppConnection.tsx @@ -8,10 +8,11 @@ import qrCodeImage from 'assets/img/qr-code.png'; import Block from 'components/GBlock/Block'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; +import { WithPermissionControlDisplay } from 'containers/WithPermissionControl/WithPermissionControlDisplay'; import { User } from 'models/user/user.types'; import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; -import { isUserActionAllowed, UserActions } from 'utils/authorization'; +import { UserActions } from 'utils/authorization'; import { GRAFANA_LICENSE_OSS } from 'utils/consts'; import styles from './MobileAppConnection.module.scss'; @@ -41,18 +42,17 @@ const MobileAppConnection = observer(({ userPk }: Props) => { return ( Please connect Cloud OnCall to use the mobile app - {isUserActionAllowed(UserActions.OtherSettingsWrite) ? ( + - ) : ( - - You do not have permission to perform this action. Ask an admin to connect Cloud OnCall or upgrade your - permissions. - - )} + ); } diff --git a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx index ff96a67f32..c68673f342 100644 --- a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx +++ b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import GForm from 'components/GForm/GForm'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { OutgoingWebhook } from 'models/outgoing_webhook/outgoing_webhook.types'; import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization'; @@ -56,11 +56,11 @@ const OutgoingWebhookForm = observer((props: OutgoingWebhookFormProps) => { >
- + - +
); diff --git a/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx b/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx index ac5264060a..498d2410e7 100644 --- a/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx +++ b/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx @@ -9,7 +9,7 @@ import NotificationPolicy from 'components/Policy/NotificationPolicy'; import SortableList from 'components/SortableList/SortableList'; import Text from 'components/Text/Text'; import Timeline from 'components/Timeline/Timeline'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { NotificationPolicyType } from 'models/notification_policy'; import { User as UserType } from 'models/user/user.types'; import { AppFeature } from 'state/features'; @@ -154,11 +154,11 @@ const PersonalNotificationSettings = observer((props: PersonalNotificationSettin ))}
- + - +
diff --git a/grafana-plugin/src/containers/Rotations/Rotations.tsx b/grafana-plugin/src/containers/Rotations/Rotations.tsx index ec1a65a3ec..882fdebbae 100644 --- a/grafana-plugin/src/containers/Rotations/Rotations.tsx +++ b/grafana-plugin/src/containers/Rotations/Rotations.tsx @@ -11,7 +11,7 @@ import Text from 'components/Text/Text'; import TimelineMarks from 'components/TimelineMarks/TimelineMarks'; import Rotation from 'containers/Rotation/Rotation'; import RotationForm from 'containers/RotationForm/RotationForm'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { getColor, getFromString } from 'models/schedule/schedule.helpers'; import { Layer, Schedule, ScheduleType, Shift } from 'models/schedule/schedule.types'; import { Timezone } from 'models/timezone/timezone.types'; @@ -112,11 +112,11 @@ class Rotations extends Component { ) : ( - + - + ) ) : ( ) : ( - + - + )} diff --git a/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx b/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx index a926fb4c4c..f43956dfde 100644 --- a/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx +++ b/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import GForm from 'components/GForm/GForm'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Schedule, ScheduleType } from 'models/schedule/schedule.types'; import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization'; @@ -77,11 +77,11 @@ const ScheduleForm = observer((props: ScheduleFormProps) => {
- + - +
diff --git a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx index 1d1494cb6c..6c993f9947 100644 --- a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx +++ b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx @@ -7,7 +7,7 @@ import CopyToClipboard from 'react-copy-to-clipboard'; import Block from 'components/GBlock/Block'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { useStore } from 'state/useStore'; import { openNotification } from 'utils'; import { UserActions } from 'utils/authorization'; @@ -43,11 +43,11 @@ const TelegramIntegrationButton = observer((props: TelegramIntegrationProps) => return ( <> - + - + {showModal && } ); diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx index d9fe2d3add..db7c46df78 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx @@ -5,7 +5,7 @@ import cn from 'classnames/bind'; import CopyToClipboard from 'react-copy-to-clipboard'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { User } from 'models/user/user.types'; import { useStore } from 'state/useStore'; import { openNotification } from 'utils'; @@ -88,7 +88,7 @@ const ICalConnector = (props: ICalConnectorProps) => { In case you lost your iCal link you can revoke it and generate a new one. - + - + )} ) : ( - + - + )} )} diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx index e6502cc5e4..a500ff34e4 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx @@ -5,12 +5,13 @@ import { observer } from 'mobx-react'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; +import { WithPermissionControlDisplay } from 'containers/WithPermissionControl/WithPermissionControlDisplay'; import { User } from 'models/user/user.types'; import { AppFeature } from 'state/features'; import { WithStoreProps } from 'state/types'; import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; -import { isUserActionAllowed, UserActions } from 'utils/authorization'; +import { UserActions } from 'utils/authorization'; interface CloudPhoneSettingsProps extends WithStoreProps { userPk?: User['pk']; @@ -119,7 +120,11 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { return ( <> - {isUserActionAllowed(UserActions.OtherSettingsWrite) ? ( + OnCall uses Grafana Cloud for SMS and phone call notifications @@ -135,12 +140,7 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { {!syncing ? : } - ) : ( - - OnCall uses Grafana Cloud for SMS and phone call notifications - You do not have permission to perform this action. Ask an admin to upgrade your permissions. - - )} + ); }); diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx index b28fbe5a8c..8393a2c84b 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { User } from 'models/user/user.types'; import { rootStore } from 'state'; import { AppFeature } from 'state/features'; @@ -180,7 +180,7 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => { invalid={showPhoneInputError} error={showPhoneInputError ? 'Enter a valid phone number' : null} > - + { value={phone} onChange={onChangePhoneCallback} /> - + {!user.verified_phone_number && ( {showVerifyOrSendCodeButton && ( - + - + )} {showForgetNumber && ( - + - + )} {user.verified_phone_number && ( <> - + - + { }, []); return ( - <> + {telegramConfigured || !store.hasFeature(AppFeature.LiveSettings) ? ( Manual connection @@ -96,7 +101,7 @@ const TelegramInfo = observer((_props: TelegramInfoProps) => { )} )} - + ); }); diff --git a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlDisplay.tsx b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlDisplay.tsx new file mode 100644 index 0000000000..c8ffed9ca8 --- /dev/null +++ b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlDisplay.tsx @@ -0,0 +1,28 @@ +import React, { ReactElement } from 'react'; + +import { VerticalGroup } from '@grafana/ui'; + +import Text from 'components/Text/Text'; +import { isUserActionAllowed, UserAction } from 'utils/authorization'; + +interface WithPermissionControlDisplayProps { + userAction: UserAction; + children: ReactElement; + message: string; + title?: string; +} + +export const WithPermissionControlDisplay: React.FC = (props) => { + const { userAction, children, title, message } = props; + + const hasPermission = isUserActionAllowed(userAction); + + return hasPermission ? ( + children + ) : ( + + {title && {title}} + {message} + + ); +}; diff --git a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.module.css b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlTooltip.module.css similarity index 100% rename from grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.module.css rename to grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlTooltip.module.css diff --git a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlTooltip.tsx similarity index 85% rename from grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx rename to grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlTooltip.tsx index 1165d37641..4d419215b6 100644 --- a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx +++ b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControlTooltip.tsx @@ -6,18 +6,18 @@ import { observer } from 'mobx-react'; import { isUserActionAllowed, UserAction } from 'utils/authorization'; -import styles from './WithPermissionControl.module.css'; +import styles from './WithPermissionControlTooltip.module.css'; const cx = cn.bind(styles); -interface WithPermissionControlProps { +interface WithPermissionControlTooltipProps { userAction: UserAction; children: ReactElement; disableByPaywall?: boolean; className?: string; } -export const WithPermissionControl = observer((props: WithPermissionControlProps) => { +export const WithPermissionControlTooltip = observer((props: WithPermissionControlTooltipProps) => { const { userAction, children, className } = props; const disabledByPermissions = !isUserActionAllowed(userAction); diff --git a/grafana-plugin/src/containers/WithPermissionControl2/WithPermissionControl.tsx b/grafana-plugin/src/containers/WithPermissionControl2/WithPermissionControl.tsx deleted file mode 100644 index a3dd5b0bbd..0000000000 --- a/grafana-plugin/src/containers/WithPermissionControl2/WithPermissionControl.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { ReactElement, useMemo } from 'react'; - -import { Tooltip } from '@grafana/ui'; -import { observer } from 'mobx-react'; - -import { isUserActionAllowed, UserAction } from 'utils/authorization'; - -interface WithPermissionControlProps { - userAction: UserAction; - children: (disabled?: boolean) => ReactElement; -} - -export const WithPermissionControl = observer((props: WithPermissionControlProps) => { - const { userAction, children } = props; - - const disabled = !isUserActionAllowed(userAction); - - const element = useMemo(() => children(disabled), [disabled]); - - return disabled ? ( - - {element} - - ) : ( - element - ); -}); diff --git a/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx b/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx index 61274d4a97..71b7cfa840 100644 --- a/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx +++ b/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx @@ -23,7 +23,7 @@ import WithConfirm from 'components/WithConfirm/WithConfirm'; import EscalationChainCard from 'containers/EscalationChainCard/EscalationChainCard'; import EscalationChainForm from 'containers/EscalationChainForm/EscalationChainForm'; import EscalationChainSteps from 'containers/EscalationChainSteps/EscalationChainSteps'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'; import { PageProps, WithStoreProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; @@ -161,7 +161,7 @@ class EscalationChainsPage extends React.Component
- + - +
{searchResult ? ( No escalations found, check your filtering and current team. - + - + } /> @@ -272,7 +272,7 @@ class EscalationChainsPage extends React.Component
- + - - + + 0} @@ -295,7 +295,7 @@ class EscalationChainsPage extends React.Component - + {escalationChain.number_of_integrations > 0 && ( diff --git a/grafana-plugin/src/pages/incident/Incident.helpers.tsx b/grafana-plugin/src/pages/incident/Incident.helpers.tsx index cd3e70b15b..25908a4872 100644 --- a/grafana-plugin/src/pages/incident/Incident.helpers.tsx +++ b/grafana-plugin/src/pages/incident/Incident.helpers.tsx @@ -8,7 +8,7 @@ import { MatchMediaTooltip } from 'components/MatchMediaTooltip/MatchMediaToolti import PluginLink from 'components/PluginLink/PluginLink'; import Tag from 'components/Tag/Tag'; import Text from 'components/Text/Text'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { MaintenanceIntegration } from 'models/alert_receive_channel'; import { Alert as AlertType, Alert, IncidentStatus } from 'models/alertgroup/alertgroup.types'; import { User } from 'models/user/user.types'; @@ -154,35 +154,35 @@ export function getActionButtons(incident: AlertType, cx: any, callbacks: { [key const { onResolve, onUnresolve, onAcknowledge, onUnacknowledge, onSilence, onUnsilence } = callbacks; const resolveButton = ( - + - + ); const unacknowledgeButton = ( - + - + ); const unresolveButton = ( - + - + ); const acknowledgeButton = ( - + - + ); const buttons = []; @@ -201,11 +201,11 @@ export function getActionButtons(incident: AlertType, cx: any, callbacks: { [key if (incident.status === IncidentStatus.Silenced) { buttons.push( - + - + ); } diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx index aec75be1ac..cb728f7e5e 100644 --- a/grafana-plugin/src/pages/incident/Incident.tsx +++ b/grafana-plugin/src/pages/incident/Incident.tsx @@ -39,7 +39,7 @@ import EscalationVariants from 'containers/EscalationVariants/EscalationVariants import { prepareForEdit, prepareForUpdate } from 'containers/EscalationVariants/EscalationVariants.helpers'; import IntegrationSettings from 'containers/IntegrationSettings/IntegrationSettings'; import { IntegrationSettingsTab } from 'containers/IntegrationSettings/IntegrationSettings.types'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Alert as AlertType, Alert, @@ -260,11 +260,11 @@ class IncidentPage extends React.Component #{incident.root_alert_group.inside_organization_number}{' '} {incident.root_alert_group.render_for_web.title} {' '} - + - + )} @@ -764,11 +764,11 @@ function AttachedIncidentsList({ #{incident.inside_organization_number} {incident.render_for_web.title} - + - + ); })} diff --git a/grafana-plugin/src/pages/incident/parts/PagedUsers.tsx b/grafana-plugin/src/pages/incident/parts/PagedUsers.tsx index 41aa7f6183..8fcf8824d5 100644 --- a/grafana-plugin/src/pages/incident/parts/PagedUsers.tsx +++ b/grafana-plugin/src/pages/incident/parts/PagedUsers.tsx @@ -6,7 +6,7 @@ import cn from 'classnames/bind'; import Avatar from 'components/Avatar/Avatar'; import Text from 'components/Text/Text'; import WithConfirm from 'components/WithConfirm/WithConfirm'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Alert } from 'models/alertgroup/alertgroup.types'; import { User } from 'models/user/user.types'; import { UserActions } from 'utils/authorization'; @@ -46,7 +46,7 @@ const PagedUsers = (props: PagedUsersProps) => { {pagedUser.username} - + { name="trash-alt" /> - + ))} diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx index 7a3b36335d..4938664705 100644 --- a/grafana-plugin/src/pages/incidents/Incidents.tsx +++ b/grafana-plugin/src/pages/incidents/Incidents.tsx @@ -18,7 +18,7 @@ import Tutorial from 'components/Tutorial/Tutorial'; import { TutorialStep } from 'components/Tutorial/Tutorial.types'; import { IncidentsFiltersType } from 'containers/IncidentsFilters/IncidentFilters.types'; import IncidentsFilters from 'containers/IncidentsFilters/IncidentsFilters'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Alert, Alert as AlertType, AlertAction } from 'models/alertgroup/alertgroup.types'; import { renderRelatedUsers } from 'pages/incident/Incident.helpers'; import { PageProps, WithStoreProps } from 'state/types'; @@ -109,11 +109,11 @@ class Incidents extends React.Component
Alert Groups - + - +
{this.renderIncidentFilters()} @@ -233,7 +233,7 @@ class Incidents extends React.Component
{'resolve' in store.alertGroupStore.bulkActions && ( - + - + )} {'acknowledge' in store.alertGroupStore.bulkActions && ( - + - + )} {'silence' in store.alertGroupStore.bulkActions && ( - + - + )} {'restart' in store.alertGroupStore.bulkActions && ( - + this.getBulkActionClickHandler('silence', ev)} /> - + )} {hasSelected diff --git a/grafana-plugin/src/pages/incidents/parts/IncidentDropdown.tsx b/grafana-plugin/src/pages/incidents/parts/IncidentDropdown.tsx index 59b552e890..0167ad5870 100644 --- a/grafana-plugin/src/pages/incidents/parts/IncidentDropdown.tsx +++ b/grafana-plugin/src/pages/incidents/parts/IncidentDropdown.tsx @@ -6,7 +6,7 @@ import cn from 'classnames/bind'; import Tag from 'components/Tag/Tag'; import Text from 'components/Text/Text'; import { WithContextMenu } from 'components/WithContextMenu/WithContextMenu'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Alert, AlertAction, IncidentStatus } from 'models/alertgroup/alertgroup.types'; import styles from 'pages/incidents/parts/IncidentDropdown.module.scss'; import { UserActions } from 'utils/authorization'; @@ -92,7 +92,7 @@ export const IncidentDropdown: FC<{ forceIsOpen={forcedOpenAction === AlertAction.Resolve} renderMenuItems={() => (
- +
onClickFn(e, AlertAction.Resolve, onUnresolve, IncidentStatus.Firing)} @@ -104,7 +104,7 @@ export const IncidentDropdown: FC<{ )}
-
+
)} > @@ -119,7 +119,7 @@ export const IncidentDropdown: FC<{ forceIsOpen={forcedOpenAction === AlertAction.Acknowledge} renderMenuItems={() => (
- +
onClickFn(e, AlertAction.Acknowledge, onUnacknowledge, IncidentStatus.Firing)} @@ -131,8 +131,8 @@ export const IncidentDropdown: FC<{ )}
-
- + +
onClickFn(e, AlertAction.Acknowledge, onResolve, IncidentStatus.Resolved)} @@ -144,7 +144,7 @@ export const IncidentDropdown: FC<{ )}
-
+
)} > @@ -159,7 +159,7 @@ export const IncidentDropdown: FC<{ forceIsOpen={forcedOpenAction === AlertAction.unResolve} renderMenuItems={() => (
- +
onClickFn(e, AlertAction.unResolve, onAcknowledge, IncidentStatus.Acknowledged)} @@ -171,8 +171,8 @@ export const IncidentDropdown: FC<{ )}
-
- + +
onClickFn(e, AlertAction.unResolve, onResolve, IncidentStatus.Resolved)} @@ -184,7 +184,7 @@ export const IncidentDropdown: FC<{ )}
-
+
(
- +
onClickFn(e, AlertAction.Silence, onUnsilence, IncidentStatus.Firing)} @@ -229,8 +229,8 @@ export const IncidentDropdown: FC<{ )}
-
- + +
onClickFn(e, AlertAction.Silence, onAcknowledge, IncidentStatus.Acknowledged)} @@ -242,8 +242,8 @@ export const IncidentDropdown: FC<{ )}
-
- + +
onClickFn(e, AlertAction.Silence, onAcknowledge, IncidentStatus.Resolved)} @@ -255,7 +255,7 @@ export const IncidentDropdown: FC<{ )}
-
+
)} > diff --git a/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx b/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx index 372ed3792e..586f5ff075 100644 --- a/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx +++ b/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { ButtonCascader, ComponentSize } from '@grafana/ui'; import { observer } from 'mobx-react'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { SelectOption } from 'state/types'; import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization'; @@ -23,7 +23,7 @@ export const SilenceButtonCascader = observer((props: SilenceButtonCascaderProps const silenceOptions = alertGroupStore.silenceOptions || []; return ( - + Silence - + ); function getOptions() { diff --git a/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx b/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx index c0e10845a8..764a8b360c 100644 --- a/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx +++ b/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { Select } from '@grafana/ui'; import { observer } from 'mobx-react'; -import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; +import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { SelectOption } from 'state/types'; import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization'; @@ -24,7 +24,7 @@ export const SilenceSelect = observer((props: SilenceSelectProps) => { const silenceOptions = alertGroupStore.silenceOptions || []; return ( - +