319 telegram warning bug (#1424)
# What this PR does When you disable Telegram feature we did not handle it in our frontend. Now if the fieture is disabled we do not shoe Telegram at Chat-ops, at Users. Also some crarification was added to the instructions that discussion group should be unique for each channel ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/319 https://github.com/grafana/oncall/issues/938
This commit is contained in:
parent
7ea5b07704
commit
db8914bdf7
10 changed files with 57 additions and 27 deletions
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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<NotificationPolicyProps, any> {
|
||||
|
|
@ -149,7 +152,11 @@ export class NotificationPolicy extends React.Component<NotificationPolicyProps,
|
|||
}
|
||||
|
||||
_renderTelegramNote() {
|
||||
const { telegramVerified } = this.props;
|
||||
const { telegramVerified, store } = this.props;
|
||||
|
||||
if (!store.hasFeature(AppFeature.Telegram)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return telegramVerified ? (
|
||||
<PolicyNote type="success">Telegram is connected</PolicyNote>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ const PersonalNotificationSettings = observer((props: PersonalNotificationSettin
|
|||
waitDelays={get(userStore.notificationChoices, 'wait_delay.choices', [])}
|
||||
notifyByOptions={userStore.notifyByOptions}
|
||||
color={getColor(index)}
|
||||
store={store}
|
||||
/>
|
||||
))}
|
||||
<Timeline.Item number={notificationPolicies.length + 1} color={getColor(notificationPolicies.length)}>
|
||||
|
|
|
|||
|
|
@ -103,11 +103,12 @@ const TelegramModal = (props: TelegramModalProps) => {
|
|||
<Text type="primary">Sign Messages</Text> in settings.
|
||||
</Text>
|
||||
<Text type="secondary">
|
||||
2. Create a new <Text type="primary">Discussion group</Text>. This group handles alert actions and comments.{' '}
|
||||
2. Create a new <Text type="primary">Discussion group</Text>. This group handles alert actions, comments and
|
||||
must be unique for each OnCall telegram channel.{' '}
|
||||
</Text>
|
||||
<Text type="secondary">
|
||||
3. Connect the discussion group with the channel. In <Text type="primary">Manage Channel</Text>, click{' '}
|
||||
<Text type="primary">Discussion</Text> to find and add your group.{' '}
|
||||
<Text type="primary">Discussion</Text> to find and add the freshly created group.{' '}
|
||||
</Text>
|
||||
<Text type="secondary">
|
||||
4. Go to{' '}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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<ConnectorsProps> = (props) => {
|
||||
const store = useStore();
|
||||
return (
|
||||
<div>
|
||||
<PhoneConnector {...props} />
|
||||
<SlackConnector {...props} />
|
||||
<TelegramConnector {...props} />
|
||||
{store.hasFeature(AppFeature.Telegram) && <TelegramConnector {...props} />}
|
||||
<ICalConnector {...props} />
|
||||
<MobileAppConnector {...props} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
<HorizontalGroup>
|
||||
<div className={cx('status-tag-container')}>{getIncidentStatusTag(incident)}</div>
|
||||
{integration && (
|
||||
<>
|
||||
<HorizontalGroup>
|
||||
<PluginLink
|
||||
disabled={incident.alert_receive_channel.deleted}
|
||||
query={{ page: 'integrations', id: incident.alert_receive_channel.id }}
|
||||
|
|
@ -331,7 +331,7 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
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<IncidentPageProps, IncidentPageState>
|
|||
</Button>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</>
|
||||
</HorizontalGroup>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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<AppRootProps, ChatOpsState> {
|
||||
class ChatOpsPage extends React.Component<ChatOpsProps, ChatOpsState> {
|
||||
state: ChatOpsState = {
|
||||
activeTab: ChatOpsTab.Slack,
|
||||
};
|
||||
|
|
@ -70,21 +72,27 @@ interface TabsProps {
|
|||
|
||||
const Tabs = (props: TabsProps) => {
|
||||
const { activeTab, onTabChange } = props;
|
||||
const store = useStore();
|
||||
|
||||
return (
|
||||
<VerticalTabsBar activeTab={activeTab} onChange={onTabChange}>
|
||||
<VerticalTab id={ChatOpsTab.Slack}>
|
||||
<HorizontalGroup>
|
||||
<Icon name="slack" />
|
||||
Slack
|
||||
</HorizontalGroup>
|
||||
</VerticalTab>
|
||||
<VerticalTab id={ChatOpsTab.Telegram}>
|
||||
<HorizontalGroup>
|
||||
<Icon name="message" />
|
||||
Telegram
|
||||
</HorizontalGroup>
|
||||
</VerticalTab>
|
||||
{store.hasFeature(AppFeature.Slack) && (
|
||||
<VerticalTab id={ChatOpsTab.Slack}>
|
||||
<HorizontalGroup>
|
||||
<Icon name="slack" />
|
||||
Slack
|
||||
</HorizontalGroup>
|
||||
</VerticalTab>
|
||||
)}
|
||||
|
||||
{store.hasFeature(AppFeature.Telegram) && (
|
||||
<VerticalTab id={ChatOpsTab.Telegram}>
|
||||
<HorizontalGroup>
|
||||
<Icon name="message" />
|
||||
Telegram
|
||||
</HorizontalGroup>
|
||||
</VerticalTab>
|
||||
)}
|
||||
</VerticalTabsBar>
|
||||
);
|
||||
};
|
||||
|
|
@ -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 && (
|
||||
<div className={cx('messenger-settings')}>
|
||||
<SlackSettings />
|
||||
</div>
|
||||
)}
|
||||
{activeTab === ChatOpsTab.Telegram && (
|
||||
{store.hasFeature(AppFeature.Telegram) && activeTab === ChatOpsTab.Telegram && (
|
||||
<div className={cx('messenger-settings')}>
|
||||
<TelegramSettings />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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<UsersProps, UsersState> {
|
|||
};
|
||||
|
||||
renderContacts = (user: UserType) => {
|
||||
const { store } = this.props;
|
||||
return (
|
||||
<div className={cx('contacts')}>
|
||||
<div className={cx('contact')}>Slack: {user.slack_user_identity?.name || '-'}</div>
|
||||
<div className={cx('contact')}>Telegram: {user.telegram_configuration?.telegram_nick_name || '-'}</div>
|
||||
{store.hasFeature(AppFeature.Telegram) && (
|
||||
<div className={cx('contact')}>Telegram: {user.telegram_configuration?.telegram_nick_name || '-'}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -314,6 +318,7 @@ class Users extends React.Component<UsersProps, UsersState> {
|
|||
};
|
||||
|
||||
renderNote = (user: UserType) => {
|
||||
const { store } = this.props;
|
||||
if (user.hidden_fields === true) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -346,7 +351,7 @@ class Users extends React.Component<UsersProps, UsersState> {
|
|||
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');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue