diff --git a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.config.ts b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.config.ts index 450faa7b..86fc486d 100644 --- a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.config.ts +++ b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.config.ts @@ -1,5 +1,4 @@ import { TemplateForEdit, commonTemplateForEdit } from './CommonAlertTemplatesForm.config'; - export interface Template { name: string; group: string; diff --git a/grafana-plugin/src/components/AlertTemplates/CommonAlertTemplatesForm.config.ts b/grafana-plugin/src/components/AlertTemplates/CommonAlertTemplatesForm.config.ts index 9760024f..24e9925e 100644 --- a/grafana-plugin/src/components/AlertTemplates/CommonAlertTemplatesForm.config.ts +++ b/grafana-plugin/src/components/AlertTemplates/CommonAlertTemplatesForm.config.ts @@ -1,3 +1,5 @@ +import { TemplateOptions } from 'pages/integration_2/Integration2.config'; + export interface Template { name: string; group: string; @@ -9,6 +11,7 @@ export interface TemplateForEdit { description?: string; additionalData?: { chatOpsName?: string; + chatOpsDisplayName?: string; data?: string; additionalDescription?: string; }; @@ -18,17 +21,17 @@ export interface TemplateForEdit { export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { web_title_template: { displayName: 'Web title', - name: 'web_title_template', + name: TemplateOptions.WebTitle.key, description: '', }, web_message_template: { displayName: 'Web message', - name: 'web_message_template', + name: TemplateOptions.WebMessage.key, description: '', }, slack_title_template: { name: 'slack_title_template', - displayName: 'Slack title', + displayName: TemplateOptions.SlackTitle.key, description: '', additionalData: { chatOpsName: 'slack', @@ -36,22 +39,22 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, sms_title_template: { - name: 'sms_title_template', + name: TemplateOptions.SMS.key, displayName: 'Sms title', description: '', }, phone_call_title_template: { - name: 'phone_call_title_template', + name: TemplateOptions.Phone.key, displayName: 'Phone call title', description: '', }, email_title_template: { - name: 'email_title_template', + name: TemplateOptions.EmailTitle.key, displayName: 'Email title', description: '', }, telegram_title_template: { - name: 'telegram_title_template', + name: TemplateOptions.TelegramTitle.key, displayName: 'Telegram title', description: '', additionalData: { @@ -59,7 +62,7 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, slack_message_template: { - name: 'slack_message_template', + name: TemplateOptions.SlackMessage.key, displayName: 'Slack message', description: '', additionalData: { @@ -68,12 +71,12 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, email_message_template: { - name: 'email_message_template', + name: TemplateOptions.EmailMessage.key, displayName: 'Email message', description: '', }, telegram_message_template: { - name: 'telegram_message_template', + name: TemplateOptions.TelegramMessage.key, displayName: 'Telegram message', description: '', additionalData: { @@ -81,7 +84,7 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, slack_image_url_template: { - name: 'slack_image_url_template', + name: TemplateOptions.SlackImage.key, displayName: 'Slack image url', description: '', additionalData: { @@ -90,12 +93,12 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, web_image_url_template: { - name: 'web_image_url_template', + name: TemplateOptions.WebImage.key, displayName: 'Web image url', description: '', }, telegram_image_url_template: { - name: 'telegram_image_url_template', + name: TemplateOptions.TelegramImage.key, displayName: 'Telegram image url', description: '', additionalData: { @@ -103,32 +106,29 @@ export const commonTemplateForEdit: { [id: string]: TemplateForEdit } = { }, }, grouping_id_template: { - name: 'grouping_id_template', + name: TemplateOptions.Grouping.key, displayName: 'Grouping', description: 'Reduce noise, minimize duplication with Alert Grouping, based on time, alert content, and even multiple features at the same time. Check the cheasheet to customize your template.', - additionalData: { - additionalDescription: 'Alerts with this Grouping ID are grouped together', - }, }, acknowledge_condition_template: { - name: 'acknowledge_condition_template', + name: TemplateOptions.Autoacknowledge.key, displayName: 'Acknowledge condition', description: '', }, resolve_condition_template: { - name: 'resolve_condition_template', + name: TemplateOptions.Resolve.key, displayName: 'Resolve condition', description: - 'When monitoring systems return to normal, they can send "resolve" alerts. If Autoresolution Template is True, the alert will resolve its group as "resolved by source". If the group is already resolved, the alert will be added to that group', + 'When monitoring systems return to normal, they can send "resolve" alerts. OnCall can use these signals to resolve alert groups accordingly.', }, source_link_template: { - name: 'source_link_template', + name: TemplateOptions.SourceLink.key, displayName: 'Source link', description: '', }, route_template: { - name: 'route_template', + name: TemplateOptions.Routing.key, displayName: 'Routing', description: 'Routes direct alerts to different escalation chains based on the content, such as severity or region.', diff --git a/grafana-plugin/src/components/CheatSheet/CheatSheet.config.ts b/grafana-plugin/src/components/CheatSheet/CheatSheet.config.ts index e921f173..3f0e600d 100644 --- a/grafana-plugin/src/components/CheatSheet/CheatSheet.config.ts +++ b/grafana-plugin/src/components/CheatSheet/CheatSheet.config.ts @@ -47,7 +47,12 @@ export const genericTemplateCheatSheet: CheatSheetInterface = { { name: 'Markdown refresher', listItems: [ - { codeExample: '**bold**, _italic_, >quote, `code`, ```multiline code```, [``](url), - bullet list' }, + { + codeExample: `**bold**, _italic_, >quote, \`code\`, +\`\`\`multiline code\`\`\` + +- bullet list`, + }, ], }, { @@ -56,10 +61,17 @@ export const genericTemplateCheatSheet: CheatSheetInterface = { { listItemName: ' {{ payload.labels.foo }} - extract field value' }, { listItemName: 'Conditions', - codeExample: '{%- if "status" in payload %} \n {{ payload.status }} \n {% endif -%}', + codeExample: `{%- if "status" in payload %} + {{ payload.status }} +{% endif -%}`, + }, + { listItemName: 'Booleans', codeExample: '{{ payload.status == "resolved" }}' }, + { + listItemName: 'Loops', + codeExample: `{% for label in labels %} + {{ label.title }} +{% endfor %}`, }, - { listItemName: 'Booleans', codeExample: '{{ payload.status == “resolved” }}' }, - { listItemName: 'Loops', codeExample: '{% for label in labels %} \n {{ label.title }} \n {% endfor %}' }, ], }, { @@ -132,11 +144,17 @@ export const slackMessageTemplateCheatSheet: CheatSheetInterface = { listItems: [ { listItemName: 'Examples Convert Web template in Classic Markdown to Slack markdown', - codeExample: '{{ web_message \n| replace("**", "*") \n| regex_replace("/((.*))[(.*)]/", "<$2|$1>") }}', + codeExample: `{{ + web_message + | replace("**", "*") + | regex_replace("/((.*))[(.*)]/", "<$2|$1>") +}}`, }, { listItemName: 'Show status if exists', - codeExample: '{%- if "status" in payload %} \n **Status**: {{ payload.status }} \n {% endif -%}', + codeExample: `{%- if "status" in payload %} +**Status**: {{ payload.status }} +{% endif -%}`, }, { listItemName: 'Show field value or “N/A” is not exist', @@ -144,8 +162,10 @@ export const slackMessageTemplateCheatSheet: CheatSheetInterface = { }, { listItemName: 'Iterate over labels dictionary', - codeExample: - '**Labels:** \n {% for k, v in payload["labels"].items() %} \n *{{ k }}*: {{ v }} \n {% endfor %} ', + codeExample: `**Labels:** +{% for k, v in payload["labels"].items() %} +*{{ k }}*: {{ v }} +{% endfor %}`, }, ], }, diff --git a/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css b/grafana-plugin/src/components/CheatSheet/CheatSheet.module.scss similarity index 60% rename from grafana-plugin/src/components/CheatSheet/CheatSheet.module.css rename to grafana-plugin/src/components/CheatSheet/CheatSheet.module.scss index 075a4ca5..648d9b98 100644 --- a/grafana-plugin/src/components/CheatSheet/CheatSheet.module.css +++ b/grafana-plugin/src/components/CheatSheet/CheatSheet.module.scss @@ -2,16 +2,23 @@ width: 40%; height: 100%; padding: 16px; + padding-right: 0; border: var(--border-weak); min-width: min-content; overflow-y: scroll; } - -.cheatsheet-container > div { + +.cheatsheet-innerContainer { + padding-right: 16px; + overflow-y: scroll; height: 100%; - max-height: 100%; + + > div { + height: 100%; + max-height: 100%; + } } - + .cheatsheet-item { margin-bottom: 24px; } @@ -20,3 +27,7 @@ margin-bottom: 16px; width: 100%; } + +.code { + white-space: pre; +} \ No newline at end of file diff --git a/grafana-plugin/src/components/CheatSheet/CheatSheet.tsx b/grafana-plugin/src/components/CheatSheet/CheatSheet.tsx index bffd6cde..85329a4f 100644 --- a/grafana-plugin/src/components/CheatSheet/CheatSheet.tsx +++ b/grafana-plugin/src/components/CheatSheet/CheatSheet.tsx @@ -9,8 +9,7 @@ import Text from 'components/Text/Text'; import { openNotification } from 'utils'; import { CheatSheetInterface, CheatSheetItem } from './CheatSheet.config'; - -import styles from './CheatSheet.module.css'; +import styles from './CheatSheet.module.scss'; interface CheatSheetProps { cheatSheetName: string; @@ -24,22 +23,24 @@ const CheatSheet = (props: CheatSheetProps) => { const { cheatSheetName, cheatSheetData, onClose } = props; return (
- - - {cheatSheetName} cheatsheet - - - {cheatSheetData.description} -
- {cheatSheetData.fields?.map((field: CheatSheetItem) => { - return ( -
- -
- ); - })} -
-
+
+ + + {cheatSheetName} cheatsheet + + + {cheatSheetData.description} +
+ {cheatSheetData.fields?.map((field: CheatSheetItem) => { + return ( +
+ +
+ ); + })} +
+
+
); }; @@ -65,7 +66,9 @@ const CheatSheetListItem = (props: CheatSheetListItemProps) => {
- {item.codeExample} + + {item.codeExample} + openNotification('Example copied')}> diff --git a/grafana-plugin/src/components/Integrations/IntegrationBlock.module.scss b/grafana-plugin/src/components/Integrations/IntegrationBlock.module.scss index dc6e9221..5b1bfaff 100644 --- a/grafana-plugin/src/components/Integrations/IntegrationBlock.module.scss +++ b/grafana-plugin/src/components/Integrations/IntegrationBlock.module.scss @@ -5,17 +5,24 @@ .integrationBlock__heading { background-color: var(--background-secondary); - border: none; + border: var(--border-medium) !important; + border-radius: 0 !important; + border-top-left-radius: 4px !important; + border-top-right-radius: 4px !important; } .integrationBlock__content { background: var(--background-primary); - border: var(--border-weak); + border: var(--border-medium) !important; + + border-top: none !important; padding-bottom: 0; + border-bottom-left-radius: 4px !important; + border-bottom-right-radius: 4px !important; &--collapsedBorder { - border-left: none; padding-left: 0; padding-right: 0; + padding-bottom: 24px; } } diff --git a/grafana-plugin/src/components/Integrations/IntegrationBlockItem.module.scss b/grafana-plugin/src/components/Integrations/IntegrationBlockItem.module.scss index 04f5c8c7..9f8f584e 100644 --- a/grafana-plugin/src/components/Integrations/IntegrationBlockItem.module.scss +++ b/grafana-plugin/src/components/Integrations/IntegrationBlockItem.module.scss @@ -3,6 +3,7 @@ flex-direction: row; margin-bottom: 4px; max-width: 100%; + margin-left: 16px; &__content { width: 100%; diff --git a/grafana-plugin/src/components/Integrations/IntegrationTemplateBlock.tsx b/grafana-plugin/src/components/Integrations/IntegrationTemplateBlock.tsx index 7002af5f..889eb9d2 100644 --- a/grafana-plugin/src/components/Integrations/IntegrationTemplateBlock.tsx +++ b/grafana-plugin/src/components/Integrations/IntegrationTemplateBlock.tsx @@ -53,7 +53,7 @@ const IntegrationTemplateBlock: React.FC = ({ - +
} /> diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index 716147ef..29807d16 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -33,8 +33,8 @@ import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_ import { AlertTemplatesDTO } from 'models/alert_templates'; import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import CommonIntegrationHelper from 'pages/integration_2/CommonIntegration2.helper'; -import { MONACO_INPUT_HEIGHT_SMALL, MONACO_OPTIONS } from 'pages/integration_2/Integration2.config'; import IntegrationHelper from 'pages/integration_2/Integration2.helper'; +import { MONACO_INPUT_HEIGHT_SMALL, MONACO_OPTIONS } from 'pages/integration_2/Integration2Common.config'; import { useStore } from 'state/useStore'; import { openNotification } from 'utils'; import { UserActions } from 'utils/authorization'; @@ -121,6 +121,7 @@ const ExpandedIntegrationRouteDisplay: React.FC @@ -323,26 +324,36 @@ export const RouteButtonsDisplay: React.FC = ({ return ( - {routeIndex > 0 && !channelFilter.is_default && ( - - - @@ -249,9 +250,6 @@ const Result = (props: ResultProps) => { const { alertReceiveChannelId, template, templateBody, chatOpsPermalink, payload, error, onSaveAndFollowLink } = props; - const getCapitalizedChatopsName = (name: string) => { - return name.charAt(0).toUpperCase() + name.slice(1); - }; return (
@@ -286,7 +284,7 @@ const Result = (props: ResultProps) => { diff --git a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx index c558d4f7..49b5c940 100644 --- a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx +++ b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx @@ -10,7 +10,7 @@ import TooltipBadge from 'components/TooltipBadge/TooltipBadge'; import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; import { AlertTemplatesDTO } from 'models/alert_templates'; import { Alert } from 'models/alertgroup/alertgroup.types'; -import { MONACO_PAYLOAD_OPTIONS } from 'pages/integration_2/Integration2.config'; +import { MONACO_OPTIONS, MONACO_PAYLOAD_OPTIONS } from 'pages/integration_2/Integration2Common.config'; import { useStore } from 'state/useStore'; import styles from './TemplatesAlertGroupsList.module.css'; @@ -129,6 +129,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { className={cx('alert-groups-last-payload-badge')} />
+ {/* Editor used for Editing Given Payload */} { useAutoCompleteList={false} language={MONACO_LANGUAGE.json} data={templates} - monacoOptions={MONACO_PAYLOAD_OPTIONS} - showLineNumbers + monacoOptions={{ + ...MONACO_OPTIONS, + readOnly: false, + }} height={getCodeEditorHeight()} onChange={getChangeHandler()} /> diff --git a/grafana-plugin/src/models/channel_filter/channel_filter.types.ts b/grafana-plugin/src/models/channel_filter/channel_filter.types.ts index ab844e59..67835515 100644 --- a/grafana-plugin/src/models/channel_filter/channel_filter.types.ts +++ b/grafana-plugin/src/models/channel_filter/channel_filter.types.ts @@ -1,7 +1,7 @@ import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'; import { SlackChannel } from 'models/slack_channel/slack_channel.types'; -import { TelegramChannel } from 'models/telegram_channel/telegram_channel.types'; +import { TelegramChannel, TelegramChannelDetails } from 'models/telegram_channel/telegram_channel.types'; export enum FilteringTermType { regex, @@ -15,6 +15,7 @@ export interface ChannelFilter { slack_channel_id?: SlackChannel['id']; slack_channel?: SlackChannel; telegram_channel?: TelegramChannel['id']; + telegram_channel_details?: TelegramChannelDetails; created_at: string; filtering_term: string; filtering_term_as_jinja2: string; diff --git a/grafana-plugin/src/models/telegram_channel/telegram_channel.types.ts b/grafana-plugin/src/models/telegram_channel/telegram_channel.types.ts index 9a5f7f2b..0e28793f 100644 --- a/grafana-plugin/src/models/telegram_channel/telegram_channel.types.ts +++ b/grafana-plugin/src/models/telegram_channel/telegram_channel.types.ts @@ -6,3 +6,8 @@ export interface TelegramChannel { discussion_group_name: string; is_default_channel: false; } + +export interface TelegramChannelDetails { + display_name: string; + id: string; +} diff --git a/grafana-plugin/src/pages/integration_2/Integration2.config.ts b/grafana-plugin/src/pages/integration_2/Integration2.config.ts index 4c4ded1f..2df53402 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.config.ts +++ b/grafana-plugin/src/pages/integration_2/Integration2.config.ts @@ -3,125 +3,12 @@ Any change to this file needs to be done in the oncall-private also */ -import { KeyValuePair } from 'utils'; +import { BASE_INTEGRATION_TEMPLATES_LIST, BaseTemplateOptions } from './Integration2Common.config'; -export const TEXTAREA_ROWS_COUNT = 4; -export const MAX_CHARACTERS_COUNT = 50; - -export const MONACO_OPTIONS = { - renderLineHighlight: false, - readOnly: true, - scrollbar: { - vertical: 'hidden', - horizontal: 'hidden', - verticalScrollbarSize: 0, - handleMouseWheel: false, - }, - hideCursorInOverviewRuler: true, - minimap: { enabled: false }, - cursorStyle: { - display: 'none', - }, +export const TemplateOptions = { + ...BaseTemplateOptions, }; -export const MONACO_PAYLOAD_OPTIONS = { - renderLineHighlight: false, - readOnly: false, - hideCursorInOverviewRuler: true, - minimap: { enabled: false }, - cursorStyle: { - display: 'none', - }, +export const INTEGRATION_TEMPLATES_LIST = { + ...BASE_INTEGRATION_TEMPLATES_LIST, }; - -export const MONACO_INPUT_HEIGHT_SMALL = '32px'; -export const MONACO_INPUT_HEIGHT_TALL = '120px'; - -const TemplateOptions = { - SourceLink: new KeyValuePair('source_link_template', 'Source Link'), - Autoacknowledge: new KeyValuePair('acknowledge_condition_template', 'Autoacknowledge'), - Phone: new KeyValuePair('phone_call_title_template', 'Phone'), - SMS: new KeyValuePair('sms_title_template', 'SMS'), - SlackTitle: new KeyValuePair('slack_title_template', 'Title'), - SlackMessage: new KeyValuePair('slack_message_template', 'Message'), - SlackImage: new KeyValuePair('slack_image_url_template', 'Image'), - EmailTitle: new KeyValuePair('email_title_template', 'Title'), - EmailMessage: new KeyValuePair('email_message_template', 'Message'), - TelegramTitle: new KeyValuePair('telegram_title_template', 'Title'), - TelegramMessage: new KeyValuePair('telegram_message_template', 'Message'), - TelegramImage: new KeyValuePair('telegram_image_url_template', 'Image'), - - Email: new KeyValuePair('Email', 'Email'), - Slack: new KeyValuePair('Slack', 'Slack'), - MSTeams: new KeyValuePair('Microsoft Teams', 'Microsoft Teams'), - Telegram: new KeyValuePair('Telegram', 'Telegram'), -}; - -export const INTEGRATION_TEMPLATES_LIST = [ - { - label: TemplateOptions.SourceLink.value, - value: TemplateOptions.SourceLink.key, - }, - { - label: TemplateOptions.Autoacknowledge.value, - value: TemplateOptions.Autoacknowledge.key, - }, - { - label: TemplateOptions.Phone.value, - value: TemplateOptions.Phone.key, - }, - { - label: TemplateOptions.SMS.value, - value: TemplateOptions.SMS.key, - }, - { - label: TemplateOptions.Email.value, - value: TemplateOptions.Email.key, - children: [ - { - label: TemplateOptions.EmailTitle.value, - value: TemplateOptions.EmailTitle.key, - }, - { - label: TemplateOptions.EmailMessage.value, - value: TemplateOptions.EmailMessage.key, - }, - ], - }, - { - label: TemplateOptions.Slack.value, - value: TemplateOptions.Slack.key, - children: [ - { - label: TemplateOptions.SlackTitle.value, - value: TemplateOptions.SlackTitle.key, - }, - { - label: TemplateOptions.SlackMessage.value, - value: TemplateOptions.SlackMessage.key, - }, - { - label: TemplateOptions.SlackImage.value, - value: TemplateOptions.SlackImage.key, - }, - ], - }, - { - label: TemplateOptions.Telegram.value, - value: TemplateOptions.Telegram.key, - children: [ - { - label: TemplateOptions.TelegramTitle.value, - value: TemplateOptions.TelegramTitle.key, - }, - { - label: TemplateOptions.TelegramMessage.value, - value: TemplateOptions.TelegramMessage.key, - }, - { - label: TemplateOptions.TelegramImage.value, - value: TemplateOptions.TelegramImage.key, - }, - ], - }, -]; diff --git a/grafana-plugin/src/pages/integration_2/Integration2.helper.ts b/grafana-plugin/src/pages/integration_2/Integration2.helper.ts index 02d78d37..8209b34d 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.helper.ts +++ b/grafana-plugin/src/pages/integration_2/Integration2.helper.ts @@ -11,7 +11,7 @@ import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import { RootStore } from 'state'; import { AppFeature } from 'state/features'; -import { MAX_CHARACTERS_COUNT, TEXTAREA_ROWS_COUNT } from './Integration2.config'; +import { MAX_CHARACTERS_COUNT, TEXTAREA_ROWS_COUNT } from './Integration2Common.config'; const IntegrationHelper = { getFilteredTemplate: (template: string, isTextArea: boolean): string => { @@ -63,7 +63,6 @@ const IntegrationHelper = { getChatOpsChannels(channelFilter: ChannelFilter, store: RootStore): Array<{ name: string; icon: IconName }> { const channels: Array<{ name: string; icon: IconName }> = []; - const telegram = Object.keys(store.telegramChannelStore.items).map((k) => store.telegramChannelStore.items[k]); if (store.hasFeature(AppFeature.Slack) && channelFilter.notify_in_slack) { const matchingSlackChannel = store.teamStore.currentTeam?.slack_channel?.id @@ -77,15 +76,12 @@ const IntegrationHelper = { } } - const matchingTelegram = telegram.find((t) => t.id === channelFilter.telegram_channel); - if ( store.hasFeature(AppFeature.Telegram) && - channelFilter.telegram_channel && - channelFilter.notify_in_telegram && - matchingTelegram?.channel_name + channelFilter.telegram_channel_details && + channelFilter.notify_in_telegram ) { - channels.push({ name: matchingTelegram.channel_name, icon: 'telegram-alt' }); + channels.push({ name: channelFilter.telegram_channel_details.display_name, icon: 'telegram-alt' }); } return channels; diff --git a/grafana-plugin/src/pages/integration_2/Integration2.module.scss b/grafana-plugin/src/pages/integration_2/Integration2.module.scss index 85a69759..acad5bc8 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.module.scss +++ b/grafana-plugin/src/pages/integration_2/Integration2.module.scss @@ -49,7 +49,7 @@ $LARGE-MARGIN: 24px; &__description { display: block; - margin-bottom: $LARGE-MARGIN; + margin-bottom: 32px;; } &__counter { @@ -118,6 +118,9 @@ $LARGE-MARGIN: 24px; flex-grow: 1; max-width: calc(100% - 80px); } +.input-with-toggler { + max-width: calc(100% - 134px); +} .how-to-connect__container { display: flex; @@ -205,3 +208,11 @@ $LARGE-MARGIN: 24px; gap: 4px; } } + +.radius { + border-radius: 4px; +} + +.inline-switch { + height: 34px; +} \ No newline at end of file diff --git a/grafana-plugin/src/pages/integration_2/Integration2.tsx b/grafana-plugin/src/pages/integration_2/Integration2.tsx index fa988e9d..f6f62b5a 100644 --- a/grafana-plugin/src/pages/integration_2/Integration2.tsx +++ b/grafana-plugin/src/pages/integration_2/Integration2.tsx @@ -58,10 +58,9 @@ import { import { AlertTemplatesDTO } from 'models/alert_templates'; import { ChannelFilter } from 'models/channel_filter'; import { MaintenanceType } from 'models/maintenance/maintenance.types'; -import { INTEGRATION_TEMPLATES_LIST, MONACO_PAYLOAD_OPTIONS } from 'pages/integration_2/Integration2.config'; +import { INTEGRATION_TEMPLATES_LIST } from 'pages/integration_2/Integration2.config'; import IntegrationHelper from 'pages/integration_2/Integration2.helper'; import styles from 'pages/integration_2/Integration2.module.scss'; -import { AppFeature } from 'state/features'; import { PageProps, SelectOption, WithStoreProps } from 'state/types'; import { useStore } from 'state/useStore'; import { withMobXProviderContext } from 'state/withStore'; @@ -72,6 +71,8 @@ import { UserActions } from 'utils/authorization'; import { PLUGIN_ROOT } from 'utils/consts'; import sanitize from 'utils/sanitize'; +import { MONACO_PAYLOAD_OPTIONS } from './Integration2Common.config'; + const cx = cn.bind(styles); interface Integration2Props extends WithStoreProps, PageProps, RouteComponentProps<{ id: string }> {} @@ -118,15 +119,9 @@ class Integration2 extends React.Component } = this.props; const { - store, - store: { alertReceiveChannelStore, telegramChannelStore }, + store: { alertReceiveChannelStore }, } = this.props; - if (store.hasFeature(AppFeature.Telegram)) { - // workaround until we get the whole telegram data in response - telegramChannelStore.updateItems(); - } - if (query?.template) { this.openEditTemplateModal(query.template, query.routeId && query.routeId); } @@ -311,7 +306,7 @@ class Integration2 extends React.Component border={getVar('--border-weak')} className={cx('tag')} > - + Templates @@ -677,7 +672,7 @@ const IntegrationSendDemoPayloadModal: React.FC = ({ alertReceiveChannel, changeIsTemplateSettingsOpen, }) => { - const { maintenanceStore, alertReceiveChannelStore } = useStore(); + const { maintenanceStore, alertReceiveChannelStore, heartbeatStore } = useStore(); const history = useHistory(); @@ -830,11 +825,13 @@ const IntegrationActions: React.FC = ({ Integration Settings
- -
setIsHearbeatFormOpen(true)}> - Hearbeat Settings -
-
+ {showHeartbeatSettings() && ( + +
setIsHearbeatFormOpen(true)}> + Heartbeat Settings +
+
+ )} {!alertReceiveChannel.maintenance_till && ( @@ -935,6 +932,12 @@ const IntegrationActions: React.FC = ({ ); + function showHeartbeatSettings() { + const heartbeatId = alertReceiveChannelStore.alertReceiveChannelToHeartbeat[alertReceiveChannel.id]; + const heartbeat = heartbeatStore.items[heartbeatId]; + return !!heartbeat?.last_heartbeat_time_verbal; + } + function deleteIntegration() { alertReceiveChannelStore .deleteAlertReceiveChannel(alertReceiveChannel.id) @@ -976,7 +979,7 @@ const HowToConnectComponent: React.FC<{ id: AlertReceiveChannel['id'] }> = ({ id border={getVar('--border-weak')} className={cx('how-to-connect__tag')} > - + HTTP Endpoint @@ -1082,20 +1085,22 @@ const IntegrationHeader: React.FC = ({ {renderHearbeat(alertReceiveChannel)} -
- Type: - - - {integration?.display_name} - -
-
- Team: - -
-
- Created by: - +
+
+ Type: + + + {integration?.display_name} + +
+
+ Team: + +
+
+ Created by: + +
); diff --git a/grafana-plugin/src/pages/integration_2/Integration2Common.config.ts b/grafana-plugin/src/pages/integration_2/Integration2Common.config.ts new file mode 100644 index 00000000..1ff003cf --- /dev/null +++ b/grafana-plugin/src/pages/integration_2/Integration2Common.config.ts @@ -0,0 +1,129 @@ +import { KeyValuePair } from 'utils'; + +export const TEXTAREA_ROWS_COUNT = 4; +export const MAX_CHARACTERS_COUNT = 50; + +export const MONACO_OPTIONS = { + renderLineHighlight: false, + readOnly: true, + scrollbar: { + vertical: 'hidden', + horizontal: 'hidden', + verticalScrollbarSize: 0, + handleMouseWheel: false, + }, + hideCursorInOverviewRuler: true, + minimap: { enabled: false }, + cursorStyle: { + display: 'none', + }, +}; + +export const MONACO_PAYLOAD_OPTIONS = { + renderLineHighlight: false, + readOnly: false, + hideCursorInOverviewRuler: true, + minimap: { enabled: false }, + cursorStyle: { + display: 'none', + }, +}; + +export const MONACO_INPUT_HEIGHT_SMALL = '32px'; +export const MONACO_INPUT_HEIGHT_TALL = '120px'; + +export const BaseTemplateOptions = { + WebTitle: new KeyValuePair('web_title_template', 'Web Title'), + WebMessage: new KeyValuePair('web_message_template', 'Web Message'), + WebImage: new KeyValuePair('web_image_url_template', 'Web Image'), + Grouping: new KeyValuePair('grouping_id_template', 'Grouping'), + Resolve: new KeyValuePair('resolve_condition_template', 'Resolve condition'), + Routing: new KeyValuePair('route_template', 'Routing'), + + SourceLink: new KeyValuePair('source_link_template', 'Source Link'), + Autoacknowledge: new KeyValuePair('acknowledge_condition_template', 'Autoacknowledge'), + Phone: new KeyValuePair('phone_call_title_template', 'Phone'), + SMS: new KeyValuePair('sms_title_template', 'SMS'), + SlackTitle: new KeyValuePair('slack_title_template', 'Title'), + SlackMessage: new KeyValuePair('slack_message_template', 'Message'), + SlackImage: new KeyValuePair('slack_image_url_template', 'Image'), + EmailTitle: new KeyValuePair('email_title_template', 'Title'), + EmailMessage: new KeyValuePair('email_message_template', 'Message'), + TelegramTitle: new KeyValuePair('telegram_title_template', 'Title'), + TelegramMessage: new KeyValuePair('telegram_message_template', 'Message'), + TelegramImage: new KeyValuePair('telegram_image_url_template', 'Image'), + + Email: new KeyValuePair('Email', 'Email'), + Slack: new KeyValuePair('Slack', 'Slack'), + MSTeams: new KeyValuePair('Microsoft Teams', 'Microsoft Teams'), + Telegram: new KeyValuePair('Telegram', 'Telegram'), +}; + +export const BASE_INTEGRATION_TEMPLATES_LIST = [ + { + label: BaseTemplateOptions.SourceLink.value, + value: BaseTemplateOptions.SourceLink.key, + }, + { + label: BaseTemplateOptions.Autoacknowledge.value, + value: BaseTemplateOptions.Autoacknowledge.key, + }, + { + label: BaseTemplateOptions.Phone.value, + value: BaseTemplateOptions.Phone.key, + }, + { + label: BaseTemplateOptions.SMS.value, + value: BaseTemplateOptions.SMS.key, + }, + { + label: BaseTemplateOptions.Email.value, + value: BaseTemplateOptions.Email.key, + children: [ + { + label: BaseTemplateOptions.EmailTitle.value, + value: BaseTemplateOptions.EmailTitle.key, + }, + { + label: BaseTemplateOptions.EmailMessage.value, + value: BaseTemplateOptions.EmailMessage.key, + }, + ], + }, + { + label: BaseTemplateOptions.Slack.value, + value: BaseTemplateOptions.Slack.key, + children: [ + { + label: BaseTemplateOptions.SlackTitle.value, + value: BaseTemplateOptions.SlackTitle.key, + }, + { + label: BaseTemplateOptions.SlackMessage.value, + value: BaseTemplateOptions.SlackMessage.key, + }, + { + label: BaseTemplateOptions.SlackImage.value, + value: BaseTemplateOptions.SlackImage.key, + }, + ], + }, + { + label: BaseTemplateOptions.Telegram.value, + value: BaseTemplateOptions.Telegram.key, + children: [ + { + label: BaseTemplateOptions.TelegramTitle.value, + value: BaseTemplateOptions.TelegramTitle.key, + }, + { + label: BaseTemplateOptions.TelegramMessage.value, + value: BaseTemplateOptions.TelegramMessage.key, + }, + { + label: BaseTemplateOptions.TelegramImage.value, + value: BaseTemplateOptions.TelegramImage.key, + }, + ], + }, +]; diff --git a/grafana-plugin/src/pages/integrations_2/Integrations2.module.scss b/grafana-plugin/src/pages/integrations_2/Integrations2.module.scss index 4f86de25..7274e16f 100644 --- a/grafana-plugin/src/pages/integrations_2/Integrations2.module.scss +++ b/grafana-plugin/src/pages/integrations_2/Integrations2.module.scss @@ -44,4 +44,4 @@ &:hover { background: var(--gray-9); } -} \ No newline at end of file +} diff --git a/grafana-plugin/src/pages/integrations_2/Integrations2.tsx b/grafana-plugin/src/pages/integrations_2/Integrations2.tsx index 66ee4d3f..f26c035a 100644 --- a/grafana-plugin/src/pages/integrations_2/Integrations2.tsx +++ b/grafana-plugin/src/pages/integrations_2/Integrations2.tsx @@ -74,6 +74,7 @@ class Integrations extends React.Component const { query: { p }, } = this.props; + this.setState({ page: p ? Number(p) : 1 }, this.update); this.parseQueryParams(); diff --git a/grafana-plugin/src/style/utils.css b/grafana-plugin/src/style/utils.css index faefb202..d3a37abc 100644 --- a/grafana-plugin/src/style/utils.css +++ b/grafana-plugin/src/style/utils.css @@ -68,3 +68,15 @@ margin-top: 8px; opacity: 15%; } + +.u-flex-xs { + gap: 4px; +} + +.u-margin-right-xs { + margin-right: 4px; +} + +.u-margin-right-md { + margin-right: 8px; +}