1 |
- {"version":3,"file":"NewNotificationChannel.f5e783ccddea5ec5863c.js","mappings":"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","sources":["webpack://grafana/./public/app/features/alerting/NewNotificationChannelPage.tsx","webpack://grafana/./public/app/features/alerting/components/OptionElement.tsx","webpack://grafana/./public/app/features/alerting/components/NotificationChannelOptions.tsx","webpack://grafana/./public/app/features/alerting/components/BasicSettings.tsx","webpack://grafana/./public/app/features/alerting/components/ChannelSettings.tsx","webpack://grafana/./public/app/features/alerting/components/NotificationSettings.tsx","webpack://grafana/./public/app/features/alerting/components/NotificationChannelForm.tsx","webpack://grafana/./public/app/features/alerting/state/actions.ts","webpack://grafana/./public/app/features/alerting/utils/notificationChannels.ts"],"sourcesContent":["import React, { PureComponent } from 'react';\nimport { connect, ConnectedProps } from 'react-redux';\n\nimport { config } from '@grafana/runtime';\nimport { Form } from '@grafana/ui';\nimport Page from 'app/core/components/Page/Page';\nimport { getNavModel } from 'app/core/selectors/navModel';\n\nimport { NotificationChannelDTO, StoreState } from '../../types';\n\nimport { NotificationChannelForm } from './components/NotificationChannelForm';\nimport { createNotificationChannel, loadNotificationTypes, testNotificationChannel } from './state/actions';\nimport { resetSecureField } from './state/reducers';\nimport {\n defaultValues,\n mapChannelsToSelectableValue,\n transformSubmitData,\n transformTestData,\n} from './utils/notificationChannels';\n\nclass NewNotificationChannelPage extends PureComponent<Props> {\n componentDidMount() {\n this.props.loadNotificationTypes();\n }\n\n onSubmit = (data: NotificationChannelDTO) => {\n this.props.createNotificationChannel(transformSubmitData({ ...defaultValues, ...data }));\n };\n\n onTestChannel = (data: NotificationChannelDTO) => {\n this.props.testNotificationChannel(transformTestData({ ...defaultValues, ...data }));\n };\n\n render() {\n const { navModel, notificationChannelTypes } = this.props;\n\n return (\n <Page navModel={navModel}>\n <Page.Contents>\n <h2 className=\"page-sub-heading\">New notification channel</h2>\n <Form onSubmit={this.onSubmit} validateOn=\"onChange\" defaultValues={defaultValues} maxWidth={600}>\n {({ register, errors, control, getValues, watch }) => {\n const selectedChannel = notificationChannelTypes.find((c) => c.value === getValues().type.value);\n\n return (\n <NotificationChannelForm\n selectableChannels={mapChannelsToSelectableValue(notificationChannelTypes, true)}\n selectedChannel={selectedChannel}\n onTestChannel={this.onTestChannel}\n register={register}\n errors={errors}\n getValues={getValues}\n control={control}\n watch={watch}\n imageRendererAvailable={config.rendererAvailable}\n resetSecureField={this.props.resetSecureField}\n secureFields={{}}\n />\n );\n }}\n </Form>\n </Page.Contents>\n </Page>\n );\n }\n}\n\nconst mapStateToProps = (state: StoreState) => ({\n navModel: getNavModel(state.navIndex, 'channels'),\n notificationChannelTypes: state.notificationChannel.notificationChannelTypes,\n});\n\nconst mapDispatchToProps = {\n createNotificationChannel,\n loadNotificationTypes,\n testNotificationChannel,\n resetSecureField,\n};\n\nconst connector = connect(mapStateToProps, mapDispatchToProps);\ntype Props = ConnectedProps<typeof connector>;\nexport default connector(NewNotificationChannelPage);\n","import React, { FC } from 'react';\n\nimport { FormAPI, Input, InputControl, Select, TextArea } from '@grafana/ui';\n\nimport { NotificationChannelOption } from '../../../types';\n\ninterface Props extends Pick<FormAPI<any>, 'register' | 'control'> {\n option: NotificationChannelOption;\n invalid?: boolean;\n}\n\nexport const OptionElement: FC<Props> = ({ control, option, register, invalid }) => {\n const modelValue = option.secure ? `secureSettings.${option.propertyName}` : `settings.${option.propertyName}`;\n switch (option.element) {\n case 'input':\n return (\n <Input\n {...register(`${modelValue}`, {\n required: option.required ? 'Required' : false,\n validate: (v) => (option.validationRule !== '' ? validateOption(v, option.validationRule) : true),\n })}\n invalid={invalid}\n type={option.inputType}\n placeholder={option.placeholder}\n />\n );\n\n case 'select':\n return (\n <InputControl\n control={control}\n name={`${modelValue}`}\n render={({ field: { ref, ...field } }) => (\n <Select {...field} options={option.selectOptions ?? undefined} invalid={invalid} />\n )}\n />\n );\n\n case 'textarea':\n return (\n <TextArea\n invalid={invalid}\n {...register(`${modelValue}`, {\n required: option.required ? 'Required' : false,\n validate: (v) => (option.validationRule !== '' ? validateOption(v, option.validationRule) : true),\n })}\n />\n );\n\n default:\n console.error('Element not supported', option.element);\n return null;\n }\n};\n\nconst validateOption = (value: string, validationRule: string) => {\n return RegExp(validationRule).test(value) ? true : 'Invalid format';\n};\n","import React, { FC } from 'react';\n\nimport { SelectableValue } from '@grafana/data';\nimport { Button, Checkbox, Field, Input } from '@grafana/ui';\n\nimport { NotificationChannelDTO, NotificationChannelOption, NotificationChannelSecureFields } from '../../../types';\n\nimport { NotificationSettingsProps } from './NotificationChannelForm';\nimport { OptionElement } from './OptionElement';\n\ninterface Props extends NotificationSettingsProps {\n selectedChannelOptions: NotificationChannelOption[];\n currentFormValues: NotificationChannelDTO;\n secureFields: NotificationChannelSecureFields;\n\n onResetSecureField: (key: string) => void;\n}\n\nexport const NotificationChannelOptions: FC<Props> = ({\n control,\n currentFormValues,\n errors,\n selectedChannelOptions,\n register,\n onResetSecureField,\n secureFields,\n}) => {\n return (\n <>\n {selectedChannelOptions.map((option: NotificationChannelOption, index: number) => {\n const key = `${option.label}-${index}`;\n // Some options can be dependent on other options, this determines what is selected in the dependency options\n // I think this needs more thought.\n const selectedOptionValue =\n currentFormValues[`settings.${option.showWhen.field}`] &&\n (currentFormValues[`settings.${option.showWhen.field}`] as SelectableValue<string>).value;\n\n if (option.showWhen.field && selectedOptionValue !== option.showWhen.is) {\n return null;\n }\n\n if (option.element === 'checkbox') {\n return (\n <Field key={key}>\n <Checkbox\n {...register(\n option.secure ? `secureSettings.${option.propertyName}` : `settings.${option.propertyName}`\n )}\n label={option.label}\n description={option.description}\n />\n </Field>\n );\n }\n return (\n <Field\n key={key}\n label={option.label}\n description={option.description}\n invalid={errors.settings && !!errors.settings[option.propertyName]}\n error={errors.settings && errors.settings[option.propertyName]?.message}\n >\n {secureFields && secureFields[option.propertyName] ? (\n <Input\n readOnly={true}\n value=\"Configured\"\n suffix={\n <Button onClick={() => onResetSecureField(option.propertyName)} fill=\"text\" type=\"button\" size=\"sm\">\n Clear\n </Button>\n }\n />\n ) : (\n <OptionElement option={option} register={register} control={control} />\n )}\n </Field>\n );\n })}\n </>\n );\n};\n","import React, { FC } from 'react';\n\nimport { SelectableValue } from '@grafana/data';\nimport { Field, Input, InputControl, Select } from '@grafana/ui';\n\nimport { NotificationChannelSecureFields, NotificationChannelType } from '../../../types';\n\nimport { NotificationSettingsProps } from './NotificationChannelForm';\nimport { NotificationChannelOptions } from './NotificationChannelOptions';\n\ninterface Props extends NotificationSettingsProps {\n selectedChannel: NotificationChannelType;\n channels: Array<SelectableValue<string>>;\n secureFields: NotificationChannelSecureFields;\n resetSecureField: (key: string) => void;\n}\n\nexport const BasicSettings: FC<Props> = ({\n control,\n currentFormValues,\n errors,\n secureFields,\n selectedChannel,\n channels,\n register,\n resetSecureField,\n}) => {\n return (\n <>\n <Field label=\"Name\" invalid={!!errors.name} error={errors.name && errors.name.message}>\n <Input {...register('name', { required: 'Name is required' })} />\n </Field>\n <Field label=\"Type\">\n <InputControl\n name=\"type\"\n render={({ field: { ref, ...field } }) => <Select {...field} options={channels} />}\n control={control}\n rules={{ required: true }}\n />\n </Field>\n <NotificationChannelOptions\n selectedChannelOptions={selectedChannel.options.filter((o) => o.required)}\n currentFormValues={currentFormValues}\n secureFields={secureFields}\n onResetSecureField={resetSecureField}\n register={register}\n errors={errors}\n control={control}\n />\n </>\n );\n};\n","import React, { FC } from 'react';\n\nimport { Alert, CollapsableSection } from '@grafana/ui';\n\nimport { NotificationChannelSecureFields, NotificationChannelType } from '../../../types';\n\nimport { NotificationSettingsProps } from './NotificationChannelForm';\nimport { NotificationChannelOptions } from './NotificationChannelOptions';\n\ninterface Props extends NotificationSettingsProps {\n selectedChannel: NotificationChannelType;\n secureFields: NotificationChannelSecureFields;\n resetSecureField: (key: string) => void;\n}\n\nexport const ChannelSettings: FC<Props> = ({\n control,\n currentFormValues,\n errors,\n selectedChannel,\n secureFields,\n register,\n resetSecureField,\n}) => {\n return (\n <CollapsableSection label={`Optional ${selectedChannel.heading}`} isOpen={false}>\n {selectedChannel.info !== '' && <Alert severity=\"info\" title={selectedChannel.info ?? ''} />}\n <NotificationChannelOptions\n selectedChannelOptions={selectedChannel.options.filter((o) => !o.required)}\n currentFormValues={currentFormValues}\n register={register}\n errors={errors}\n control={control}\n onResetSecureField={resetSecureField}\n secureFields={secureFields}\n />\n </CollapsableSection>\n );\n};\n","import React, { FC } from 'react';\n\nimport { Checkbox, CollapsableSection, Field, InfoBox, Input } from '@grafana/ui';\n\nimport { NotificationSettingsProps } from './NotificationChannelForm';\n\ninterface Props extends NotificationSettingsProps {\n imageRendererAvailable: boolean;\n}\n\nexport const NotificationSettings: FC<Props> = ({ currentFormValues, imageRendererAvailable, register }) => {\n return (\n <CollapsableSection label=\"Notification settings\" isOpen={false}>\n <Field>\n <Checkbox {...register('isDefault')} label=\"Default\" description=\"Use this notification for all alerts\" />\n </Field>\n <Field>\n <Checkbox\n {...register('settings.uploadImage')}\n label=\"Include image\"\n description=\"Captures an image and include it in the notification\"\n />\n </Field>\n {currentFormValues.uploadImage && !imageRendererAvailable && (\n <InfoBox title=\"No image renderer available/installed\">\n Grafana cannot find an image renderer to capture an image for the notification. Please make sure the Grafana\n Image Renderer plugin is installed. Please contact your Grafana administrator to install the plugin.\n </InfoBox>\n )}\n <Field>\n <Checkbox\n {...register('disableResolveMessage')}\n label=\"Disable Resolve Message\"\n description=\"Disable the resolve message [OK] that is sent when alerting state returns to false\"\n />\n </Field>\n <Field>\n <Checkbox\n {...register('sendReminder')}\n label=\"Send reminders\"\n description=\"Send additional notifications for triggered alerts\"\n />\n </Field>\n {currentFormValues.sendReminder && (\n <>\n <Field\n label=\"Send reminder every\"\n description=\"Specify how often reminders should be sent, e.g. every 30s, 1m, 10m, 30m', or 1h etc.\n Alert reminders are sent after rules are evaluated. A reminder can never be sent more frequently\n than a configured alert rule evaluation interval.\"\n >\n <Input {...register('frequency')} width={8} />\n </Field>\n </>\n )}\n </CollapsableSection>\n );\n};\n","import { css } from '@emotion/css';\nimport React, { FC, useEffect } from 'react';\n\nimport { GrafanaTheme, SelectableValue } from '@grafana/data';\nimport { Button, FormAPI, HorizontalGroup, stylesFactory, useTheme, Spinner } from '@grafana/ui';\nimport config from 'app/core/config';\n\nimport { NotificationChannelType, NotificationChannelDTO, NotificationChannelSecureFields } from '../../../types';\n\nimport { BasicSettings } from './BasicSettings';\nimport { ChannelSettings } from './ChannelSettings';\nimport { NotificationSettings } from './NotificationSettings';\n\ninterface Props\n extends Pick<FormAPI<NotificationChannelDTO>, 'control' | 'errors' | 'register' | 'watch' | 'getValues'> {\n selectableChannels: Array<SelectableValue<string>>;\n selectedChannel?: NotificationChannelType;\n imageRendererAvailable: boolean;\n secureFields: NotificationChannelSecureFields;\n resetSecureField: (key: string) => void;\n onTestChannel: (data: NotificationChannelDTO) => void;\n}\n\nexport interface NotificationSettingsProps\n extends Pick<FormAPI<NotificationChannelDTO>, 'control' | 'errors' | 'register'> {\n currentFormValues: NotificationChannelDTO;\n}\n\nexport const NotificationChannelForm: FC<Props> = ({\n control,\n errors,\n selectedChannel,\n selectableChannels,\n register,\n watch,\n getValues,\n imageRendererAvailable,\n onTestChannel,\n resetSecureField,\n secureFields,\n}) => {\n const styles = getStyles(useTheme());\n\n useEffect(() => {\n /*\n Find fields that have dependencies on other fields and removes duplicates.\n Needs to be prefixed with settings.\n */\n const fieldsToWatch =\n new Set(\n selectedChannel?.options\n .filter((o) => o.showWhen.field)\n .map((option) => {\n return `settings.${option.showWhen.field}`;\n })\n ) || [];\n watch(['type', 'sendReminder', 'uploadImage', ...fieldsToWatch]);\n }, [selectedChannel?.options, watch]);\n\n const currentFormValues = getValues();\n\n if (!selectedChannel) {\n return <Spinner />;\n }\n\n return (\n <div className={styles.formContainer}>\n <div className={styles.formItem}>\n <BasicSettings\n selectedChannel={selectedChannel}\n channels={selectableChannels}\n secureFields={secureFields}\n resetSecureField={resetSecureField}\n currentFormValues={currentFormValues}\n register={register}\n errors={errors}\n control={control}\n />\n </div>\n {/* If there are no non-required fields, don't render this section*/}\n {selectedChannel.options.filter((o) => !o.required).length > 0 && (\n <div className={styles.formItem}>\n <ChannelSettings\n selectedChannel={selectedChannel}\n secureFields={secureFields}\n resetSecureField={resetSecureField}\n currentFormValues={currentFormValues}\n register={register}\n errors={errors}\n control={control}\n />\n </div>\n )}\n <div className={styles.formItem}>\n <NotificationSettings\n imageRendererAvailable={imageRendererAvailable}\n currentFormValues={currentFormValues}\n register={register}\n errors={errors}\n control={control}\n />\n </div>\n <div className={styles.formButtons}>\n <HorizontalGroup>\n <Button type=\"submit\">Save</Button>\n <Button type=\"button\" variant=\"secondary\" onClick={() => onTestChannel(getValues())}>\n Test\n </Button>\n <a href={`${config.appSubUrl}/alerting/notifications`}>\n <Button type=\"button\" variant=\"secondary\">\n Back\n </Button>\n </a>\n </HorizontalGroup>\n </div>\n </div>\n );\n};\n\nconst getStyles = stylesFactory((theme: GrafanaTheme) => {\n return {\n formContainer: css``,\n formItem: css`\n flex-grow: 1;\n padding-top: ${theme.spacing.md};\n `,\n formButtons: css`\n padding-top: ${theme.spacing.xl};\n `,\n };\n});\n","import { getBackendSrv, locationService } from '@grafana/runtime';\nimport { notifyApp } from 'app/core/actions';\nimport { createErrorNotification, createSuccessNotification } from 'app/core/copy/appNotification';\nimport { AlertRuleDTO, NotifierDTO, ThunkResult } from 'app/types';\n\nimport { loadAlertRules, loadedAlertRules, notificationChannelLoaded, setNotificationChannels } from './reducers';\n\nexport function getAlertRulesAsync(options: { state: string }): ThunkResult<void> {\n return async (dispatch) => {\n dispatch(loadAlertRules());\n const rules: AlertRuleDTO[] = await getBackendSrv().get('/api/alerts', options);\n dispatch(loadedAlertRules(rules));\n };\n}\n\nexport function togglePauseAlertRule(id: number, options: { paused: boolean }): ThunkResult<void> {\n return async (dispatch) => {\n await getBackendSrv().post(`/api/alerts/${id}/pause`, options);\n const stateFilter = locationService.getSearchObject().state || 'all';\n dispatch(getAlertRulesAsync({ state: stateFilter.toString() }));\n };\n}\n\nexport function createNotificationChannel(data: any): ThunkResult<Promise<void>> {\n return async (dispatch) => {\n try {\n await getBackendSrv().post(`/api/alert-notifications`, data);\n dispatch(notifyApp(createSuccessNotification('Notification created')));\n locationService.push('/alerting/notifications');\n } catch (error) {\n dispatch(notifyApp(createErrorNotification(error.data.error)));\n }\n };\n}\n\nexport function updateNotificationChannel(data: any): ThunkResult<void> {\n return async (dispatch) => {\n try {\n await getBackendSrv().put(`/api/alert-notifications/${data.id}`, data);\n dispatch(notifyApp(createSuccessNotification('Notification updated')));\n } catch (error) {\n dispatch(notifyApp(createErrorNotification(error.data.error)));\n }\n };\n}\n\nexport function testNotificationChannel(data: any): ThunkResult<void> {\n return async (dispatch, getState) => {\n const channel = getState().notificationChannel.notificationChannel;\n await getBackendSrv().post('/api/alert-notifications/test', { id: channel.id, ...data });\n };\n}\n\nexport function loadNotificationTypes(): ThunkResult<void> {\n return async (dispatch) => {\n const alertNotifiers: NotifierDTO[] = await getBackendSrv().get(`/api/alert-notifiers`);\n\n const notificationTypes = alertNotifiers.sort((o1, o2) => {\n if (o1.name > o2.name) {\n return 1;\n }\n return -1;\n });\n\n dispatch(setNotificationChannels(notificationTypes));\n };\n}\n\nexport function loadNotificationChannel(id: number): ThunkResult<void> {\n return async (dispatch) => {\n await dispatch(loadNotificationTypes());\n const notificationChannel = await getBackendSrv().get(`/api/alert-notifications/${id}`);\n dispatch(notificationChannelLoaded(notificationChannel));\n };\n}\n","import memoizeOne from 'memoize-one';\n\nimport { SelectableValue } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { NotificationChannelDTO, NotificationChannelType } from 'app/types';\n\nexport const defaultValues: NotificationChannelDTO = {\n id: -1,\n name: '',\n type: { value: 'email', label: 'Email' },\n sendReminder: false,\n disableResolveMessage: false,\n frequency: '15m',\n settings: {\n uploadImage: config.rendererAvailable,\n autoResolve: true,\n httpMethod: 'POST',\n severity: 'critical',\n },\n secureSettings: {},\n secureFields: {},\n isDefault: false,\n};\n\nexport const mapChannelsToSelectableValue = memoizeOne(\n (notificationChannels: NotificationChannelType[], includeDescription: boolean): Array<SelectableValue<string>> => {\n return notificationChannels.map((channel) => {\n if (includeDescription) {\n return {\n value: channel.value,\n label: channel.label,\n description: channel.description,\n };\n }\n return {\n value: channel.value,\n label: channel.label,\n };\n });\n }\n);\n\nexport const transformSubmitData = (formData: NotificationChannelDTO) => {\n /*\n Some settings can be options in a select, in order to not save a SelectableValue<T>\n we need to use check if it is a SelectableValue and use its value.\n */\n const settings = Object.fromEntries(\n Object.entries(formData.settings).map(([key, value]) => {\n return [key, value && value.hasOwnProperty('value') ? value.value : value];\n })\n );\n\n return {\n ...defaultValues,\n ...formData,\n frequency: formData.frequency === '' ? defaultValues.frequency : formData.frequency,\n type: formData.type.value,\n settings: { ...defaultValues.settings, ...settings },\n secureSettings: { ...formData.secureSettings },\n };\n};\n\nexport const transformTestData = (formData: NotificationChannelDTO) => {\n return {\n name: formData.name,\n type: formData.type.value,\n frequency: formData.frequency ?? defaultValues.frequency,\n settings: { ...Object.assign(defaultValues.settings, formData.settings) },\n secureSettings: { ...formData.secureSettings },\n };\n};\n"],"names":["NewNotificationChannelPage","PureComponent","data","this","props","createNotificationChannel","transformSubmitData","defaultValues","testNotificationChannel","transformTestData","componentDidMount","loadNotificationTypes","render","navModel","notificationChannelTypes","className","Form","onSubmit","validateOn","maxWidth","register","errors","control","getValues","watch","selectedChannel","find","c","value","type","selectableChannels","mapChannelsToSelectableValue","onTestChannel","imageRendererAvailable","config","resetSecureField","secureFields","mapDispatchToProps","connect","state","getNavModel","navIndex","notificationChannel","OptionElement","option","invalid","modelValue","secure","propertyName","element","Input","required","validate","v","validationRule","validateOption","inputType","placeholder","InputControl","name","field","Select","options","selectOptions","undefined","TextArea","console","error","RegExp","test","NotificationChannelOptions","currentFormValues","selectedChannelOptions","onResetSecureField","map","index","key","label","selectedOptionValue","showWhen","is","Field","Checkbox","description","settings","message","readOnly","suffix","Button","onClick","fill","size","BasicSettings","channels","rules","filter","o","ChannelSettings","CollapsableSection","heading","isOpen","info","Alert","severity","title","NotificationSettings","uploadImage","InfoBox","sendReminder","width","NotificationChannelForm","styles","getStyles","useTheme","useEffect","fieldsToWatch","Set","formContainer","formItem","length","formButtons","HorizontalGroup","variant","href","Spinner","stylesFactory","theme","css","spacing","md","xl","getAlertRulesAsync","async","dispatch","loadAlertRules","getBackendSrv","get","loadedAlertRules","togglePauseAlertRule","id","post","locationService","toString","notifyApp","createSuccessNotification","createErrorNotification","updateNotificationChannel","put","getState","channel","notificationTypes","sort","o1","o2","setNotificationChannels","loadNotificationChannel","notificationChannelLoaded","disableResolveMessage","frequency","autoResolve","httpMethod","secureSettings","isDefault","memoizeOne","notificationChannels","includeDescription","formData","Object","fromEntries","entries","hasOwnProperty","assign"],"sourceRoot":""}
|