import { BeakerIcon, SaveIcon } from '@heroicons/react/solid'; import axios from 'axios'; import { Field, Form, Formik } from 'formik'; import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; import useSWR from 'swr'; import * as Yup from 'yup'; import globalMessages from '../../../../i18n/globalMessages'; import Button from '../../../Common/Button'; import LoadingSpinner from '../../../Common/LoadingSpinner'; import NotificationTypeSelector from '../../../NotificationTypeSelector'; const messages = defineMessages({ agentenabled: 'Enable Agent', url: 'Server URL', token: 'Application Token', validationUrlRequired: 'You must provide a valid URL', validationUrlTrailingSlash: 'URL must not end in a trailing slash', validationTokenRequired: 'You must provide an application token', gotifysettingssaved: 'Gotify notification settings saved successfully!', gotifysettingsfailed: 'Gotify notification settings failed to save.', toastGotifyTestSending: 'Sending Gotify test notification…', toastGotifyTestSuccess: 'Gotify test notification sent!', toastGotifyTestFailed: 'Gotify test notification failed to send.', validationTypes: 'You must select at least one notification type', }); const NotificationsGotify: React.FC = () => { const intl = useIntl(); const { addToast, removeToast } = useToasts(); const [isTesting, setIsTesting] = useState(false); const { data, error, mutate: revalidate, } = useSWR('/api/v1/settings/notifications/gotify'); const NotificationsGotifySchema = Yup.object().shape({ url: Yup.string() .when('enabled', { is: true, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationUrlRequired)), otherwise: Yup.string().nullable(), }) .matches( // eslint-disable-next-line no-useless-escape /^(https?:)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*)?([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i, intl.formatMessage(messages.validationUrlRequired) ) .test( 'no-trailing-slash', intl.formatMessage(messages.validationUrlTrailingSlash), (value) => !value || !value.endsWith('/') ), token: Yup.string().when('enabled', { is: true, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationTokenRequired)), otherwise: Yup.string().nullable(), }), }); if (!data && !error) { return ; } return ( { try { await axios.post('/api/v1/settings/notifications/gotify', { enabled: values.enabled, types: values.types, options: { url: values.url, token: values.token, }, }); addToast(intl.formatMessage(messages.gotifysettingssaved), { appearance: 'success', autoDismiss: true, }); } catch (e) { addToast(intl.formatMessage(messages.gotifysettingsfailed), { appearance: 'error', autoDismiss: true, }); } finally { revalidate(); } }} > {({ errors, touched, isSubmitting, values, isValid, setFieldValue, setFieldTouched, }) => { const testSettings = async () => { setIsTesting(true); let toastId: string | undefined; try { addToast( intl.formatMessage(messages.toastGotifyTestSending), { autoDsmiss: false, appearance: 'info', }, (id) => { toastId = id; } ); await axios.post('/api/v1/settings/notifications/gotify/test', { enabled: true, types: values.types, options: { url: values.url, token: values.token, }, }); if (toastId) { removeToast(toastId); } addToast(intl.formatMessage(messages.toastGotifyTestSuccess), { autoDismiss: true, appearance: 'success', }); } catch (e) { if (toastId) { removeToast(toastId); } addToast(intl.formatMessage(messages.toastGotifyTestFailed), { autoDismiss: true, appearance: 'error', }); } finally { setIsTesting(false); } }; return (
{errors.url && touched.url && (
{errors.url}
)}
{errors.token && touched.token && (
{errors.token}
)}
{ setFieldValue('types', newTypes); setFieldTouched('types'); if (newTypes) { setFieldValue('enabled', true); } }} error={ values.enabled && !values.types && touched.types ? intl.formatMessage(messages.validationTypes) : undefined } />
); }}
); }; export default NotificationsGotify;