mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 05:45:56 +08:00
(feature): UI for Test alert channels (#994)
* (feature): Implemented test channel function for webhook and slack
This commit is contained in:
parent
508c6ced80
commit
2b5b79e34a
30
frontend/public/locales/en-GB/channels.json
Normal file
30
frontend/public/locales/en-GB/channels.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"page_title_create": "New Notification Channels",
|
||||
"page_title_edit": "Edit Notification Channels",
|
||||
"button_save_channel": "Save",
|
||||
"button_test_channel": "Test",
|
||||
"button_return": "Back",
|
||||
"field_channel_name": "Name",
|
||||
"field_channel_type": "Type",
|
||||
"field_webhook_url": "Webhook URL",
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
"field_slack_description": "Description",
|
||||
"field_webhook_username": "User Name (optional)",
|
||||
"field_webhook_password": "Password (optional)",
|
||||
"placeholder_slack_description": "Description",
|
||||
"help_webhook_username": "Leave empty for bearer auth or when authentication is not necessary.",
|
||||
"help_webhook_password": "Specify a password or bearer token",
|
||||
"channel_creation_done": "Successfully created the channel",
|
||||
"channel_creation_failed": "An unexpected error occurred while creating this channel",
|
||||
"channel_edit_done": "Channels Edited Successfully",
|
||||
"channel_edit_failed": "An unexpected error occurred while updating this channel",
|
||||
"selected_channel_invalid": "Channel type selected is invalid",
|
||||
"username_no_password": "A Password must be provided with user name",
|
||||
"test_unsupported": "Sorry, this channel type does not support test yet",
|
||||
"channel_test_done": "An alert has been sent to this channel",
|
||||
"channel_test_failed": "Failed to send a test message to this channel, please confirm that the parameters are set correctly",
|
||||
"channel_test_unexpected": "An unexpected error occurred while sending a message to this channel, please try again",
|
||||
"webhook_url_required": "Webhook URL is mandatory",
|
||||
"slack_channel_help": "Specify channel or user, use #channel-name, @username (has to be all lowercase, no whitespace)"
|
||||
}
|
30
frontend/public/locales/en/channels.json
Normal file
30
frontend/public/locales/en/channels.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"page_title_create": "New Notification Channels",
|
||||
"page_title_edit": "Edit Notification Channels",
|
||||
"button_save_channel": "Save",
|
||||
"button_test_channel": "Test",
|
||||
"button_return": "Back",
|
||||
"field_channel_name": "Name",
|
||||
"field_channel_type": "Type",
|
||||
"field_webhook_url": "Webhook URL",
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
"field_slack_description": "Description",
|
||||
"field_webhook_username": "User Name (optional)",
|
||||
"field_webhook_password": "Password (optional)",
|
||||
"placeholder_slack_description": "Description",
|
||||
"help_webhook_username": "Leave empty for bearer auth or when authentication is not necessary.",
|
||||
"help_webhook_password": "Specify a password or bearer token",
|
||||
"channel_creation_done": "Successfully created the channel",
|
||||
"channel_creation_failed": "An unexpected error occurred while creating this channel",
|
||||
"channel_edit_done": "Channels Edited Successfully",
|
||||
"channel_edit_failed": "An unexpected error occurred while updating this channel",
|
||||
"selected_channel_invalid": "Channel type selected is invalid",
|
||||
"username_no_password": "A Password must be provided with user name",
|
||||
"test_unsupported": "Sorry, this channel type does not support test yet",
|
||||
"channel_test_done": "An alert has been sent to this channel",
|
||||
"channel_test_failed": "Failed to send a test message to this channel, please confirm that the parameters are set correctly",
|
||||
"channel_test_unexpected": "An unexpected error occurred while sending a message to this channel, please try again",
|
||||
"webhook_url_required": "Webhook URL is mandatory",
|
||||
"slack_channel_help": "Specify channel or user, use #channel-name, @username (has to be all lowercase, no whitespace)"
|
||||
}
|
35
frontend/src/api/channels/testSlack.ts
Normal file
35
frontend/src/api/channels/testSlack.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/channels/createSlack';
|
||||
|
||||
const testSlack = async (
|
||||
props: Props,
|
||||
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await axios.post('/testChannel', {
|
||||
name: props.name,
|
||||
slack_configs: [
|
||||
{
|
||||
send_resolved: true,
|
||||
api_url: props.api_url,
|
||||
channel: props.channel,
|
||||
title: props.title,
|
||||
text: props.text,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: 'Success',
|
||||
payload: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
}
|
||||
};
|
||||
|
||||
export default testSlack;
|
51
frontend/src/api/channels/testWebhook.ts
Normal file
51
frontend/src/api/channels/testWebhook.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/channels/createWebhook';
|
||||
|
||||
const testWebhook = async (
|
||||
props: Props,
|
||||
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
|
||||
try {
|
||||
let httpConfig = {};
|
||||
|
||||
if (props.username !== '' && props.password !== '') {
|
||||
httpConfig = {
|
||||
basic_auth: {
|
||||
username: props.username,
|
||||
password: props.password,
|
||||
},
|
||||
};
|
||||
} else if (props.username === '' && props.password !== '') {
|
||||
httpConfig = {
|
||||
authorization: {
|
||||
type: 'bearer',
|
||||
credentials: props.password,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const response = await axios.post('/testChannel', {
|
||||
name: props.name,
|
||||
webhook_configs: [
|
||||
{
|
||||
send_resolved: true,
|
||||
url: props.api_url,
|
||||
http_config: httpConfig,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: 'Success',
|
||||
payload: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
}
|
||||
};
|
||||
|
||||
export default testWebhook;
|
@ -1,10 +1,13 @@
|
||||
import { Form, notification } from 'antd';
|
||||
import createSlackApi from 'api/channels/createSlack';
|
||||
import createWebhookApi from 'api/channels/createWebhook';
|
||||
import testSlackApi from 'api/channels/testSlack';
|
||||
import testWebhookApi from 'api/channels/testWebhook';
|
||||
import ROUTES from 'constants/routes';
|
||||
import FormAlertChannels from 'container/FormAlertChannels';
|
||||
import history from 'lib/history';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
ChannelType,
|
||||
@ -17,6 +20,9 @@ import {
|
||||
function CreateAlertChannels({
|
||||
preType = 'slack',
|
||||
}: CreateAlertChannelsProps): JSX.Element {
|
||||
// init namespace for translations
|
||||
const { t } = useTranslation('channels');
|
||||
|
||||
const [formInstance] = Form.useForm();
|
||||
|
||||
const [selectedConfig, setSelectedConfig] = useState<
|
||||
@ -45,6 +51,7 @@ function CreateAlertChannels({
|
||||
{{- end }}`,
|
||||
});
|
||||
const [savingState, setSavingState] = useState<boolean>(false);
|
||||
const [testingState, setTestingState] = useState<boolean>(false);
|
||||
const [notifications, NotificationElement] = notification.useNotification();
|
||||
|
||||
const [type, setType] = useState<ChannelType>(preType);
|
||||
@ -52,26 +59,26 @@ function CreateAlertChannels({
|
||||
setType(value as ChannelType);
|
||||
}, []);
|
||||
|
||||
const onTestHandler = useCallback(() => {
|
||||
console.log('test');
|
||||
}, []);
|
||||
const prepareSlackRequest = useCallback(() => {
|
||||
return {
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
channel: selectedConfig?.channel || '',
|
||||
name: selectedConfig?.name || '',
|
||||
send_resolved: true,
|
||||
text: selectedConfig?.text || '',
|
||||
title: selectedConfig?.title || '',
|
||||
};
|
||||
}, [selectedConfig]);
|
||||
|
||||
const onSlackHandler = useCallback(async () => {
|
||||
try {
|
||||
setSavingState(true);
|
||||
const response = await createSlackApi({
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
channel: selectedConfig?.channel || '',
|
||||
name: selectedConfig?.name || '',
|
||||
send_resolved: true,
|
||||
text: selectedConfig?.text || '',
|
||||
title: selectedConfig?.title || '',
|
||||
});
|
||||
const response = await createSlackApi(prepareSlackRequest());
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: 'Successfully created the channel',
|
||||
description: t('channel_creation_done'),
|
||||
});
|
||||
setTimeout(() => {
|
||||
history.replace(ROUTES.SETTINGS);
|
||||
@ -79,21 +86,20 @@ function CreateAlertChannels({
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: response.error || 'Error while creating the channel',
|
||||
description: response.error || t('channel_creation_failed'),
|
||||
});
|
||||
}
|
||||
setSavingState(false);
|
||||
} catch (error) {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description:
|
||||
'An unexpected error occurred while creating this channel, please try again',
|
||||
description: t('channel_creation_failed'),
|
||||
});
|
||||
setSavingState(false);
|
||||
}
|
||||
}, [notifications, selectedConfig]);
|
||||
}, [prepareSlackRequest, t, notifications]);
|
||||
|
||||
const onWebhookHandler = useCallback(async () => {
|
||||
const prepareWebhookRequest = useCallback(() => {
|
||||
// initial api request without auth params
|
||||
let request: WebhookChannel = {
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
@ -101,39 +107,42 @@ function CreateAlertChannels({
|
||||
send_resolved: true,
|
||||
};
|
||||
|
||||
setSavingState(true);
|
||||
|
||||
try {
|
||||
if (selectedConfig?.username !== '' || selectedConfig?.password !== '') {
|
||||
if (selectedConfig?.username !== '') {
|
||||
// if username is not null then password must be passed
|
||||
if (selectedConfig?.password !== '') {
|
||||
request = {
|
||||
...request,
|
||||
username: selectedConfig.username,
|
||||
password: selectedConfig.password,
|
||||
};
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: 'A Password must be provided with user name',
|
||||
});
|
||||
}
|
||||
} else if (selectedConfig?.password !== '') {
|
||||
// only password entered, set bearer token
|
||||
if (selectedConfig?.username !== '' || selectedConfig?.password !== '') {
|
||||
if (selectedConfig?.username !== '') {
|
||||
// if username is not null then password must be passed
|
||||
if (selectedConfig?.password !== '') {
|
||||
request = {
|
||||
...request,
|
||||
username: '',
|
||||
username: selectedConfig.username,
|
||||
password: selectedConfig.password,
|
||||
};
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('username_no_password'),
|
||||
});
|
||||
}
|
||||
} else if (selectedConfig?.password !== '') {
|
||||
// only password entered, set bearer token
|
||||
request = {
|
||||
...request,
|
||||
username: '',
|
||||
password: selectedConfig.password,
|
||||
};
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}, [notifications, t, selectedConfig]);
|
||||
|
||||
const onWebhookHandler = useCallback(async () => {
|
||||
setSavingState(true);
|
||||
try {
|
||||
const request = prepareWebhookRequest();
|
||||
const response = await createWebhookApi(request);
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: 'Successfully created the channel',
|
||||
description: t('channel_creation_done'),
|
||||
});
|
||||
setTimeout(() => {
|
||||
history.replace(ROUTES.SETTINGS);
|
||||
@ -141,19 +150,17 @@ function CreateAlertChannels({
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: response.error || 'Error while creating the channel',
|
||||
description: response.error || t('channel_creation_failed'),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description:
|
||||
'An unexpected error occurred while creating this channel, please try again',
|
||||
description: t('channel_creation_failed'),
|
||||
});
|
||||
}
|
||||
setSavingState(false);
|
||||
}, [notifications, selectedConfig]);
|
||||
|
||||
}, [prepareWebhookRequest, t, notifications]);
|
||||
const onSaveHandler = useCallback(
|
||||
async (value: ChannelType) => {
|
||||
switch (value) {
|
||||
@ -166,11 +173,64 @@ function CreateAlertChannels({
|
||||
default:
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: 'channel type selected is invalid',
|
||||
description: t('selected_channel_invalid'),
|
||||
});
|
||||
}
|
||||
},
|
||||
[onSlackHandler, onWebhookHandler, notifications],
|
||||
[onSlackHandler, t, onWebhookHandler, notifications],
|
||||
);
|
||||
|
||||
const performChannelTest = useCallback(
|
||||
async (channelType: ChannelType) => {
|
||||
setTestingState(true);
|
||||
try {
|
||||
let request;
|
||||
let response;
|
||||
switch (channelType) {
|
||||
case WebhookType:
|
||||
request = prepareWebhookRequest();
|
||||
response = await testWebhookApi(request);
|
||||
break;
|
||||
case SlackType:
|
||||
request = prepareSlackRequest();
|
||||
response = await testSlackApi(request);
|
||||
break;
|
||||
default:
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('test_unsupported'),
|
||||
});
|
||||
setTestingState(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: t('channel_test_done'),
|
||||
});
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('channel_test_failed'),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('channel_test_unexpected'),
|
||||
});
|
||||
}
|
||||
setTestingState(false);
|
||||
},
|
||||
[prepareWebhookRequest, t, prepareSlackRequest, notifications],
|
||||
);
|
||||
|
||||
const onTestHandler = useCallback(
|
||||
async (value: ChannelType) => {
|
||||
performChannelTest(value);
|
||||
},
|
||||
[performChannelTest],
|
||||
);
|
||||
|
||||
return (
|
||||
@ -183,8 +243,9 @@ function CreateAlertChannels({
|
||||
onTestHandler,
|
||||
onSaveHandler,
|
||||
savingState,
|
||||
testingState,
|
||||
NotificationElement,
|
||||
title: 'New Notification Channels',
|
||||
title: t('page_title_create'),
|
||||
initialValue: {
|
||||
type,
|
||||
...selectedConfig,
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { Form, notification } from 'antd';
|
||||
import editSlackApi from 'api/channels/editSlack';
|
||||
import editWebhookApi from 'api/channels/editWebhook';
|
||||
import testSlackApi from 'api/channels/testSlack';
|
||||
import testWebhookApi from 'api/channels/testWebhook';
|
||||
import ROUTES from 'constants/routes';
|
||||
import {
|
||||
ChannelType,
|
||||
@ -12,11 +14,15 @@ import {
|
||||
import FormAlertChannels from 'container/FormAlertChannels';
|
||||
import history from 'lib/history';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
function EditAlertChannels({
|
||||
initialValue,
|
||||
}: EditAlertChannelsProps): JSX.Element {
|
||||
// init namespace for translations
|
||||
const { t } = useTranslation('channels');
|
||||
|
||||
const [formInstance] = Form.useForm();
|
||||
const [selectedConfig, setSelectedConfig] = useState<
|
||||
Partial<SlackChannel & WebhookChannel>
|
||||
@ -24,6 +30,7 @@ function EditAlertChannels({
|
||||
...initialValue,
|
||||
});
|
||||
const [savingState, setSavingState] = useState<boolean>(false);
|
||||
const [testingState, setTestingState] = useState<boolean>(false);
|
||||
const [notifications, NotificationElement] = notification.useNotification();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
@ -35,9 +42,8 @@ function EditAlertChannels({
|
||||
setType(value as ChannelType);
|
||||
}, []);
|
||||
|
||||
const onSlackEditHandler = useCallback(async () => {
|
||||
setSavingState(true);
|
||||
const response = await editSlackApi({
|
||||
const prepareSlackRequest = useCallback(() => {
|
||||
return {
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
channel: selectedConfig?.channel || '',
|
||||
name: selectedConfig?.name || '',
|
||||
@ -45,12 +51,27 @@ function EditAlertChannels({
|
||||
text: selectedConfig?.text || '',
|
||||
title: selectedConfig?.title || '',
|
||||
id,
|
||||
});
|
||||
};
|
||||
}, [id, selectedConfig]);
|
||||
|
||||
const onSlackEditHandler = useCallback(async () => {
|
||||
setSavingState(true);
|
||||
|
||||
if (selectedConfig?.api_url === '') {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('webhook_url_required'),
|
||||
});
|
||||
setSavingState(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await editSlackApi(prepareSlackRequest());
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: 'Channels Edited Successfully',
|
||||
description: t('channel_edit_done'),
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
@ -59,15 +80,27 @@ function EditAlertChannels({
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: response.error || 'error while updating the Channels',
|
||||
description: response.error || t('channel_edit_failed'),
|
||||
});
|
||||
}
|
||||
setSavingState(false);
|
||||
}, [selectedConfig, notifications, id]);
|
||||
}, [prepareSlackRequest, t, notifications, selectedConfig]);
|
||||
|
||||
const prepareWebhookRequest = useCallback(() => {
|
||||
const { name, username, password } = selectedConfig;
|
||||
return {
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
name: name || '',
|
||||
send_resolved: true,
|
||||
username,
|
||||
password,
|
||||
id,
|
||||
};
|
||||
}, [id, selectedConfig]);
|
||||
|
||||
const onWebhookEditHandler = useCallback(async () => {
|
||||
setSavingState(true);
|
||||
const { name, username, password } = selectedConfig;
|
||||
const { username, password } = selectedConfig;
|
||||
|
||||
const showError = (msg: string): void => {
|
||||
notifications.error({
|
||||
@ -77,40 +110,33 @@ function EditAlertChannels({
|
||||
};
|
||||
|
||||
if (selectedConfig?.api_url === '') {
|
||||
showError('Webhook URL is mandatory');
|
||||
showError(t('webhook_url_required'));
|
||||
setSavingState(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (username && (!password || password === '')) {
|
||||
showError('Please enter a password');
|
||||
showError(t('username_no_password'));
|
||||
setSavingState(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await editWebhookApi({
|
||||
api_url: selectedConfig?.api_url || '',
|
||||
name: name || '',
|
||||
send_resolved: true,
|
||||
username,
|
||||
password,
|
||||
id,
|
||||
});
|
||||
const response = await editWebhookApi(prepareWebhookRequest());
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: 'Channels Edited Successfully',
|
||||
description: t('channel_edit_done'),
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
history.replace(ROUTES.SETTINGS);
|
||||
}, 2000);
|
||||
} else {
|
||||
showError(response.error || 'error while updating the Channels');
|
||||
showError(response.error || t('channel_edit_failed'));
|
||||
}
|
||||
setSavingState(false);
|
||||
}, [selectedConfig, notifications, id]);
|
||||
}, [prepareWebhookRequest, t, notifications, selectedConfig]);
|
||||
|
||||
const onSaveHandler = useCallback(
|
||||
(value: ChannelType) => {
|
||||
@ -123,9 +149,58 @@ function EditAlertChannels({
|
||||
[onSlackEditHandler, onWebhookEditHandler],
|
||||
);
|
||||
|
||||
const onTestHandler = useCallback(() => {
|
||||
console.log('test');
|
||||
}, []);
|
||||
const performChannelTest = useCallback(
|
||||
async (channelType: ChannelType) => {
|
||||
setTestingState(true);
|
||||
try {
|
||||
let request;
|
||||
let response;
|
||||
switch (channelType) {
|
||||
case WebhookType:
|
||||
request = prepareWebhookRequest();
|
||||
response = await testWebhookApi(request);
|
||||
break;
|
||||
case SlackType:
|
||||
request = prepareSlackRequest();
|
||||
response = await testSlackApi(request);
|
||||
break;
|
||||
default:
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('test_unsupported'),
|
||||
});
|
||||
setTestingState(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success',
|
||||
description: t('channel_test_done'),
|
||||
});
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('channel_test_failed'),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('channel_test_failed'),
|
||||
});
|
||||
}
|
||||
setTestingState(false);
|
||||
},
|
||||
[prepareWebhookRequest, t, prepareSlackRequest, notifications],
|
||||
);
|
||||
|
||||
const onTestHandler = useCallback(
|
||||
async (value: ChannelType) => {
|
||||
performChannelTest(value);
|
||||
},
|
||||
[performChannelTest],
|
||||
);
|
||||
|
||||
return (
|
||||
<FormAlertChannels
|
||||
@ -136,9 +211,10 @@ function EditAlertChannels({
|
||||
type,
|
||||
onTestHandler,
|
||||
onSaveHandler,
|
||||
testingState,
|
||||
savingState,
|
||||
NotificationElement,
|
||||
title: 'Edit Notification Channels',
|
||||
title: t('page_title_edit'),
|
||||
initialValue,
|
||||
nameDisable: true,
|
||||
}}
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { Input } from 'antd';
|
||||
import FormItem from 'antd/lib/form/FormItem';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { SlackChannel } from '../../CreateAlertChannels/config';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
const { t } = useTranslation('channels');
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormItem name="api_url" label="Webhook URL">
|
||||
<FormItem name="api_url" label={t('field_webhook_url')}>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
@ -22,8 +25,8 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
|
||||
<FormItem
|
||||
name="channel"
|
||||
help="Specify channel or user, use #channel-name, @username (has to be all lowercase, no whitespace),"
|
||||
label="Recipient"
|
||||
help={t('slack_channel_help')}
|
||||
label={t('field_slack_recipient')}
|
||||
>
|
||||
<Input
|
||||
onChange={(event): void =>
|
||||
@ -35,7 +38,7 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem name="title" label="Title">
|
||||
<FormItem name="title" label={t('field_slack_title')}>
|
||||
<TextArea
|
||||
rows={4}
|
||||
// value={`[{{ .Status | toUpper }}{{ if eq .Status \"firing\" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}\n{{- if gt (len .CommonLabels) (len .GroupLabels) -}}\n{{\" \"}}(\n{{- with .CommonLabels.Remove .GroupLabels.Names }}\n {{- range $index, $label := .SortedPairs -}}\n {{ if $index }}, {{ end }}\n {{- $label.Name }}=\"{{ $label.Value -}}\"\n {{- end }}\n{{- end -}}\n)\n{{- end }}`}
|
||||
@ -48,7 +51,7 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem name="text" label="Description">
|
||||
<FormItem name="text" label={t('field_slack_description')}>
|
||||
<TextArea
|
||||
onChange={(event): void =>
|
||||
setSelectedConfig((value) => ({
|
||||
@ -56,7 +59,7 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
text: event.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="description"
|
||||
placeholder={t('placeholder_slack_description')}
|
||||
/>
|
||||
</FormItem>
|
||||
</>
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { Input } from 'antd';
|
||||
import FormItem from 'antd/lib/form/FormItem';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { WebhookChannel } from '../../CreateAlertChannels/config';
|
||||
|
||||
function WebhookSettings({ setSelectedConfig }: WebhookProps): JSX.Element {
|
||||
const { t } = useTranslation('channels');
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormItem name="api_url" label="Webhook URL">
|
||||
<FormItem name="api_url" label={t('field_webhook_url')}>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
@ -19,8 +22,8 @@ function WebhookSettings({ setSelectedConfig }: WebhookProps): JSX.Element {
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="username"
|
||||
label="User Name (optional)"
|
||||
help="Leave empty for bearer auth or when authentication is not necessary."
|
||||
label={t('field_webhook_username')}
|
||||
help={t('help_webhook_username')}
|
||||
>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
@ -34,7 +37,7 @@ function WebhookSettings({ setSelectedConfig }: WebhookProps): JSX.Element {
|
||||
<FormItem
|
||||
name="password"
|
||||
label="Password (optional)"
|
||||
help="Specify a password or bearer token"
|
||||
help={t('help_webhook_password')}
|
||||
>
|
||||
<Input
|
||||
type="password"
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
} from 'container/CreateAlertChannels/config';
|
||||
import history from 'lib/history';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import SlackSettings from './Settings/Slack';
|
||||
import WebhookSettings from './Settings/Webhook';
|
||||
@ -23,14 +24,17 @@ function FormAlertChannels({
|
||||
type,
|
||||
setSelectedConfig,
|
||||
onTypeChangeHandler,
|
||||
// onTestHandler,
|
||||
onTestHandler,
|
||||
onSaveHandler,
|
||||
savingState,
|
||||
testingState,
|
||||
NotificationElement,
|
||||
title,
|
||||
initialValue,
|
||||
nameDisable = false,
|
||||
}: FormAlertChannelsProps): JSX.Element {
|
||||
const { t } = useTranslation('channels');
|
||||
|
||||
const renderSettings = (): React.ReactElement | null => {
|
||||
switch (type) {
|
||||
case SlackType:
|
||||
@ -48,7 +52,7 @@ function FormAlertChannels({
|
||||
<Title level={3}>{title}</Title>
|
||||
|
||||
<Form initialValues={initialValue} layout="vertical" form={formInstance}>
|
||||
<FormItem label="Name" labelAlign="left" name="name">
|
||||
<FormItem label={t('field_channel_name')} labelAlign="left" name="name">
|
||||
<Input
|
||||
disabled={nameDisable}
|
||||
onChange={(event): void => {
|
||||
@ -60,7 +64,7 @@ function FormAlertChannels({
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="Type" labelAlign="left" name="type">
|
||||
<FormItem label={t('field_channel_type')} labelAlign="left" name="type">
|
||||
<Select onChange={onTypeChangeHandler} value={type}>
|
||||
<Option value="slack" key="slack">
|
||||
Slack
|
||||
@ -80,15 +84,21 @@ function FormAlertChannels({
|
||||
type="primary"
|
||||
onClick={(): void => onSaveHandler(type)}
|
||||
>
|
||||
Save
|
||||
{t('button_save_channel')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={testingState}
|
||||
loading={testingState}
|
||||
onClick={(): void => onTestHandler(type)}
|
||||
>
|
||||
{t('button_test_channel')}
|
||||
</Button>
|
||||
{/* <Button onClick={onTestHandler}>Test</Button> */}
|
||||
<Button
|
||||
onClick={(): void => {
|
||||
history.replace(ROUTES.SETTINGS);
|
||||
}}
|
||||
>
|
||||
Back
|
||||
{t('button_return')}
|
||||
</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
@ -102,6 +112,8 @@ interface FormAlertChannelsProps {
|
||||
setSelectedConfig: React.Dispatch<React.SetStateAction<Partial<SlackChannel>>>;
|
||||
onTypeChangeHandler: (value: ChannelType) => void;
|
||||
onSaveHandler: (props: ChannelType) => void;
|
||||
onTestHandler: (props: ChannelType) => void;
|
||||
testingState: boolean;
|
||||
savingState: boolean;
|
||||
NotificationElement: React.ReactElement<
|
||||
unknown,
|
||||
|
Loading…
x
Reference in New Issue
Block a user