{
interface ResultProps {
alertReceiveChannelId: AlertReceiveChannel['id'];
- templateName: string;
+ // templateName: string;
templateBody: string;
+ template: TemplateForEdit;
alertGroup?: Alert;
- chatOps?: { permalink: string; name: string; comment?: string };
+ chatOpsPermalink?: string;
payload?: JSON;
error?: string;
onSaveAndFollowLink?: (link: string) => void;
}
const Result = (props: ResultProps) => {
- const { alertReceiveChannelId, templateName, chatOps, payload, templateBody, error, onSaveAndFollowLink } = props;
+ const { alertReceiveChannelId, template, templateBody, chatOpsPermalink, payload, error, onSaveAndFollowLink } =
+ props;
const getCapitalizedChatopsName = (name: string) => {
return name.charAt(0).toUpperCase() + name.slice(1);
@@ -271,8 +271,8 @@ const Result = (props: ResultProps) => {
) : (
{
)}
- {chatOps && (
+ {template?.additionalData?.additionalDescription && (
+ {template?.additionalData.additionalDescription}
+ )}
+
+ {template?.additionalData?.chatOpsName && (
-
)}
) : (
- You do not have any input data to render result. Please select Alert group to see end result
+ ← Select alert group or "Use custom payload"
)}
diff --git a/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx b/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx
index 06f98e40..e9713449 100644
--- a/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx
+++ b/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx
@@ -35,7 +35,7 @@ export const form: { name: string; fields: FormItem[] } = {
name: 'team',
label: 'Assign to Team',
description:
- 'Assigning to the teams allows you to filter Outgoing Webhooks and configure their visibility. Go to OnCall -> Settings -> Team and Access Settings for more details',
+ 'Assigning to the teams allows you to filter Outgoing Webhooks and configure their visibility. Go to OnCall -> Settings -> Team and Access Settings for more details. This setting does not effect execution of the webhook.',
type: FormItemType.GSelect,
extra: {
modelName: 'grafanaTeamStore',
@@ -48,6 +48,7 @@ export const form: { name: string; fields: FormItem[] } = {
{
name: 'trigger_type',
label: 'Trigger Type',
+ description: 'The type of event which will cause this webhook to execute.',
type: FormItemType.Select,
extra: {
options: [
@@ -135,7 +136,7 @@ export const form: { name: string; fields: FormItem[] } = {
},
validation: { required: true },
description:
- 'Integrations that this webhook applies to. If this is empty the webhook will apply to all integrations',
+ 'Integrations that this webhook applies to. If this is empty the webhook will execute for all integrations',
},
{
name: 'url',
@@ -146,6 +147,7 @@ export const form: { name: string; fields: FormItem[] } = {
{
name: 'headers',
label: 'Webhook Headers',
+ description: 'Request headers should be in JSON format.',
type: FormItemType.TextArea,
extra: {
rows: 3,
@@ -161,6 +163,8 @@ export const form: { name: string; fields: FormItem[] } = {
},
{
name: 'authorization_header',
+ description:
+ 'Value of the Authorization header, do not need to prefix with "Authorization:". For example: Bearer AbCdEf123456',
type: FormItemType.Password,
},
{
@@ -176,13 +180,14 @@ export const form: { name: string; fields: FormItem[] } = {
name: 'forward_all',
normalize: (value) => Boolean(value),
type: FormItemType.Switch,
- description: "Forwards whole payload of the alert to the webhook's url as POST/PUT data",
+ description: "Forwards whole payload of the alert group and context data to the webhook's url as POST/PUT data",
},
{
name: 'data',
getDisabled: (data) => Boolean(data?.forward_all),
type: FormItemType.TextArea,
- description: 'Available variables: {{ alert_payload }}, {{ alert_group_id }}',
+ description:
+ 'Available variables: {{ event }}, {{ user }}, {{ alert_group }}, {{ alert_group_id }}, {{ alert_payload }}, {{ integration }}, {{ notified_users }}, {{ users_to_be_notified }}, {{ responses }}',
extra: {
rows: 9,
},
diff --git a/grafana-plugin/src/pages/integration_2/Integration2.tsx b/grafana-plugin/src/pages/integration_2/Integration2.tsx
index 57d5dbe4..c7d3412e 100644
--- a/grafana-plugin/src/pages/integration_2/Integration2.tsx
+++ b/grafana-plugin/src/pages/integration_2/Integration2.tsx
@@ -22,7 +22,8 @@ import Emoji from 'react-emoji-render';
import { RouteComponentProps, useHistory, withRouter } from 'react-router-dom';
import { debounce } from 'throttle-debounce';
-import { TemplateForEdit, templateForEdit } from 'components/AlertTemplates/AlertTemplatesForm.config';
+import { templateForEdit } from 'components/AlertTemplates/AlertTemplatesForm.config';
+import { TemplateForEdit } from 'components/AlertTemplates/CommonAlertTemplatesForm.config';
import HamburgerMenu from 'components/HamburgerMenu/HamburgerMenu';
import IntegrationCollapsibleTreeView, {
IntegrationCollapsibleItem,
@@ -60,6 +61,7 @@ import { MaintenanceType } from 'models/maintenance/maintenance.types';
import { INTEGRATION_TEMPLATES_LIST, MONACO_PAYLOAD_OPTIONS } 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';
@@ -81,8 +83,8 @@ interface Integration2State extends PageBaseState {
isEditRegexpRouteTemplateModalOpen: boolean;
channelFilterIdForEdit: ChannelFilter['id'];
isTemplateSettingsOpen: boolean;
- newRoutes: string[];
isAddingRoute: boolean;
+ openRoutes: string[];
}
const ACTIONS_LIST_WIDTH = 200;
@@ -102,8 +104,8 @@ class Integration2 extends React.Component
isEditRegexpRouteTemplateModalOpen: false,
channelFilterIdForEdit: undefined,
isTemplateSettingsOpen: false,
- newRoutes: [],
isAddingRoute: false,
+ openRoutes: [],
};
}
@@ -116,9 +118,15 @@ class Integration2 extends React.Component
} = this.props;
const {
- store: { alertReceiveChannelStore },
+ store,
+ store: { alertReceiveChannelStore, telegramChannelStore },
} = 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);
}
@@ -416,7 +424,10 @@ class Integration2 extends React.Component
filtering_term_type: 1, // non-regex
})
.then(async (channelFilter: ChannelFilter) => {
- this.setState({ isAddingRoute: false, newRoutes: this.state.newRoutes.concat(channelFilter.id) });
+ this.setState((prevState) => ({
+ isAddingRoute: false,
+ openRoutes: prevState.openRoutes.concat(channelFilter.id),
+ }));
await alertReceiveChannelStore.updateChannelFilters(id, true);
await escalationPolicyStore.updateEscalationPolicies(channelFilter.escalation_chain);
openNotification('A new route has been added');
@@ -439,6 +450,8 @@ class Integration2 extends React.Component
},
} = this.props;
+ const { openRoutes } = this.state;
+
const templates = alertReceiveChannelStore.templates[id];
const channelFilterIds = alertReceiveChannelStore.channelFilterIds[id];
@@ -447,13 +460,14 @@ class Integration2 extends React.Component
({
canHoverIcon: true,
isCollapsible: true,
- // this will keep new routes expanded at the very first time
- isExpanded: this.state.newRoutes.indexOf(channelFilterId) > -1 ? true : false,
- onStateChange: () => {
- if (this.state.newRoutes.indexOf(channelFilterId) > -1) {
- // this will close them on user action
- this.setState((prevState) => ({ newRoutes: prevState.newRoutes.filter((r) => r !== channelFilterId) }));
- }
+ isExpanded: openRoutes.indexOf(channelFilterId) > -1,
+ onStateChange: (isChecked: boolean) => {
+ const newOpenRoutes = [...openRoutes];
+ this.setState({
+ openRoutes: isChecked
+ ? newOpenRoutes.concat(channelFilterId)
+ : newOpenRoutes.filter((filterId) => filterId !== channelFilterId),
+ });
},
collapsedView: (toggle) => (