diff --git a/CHANGELOG.md b/CHANGELOG.md index 352afc3b..21b1cc16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated wording throughout plugin to use 'Alert Group' instead of 'Incident' ([1565](https://github.com/grafana/oncall/pull/1565), [1576](https://github.com/grafana/oncall/pull/1576)) +- Check for enabled Telegram feature was added to ChatOps and to User pages ([319](https://github.com/grafana/oncall/issues/319)) - Filtering for Editors/Admins was added to rotation form. It is not allowed to assign Viewer to rotation ([1124](https://github.com/grafana/oncall/issues/1124)) - Modified search behaviour on the Escalation Chains page to allow for "partial searching" ([1578](https://github.com/grafana/oncall/pull/1578)) diff --git a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx index bc97f132..28b34aa9 100644 --- a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx @@ -13,6 +13,8 @@ import { NotificationPolicyType, prepareNotificationPolicy } from 'models/notifi import { NotifyBy } from 'models/notify_by'; import { User } from 'models/user/user.types'; import { WaitDelay } from 'models/wait_delay'; +import { RootStore } from 'state'; +import { AppFeature } from 'state/features'; import { UserAction } from 'utils/authorization'; import DragHandle from './DragHandle'; @@ -41,6 +43,7 @@ export interface NotificationPolicyProps { color: string; number: number; userAction: UserAction; + store: RootStore; } export class NotificationPolicy extends React.Component { @@ -149,7 +152,11 @@ export class NotificationPolicy extends React.ComponentTelegram is connected diff --git a/grafana-plugin/src/containers/AlertRules/parts/index.tsx b/grafana-plugin/src/containers/AlertRules/parts/index.tsx index 76d51bcc..5f861b4f 100644 --- a/grafana-plugin/src/containers/AlertRules/parts/index.tsx +++ b/grafana-plugin/src/containers/AlertRules/parts/index.tsx @@ -6,6 +6,7 @@ import Timeline from 'components/Timeline/Timeline'; import SlackConnector from 'containers/AlertRules/parts/connectors/SlackConnector'; import TelegramConnector from 'containers/AlertRules/parts/connectors/TelegramConnector'; import { ChannelFilter } from 'models/channel_filter'; +import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; import { getVar } from 'utils/DOM'; @@ -20,7 +21,8 @@ export const ChatOpsConnectors = (props: ChatOpsConnectorsProps) => { const { telegramChannelStore } = store; const isSlackInstalled = Boolean(store.teamStore.currentTeam?.slack_team_identity); - const isTelegramInstalled = Boolean(telegramChannelStore.currentTeamToTelegramChannel?.length > 0); + const isTelegramInstalled = + store.hasFeature(AppFeature.Telegram) && telegramChannelStore.currentTeamToTelegramChannel?.length > 0; if (!isSlackInstalled && !isTelegramInstalled) { return null; diff --git a/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx b/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx index 498d2410..14514205 100644 --- a/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx +++ b/grafana-plugin/src/containers/PersonalNotificationSettings/PersonalNotificationSettings.tsx @@ -150,6 +150,7 @@ const PersonalNotificationSettings = observer((props: PersonalNotificationSettin waitDelays={get(userStore.notificationChoices, 'wait_delay.choices', [])} notifyByOptions={userStore.notifyByOptions} color={getColor(index)} + store={store} /> ))} diff --git a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx index 6c993f99..f0f23c5c 100644 --- a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx +++ b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx @@ -103,11 +103,12 @@ const TelegramModal = (props: TelegramModalProps) => { Sign Messages in settings. - 2. Create a new Discussion group. This group handles alert actions and comments.{' '} + 2. Create a new Discussion group. This group handles alert actions, comments and + must be unique for each OnCall telegram channel.{' '} 3. Connect the discussion group with the channel. In Manage Channel, click{' '} - Discussion to find and add your group.{' '} + Discussion to find and add the freshly created group.{' '} 4. Go to{' '} diff --git a/grafana-plugin/src/containers/UserSettings/UserSettings.tsx b/grafana-plugin/src/containers/UserSettings/UserSettings.tsx index bfdf4184..2ee2d34b 100644 --- a/grafana-plugin/src/containers/UserSettings/UserSettings.tsx +++ b/grafana-plugin/src/containers/UserSettings/UserSettings.tsx @@ -7,6 +7,7 @@ import { useMediaQuery } from 'react-responsive'; import { Tabs, TabsContent } from 'containers/UserSettings/parts'; import { User as UserType } from 'models/user/user.types'; +import { AppFeature } from 'state/features'; import { useStore } from 'state/useStore'; import { isUserActionAllowed, UserActions } from 'utils/authorization'; import { BREAKPOINT_TABS } from 'utils/consts'; @@ -51,7 +52,7 @@ const UserSettings = observer(({ id, onHide, tab = UserSettingsTab.UserInfo }: U const [showNotificationSettingsTab, showSlackConnectionTab, showTelegramConnectionTab, showMobileAppConnectionTab] = [ !isDesktopOrLaptop, isCurrent && teamStore.currentTeam?.slack_team_identity && !storeUser.slack_user_identity, - isCurrent && !storeUser.telegram_configuration, + isCurrent && store.hasFeature(AppFeature.Telegram) && !storeUser.telegram_configuration, isCurrent && isUserActionAllowed(UserActions.UserSettingsWrite), ]; diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/index.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/index.tsx index c7fcc144..6ab5c0d1 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/connectors/index.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/index.tsx @@ -2,6 +2,8 @@ import React, { FC } from 'react'; import { UserSettingsTab } from 'containers/UserSettings/UserSettings.types'; import { User } from 'models/user/user.types'; +import { AppFeature } from 'state/features'; +import { useStore } from 'state/useStore'; import ICalConnector from './ICalConnector'; import MobileAppConnector from './MobileAppConnector'; @@ -15,11 +17,12 @@ interface ConnectorsProps { } export const Connectors: FC = (props) => { + const store = useStore(); return (
- + {store.hasFeature(AppFeature.Telegram) && }
diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx index c5861777..22ed9805 100644 --- a/grafana-plugin/src/pages/incident/Incident.tsx +++ b/grafana-plugin/src/pages/incident/Incident.tsx @@ -297,7 +297,7 @@ class IncidentPage extends React.Component
{getIncidentStatusTag(incident)}
{integration && ( - <> + placement="top" content={ incident.render_for_web.source_link === null - ? `The integration doesn't have direct link to the source.` + ? `The integration template Source Link is empty` : 'Go to source' } > @@ -348,7 +348,7 @@ class IncidentPage extends React.Component - + )}
diff --git a/grafana-plugin/src/pages/settings/tabs/ChatOps/ChatOps.tsx b/grafana-plugin/src/pages/settings/tabs/ChatOps/ChatOps.tsx index fbe4f886..3c91d5f7 100644 --- a/grafana-plugin/src/pages/settings/tabs/ChatOps/ChatOps.tsx +++ b/grafana-plugin/src/pages/settings/tabs/ChatOps/ChatOps.tsx @@ -8,6 +8,8 @@ import { observer } from 'mobx-react'; import VerticalTabsBar, { VerticalTab } from 'components/VerticalTabsBar/VerticalTabsBar'; import SlackSettings from 'pages/settings/tabs/ChatOps/tabs/SlackSettings/SlackSettings'; import TelegramSettings from 'pages/settings/tabs/ChatOps/tabs/TelegramSettings/TelegramSettings'; +import { AppFeature } from 'state/features'; +import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; import LocationHelper from 'utils/LocationHelper'; @@ -19,13 +21,13 @@ export enum ChatOpsTab { Slack = 'Slack', Telegram = 'Telegram', } - +interface ChatOpsProps extends AppRootProps {} interface ChatOpsState { activeTab: ChatOpsTab; } @observer -class ChatOpsPage extends React.Component { +class ChatOpsPage extends React.Component { state: ChatOpsState = { activeTab: ChatOpsTab.Slack, }; @@ -70,21 +72,27 @@ interface TabsProps { const Tabs = (props: TabsProps) => { const { activeTab, onTabChange } = props; + const store = useStore(); return ( - - - - Slack - - - - - - Telegram - - + {store.hasFeature(AppFeature.Slack) && ( + + + + Slack + + + )} + + {store.hasFeature(AppFeature.Telegram) && ( + + + + Telegram + + + )} ); }; @@ -95,15 +103,16 @@ interface TabsContentProps { const TabsContent = (props: TabsContentProps) => { const { activeTab } = props; + const store = useStore(); return ( <> - {activeTab === ChatOpsTab.Slack && ( + {store.hasFeature(AppFeature.Slack) && activeTab === ChatOpsTab.Slack && (
)} - {activeTab === ChatOpsTab.Telegram && ( + {store.hasFeature(AppFeature.Telegram) && activeTab === ChatOpsTab.Telegram && (
diff --git a/grafana-plugin/src/pages/users/Users.tsx b/grafana-plugin/src/pages/users/Users.tsx index ec37e0b0..ca831254 100644 --- a/grafana-plugin/src/pages/users/Users.tsx +++ b/grafana-plugin/src/pages/users/Users.tsx @@ -20,6 +20,7 @@ import UsersFilters from 'components/UsersFilters/UsersFilters'; import UserSettings from 'containers/UserSettings/UserSettings'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { User as UserType } from 'models/user/user.types'; +import { AppFeature } from 'state/features'; import { PageProps, WithStoreProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; import LocationHelper from 'utils/LocationHelper'; @@ -280,10 +281,13 @@ class Users extends React.Component { }; renderContacts = (user: UserType) => { + const { store } = this.props; return (
Slack: {user.slack_user_identity?.name || '-'}
-
Telegram: {user.telegram_configuration?.telegram_nick_name || '-'}
+ {store.hasFeature(AppFeature.Telegram) && ( +
Telegram: {user.telegram_configuration?.telegram_nick_name || '-'}
+ )}
); }; @@ -314,6 +318,7 @@ class Users extends React.Component { }; renderNote = (user: UserType) => { + const { store } = this.props; if (user.hidden_fields === true) { return null; } @@ -346,7 +351,7 @@ class Users extends React.Component { if (!user.slack_user_identity) { texts.push('Slack not verified'); } - if (!user.telegram_configuration) { + if (store.hasFeature(AppFeature.Telegram) && !user.telegram_configuration) { texts.push('Telegram not verified'); }