NotificationsListPage.f1ca641f4eb7496dd504.js.map 199 KB

1
  1. {"version":3,"file":"NotificationsListPage.f1ca641f4eb7496dd504.js","mappings":"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","sources":["webpack://grafana/./public/app/core/hooks/useCleanup.ts","webpack://grafana/./public/app/core/hooks/useNavModel.ts","webpack://grafana/./public/app/features/alerting/NotificationsListPage.tsx","webpack://grafana/./public/app/features/alerting/unified/utils/cloud-alertmanager-notifier-types.ts","webpack://grafana/./public/app/features/alerting/unified/utils/receiver-form.ts","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx","webpack://grafana/./public/app/features/alerting/unified/hooks/useControlledFieldArray.ts","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/CollapsibleSection.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/styles.ts","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/SubformArrayField.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/SubformField.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/fields/DeletedSubform.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/EditReceiverView.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/TemplateForm.tsx","webpack://grafana/./public/app/features/alerting/unified/utils/templates.ts","webpack://grafana/./public/app/features/alerting/unified/components/receivers/EditTemplateView.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/GlobalConfigForm.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/NewReceiverView.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/NewTemplateView.tsx","webpack://grafana/./public/app/plugins/datasource/alertmanager/consts.ts","webpack://grafana/./public/app/features/alerting/unified/utils/receivers.ts","webpack://grafana/./public/app/features/alerting/unified/components/receivers/ReceiversSection.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/ReceiversTable.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx","webpack://grafana/./public/app/features/alerting/unified/components/receivers/ReceiversAndTemplatesView.tsx","webpack://grafana/./public/app/features/alerting/unified/Receivers.tsx","webpack://grafana/./public/app/features/alerting/unified/components/AlertingPageWrapper.tsx","webpack://grafana/./public/app/features/alerting/unified/components/Authorize.tsx","webpack://grafana/./public/app/features/alerting/unified/components/NoAlertManagerWarning.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/ActionIcon.tsx","webpack://grafana/./public/app/features/alerting/unified/hooks/useAlertManagerSourceName.ts","webpack://grafana/./public/app/features/alerting/unified/hooks/useAlertManagerSources.ts","webpack://grafana/./public/app/features/alerting/unified/styles/table.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { cleanUpAction, StateSelector } from '../actions/cleanUp';\n\nexport function useCleanup<T>(stateSelector: StateSelector<T>) {\n const dispatch = useDispatch();\n //bit of a hack to unburden user from having to wrap stateSelcetor in a useCallback. Otherwise cleanup would happen on every render\n const selectorRef = useRef(stateSelector);\n selectorRef.current = stateSelector;\n useEffect(() => {\n return () => {\n dispatch(cleanUpAction({ stateSelector: selectorRef.current }));\n };\n }, [dispatch]);\n}\n","import { useSelector } from 'react-redux';\n\nimport { NavModel } from '@grafana/data';\nimport { StoreState } from 'app/types/store';\n\nimport { getNavModel } from '../selectors/navModel';\n\nexport const useNavModel = (id: string): NavModel => {\n const navIndex = useSelector((state: StoreState) => state.navIndex);\n return getNavModel(navIndex, id);\n};\n","import React, { useState, FC, useEffect } from 'react';\nimport { useAsyncFn } from 'react-use';\n\nimport { getBackendSrv } from '@grafana/runtime';\nimport { HorizontalGroup, Button, LinkButton } from '@grafana/ui';\nimport EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';\nimport Page from 'app/core/components/Page/Page';\nimport { appEvents } from 'app/core/core';\nimport { useNavModel } from 'app/core/hooks/useNavModel';\nimport { AlertNotification } from 'app/types/alerting';\n\nimport { ShowConfirmModalEvent } from '../../types/events';\n\nconst NotificationsListPage: FC = () => {\n const navModel = useNavModel('channels');\n\n const [notifications, setNotifications] = useState<AlertNotification[]>([]);\n\n const getNotifications = async () => {\n return await getBackendSrv().get(`/api/alert-notifications`);\n };\n\n const [state, fetchNotifications] = useAsyncFn(getNotifications);\n useEffect(() => {\n fetchNotifications().then((res) => {\n setNotifications(res);\n });\n }, [fetchNotifications]);\n\n const deleteNotification = (id: number) => {\n appEvents.publish(\n new ShowConfirmModalEvent({\n title: 'Delete',\n text: 'Do you want to delete this notification channel?',\n text2: `Deleting this notification channel will not delete from alerts any references to it`,\n icon: 'trash-alt',\n confirmText: 'Delete',\n yesText: 'Delete',\n onConfirm: async () => {\n deleteNotificationConfirmed(id);\n },\n })\n );\n };\n\n const deleteNotificationConfirmed = async (id: number) => {\n await getBackendSrv().delete(`/api/alert-notifications/${id}`);\n const notifications = await fetchNotifications();\n setNotifications(notifications);\n };\n\n return (\n <Page navModel={navModel}>\n <Page.Contents>\n {state.error && <p>{state.error}</p>}\n {!!notifications.length && (\n <>\n <div className=\"page-action-bar\">\n <div className=\"page-action-bar__spacer\" />\n <LinkButton icon=\"channel-add\" href=\"alerting/notification/new\">\n New channel\n </LinkButton>\n </div>\n <table className=\"filter-table filter-table--hover\">\n <thead>\n <tr>\n <th style={{ minWidth: '200px' }}>\n <strong>Name</strong>\n </th>\n <th style={{ minWidth: '100px' }}>Type</th>\n <th style={{ width: '1%' }}></th>\n </tr>\n </thead>\n <tbody>\n {notifications.map((notification) => (\n <tr key={notification.id}>\n <td className=\"link-td\">\n <a href={`alerting/notification/${notification.id}/edit`}>{notification.name}</a>\n </td>\n <td className=\"link-td\">\n <a href={`alerting/notification/${notification.id}/edit`}>{notification.type}</a>\n </td>\n <td className=\"text-right\">\n <HorizontalGroup justify=\"flex-end\">\n {notification.isDefault && (\n <Button disabled variant=\"secondary\" size=\"sm\">\n default\n </Button>\n )}\n <Button\n variant=\"destructive\"\n icon=\"times\"\n size=\"sm\"\n onClick={() => {\n deleteNotification(notification.id);\n }}\n />\n </HorizontalGroup>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </>\n )}\n\n {!(notifications.length || state.loading) && (\n <EmptyListCTA\n title=\"There are no notification channels defined yet\"\n buttonIcon=\"channel-add\"\n buttonLink=\"alerting/notification/new\"\n buttonTitle=\"Add channel\"\n proTip=\"You can include images in your alert notifications.\"\n proTipLink=\"http://docs.grafana.org/alerting/notifications/\"\n proTipLinkTitle=\"Learn more\"\n proTipTarget=\"_blank\"\n />\n )}\n </Page.Contents>\n </Page>\n );\n};\n\nexport default NotificationsListPage;\n","import { NotificationChannelOption, NotifierDTO } from 'app/types';\n\nfunction option(\n propertyName: string,\n label: string,\n description: string,\n rest: Partial<NotificationChannelOption> = {}\n): NotificationChannelOption {\n return {\n propertyName,\n label,\n description,\n element: 'input',\n inputType: '',\n required: false,\n secure: false,\n placeholder: '',\n validationRule: '',\n showWhen: { field: '', is: '' },\n dependsOn: '',\n ...rest,\n };\n}\n\nconst basicAuthOption: NotificationChannelOption = option(\n 'basic_auth',\n 'Basic auth',\n 'Sets the `Authorization` header with the configured username and password. Password and password_file are mutually exclusive.',\n {\n element: 'subform',\n subformOptions: [\n option('username', 'Username', ''),\n option('password', 'Password', ''),\n option('password_file', 'Password file', ''),\n ],\n }\n);\n\nconst tlsConfigOption: NotificationChannelOption = option('tls_config', 'TLS config', 'Configures the TLS settings.', {\n element: 'subform',\n subformOptions: [\n option('ca_file', 'CA file', 'CA certificate to validate the server certificate with.'),\n option('cert_file', 'Cert file', 'Certificate for client cert authentication to the server.'),\n option('key_file', 'Key file', 'Key file for client cert authentication to the server.'),\n option('server_name', 'Server name', 'ServerName extension to indicate the name of the server.'),\n option('insecure_skip_verify', 'Skip verify', 'Disable validation of the server certificate.', {\n element: 'checkbox',\n }),\n ],\n});\n\nconst httpConfigOption: NotificationChannelOption = option(\n 'http_config',\n 'HTTP Config',\n 'Note that `basic_auth`, `bearer_token` and `bearer_token_file` options are mutually exclusive.',\n {\n element: 'subform',\n subformOptions: [\n option('bearer_token', 'Bearer token', 'Sets the `Authorization` header with the configured bearer token.'),\n option(\n 'bearer_token_file',\n 'Bearer token file',\n 'Sets the `Authorization` header with the bearer token read from the configured file.'\n ),\n option('proxy_url', 'Proxy URL', 'Optional proxy URL.'),\n basicAuthOption,\n tlsConfigOption,\n ],\n }\n);\n\nexport const cloudNotifierTypes: NotifierDTO[] = [\n {\n name: 'Email',\n description: 'Send notification over SMTP',\n type: 'email',\n info: '',\n heading: 'Email settings',\n options: [\n option('to', 'To', 'The email address to send notifications to.', { required: true }),\n option('from', 'From', 'The sender address.'),\n option('smarthost', 'SMTP host', 'The SMTP host through which emails are sent.'),\n option('hello', 'Hello', 'The hostname to identify to the SMTP server.'),\n option('auth_username', 'Username', 'SMTP authentication information'),\n option('auth_password', 'Password', 'SMTP authentication information'),\n option('auth_secret', 'Secret', 'SMTP authentication information'),\n option('auth_identity', 'Identity', 'SMTP authentication information'),\n option('require_tls', 'Require TLS', 'The SMTP TLS requirement', { element: 'checkbox' }),\n option('html', 'Email HTML body', 'The HTML body of the email notification.', {\n placeholder: '{{ template \"email.default.html\" . }}',\n element: 'textarea',\n }),\n option('text', 'Email text body', 'The text body of the email notification.', { element: 'textarea' }),\n option(\n 'headers',\n 'Headers',\n 'Further headers email header key/value pairs. Overrides any headers previously set by the notification implementation.',\n { element: 'key_value_map' }\n ),\n tlsConfigOption,\n ],\n },\n {\n name: 'PagerDuty',\n description: 'Send notifications to PagerDuty',\n type: 'pagerduty',\n info: '',\n heading: 'PagerDuty settings',\n options: [\n option(\n 'routing_key',\n 'Routing key',\n 'The PagerDuty integration key (when using PagerDuty integration type `Events API v2`)'\n ),\n option(\n 'service_key',\n 'Service key',\n 'The PagerDuty integration key (when using PagerDuty integration type `Prometheus`).'\n ),\n option('url', 'URL', 'The URL to send API requests to'),\n option('client', 'Client', 'The client identification of the Alertmanager.', {\n placeholder: '{{ template \"pagerduty.default.client\" . }}',\n }),\n option('client_url', 'Client URL', 'A backlink to the sender of the notification.', {\n placeholder: '{{ template \"pagerduty.default.clientURL\" . }}',\n }),\n option('description', 'Description', 'A description of the incident.', {\n placeholder: '{{ template \"pagerduty.default.description\" .}}',\n }),\n option('severity', 'Severity', 'Severity of the incident.', { placeholder: 'error' }),\n option(\n 'details',\n 'Details',\n 'A set of arbitrary key/value pairs that provide further detail about the incident.',\n {\n element: 'key_value_map',\n }\n ),\n option('images', 'Images', 'Images to attach to the incident.', {\n element: 'subform_array',\n subformOptions: [\n option('href', 'URL', '', { required: true }),\n option('source', 'Source', '', { required: true }),\n option('alt', 'Alt', '', { required: true }),\n ],\n }),\n option('links', 'Links', 'Links to attach to the incident.', {\n element: 'subform_array',\n subformOptions: [option('href', 'URL', '', { required: true }), option('text', 'Text', '', { required: true })],\n }),\n httpConfigOption,\n ],\n },\n {\n name: 'Pushover',\n description: 'Send notifications to Pushover',\n type: 'pushover',\n info: '',\n heading: 'Pushover settings',\n options: [\n option('user_key', 'User key', 'The recipient user’s user key.', { required: true }),\n option('token', 'Token', 'Your registered application’s API token, see https://pushover.net/app', {\n required: true,\n }),\n option('title', 'Title', 'Notification title.', {\n placeholder: '{{ template \"pushover.default.title\" . }}',\n }),\n option('message', 'Message', 'Notification message.', {\n placeholder: '{{ template \"pushover.default.message\" . }}',\n }),\n option('url', 'URL', 'A supplementary URL shown alongside the message.', {\n placeholder: '{{ template \"pushover.default.url\" . }}',\n }),\n option('priority', 'Priority', 'Priority, see https://pushover.net/api#priority', {\n placeholder: '{{ if eq .Status \"firing\" }}2{{ else }}0{{ end }}',\n }),\n option(\n 'retry',\n 'Retry',\n 'How often the Pushover servers will send the same notification to the user. Must be at least 30 seconds.',\n {\n placeholder: '1m',\n }\n ),\n option(\n 'expire',\n 'Expire',\n 'How long your notification will continue to be retried for, unless the user acknowledges the notification.',\n {\n placeholder: '1h',\n }\n ),\n httpConfigOption,\n ],\n },\n {\n name: 'Slack',\n description: 'Send notifications to Slack',\n type: 'slack',\n info: '',\n heading: 'Slack settings',\n options: [\n option('api_url', 'Webhook URL', 'The Slack webhook URL.'),\n option('channel', 'Channel', 'The #channel or @user to send notifications to.', { required: true }),\n option('icon_emoji', 'Emoji icon', ''),\n option('icon_url', 'Icon URL', ''),\n option('link_names', 'Names link', '', { element: 'checkbox' }),\n option('username', 'Username', '', { placeholder: '{{ template \"slack.default.username\" . }}' }),\n option('callback_id', 'Callback ID', '', { placeholder: '{{ template \"slack.default.callbackid\" . }}' }),\n option('color', 'Color', '', { placeholder: '{{ if eq .Status \"firing\" }}danger{{ else }}good{{ end }}' }),\n option('fallback', 'Fallback', '', { placeholder: '{{ template \"slack.default.fallback\" . }}' }),\n option('footer', 'Footer', '', { placeholder: '{{ template \"slack.default.footer\" . }}' }),\n option('mrkdwn_in', 'Mrkdwn fields', 'An array of field names that should be formatted by mrkdwn syntax.', {\n element: 'string_array',\n }),\n option('pretext', 'Pre-text', '', { placeholder: '{{ template \"slack.default.pretext\" . }}' }),\n option('short_fields', 'Short fields', '', { element: 'checkbox' }),\n option('text', 'Message body', '', { element: 'textarea', placeholder: '{{ template \"slack.default.text\" . }}' }),\n option('title', 'Title', '', { placeholder: '{{ template \"slack.default.title\" . }}' }),\n option('title_link', 'Title link', '', { placeholder: '{{ template \"slack.default.titlelink\" . }}' }),\n option('image_url', 'Image URL', ''),\n option('thumb_url', 'Thumbnail URL', ''),\n option('actions', 'Actions', '', {\n element: 'subform_array',\n subformOptions: [\n option('text', 'Text', '', { required: true }),\n option('type', 'Type', '', { required: true }),\n option('url', 'URL', 'Either url or name and value are mandatory.'),\n option('name', 'Name', ''),\n option('value', 'Value', ''),\n option('confirm', 'Confirm', '', {\n element: 'subform',\n subformOptions: [\n option('text', 'Text', '', { required: true }),\n option('dismiss_text', 'Dismiss text', ''),\n option('ok_text', 'OK text', ''),\n option('title', 'Title', ''),\n ],\n }),\n option('style', 'Style', ''),\n ],\n }),\n option('fields', 'Fields', '', {\n element: 'subform_array',\n subformOptions: [\n option('title', 'Title', '', { required: true }),\n option('value', 'Value', '', { required: true }),\n option('short', 'Short', '', { element: 'checkbox' }),\n ],\n }),\n httpConfigOption,\n ],\n },\n {\n name: 'OpsGenie',\n description: 'Send notifications to OpsGenie',\n type: 'opsgenie',\n info: '',\n heading: 'OpsGenie settings',\n options: [\n option('api_key', 'API key', 'The API key to use when talking to the OpsGenie API.'),\n option('api_url', 'API URL', 'The host to send OpsGenie API requests to.'),\n option('message', 'Message', 'Alert text limited to 130 characters.'),\n option('description', 'Description', 'A description of the incident.', {\n placeholder: '{{ template \"opsgenie.default.description\" . }}',\n }),\n option('source', 'Source', 'A backlink to the sender of the notification.', {\n placeholder: '{{ template \"opsgenie.default.source\" . }}',\n }),\n option(\n 'details',\n 'Details',\n 'A set of arbitrary key/value pairs that provide further detail about the incident.',\n {\n element: 'key_value_map',\n }\n ),\n option('tags', 'Tags', 'Comma separated list of tags attached to the notifications.'),\n option('note', 'Note', 'Additional alert note.'),\n option('priority', 'Priority', 'Priority level of alert. Possible values are P1, P2, P3, P4, and P5.'),\n option('responders', 'Responders', 'List of responders responsible for notifications.', {\n element: 'subform_array',\n subformOptions: [\n option('type', 'Type', '\"team\", \"user\", \"escalation\" or schedule\".', { required: true }),\n option('id', 'ID', 'Exactly one of these fields should be defined.'),\n option('name', 'Name', 'Exactly one of these fields should be defined.'),\n option('username', 'Username', 'Exactly one of these fields should be defined.'),\n ],\n }),\n httpConfigOption,\n ],\n },\n {\n name: 'VictorOps',\n description: 'Send notifications to VictorOps',\n type: 'victorops',\n info: '',\n heading: 'VictorOps settings',\n options: [\n option('api_key', 'API key', 'The API key to use when talking to the VictorOps API.'),\n option('api_url', 'API URL', 'The VictorOps API URL.'),\n option('routing_key', 'Routing key', 'A key used to map the alert to a team.', { required: true }),\n option('message_type', 'Message type', 'Describes the behavior of the alert (CRITICAL, WARNING, INFO).'),\n option('entity_display_name', 'Entity display name', 'Contains summary of the alerted problem.', {\n placeholder: '{{ template \"victorops.default.entity_display_name\" . }}',\n }),\n option('state_message', 'State message', 'Contains long explanation of the alerted problem.', {\n placeholder: '{{ template \"victorops.default.state_message\" . }}',\n }),\n option('monitoring_tool', 'Monitoring tool', 'The monitoring tool the state message is from.', {\n placeholder: '{{ template \"victorops.default.monitoring_tool\" . }}',\n }),\n httpConfigOption,\n ],\n },\n {\n name: 'Webhook',\n description: 'Send notifications to a webhook',\n type: 'webhook',\n info: '',\n heading: 'Webhook settings',\n options: [\n option('url', 'URL', 'The endpoint to send HTTP POST requests to.', { required: true }),\n option(\n 'max_alerts',\n 'Max alerts',\n 'The maximum number of alerts to include in a single webhook message. Alerts above this threshold are truncated. When leaving this at its default value of 0, all alerts are included.',\n { placeholder: '0', validationRule: '(^\\\\d+$|^$)' }\n ),\n httpConfigOption,\n ],\n },\n];\n\nexport const globalConfigOptions: NotificationChannelOption[] = [\n // email\n option('smtp_from', 'SMTP from', 'The default SMTP From header field.'),\n option(\n 'smtp_smarthost',\n 'SMTP smarthost',\n 'The default SMTP smarthost used for sending emails, including port number. Port number usually is 25, or 587 for SMTP over TLS (sometimes referred to as STARTTLS). Example: smtp.example.org:587'\n ),\n option('smtp_hello', 'SMTP hello', 'The default hostname to identify to the SMTP server.', {\n placeholder: 'localhost',\n }),\n option(\n 'smtp_auth_username',\n 'SMTP auth username',\n \"SMTP Auth using CRAM-MD5, LOGIN and PLAIN. If empty, Alertmanager doesn't authenticate to the SMTP server.\"\n ),\n option('smtp_auth_password', 'SMTP auth password', 'SMTP Auth using LOGIN and PLAIN.'),\n option('smtp_auth_identity', 'SMTP auth identity', 'SMTP Auth using PLAIN.'),\n option('smtp_auth_secret', 'SMTP auth secret', 'SMTP Auth using CRAM-MD5.'),\n option(\n 'smtp_require_tls',\n 'SMTP require TLS',\n 'The default SMTP TLS requirement. Note that Go does not support unencrypted connections to remote SMTP endpoints.',\n {\n element: 'checkbox',\n }\n ),\n\n // slack\n option('slack_api_url', 'Slack API URL', ''),\n option('victorops_api_key', 'VictorOps API key', ''),\n option('victorops_api_url', 'VictorOps API URL', '', {\n placeholder: 'https://alert.victorops.com/integrations/generic/20131114/alert/',\n }),\n option('pagerduty_url', 'PagerDuty URL', 'https://events.pagerduty.com/v2/enqueue'),\n option('opsgenie_api_key', 'OpsGenie API key', ''),\n option('opsgenie_api_url', 'OpsGenie API URL', '', { placeholder: 'https://api.opsgenie.com/' }),\n option('wechat_api_url', 'WeChat API URL', '', { placeholder: 'https://qyapi.weixin.qq.com/cgi-bin/' }),\n option('wechat_api_secret', 'WeChat API secret', ''),\n option('wechat_api_corp_id', 'WeChat API corp id', ''),\n httpConfigOption,\n option(\n 'resolve_timeout',\n 'Resolve timeout',\n 'ResolveTimeout is the default value used by alertmanager if the alert does not include EndsAt, after this time passes it can declare the alert as resolved if it has not been updated. This has no impact on alerts from Prometheus, as they always include EndsAt.',\n {\n placeholder: '5m',\n }\n ),\n];\n","import { isArray } from 'lodash';\n\nimport {\n AlertManagerCortexConfig,\n GrafanaManagedReceiverConfig,\n Receiver,\n Route,\n} from 'app/plugins/datasource/alertmanager/types';\nimport { CloudNotifierType, NotifierDTO, NotifierType } from 'app/types';\n\nimport {\n CloudChannelConfig,\n CloudChannelMap,\n CloudChannelValues,\n GrafanaChannelMap,\n GrafanaChannelValues,\n ReceiverFormValues,\n} from '../types/receiver-form';\n\nexport function grafanaReceiverToFormValues(\n receiver: Receiver,\n notifiers: NotifierDTO[]\n): [ReceiverFormValues<GrafanaChannelValues>, GrafanaChannelMap] {\n const channelMap: GrafanaChannelMap = {};\n // giving each form receiver item a unique id so we can use it to map back to \"original\" items\n // as well as to use as `key` prop.\n // @TODO use uid once backend is fixed to provide it. then we can get rid of the GrafanaChannelMap\n let idCounter = 1;\n const values = {\n name: receiver.name,\n items:\n receiver.grafana_managed_receiver_configs?.map((channel) => {\n const id = String(idCounter++);\n channelMap[id] = channel;\n const notifier = notifiers.find(({ type }) => type === channel.type);\n return grafanaChannelConfigToFormChannelValues(id, channel, notifier);\n }) ?? [],\n };\n return [values, channelMap];\n}\n\nexport function cloudReceiverToFormValues(\n receiver: Receiver,\n notifiers: NotifierDTO[]\n): [ReceiverFormValues<CloudChannelValues>, CloudChannelMap] {\n const channelMap: CloudChannelMap = {};\n // giving each form receiver item a unique id so we can use it to map back to \"original\" items\n let idCounter = 1;\n const items: CloudChannelValues[] = Object.entries(receiver)\n // filter out only config items that are relevant to cloud\n .filter(([type]) => type.endsWith('_configs') && type !== 'grafana_managed_receiver_configs')\n // map property names to cloud notifier types by removing the `_config` suffix\n .map(([type, configs]): [CloudNotifierType, CloudChannelConfig[]] => [\n type.replace('_configs', '') as CloudNotifierType,\n configs as CloudChannelConfig[],\n ])\n // convert channel configs to form values\n .map(([type, configs]) =>\n configs.map((config) => {\n const id = String(idCounter++);\n channelMap[id] = { type, config };\n const notifier = notifiers.find((notifier) => notifier.type === type);\n if (!notifier) {\n throw new Error(`unknown cloud notifier: ${type}`);\n }\n return cloudChannelConfigToFormChannelValues(id, type, config);\n })\n )\n .flat();\n const values = {\n name: receiver.name,\n items,\n };\n return [values, channelMap];\n}\n\nexport function formValuesToGrafanaReceiver(\n values: ReceiverFormValues<GrafanaChannelValues>,\n channelMap: GrafanaChannelMap,\n defaultChannelValues: GrafanaChannelValues\n): Receiver {\n return {\n name: values.name,\n grafana_managed_receiver_configs: (values.items ?? []).map((channelValues) => {\n const existing: GrafanaManagedReceiverConfig | undefined = channelMap[channelValues.__id];\n return formChannelValuesToGrafanaChannelConfig(channelValues, defaultChannelValues, values.name, existing);\n }),\n };\n}\n\nexport function formValuesToCloudReceiver(\n values: ReceiverFormValues<CloudChannelValues>,\n defaults: CloudChannelValues\n): Receiver {\n const recv: Receiver = {\n name: values.name,\n };\n values.items.forEach(({ __id, type, settings, sendResolved }) => {\n const channel = omitEmptyValues({\n ...settings,\n send_resolved: sendResolved ?? defaults.sendResolved,\n });\n\n const configsKey = `${type}_configs`;\n if (!recv[configsKey]) {\n recv[configsKey] = [channel];\n } else {\n (recv[configsKey] as unknown[]).push(channel);\n }\n });\n return recv;\n}\n\n// will add new receiver, or replace exisitng one\nexport function updateConfigWithReceiver(\n config: AlertManagerCortexConfig,\n receiver: Receiver,\n replaceReceiverName?: string\n): AlertManagerCortexConfig {\n const oldReceivers = config.alertmanager_config.receivers ?? [];\n\n // sanity check that name is not duplicated\n if (receiver.name !== replaceReceiverName && !!oldReceivers.find(({ name }) => name === receiver.name)) {\n throw new Error(`Duplicate receiver name ${receiver.name}`);\n }\n\n // sanity check that existing receiver exists\n if (replaceReceiverName && !oldReceivers.find(({ name }) => name === replaceReceiverName)) {\n throw new Error(`Expected receiver ${replaceReceiverName} to exist, but did not find it in the config`);\n }\n\n const updated: AlertManagerCortexConfig = {\n ...config,\n alertmanager_config: {\n // @todo rename receiver on routes as necessary\n ...config.alertmanager_config,\n receivers: replaceReceiverName\n ? oldReceivers.map((existingReceiver) =>\n existingReceiver.name === replaceReceiverName ? receiver : existingReceiver\n )\n : [...oldReceivers, receiver],\n },\n };\n\n // if receiver was renamed, rename it in routes as well\n if (updated.alertmanager_config.route && replaceReceiverName && receiver.name !== replaceReceiverName) {\n updated.alertmanager_config.route = renameReceiverInRoute(\n updated.alertmanager_config.route,\n replaceReceiverName,\n receiver.name\n );\n }\n\n return updated;\n}\n\nfunction renameReceiverInRoute(route: Route, oldName: string, newName: string) {\n const updated: Route = {\n ...route,\n };\n if (updated.receiver === oldName) {\n updated.receiver = newName;\n }\n if (updated.routes) {\n updated.routes = updated.routes.map((route) => renameReceiverInRoute(route, oldName, newName));\n }\n return updated;\n}\n\nfunction cloudChannelConfigToFormChannelValues(\n id: string,\n type: CloudNotifierType,\n channel: CloudChannelConfig\n): CloudChannelValues {\n return {\n __id: id,\n type,\n settings: {\n ...channel,\n },\n secureFields: {},\n secureSettings: {},\n sendResolved: channel.send_resolved,\n };\n}\n\nfunction grafanaChannelConfigToFormChannelValues(\n id: string,\n channel: GrafanaManagedReceiverConfig,\n notifier?: NotifierDTO\n): GrafanaChannelValues {\n const values: GrafanaChannelValues = {\n __id: id,\n type: channel.type as NotifierType,\n secureSettings: {},\n settings: { ...channel.settings },\n secureFields: { ...channel.secureFields },\n disableResolveMessage: channel.disableResolveMessage,\n };\n\n // work around https://github.com/grafana/alerting-squad/issues/100\n notifier?.options.forEach((option) => {\n if (option.secure && values.settings[option.propertyName]) {\n delete values.settings[option.propertyName];\n values.secureFields[option.propertyName] = true;\n }\n });\n\n return values;\n}\n\nexport function formChannelValuesToGrafanaChannelConfig(\n values: GrafanaChannelValues,\n defaults: GrafanaChannelValues,\n name: string,\n existing?: GrafanaManagedReceiverConfig\n): GrafanaManagedReceiverConfig {\n const channel: GrafanaManagedReceiverConfig = {\n settings: omitEmptyValues({\n ...(existing && existing.type === values.type ? existing.settings ?? {} : {}),\n ...(values.settings ?? {}),\n }),\n secureSettings: values.secureSettings ?? {},\n type: values.type,\n name,\n disableResolveMessage:\n values.disableResolveMessage ?? existing?.disableResolveMessage ?? defaults.disableResolveMessage,\n };\n if (existing) {\n channel.uid = existing.uid;\n }\n return channel;\n}\n\n// will remove properties that have empty ('', null, undefined) object properties.\n// traverses nested objects and arrays as well. in place, mutates the object.\n// this is needed because form will submit empty string for not filled in fields,\n// but for cloud alertmanager receiver config to use global default value the property must be omitted entirely\n// this isn't a perfect solution though. No way for user to intentionally provide an empty string. Will need rethinking later\nexport function omitEmptyValues<T>(obj: T): T {\n if (isArray(obj)) {\n obj.forEach(omitEmptyValues);\n } else if (typeof obj === 'object' && obj !== null) {\n Object.entries(obj).forEach(([key, value]) => {\n if (value === '' || value === null || value === undefined) {\n delete (obj as any)[key];\n } else {\n omitEmptyValues(value);\n }\n });\n }\n return obj;\n}\n","import React, { FC } from 'react';\nimport { useFormContext } from 'react-hook-form';\n\nimport { Checkbox, Field } from '@grafana/ui';\n\nimport { CommonSettingsComponentProps } from '../../../types/receiver-form';\n\nexport const CloudCommonChannelSettings: FC<CommonSettingsComponentProps> = ({\n pathPrefix,\n className,\n readOnly = false,\n}) => {\n const { register } = useFormContext();\n return (\n <div className={className}>\n <Field disabled={readOnly}>\n <Checkbox\n {...register(`${pathPrefix}sendResolved`)}\n label=\"Send resolved\"\n disabled={readOnly}\n description=\"Whether or not to notify about resolved alerts.\"\n />\n </Field>\n </div>\n );\n};\n","import { set } from 'lodash';\nimport { useCallback } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\n\ninterface Options<R> {\n name: string;\n formAPI: UseFormReturn<any>;\n defaults?: R[];\n\n // if true, sets `__deleted: true` but does not remove item from the array in values\n softDelete?: boolean;\n}\n\nexport type ControlledField<R> = R & {\n __deleted?: boolean;\n};\n\nconst EMPTY_ARRAY = [] as const;\n\n/*\n * react-hook-form's own useFieldArray is uncontrolled and super buggy.\n * this is a simple controlled version. It's dead simple and more robust at the cost of re-rendering the form\n * on every change to the sub forms in the array.\n * Warning: you'll have to take care of your own unique identiifer to use as `key` for the ReactNode array.\n * Using index will cause problems.\n */\nexport function useControlledFieldArray<R>(options: Options<R>) {\n const { name, formAPI, defaults, softDelete } = options;\n const { watch, getValues, reset, setValue } = formAPI;\n\n const fields: Array<ControlledField<R>> = watch(name) ?? defaults ?? EMPTY_ARRAY;\n\n const update = useCallback(\n (updateFn: (fields: R[]) => R[]) => {\n const values = JSON.parse(JSON.stringify(getValues()));\n const newItems = updateFn(fields ?? []);\n reset(set(values, name, newItems));\n },\n [getValues, name, reset, fields]\n );\n\n return {\n fields,\n append: useCallback((values: R) => update((fields) => [...fields, values]), [update]),\n remove: useCallback(\n (index: number) => {\n if (softDelete) {\n setValue(`${name}.${index}.__deleted`, true);\n } else {\n update((items) => {\n const newItems = items.slice();\n newItems.splice(index, 1);\n return newItems;\n });\n }\n },\n [update, name, setValue, softDelete]\n ),\n };\n}\n","import { css } from '@emotion/css';\nimport React, { FC, useEffect, useState } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Button, Input, useStyles2 } from '@grafana/ui';\n\nimport { ActionIcon } from '../../../rules/ActionIcon';\n\ninterface Props {\n value?: Record<string, string>;\n readOnly?: boolean;\n onChange: (value: Record<string, string>) => void;\n}\n\nexport const KeyValueMapInput: FC<Props> = ({ value, onChange, readOnly = false }) => {\n const styles = useStyles2(getStyles);\n const [pairs, setPairs] = useState(recordToPairs(value));\n useEffect(() => setPairs(recordToPairs(value)), [value]);\n\n const emitChange = (pairs: Array<[string, string]>) => {\n onChange(pairsToRecord(pairs));\n };\n\n const deleteItem = (index: number) => {\n const newPairs = pairs.slice();\n const removed = newPairs.splice(index, 1)[0];\n setPairs(newPairs);\n if (removed[0]) {\n emitChange(newPairs);\n }\n };\n\n const updatePair = (values: [string, string], index: number) => {\n const old = pairs[index];\n const newPairs = pairs.map((pair, i) => (i === index ? values : pair));\n setPairs(newPairs);\n if (values[0] || old[0]) {\n emitChange(newPairs);\n }\n };\n\n return (\n <div>\n {!!pairs.length && (\n <table className={styles.table}>\n <thead>\n <tr>\n <th>Name</th>\n <th>Value</th>\n {!readOnly && <th></th>}\n </tr>\n </thead>\n <tbody>\n {pairs.map(([key, value], index) => (\n <tr key={index}>\n <td>\n <Input\n readOnly={readOnly}\n value={key}\n onChange={(e) => updatePair([e.currentTarget.value, value], index)}\n />\n </td>\n <td>\n <Input\n readOnly={readOnly}\n value={value}\n onChange={(e) => updatePair([key, e.currentTarget.value], index)}\n />\n </td>\n {!readOnly && (\n <td>\n <ActionIcon icon=\"trash-alt\" tooltip=\"delete\" onClick={() => deleteItem(index)} />\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n )}\n {!readOnly && (\n <Button\n className={styles.addButton}\n type=\"button\"\n variant=\"secondary\"\n icon=\"plus\"\n size=\"sm\"\n onClick={() => setPairs([...pairs, ['', '']])}\n >\n Add\n </Button>\n )}\n </div>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n addButton: css`\n margin-top: ${theme.spacing(1)};\n `,\n table: css`\n tbody td {\n padding: 0 ${theme.spacing(1)} ${theme.spacing(1)} 0;\n }\n `,\n});\n\nconst pairsToRecord = (pairs: Array<[string, string]>): Record<string, string> => {\n const record: Record<string, string> = {};\n for (const [key, value] of pairs) {\n if (key) {\n record[key] = value;\n }\n }\n return record;\n};\n\nconst recordToPairs = (obj?: Record<string, string>): Array<[string, string]> => Object.entries(obj ?? {});\n","import { css } from '@emotion/css';\nimport React, { FC } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Button, Input, useStyles2 } from '@grafana/ui';\n\nimport { ActionIcon } from '../../../rules/ActionIcon';\n\ninterface Props {\n value?: string[];\n readOnly?: boolean;\n onChange: (value: string[]) => void;\n}\n\nexport const StringArrayInput: FC<Props> = ({ value, onChange, readOnly = false }) => {\n const styles = useStyles2(getStyles);\n\n const deleteItem = (index: number) => {\n if (!value) {\n return;\n }\n const newValue = value.slice();\n newValue.splice(index, 1);\n onChange(newValue);\n };\n\n const updateValue = (itemValue: string, index: number) => {\n if (!value) {\n return;\n }\n onChange(value.map((v, i) => (i === index ? itemValue : v)));\n };\n\n return (\n <div>\n {!!value?.length &&\n value.map((v, index) => (\n <div key={index} className={styles.row}>\n <Input readOnly={readOnly} value={v} onChange={(e) => updateValue(e.currentTarget.value, index)} />\n {!readOnly && (\n <ActionIcon\n className={styles.deleteIcon}\n icon=\"trash-alt\"\n tooltip=\"delete\"\n onClick={() => deleteItem(index)}\n />\n )}\n </div>\n ))}\n {!readOnly && (\n <Button\n className={styles.addButton}\n type=\"button\"\n variant=\"secondary\"\n icon=\"plus\"\n size=\"sm\"\n onClick={() => onChange([...(value ?? []), ''])}\n >\n Add\n </Button>\n )}\n </div>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n row: css`\n display: flex;\n flex-direction: row;\n margin-bottom: ${theme.spacing(1)};\n align-items: center;\n `,\n deleteIcon: css`\n margin-left: ${theme.spacing(1)};\n `,\n addButton: css`\n margin-top: ${theme.spacing(1)};\n `,\n});\n","import { css, cx } from '@emotion/css';\nimport React, { FC, useState } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { IconSize, useStyles2 } from '@grafana/ui';\n\nimport { CollapseToggle } from '../../CollapseToggle';\n\ninterface Props {\n label: string;\n description?: string;\n className?: string;\n size?: IconSize;\n}\n\nexport const CollapsibleSection: FC<Props> = ({ label, description, children, className, size = 'xl' }) => {\n const styles = useStyles2(getStyles);\n const [isCollapsed, setIsCollapsed] = useState(true);\n\n const toggleCollapse = () => setIsCollapsed(!isCollapsed);\n\n return (\n <div className={cx(styles.wrapper, className)}>\n <div className={styles.heading} onClick={toggleCollapse}>\n <CollapseToggle className={styles.caret} size={size} onToggle={toggleCollapse} isCollapsed={isCollapsed} />\n <h6>{label}</h6>\n </div>\n {description && <p className={styles.description}>{description}</p>}\n <div className={isCollapsed ? styles.hidden : undefined}>{children}</div>\n </div>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css`\n margin-top: ${theme.spacing(1)};\n padding-bottom: ${theme.spacing(1)};\n `,\n caret: css`\n margin-left: -${theme.spacing(0.5)}; // make it align with fields despite icon size\n `,\n heading: css`\n cursor: pointer;\n h6 {\n display: inline-block;\n }\n `,\n hidden: css`\n display: none;\n `,\n description: css`\n color: ${theme.colors.text.secondary};\n font-size: ${theme.typography.size.sm};\n font-weight: ${theme.typography.fontWeightRegular};\n margin: 0;\n `,\n});\n","import { css } from '@emotion/css';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nexport const getReceiverFormFieldStyles = (theme: GrafanaTheme2) => ({\n collapsibleSection: css`\n margin: 0;\n padding: 0;\n `,\n wrapper: css`\n margin: ${theme.spacing(2, 0)};\n padding: ${theme.spacing(1)};\n border: solid 1px ${theme.colors.border.medium};\n border-radius: ${theme.shape.borderRadius(1)};\n position: relative;\n `,\n description: css`\n color: ${theme.colors.text.secondary};\n font-size: ${theme.typography.size.sm};\n font-weight: ${theme.typography.fontWeightRegular};\n margin: 0;\n `,\n deleteIcon: css`\n position: absolute;\n right: ${theme.spacing(1)};\n top: ${theme.spacing(1)};\n `,\n addButton: css`\n margin-top: ${theme.spacing(1)};\n `,\n});\n","import React, { FC } from 'react';\nimport { FieldError, DeepMap, useFormContext } from 'react-hook-form';\n\nimport { Button, useStyles2 } from '@grafana/ui';\nimport { useControlledFieldArray } from 'app/features/alerting/unified/hooks/useControlledFieldArray';\nimport { NotificationChannelOption } from 'app/types';\n\nimport { ActionIcon } from '../../../rules/ActionIcon';\nimport { CollapsibleSection } from '../CollapsibleSection';\n\nimport { OptionField } from './OptionField';\nimport { getReceiverFormFieldStyles } from './styles';\n\ninterface Props {\n defaultValues?: any[];\n option: NotificationChannelOption;\n pathPrefix: string;\n errors?: Array<DeepMap<any, FieldError>>;\n readOnly?: boolean;\n}\n\nexport const SubformArrayField: FC<Props> = ({ option, pathPrefix, errors, defaultValues, readOnly = false }) => {\n const styles = useStyles2(getReceiverFormFieldStyles);\n const path = `${pathPrefix}${option.propertyName}`;\n const formAPI = useFormContext();\n const { fields, append, remove } = useControlledFieldArray({ name: path, formAPI, defaults: defaultValues });\n\n return (\n <div className={styles.wrapper}>\n <CollapsibleSection\n className={styles.collapsibleSection}\n label={`${option.label} (${fields.length})`}\n description={option.description}\n >\n {(fields ?? defaultValues ?? []).map((field, itemIndex) => {\n return (\n <div key={itemIndex} className={styles.wrapper}>\n {!readOnly && (\n <ActionIcon\n data-testid={`${path}.${itemIndex}.delete-button`}\n icon=\"trash-alt\"\n tooltip=\"delete\"\n onClick={() => remove(itemIndex)}\n className={styles.deleteIcon}\n />\n )}\n {option.subformOptions?.map((option) => (\n <OptionField\n readOnly={readOnly}\n defaultValue={field?.[option.propertyName]}\n key={option.propertyName}\n option={option}\n pathPrefix={`${path}.${itemIndex}.`}\n error={errors?.[itemIndex]?.[option.propertyName]}\n />\n ))}\n </div>\n );\n })}\n {!readOnly && (\n <Button\n data-testid={`${path}.add-button`}\n className={styles.addButton}\n type=\"button\"\n variant=\"secondary\"\n icon=\"plus\"\n size=\"sm\"\n onClick={() => append({ __id: String(Math.random()) })}\n >\n Add\n </Button>\n )}\n </CollapsibleSection>\n </div>\n );\n};\n","import React, { FC, useState } from 'react';\nimport { FieldError, DeepMap, useFormContext } from 'react-hook-form';\n\nimport { Button, useStyles2 } from '@grafana/ui';\nimport { NotificationChannelOption } from 'app/types';\n\nimport { ActionIcon } from '../../../rules/ActionIcon';\n\nimport { OptionField } from './OptionField';\nimport { getReceiverFormFieldStyles } from './styles';\n\ninterface Props {\n defaultValue: any;\n option: NotificationChannelOption;\n pathPrefix: string;\n errors?: DeepMap<any, FieldError>;\n readOnly?: boolean;\n}\n\nexport const SubformField: FC<Props> = ({ option, pathPrefix, errors, defaultValue, readOnly = false }) => {\n const styles = useStyles2(getReceiverFormFieldStyles);\n const name = `${pathPrefix}${option.propertyName}`;\n const { watch } = useFormContext();\n const _watchValue = watch(name);\n const value = _watchValue === undefined ? defaultValue : _watchValue;\n\n const [show, setShow] = useState(!!value);\n\n return (\n <div className={styles.wrapper} data-testid={`${name}.container`}>\n <h6>{option.label}</h6>\n {option.description && <p className={styles.description}>{option.description}</p>}\n {show && (\n <>\n {!readOnly && (\n <ActionIcon\n data-testid={`${name}.delete-button`}\n icon=\"trash-alt\"\n tooltip=\"delete\"\n onClick={() => setShow(false)}\n className={styles.deleteIcon}\n />\n )}\n {(option.subformOptions ?? []).map((subOption) => {\n return (\n <OptionField\n readOnly={readOnly}\n defaultValue={defaultValue?.[subOption.propertyName]}\n key={subOption.propertyName}\n option={subOption}\n pathPrefix={`${name}.`}\n error={errors?.[subOption.propertyName]}\n />\n );\n })}\n </>\n )}\n {!show && !readOnly && (\n <Button\n className={styles.addButton}\n type=\"button\"\n variant=\"secondary\"\n icon=\"plus\"\n size=\"sm\"\n onClick={() => setShow(true)}\n data-testid={`${name}.add-button`}\n >\n Add\n </Button>\n )}\n </div>\n );\n};\n","import { css } from '@emotion/css';\nimport { isEmpty } from 'lodash';\nimport React, { FC, useEffect } from 'react';\nimport { useFormContext, FieldError, DeepMap } from 'react-hook-form';\n\nimport { Checkbox, Field, Input, InputControl, Select, TextArea } from '@grafana/ui';\nimport { NotificationChannelOption } from 'app/types';\n\nimport { KeyValueMapInput } from './KeyValueMapInput';\nimport { StringArrayInput } from './StringArrayInput';\nimport { SubformArrayField } from './SubformArrayField';\nimport { SubformField } from './SubformField';\n\ninterface Props {\n defaultValue: any;\n option: NotificationChannelOption;\n invalid?: boolean;\n pathPrefix: string;\n pathSuffix?: string;\n error?: FieldError | DeepMap<any, FieldError>;\n readOnly?: boolean;\n}\n\nexport const OptionField: FC<Props> = ({\n option,\n invalid,\n pathPrefix,\n pathSuffix = '',\n error,\n defaultValue,\n readOnly = false,\n}) => {\n const optionPath = `${pathPrefix}${pathSuffix}`;\n\n if (option.element === 'subform') {\n return (\n <SubformField\n readOnly={readOnly}\n defaultValue={defaultValue}\n option={option}\n errors={error as DeepMap<any, FieldError> | undefined}\n pathPrefix={optionPath}\n />\n );\n }\n if (option.element === 'subform_array') {\n return (\n <SubformArrayField\n readOnly={readOnly}\n defaultValues={defaultValue}\n option={option}\n pathPrefix={optionPath}\n errors={error as Array<DeepMap<any, FieldError>> | undefined}\n />\n );\n }\n return (\n <Field\n label={option.element !== 'checkbox' ? option.label : undefined}\n description={option.description || undefined}\n invalid={!!error}\n error={error?.message}\n >\n <OptionInput\n id={`${optionPath}${option.propertyName}`}\n defaultValue={defaultValue}\n option={option}\n invalid={invalid}\n pathPrefix={optionPath}\n readOnly={readOnly}\n pathIndex={pathPrefix}\n />\n </Field>\n );\n};\n\nconst OptionInput: FC<Props & { id: string; pathIndex?: string }> = ({\n option,\n invalid,\n id,\n pathPrefix = '',\n pathIndex = '',\n readOnly = false,\n}) => {\n const { control, register, unregister, getValues } = useFormContext();\n const name = `${pathPrefix}${option.propertyName}`;\n\n // workaround for https://github.com/react-hook-form/react-hook-form/issues/4993#issuecomment-829012506\n useEffect(\n () => () => {\n unregister(name, { keepValue: false });\n },\n [unregister, name]\n );\n switch (option.element) {\n case 'checkbox':\n return (\n <Checkbox\n id={id}\n readOnly={readOnly}\n disabled={readOnly}\n className={styles.checkbox}\n {...register(name)}\n label={option.label}\n description={option.description}\n />\n );\n case 'input':\n return (\n <Input\n id={id}\n readOnly={readOnly || determineReadOnly(option, getValues, pathIndex)}\n invalid={invalid}\n type={option.inputType}\n {...register(name, {\n required: determineRequired(option, getValues, pathIndex),\n validate: (v) => (option.validationRule !== '' ? validateOption(v, option.validationRule) : true),\n })}\n placeholder={option.placeholder}\n />\n );\n\n case 'select':\n return (\n <InputControl\n render={({ field: { onChange, ref, ...field } }) => (\n <Select\n disabled={readOnly}\n {...field}\n options={option.selectOptions ?? undefined}\n invalid={invalid}\n onChange={(value) => onChange(value.value)}\n />\n )}\n control={control}\n name={name}\n />\n );\n\n case 'textarea':\n return (\n <TextArea\n id={id}\n readOnly={readOnly}\n invalid={invalid}\n {...register(name, {\n required: option.required ? 'Required' : false,\n validate: (v) => (option.validationRule !== '' ? validateOption(v, option.validationRule) : true),\n })}\n />\n );\n case 'string_array':\n return (\n <InputControl\n render={({ field: { value, onChange } }) => (\n <StringArrayInput readOnly={readOnly} value={value} onChange={onChange} />\n )}\n control={control}\n name={name}\n />\n );\n case 'key_value_map':\n return (\n <InputControl\n render={({ field: { value, onChange } }) => (\n <KeyValueMapInput readOnly={readOnly} value={value} onChange={onChange} />\n )}\n control={control}\n name={name}\n />\n );\n\n default:\n console.error('Element not supported', option.element);\n return null;\n }\n};\n\nconst styles = {\n checkbox: css`\n height: auto; // native checkbox has fixed height which does not take into account description\n `,\n};\n\nconst validateOption = (value: string, validationRule: string) => {\n return RegExp(validationRule).test(value) ? true : 'Invalid format';\n};\n\nconst determineRequired = (option: NotificationChannelOption, getValues: any, pathIndex: string) => {\n if (!option.dependsOn) {\n return option.required ? 'Required' : false;\n }\n if (isEmpty(getValues(`${pathIndex}secureFields`))) {\n const dependentOn = getValues(`${pathIndex}secureSettings.${option.dependsOn}`);\n return !Boolean(dependentOn) && option.required ? 'Required' : false;\n } else {\n const dependentOn: boolean = getValues(`${pathIndex}secureFields.${option.dependsOn}`);\n return !dependentOn && option.required ? 'Required' : false;\n }\n};\n\nconst determineReadOnly = (option: NotificationChannelOption, getValues: any, pathIndex: string) => {\n if (!option.dependsOn) {\n return false;\n }\n if (isEmpty(getValues(`${pathIndex}secureFields`))) {\n return getValues(`${pathIndex}secureSettings.${option.dependsOn}`);\n } else {\n return getValues(`${pathIndex}secureFields.${option.dependsOn}`);\n }\n};\n","import React from 'react';\nimport { useFormContext, FieldError, FieldErrors, DeepMap } from 'react-hook-form';\n\nimport { Button, Field, Input } from '@grafana/ui';\nimport { NotificationChannelOption, NotificationChannelSecureFields } from 'app/types';\n\nimport { ChannelValues, ReceiverFormValues } from '../../../types/receiver-form';\n\nimport { OptionField } from './fields/OptionField';\n\nexport interface Props<R extends ChannelValues> {\n defaultValues: R;\n selectedChannelOptions: NotificationChannelOption[];\n secureFields: NotificationChannelSecureFields;\n\n onResetSecureField: (key: string) => void;\n errors?: FieldErrors<R>;\n pathPrefix?: string;\n readOnly?: boolean;\n}\n\nexport function ChannelOptions<R extends ChannelValues>({\n defaultValues,\n selectedChannelOptions,\n onResetSecureField,\n secureFields,\n errors,\n pathPrefix = '',\n readOnly = false,\n}: Props<R>): JSX.Element {\n const { watch } = useFormContext<ReceiverFormValues<R>>();\n const currentFormValues = watch() as Record<string, any>; // react hook form types ARE LYING!\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 = currentFormValues[`${pathPrefix}settings.${option.showWhen.field}`];\n\n if (option.showWhen.field && selectedOptionValue !== option.showWhen.is) {\n return null;\n }\n\n if (secureFields && secureFields[option.propertyName]) {\n return (\n <Field key={key} label={option.label} description={option.description || undefined}>\n <Input\n readOnly={true}\n value=\"Configured\"\n suffix={\n readOnly ? null : (\n <Button onClick={() => onResetSecureField(option.propertyName)} fill=\"text\" type=\"button\" size=\"sm\">\n Clear\n </Button>\n )\n }\n />\n </Field>\n );\n }\n\n const error: FieldError | DeepMap<any, FieldError> | undefined = (\n (option.secure ? errors?.secureSettings : errors?.settings) as DeepMap<any, FieldError> | undefined\n )?.[option.propertyName];\n\n const defaultValue = defaultValues?.settings?.[option.propertyName];\n\n return (\n <OptionField\n defaultValue={defaultValue}\n readOnly={readOnly}\n key={key}\n error={error}\n pathPrefix={pathPrefix}\n pathSuffix={option.secure ? 'secureSettings.' : 'settings.'}\n option={option}\n />\n );\n })}\n </>\n );\n}\n","import { css } from '@emotion/css';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useFormContext, FieldErrors } from 'react-hook-form';\n\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { Alert, Button, Field, InputControl, Select, useStyles2 } from '@grafana/ui';\nimport { NotifierDTO } from 'app/types';\n\nimport { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector';\nimport { ChannelValues, CommonSettingsComponentType } from '../../../types/receiver-form';\n\nimport { ChannelOptions } from './ChannelOptions';\nimport { CollapsibleSection } from './CollapsibleSection';\n\ninterface Props<R> {\n defaultValues: R;\n pathPrefix: string;\n notifiers: NotifierDTO[];\n onDuplicate: () => void;\n onTest?: () => void;\n commonSettingsComponent: CommonSettingsComponentType;\n\n secureFields?: Record<string, boolean>;\n errors?: FieldErrors<R>;\n onDelete?: () => void;\n readOnly?: boolean;\n}\n\nexport function ChannelSubForm<R extends ChannelValues>({\n defaultValues,\n pathPrefix,\n onDuplicate,\n onDelete,\n onTest,\n notifiers,\n errors,\n secureFields,\n commonSettingsComponent: CommonSettingsComponent,\n readOnly = false,\n}: Props<R>): JSX.Element {\n const styles = useStyles2(getStyles);\n const name = (fieldName: string) => `${pathPrefix}${fieldName}`;\n const { control, watch, register, trigger, formState, setValue } = useFormContext();\n const selectedType = watch(name('type')) ?? defaultValues.type; // nope, setting \"default\" does not work at all.\n const { loading: testingReceiver } = useUnifiedAlertingSelector((state) => state.testReceivers);\n\n useEffect(() => {\n register(`${pathPrefix}.__id`);\n /* Need to manually register secureFields or else they'll\n be lost when testing a contact point */\n register(`${pathPrefix}.secureFields`);\n }, [register, pathPrefix]);\n\n const [_secureFields, setSecureFields] = useState(secureFields ?? {});\n\n const onResetSecureField = (key: string) => {\n if (_secureFields[key]) {\n const updatedSecureFields = { ...secureFields };\n delete updatedSecureFields[key];\n setSecureFields(updatedSecureFields);\n setValue(`${pathPrefix}.secureFields`, updatedSecureFields);\n }\n };\n\n const typeOptions = useMemo(\n (): SelectableValue[] =>\n notifiers\n .map(({ name, type }) => ({\n label: name,\n value: type,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n [notifiers]\n );\n\n const handleTest = async () => {\n await trigger();\n const isValid = Object.keys(formState.errors).length === 0;\n\n if (isValid && onTest) {\n onTest();\n }\n };\n\n const notifier = notifiers.find(({ type }) => type === selectedType);\n // if there are mandatory options defined, optional options will be hidden by a collapse\n // if there aren't mandatory options, all options will be shown without collapse\n const mandatoryOptions = notifier?.options.filter((o) => o.required);\n const optionalOptions = notifier?.options.filter((o) => !o.required);\n\n const contactPointTypeInputId = `contact-point-type-${pathPrefix}`;\n return (\n <div className={styles.wrapper} data-testid=\"item-container\">\n <div className={styles.topRow}>\n <div>\n <Field label=\"Contact point type\" htmlFor={contactPointTypeInputId} data-testid={`${pathPrefix}type`}>\n <InputControl\n name={name('type')}\n defaultValue={defaultValues.type}\n render={({ field: { ref, onChange, ...field } }) => (\n <Select\n disabled={readOnly}\n inputId={contactPointTypeInputId}\n {...field}\n width={37}\n options={typeOptions}\n onChange={(value) => onChange(value?.value)}\n />\n )}\n control={control}\n rules={{ required: true }}\n />\n </Field>\n </div>\n {!readOnly && (\n <div className={styles.buttons}>\n {onTest && (\n <Button\n disabled={testingReceiver}\n size=\"xs\"\n variant=\"secondary\"\n type=\"button\"\n onClick={() => handleTest()}\n icon={testingReceiver ? 'fa fa-spinner' : 'message'}\n >\n Test\n </Button>\n )}\n <Button size=\"xs\" variant=\"secondary\" type=\"button\" onClick={() => onDuplicate()} icon=\"copy\">\n Duplicate\n </Button>\n {onDelete && (\n <Button\n data-testid={`${pathPrefix}delete-button`}\n size=\"xs\"\n variant=\"secondary\"\n type=\"button\"\n onClick={() => onDelete()}\n icon=\"trash-alt\"\n >\n Delete\n </Button>\n )}\n </div>\n )}\n </div>\n {notifier && (\n <div className={styles.innerContent}>\n <ChannelOptions<R>\n defaultValues={defaultValues}\n selectedChannelOptions={mandatoryOptions?.length ? mandatoryOptions! : optionalOptions!}\n secureFields={_secureFields}\n errors={errors}\n onResetSecureField={onResetSecureField}\n pathPrefix={pathPrefix}\n readOnly={readOnly}\n />\n {!!(mandatoryOptions?.length && optionalOptions?.length) && (\n <CollapsibleSection label={`Optional ${notifier.name} settings`}>\n {notifier.info !== '' && (\n <Alert title=\"\" severity=\"info\">\n {notifier.info}\n </Alert>\n )}\n <ChannelOptions<R>\n defaultValues={defaultValues}\n selectedChannelOptions={optionalOptions!}\n secureFields={_secureFields}\n onResetSecureField={onResetSecureField}\n errors={errors}\n pathPrefix={pathPrefix}\n readOnly={readOnly}\n />\n </CollapsibleSection>\n )}\n <CollapsibleSection label=\"Notification settings\">\n <CommonSettingsComponent pathPrefix={pathPrefix} readOnly={readOnly} />\n </CollapsibleSection>\n </div>\n )}\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n buttons: css`\n & > * + * {\n margin-left: ${theme.spacing(1)};\n }\n `,\n innerContent: css`\n max-width: 536px;\n `,\n wrapper: css`\n margin: ${theme.spacing(2, 0)};\n padding: ${theme.spacing(1)};\n border: solid 1px ${theme.colors.border.medium};\n border-radius: ${theme.shape.borderRadius(1)};\n max-width: ${theme.breakpoints.values.xl}${theme.breakpoints.unit};\n `,\n topRow: css`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n `,\n channelSettingsHeader: css`\n margin-top: ${theme.spacing(2)};\n `,\n});\n","import React, { useEffect } from 'react';\nimport { useFormContext } from 'react-hook-form';\n\ninterface Props {\n pathPrefix: string;\n}\n\n// we can't drop the deleted item from list entirely because\n// there will be a rece condition with register/unregister calls in react-hook-form\n// and fields will become randomly erroneously unregistered\nexport function DeletedSubForm({ pathPrefix }: Props): JSX.Element {\n const { register } = useFormContext();\n\n // required to be registered or react-hook-form will randomly drop the values when it feels like it\n useEffect(() => {\n register(`${pathPrefix}.__id`);\n register(`${pathPrefix}.__deleted`);\n }, [register, pathPrefix]);\n\n return <></>;\n}\n","import { css } from '@emotion/css';\nimport React, { useCallback } from 'react';\nimport { useForm, FormProvider, FieldErrors, Validate } from 'react-hook-form';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Alert, Button, Field, Input, LinkButton, useStyles2 } from '@grafana/ui';\nimport { useAppNotification } from 'app/core/copy/appNotification';\nimport { useCleanup } from 'app/core/hooks/useCleanup';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\nimport { NotifierDTO } from 'app/types';\n\nimport { useControlledFieldArray } from '../../../hooks/useControlledFieldArray';\nimport { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector';\nimport { ChannelValues, CommonSettingsComponentType, ReceiverFormValues } from '../../../types/receiver-form';\nimport { isVanillaPrometheusAlertManagerDataSource } from '../../../utils/datasource';\nimport { makeAMLink } from '../../../utils/misc';\n\nimport { ChannelSubForm } from './ChannelSubForm';\nimport { DeletedSubForm } from './fields/DeletedSubform';\n\ninterface Props<R extends ChannelValues> {\n config: AlertManagerCortexConfig;\n notifiers: NotifierDTO[];\n defaultItem: R;\n alertManagerSourceName: string;\n onTestChannel?: (channel: R) => void;\n onSubmit: (values: ReceiverFormValues<R>) => void;\n takenReceiverNames: string[]; // will validate that user entered receiver name is not one of these\n commonSettingsComponent: CommonSettingsComponentType;\n initialValues?: ReceiverFormValues<R>;\n}\n\nexport function ReceiverForm<R extends ChannelValues>({\n config,\n initialValues,\n defaultItem,\n notifiers,\n alertManagerSourceName,\n onSubmit,\n onTestChannel,\n takenReceiverNames,\n commonSettingsComponent,\n}: Props<R>): JSX.Element {\n const notifyApp = useAppNotification();\n const styles = useStyles2(getStyles);\n const readOnly = isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName);\n const defaultValues = initialValues || {\n name: '',\n items: [\n {\n ...defaultItem,\n __id: String(Math.random()),\n } as any,\n ],\n };\n\n const formAPI = useForm<ReceiverFormValues<R>>({\n // making a copy here beacuse react-hook-form will mutate these, and break if the object is frozen. for real.\n defaultValues: JSON.parse(JSON.stringify(defaultValues)),\n });\n\n useCleanup((state) => state.unifiedAlerting.saveAMConfig);\n\n const { loading } = useUnifiedAlertingSelector((state) => state.saveAMConfig);\n\n const {\n handleSubmit,\n register,\n formState: { errors },\n getValues,\n } = formAPI;\n\n const { fields, append, remove } = useControlledFieldArray<R>({ name: 'items', formAPI, softDelete: true });\n\n const validateNameIsAvailable: Validate<string> = useCallback(\n (name: string) =>\n takenReceiverNames.map((name) => name.trim().toLowerCase()).includes(name.trim().toLowerCase())\n ? 'Another receiver with this name already exists.'\n : true,\n [takenReceiverNames]\n );\n\n const submitCallback = (values: ReceiverFormValues<R>) => {\n onSubmit({\n ...values,\n items: values.items.filter((item) => !item.__deleted),\n });\n };\n\n const onInvalid = () => {\n notifyApp.error('There are errors in the form. Please correct them and try again!');\n };\n\n return (\n <FormProvider {...formAPI}>\n {!config.alertmanager_config.route && (\n <Alert severity=\"warning\" title=\"Attention\">\n Because there is no default policy configured yet, this contact point will automatically be set as default.\n </Alert>\n )}\n <form onSubmit={handleSubmit(submitCallback, onInvalid)}>\n <h4 className={styles.heading}>\n {readOnly ? 'Contact point' : initialValues ? 'Update contact point' : 'Create contact point'}\n </h4>\n <Field label=\"Name\" invalid={!!errors.name} error={errors.name && errors.name.message} required>\n <Input\n readOnly={readOnly}\n id=\"name\"\n {...register('name', {\n required: 'Name is required',\n validate: { nameIsAvailable: validateNameIsAvailable },\n })}\n width={39}\n placeholder=\"Name\"\n />\n </Field>\n {fields.map((field, index) => {\n const pathPrefix = `items.${index}.`;\n if (field.__deleted) {\n return <DeletedSubForm key={field.__id} pathPrefix={pathPrefix} />;\n }\n const initialItem = initialValues?.items.find(({ __id }) => __id === field.__id);\n return (\n <ChannelSubForm<R>\n defaultValues={field}\n key={field.__id}\n onDuplicate={() => {\n const currentValues: R = getValues().items[index];\n append({ ...currentValues, __id: String(Math.random()) });\n }}\n onTest={\n onTestChannel\n ? () => {\n const currentValues: R = getValues().items[index];\n onTestChannel(currentValues);\n }\n : undefined\n }\n onDelete={() => remove(index)}\n pathPrefix={pathPrefix}\n notifiers={notifiers}\n secureFields={initialItem?.secureFields}\n errors={errors?.items?.[index] as FieldErrors<R>}\n commonSettingsComponent={commonSettingsComponent}\n readOnly={readOnly}\n />\n );\n })}\n <>\n {!readOnly && (\n <Button\n type=\"button\"\n icon=\"plus\"\n variant=\"secondary\"\n onClick={() => append({ ...defaultItem, __id: String(Math.random()) } as R)}\n >\n New contact point type\n </Button>\n )}\n <div className={styles.buttons}>\n {!readOnly && (\n <>\n {loading && (\n <Button disabled={true} icon=\"fa fa-spinner\" variant=\"primary\">\n Saving...\n </Button>\n )}\n {!loading && <Button type=\"submit\">Save contact point</Button>}\n </>\n )}\n <LinkButton\n disabled={loading}\n fill=\"outline\"\n variant=\"secondary\"\n data-testid=\"cancel-button\"\n href={makeAMLink('alerting/notifications', alertManagerSourceName)}\n >\n Cancel\n </LinkButton>\n </div>\n </>\n </form>\n </FormProvider>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n heading: css`\n margin: ${theme.spacing(4, 0)};\n `,\n buttons: css`\n margin-top: ${theme.spacing(4)};\n\n & > * + * {\n margin-left: ${theme.spacing(1)};\n }\n `,\n});\n","import React, { FC, useMemo } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { Alert } from '@grafana/ui';\nimport { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types';\n\nimport { updateAlertManagerConfigAction } from '../../../state/actions';\nimport { CloudChannelValues, ReceiverFormValues, CloudChannelMap } from '../../../types/receiver-form';\nimport { cloudNotifierTypes } from '../../../utils/cloud-alertmanager-notifier-types';\nimport { isVanillaPrometheusAlertManagerDataSource } from '../../../utils/datasource';\nimport {\n cloudReceiverToFormValues,\n formValuesToCloudReceiver,\n updateConfigWithReceiver,\n} from '../../../utils/receiver-form';\n\nimport { CloudCommonChannelSettings } from './CloudCommonChannelSettings';\nimport { ReceiverForm } from './ReceiverForm';\n\ninterface Props {\n alertManagerSourceName: string;\n config: AlertManagerCortexConfig;\n existing?: Receiver;\n}\n\nconst defaultChannelValues: CloudChannelValues = Object.freeze({\n __id: '',\n sendResolved: true,\n secureSettings: {},\n settings: {},\n secureFields: {},\n type: 'email',\n});\n\nexport const CloudReceiverForm: FC<Props> = ({ existing, alertManagerSourceName, config }) => {\n const dispatch = useDispatch();\n const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName);\n\n // transform receiver DTO to form values\n const [existingValue] = useMemo((): [ReceiverFormValues<CloudChannelValues> | undefined, CloudChannelMap] => {\n if (!existing) {\n return [undefined, {}];\n }\n return cloudReceiverToFormValues(existing, cloudNotifierTypes);\n }, [existing]);\n\n const onSubmit = (values: ReceiverFormValues<CloudChannelValues>) => {\n const newReceiver = formValuesToCloudReceiver(values, defaultChannelValues);\n dispatch(\n updateAlertManagerConfigAction({\n newConfig: updateConfigWithReceiver(config, newReceiver, existing?.name),\n oldConfig: config,\n alertManagerSourceName,\n successMessage: existing ? 'Contact point updated.' : 'Contact point created.',\n redirectPath: '/alerting/notifications',\n })\n );\n };\n\n const takenReceiverNames = useMemo(\n () => config.alertmanager_config.receivers?.map(({ name }) => name).filter((name) => name !== existing?.name) ?? [],\n [config, existing]\n );\n\n return (\n <>\n {!isVanillaAM && (\n <Alert title=\"Info\" severity=\"info\">\n Note that empty string values will be replaced with global defaults where appropriate.\n </Alert>\n )}\n <ReceiverForm<CloudChannelValues>\n config={config}\n onSubmit={onSubmit}\n initialValues={existingValue}\n notifiers={cloudNotifierTypes}\n alertManagerSourceName={alertManagerSourceName}\n defaultItem={defaultChannelValues}\n takenReceiverNames={takenReceiverNames}\n commonSettingsComponent={CloudCommonChannelSettings}\n />\n </>\n );\n};\n","import React, { FC } from 'react';\nimport { useFormContext } from 'react-hook-form';\n\nimport { Checkbox, Field } from '@grafana/ui';\n\nimport { CommonSettingsComponentProps } from '../../../types/receiver-form';\n\nexport const GrafanaCommonChannelSettings: FC<CommonSettingsComponentProps> = ({ pathPrefix, className }) => {\n const { register } = useFormContext();\n return (\n <div className={className}>\n <Field>\n <Checkbox\n {...register(`${pathPrefix}disableResolveMessage`)}\n label=\"Disable resolved message\"\n description=\"Disable the resolve message [OK] that is sent when alerting state returns to false\"\n />\n </Field>\n </div>\n );\n};\n","import { css } from '@emotion/css';\nimport React, { useState } from 'react';\nimport { useForm, FormProvider } from 'react-hook-form';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Modal, Button, Label, useStyles2, RadioButtonGroup } from '@grafana/ui';\nimport { TestReceiversAlert } from 'app/plugins/datasource/alertmanager/types';\nimport { Annotations, Labels } from 'app/types/unified-alerting-dto';\n\nimport AnnotationsField from '../../rule-editor/AnnotationsField';\nimport LabelsField from '../../rule-editor/LabelsField';\n\ninterface Props {\n isOpen: boolean;\n onDismiss: () => void;\n onTest: (alert?: TestReceiversAlert) => void;\n}\n\ntype AnnoField = {\n key: string;\n value: string;\n};\n\ninterface FormFields {\n annotations: AnnoField[];\n labels: AnnoField[];\n}\n\nenum NotificationType {\n predefined = 'Predefined',\n custom = 'Custom',\n}\n\nconst notificationOptions = Object.values(NotificationType).map((value) => ({ label: value, value: value }));\n\nconst defaultValues: FormFields = {\n annotations: [{ key: '', value: '' }],\n labels: [{ key: '', value: '' }],\n};\n\nexport const TestContactPointModal = ({ isOpen, onDismiss, onTest }: Props) => {\n const [notificationType, setNotificationType] = useState<NotificationType>(NotificationType.predefined);\n const styles = useStyles2(getStyles);\n const formMethods = useForm<FormFields>({ defaultValues, mode: 'onBlur' });\n\n const onSubmit = (data: FormFields) => {\n if (notificationType === NotificationType.custom) {\n const alert = {\n annotations: data.annotations\n .filter(({ key, value }) => !!key && !!value)\n .reduce((acc, { key, value }) => {\n return { ...acc, [key]: value };\n }, {} as Annotations),\n labels: data.labels\n .filter(({ key, value }) => !!key && !!value)\n .reduce((acc, { key, value }) => {\n return { ...acc, [key]: value };\n }, {} as Labels),\n };\n onTest(alert);\n } else {\n onTest();\n }\n };\n\n return (\n <Modal onDismiss={onDismiss} isOpen={isOpen} title={'Test contact point'}>\n <div className={styles.section}>\n <Label>Notification message</Label>\n <RadioButtonGroup\n options={notificationOptions}\n value={notificationType}\n onChange={(value) => setNotificationType(value)}\n />\n </div>\n\n <FormProvider {...formMethods}>\n <form onSubmit={formMethods.handleSubmit(onSubmit)}>\n {notificationType === NotificationType.predefined && (\n <div className={styles.section}>\n You will send a test notification that uses a predefined alert. If you have defined a custom template or\n message, for better results switch to <strong>custom</strong> notification message, from above.\n </div>\n )}\n {notificationType === NotificationType.custom && (\n <>\n <div className={styles.section}>\n You will send a test notification that uses the annotations defined below. This is a good option if you\n use custom templates and messages.\n </div>\n <div className={styles.section}>\n <AnnotationsField />\n </div>\n <div className={styles.section}>\n <LabelsField />\n </div>\n </>\n )}\n\n <Modal.ButtonRow>\n <Button type=\"submit\">Send test notification</Button>\n </Modal.ButtonRow>\n </form>\n </FormProvider>\n </Modal>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n flexRow: css`\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n margin-bottom: ${theme.spacing(1)};\n `,\n section: css`\n margin-bottom: ${theme.spacing(2)};\n `,\n});\n","import React, { FC, useEffect, useMemo, useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LoadingPlaceholder } from '@grafana/ui';\nimport {\n AlertManagerCortexConfig,\n GrafanaManagedReceiverConfig,\n Receiver,\n TestReceiversAlert,\n} from 'app/plugins/datasource/alertmanager/types';\n\nimport { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector';\nimport {\n fetchGrafanaNotifiersAction,\n testReceiversAction,\n updateAlertManagerConfigAction,\n} from '../../../state/actions';\nimport { GrafanaChannelValues, ReceiverFormValues } from '../../../types/receiver-form';\nimport { GRAFANA_RULES_SOURCE_NAME } from '../../../utils/datasource';\nimport {\n formChannelValuesToGrafanaChannelConfig,\n formValuesToGrafanaReceiver,\n grafanaReceiverToFormValues,\n updateConfigWithReceiver,\n} from '../../../utils/receiver-form';\n\nimport { GrafanaCommonChannelSettings } from './GrafanaCommonChannelSettings';\nimport { ReceiverForm } from './ReceiverForm';\nimport { TestContactPointModal } from './TestContactPointModal';\n\ninterface Props {\n alertManagerSourceName: string;\n config: AlertManagerCortexConfig;\n existing?: Receiver;\n}\n\nconst defaultChannelValues: GrafanaChannelValues = Object.freeze({\n __id: '',\n secureSettings: {},\n settings: {},\n secureFields: {},\n disableResolveMessage: false,\n type: 'email',\n});\n\nexport const GrafanaReceiverForm: FC<Props> = ({ existing, alertManagerSourceName, config }) => {\n const grafanaNotifiers = useUnifiedAlertingSelector((state) => state.grafanaNotifiers);\n const [testChannelValues, setTestChannelValues] = useState<GrafanaChannelValues>();\n\n const dispatch = useDispatch();\n\n useEffect(() => {\n if (!(grafanaNotifiers.result || grafanaNotifiers.loading)) {\n dispatch(fetchGrafanaNotifiersAction());\n }\n }, [grafanaNotifiers, dispatch]);\n\n // transform receiver DTO to form values\n const [existingValue, id2original] = useMemo((): [\n ReceiverFormValues<GrafanaChannelValues> | undefined,\n Record<string, GrafanaManagedReceiverConfig>\n ] => {\n if (!existing || !grafanaNotifiers.result) {\n return [undefined, {}];\n }\n return grafanaReceiverToFormValues(existing, grafanaNotifiers.result!);\n }, [existing, grafanaNotifiers.result]);\n\n const onSubmit = (values: ReceiverFormValues<GrafanaChannelValues>) => {\n const newReceiver = formValuesToGrafanaReceiver(values, id2original, defaultChannelValues);\n dispatch(\n updateAlertManagerConfigAction({\n newConfig: updateConfigWithReceiver(config, newReceiver, existing?.name),\n oldConfig: config,\n alertManagerSourceName: GRAFANA_RULES_SOURCE_NAME,\n successMessage: existing ? 'Contact point updated.' : 'Contact point created',\n redirectPath: '/alerting/notifications',\n })\n );\n };\n\n const onTestChannel = (values: GrafanaChannelValues) => {\n setTestChannelValues(values);\n };\n\n const testNotification = (alert?: TestReceiversAlert) => {\n if (testChannelValues) {\n const existing: GrafanaManagedReceiverConfig | undefined = id2original[testChannelValues.__id];\n const chan = formChannelValuesToGrafanaChannelConfig(testChannelValues, defaultChannelValues, 'test', existing);\n\n const payload = {\n alertManagerSourceName,\n receivers: [\n {\n name: 'test',\n grafana_managed_receiver_configs: [chan],\n },\n ],\n alert,\n };\n\n dispatch(testReceiversAction(payload));\n }\n };\n\n const takenReceiverNames = useMemo(\n () => config.alertmanager_config.receivers?.map(({ name }) => name).filter((name) => name !== existing?.name) ?? [],\n [config, existing]\n );\n\n if (grafanaNotifiers.result) {\n return (\n <>\n <ReceiverForm<GrafanaChannelValues>\n config={config}\n onSubmit={onSubmit}\n initialValues={existingValue}\n onTestChannel={onTestChannel}\n notifiers={grafanaNotifiers.result}\n alertManagerSourceName={alertManagerSourceName}\n defaultItem={defaultChannelValues}\n takenReceiverNames={takenReceiverNames}\n commonSettingsComponent={GrafanaCommonChannelSettings}\n />\n <TestContactPointModal\n onDismiss={() => setTestChannelValues(undefined)}\n isOpen={!!testChannelValues}\n onTest={(alert) => testNotification(alert)}\n />\n </>\n );\n } else {\n return <LoadingPlaceholder text=\"Loading notifiers...\" />;\n }\n};\n","import React, { FC } from 'react';\n\nimport { InfoBox } from '@grafana/ui';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';\n\nimport { CloudReceiverForm } from './form/CloudReceiverForm';\nimport { GrafanaReceiverForm } from './form/GrafanaReceiverForm';\n\ninterface Props {\n receiverName: string;\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\nexport const EditReceiverView: FC<Props> = ({ config, receiverName, alertManagerSourceName }) => {\n const receiver = config.alertmanager_config.receivers?.find(({ name }) => name === receiverName);\n if (!receiver) {\n return (\n <InfoBox severity=\"error\" title=\"Receiver not found\">\n Sorry, this receiver does not seem to exit.\n </InfoBox>\n );\n }\n\n if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME) {\n return <GrafanaReceiverForm config={config} alertManagerSourceName={alertManagerSourceName} existing={receiver} />;\n } else {\n return <CloudReceiverForm config={config} alertManagerSourceName={alertManagerSourceName} existing={receiver} />;\n }\n};\n","import { css } from '@emotion/css';\nimport React, { FC } from 'react';\nimport { useForm, Validate } from 'react-hook-form';\nimport { useDispatch } from 'react-redux';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Alert, Button, Field, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui';\nimport { useCleanup } from 'app/core/hooks/useCleanup';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';\nimport { updateAlertManagerConfigAction } from '../../state/actions';\nimport { makeAMLink } from '../../utils/misc';\nimport { ensureDefine } from '../../utils/templates';\n\ninterface Values {\n name: string;\n content: string;\n}\n\nconst defaults: Values = Object.freeze({\n name: '',\n content: '',\n});\n\ninterface Props {\n existing?: Values;\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\nexport const TemplateForm: FC<Props> = ({ existing, alertManagerSourceName, config }) => {\n const styles = useStyles2(getStyles);\n const dispatch = useDispatch();\n\n useCleanup((state) => state.unifiedAlerting.saveAMConfig);\n\n const { loading, error } = useUnifiedAlertingSelector((state) => state.saveAMConfig);\n\n const submit = (values: Values) => {\n // wrap content in \"define\" if it's not already wrapped, in case user did not do it/\n // it's not obvious that this is needed for template to work\n const content = ensureDefine(values.name, values.content);\n\n // add new template to template map\n const template_files = {\n ...config.template_files,\n [values.name]: content,\n };\n\n // delete existing one (if name changed, otherwise it was overwritten in previous step)\n if (existing && existing.name !== values.name) {\n delete template_files[existing.name];\n }\n\n // make sure name for the template is configured on the alertmanager config object\n const templates = [\n ...(config.alertmanager_config.templates ?? []).filter((name) => name !== existing?.name),\n values.name,\n ];\n\n const newConfig: AlertManagerCortexConfig = {\n template_files,\n alertmanager_config: {\n ...config.alertmanager_config,\n templates,\n },\n };\n dispatch(\n updateAlertManagerConfigAction({\n alertManagerSourceName,\n newConfig,\n oldConfig: config,\n successMessage: 'Template saved.',\n redirectPath: '/alerting/notifications',\n })\n );\n };\n\n const {\n handleSubmit,\n register,\n formState: { errors },\n } = useForm<Values>({\n mode: 'onSubmit',\n defaultValues: existing ?? defaults,\n });\n\n const validateNameIsUnique: Validate<string> = (name: string) => {\n return !config.template_files[name] || existing?.name === name\n ? true\n : 'Another template with this name already exists.';\n };\n\n return (\n <form onSubmit={handleSubmit(submit)}>\n <h4>{existing ? 'Edit message template' : 'Create message template'}</h4>\n {error && (\n <Alert severity=\"error\" title=\"Error saving template\">\n {error.message || (error as any)?.data?.message || String(error)}\n </Alert>\n )}\n <Field label=\"Template name\" error={errors?.name?.message} invalid={!!errors.name?.message} required>\n <Input\n {...register('name', {\n required: { value: true, message: 'Required.' },\n validate: { nameIsUnique: validateNameIsUnique },\n })}\n placeholder=\"Give your template a name\"\n width={42}\n autoFocus={true}\n />\n </Field>\n <Field\n description={\n <>\n You can use the{' '}\n <a\n href=\"https://pkg.go.dev/text/template?utm_source=godoc\"\n target=\"__blank\"\n rel=\"noreferrer\"\n className={styles.externalLink}\n >\n Go templating language\n </a>\n .{' '}\n <a\n href=\"https://prometheus.io/blog/2016/03/03/custom-alertmanager-templates/\"\n target=\"__blank\"\n rel=\"noreferrer\"\n className={styles.externalLink}\n >\n More info about alertmanager templates\n </a>\n </>\n }\n label=\"Content\"\n error={errors?.content?.message}\n invalid={!!errors.content?.message}\n required\n >\n <TextArea\n {...register('content', { required: { value: true, message: 'Required.' } })}\n className={styles.textarea}\n placeholder=\"Message\"\n rows={12}\n />\n </Field>\n <div className={styles.buttons}>\n {loading && (\n <Button disabled={true} icon=\"fa fa-spinner\" variant=\"primary\">\n Saving...\n </Button>\n )}\n {!loading && (\n <Button type=\"submit\" variant=\"primary\">\n Save template\n </Button>\n )}\n <LinkButton\n disabled={loading}\n href={makeAMLink('alerting/notifications', alertManagerSourceName)}\n variant=\"secondary\"\n type=\"button\"\n fill=\"outline\"\n >\n Cancel\n </LinkButton>\n </div>\n </form>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n externalLink: css`\n color: ${theme.colors.text.secondary};\n text-decoration: underline;\n `,\n buttons: css`\n & > * + * {\n margin-left: ${theme.spacing(1)};\n }\n `,\n textarea: css`\n max-width: 758px;\n `,\n});\n","export function ensureDefine(templateName: string, templateContent: string): string {\n // notification template content must be wrapped in {{ define \"name\" }} tag,\n // but this is not obvious because user also has to provide name separately in the form.\n // so if user does not manually add {{ define }} tag, we do it automatically\n let content = templateContent.trim();\n if (!content.match(/\\{\\{\\s*define/)) {\n const indentedContent = content\n .split('\\n')\n .map((line) => ' ' + line)\n .join('\\n');\n content = `{{ define \"${templateName}\" }}\\n${indentedContent}\\n{{ end }}`;\n }\n return content;\n}\n","import React, { FC } from 'react';\n\nimport { InfoBox } from '@grafana/ui';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { TemplateForm } from './TemplateForm';\n\ninterface Props {\n templateName: string;\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\nexport const EditTemplateView: FC<Props> = ({ config, templateName, alertManagerSourceName }) => {\n const template = config.template_files?.[templateName];\n if (!template) {\n return (\n <InfoBox severity=\"error\" title=\"Template not found\">\n Sorry, this template does not seem to exit.\n </InfoBox>\n );\n }\n return (\n <TemplateForm\n alertManagerSourceName={alertManagerSourceName}\n config={config}\n existing={{ name: templateName, content: template }}\n />\n );\n};\n","import { css } from '@emotion/css';\nimport React, { FC } from 'react';\nimport { useForm, FormProvider } from 'react-hook-form';\nimport { useDispatch } from 'react-redux';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Alert, Button, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui';\nimport { useCleanup } from 'app/core/hooks/useCleanup';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';\nimport { updateAlertManagerConfigAction } from '../../state/actions';\nimport { globalConfigOptions } from '../../utils/cloud-alertmanager-notifier-types';\nimport { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource';\nimport { makeAMLink } from '../../utils/misc';\nimport { omitEmptyValues } from '../../utils/receiver-form';\n\nimport { OptionField } from './form/fields/OptionField';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\ntype FormValues = Record<string, unknown>;\n\nconst defaultValues: FormValues = {\n smtp_require_tls: true,\n} as const;\n\nexport const GlobalConfigForm: FC<Props> = ({ config, alertManagerSourceName }) => {\n const dispatch = useDispatch();\n useCleanup((state) => state.unifiedAlerting.saveAMConfig);\n const { loading, error } = useUnifiedAlertingSelector((state) => state.saveAMConfig);\n const readOnly = isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName);\n const styles = useStyles2(getStyles);\n\n const formAPI = useForm<FormValues>({\n // making a copy here beacuse react-hook-form will mutate these, and break if the object is frozen. for real.\n defaultValues: JSON.parse(\n JSON.stringify({\n ...defaultValues,\n ...(config.alertmanager_config.global ?? {}),\n })\n ),\n });\n\n const {\n handleSubmit,\n formState: { errors },\n } = formAPI;\n\n const onSubmitCallback = (values: FormValues) => {\n dispatch(\n updateAlertManagerConfigAction({\n newConfig: {\n ...config,\n alertmanager_config: {\n ...config.alertmanager_config,\n global: omitEmptyValues(values),\n },\n },\n oldConfig: config,\n alertManagerSourceName,\n successMessage: 'Global config updated.',\n redirectPath: makeAMLink('/alerting/notifications', alertManagerSourceName),\n })\n );\n };\n\n return (\n <FormProvider {...formAPI}>\n <form onSubmit={handleSubmit(onSubmitCallback)}>\n <h4 className={styles.heading}>Global config</h4>\n {error && (\n <Alert severity=\"error\" title=\"Error saving receiver\">\n {error.message || String(error)}\n </Alert>\n )}\n {globalConfigOptions.map((option) => (\n <OptionField\n readOnly={readOnly}\n defaultValue={defaultValues[option.propertyName]}\n key={option.propertyName}\n option={option}\n error={errors[option.propertyName]}\n pathPrefix={''}\n />\n ))}\n <div>\n <HorizontalGroup>\n {!readOnly && (\n <>\n {loading && (\n <Button disabled={true} icon=\"fa fa-spinner\" variant=\"primary\">\n Saving...\n </Button>\n )}\n {!loading && <Button type=\"submit\">Save global config</Button>}\n </>\n )}\n <LinkButton\n disabled={loading}\n fill=\"outline\"\n variant=\"secondary\"\n href={makeAMLink('alerting/notifications', alertManagerSourceName)}\n >\n Cancel\n </LinkButton>\n </HorizontalGroup>\n </div>\n </form>\n </FormProvider>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n heading: css`\n margin: ${theme.spacing(4, 0)};\n `,\n});\n","import React, { FC } from 'react';\n\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';\n\nimport { CloudReceiverForm } from './form/CloudReceiverForm';\nimport { GrafanaReceiverForm } from './form/GrafanaReceiverForm';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\nexport const NewReceiverView: FC<Props> = ({ alertManagerSourceName, config }) => {\n if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME) {\n return <GrafanaReceiverForm alertManagerSourceName={alertManagerSourceName} config={config} />;\n } else {\n return <CloudReceiverForm alertManagerSourceName={alertManagerSourceName} config={config} />;\n }\n};\n","import React, { FC } from 'react';\n\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { TemplateForm } from './TemplateForm';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerSourceName: string;\n}\n\nexport const NewTemplateView: FC<Props> = ({ config, alertManagerSourceName }) => {\n return <TemplateForm config={config} alertManagerSourceName={alertManagerSourceName} />;\n};\n","export const receiverTypeNames: Record<string, string> = {\n pagerduty: 'PagerDuty',\n pushover: 'Pushover',\n slack: 'Slack',\n opsgenie: 'OpsGenie',\n webhook: 'Webhook',\n victorops: 'VictorOps',\n wechat: 'WeChat',\n};\n","import { capitalize } from 'lodash';\n\nimport { receiverTypeNames } from 'app/plugins/datasource/alertmanager/consts';\nimport { GrafanaManagedReceiverConfig, Receiver } from 'app/plugins/datasource/alertmanager/types';\nimport { NotifierDTO } from 'app/types';\n\n// extract notifier type name to count map, eg { Slack: 1, Email: 2 }\n\ntype NotifierTypeCounts = Record<string, number>; // name : count\n\nexport function extractNotifierTypeCounts(receiver: Receiver, grafanaNotifiers: NotifierDTO[]): NotifierTypeCounts {\n if (receiver['grafana_managed_receiver_configs']) {\n return getGrafanaNotifierTypeCounts(receiver.grafana_managed_receiver_configs ?? [], grafanaNotifiers);\n }\n return getCortexAlertManagerNotifierTypeCounts(receiver);\n}\n\nfunction getCortexAlertManagerNotifierTypeCounts(receiver: Receiver): NotifierTypeCounts {\n return Object.entries(receiver)\n .filter(([key]) => key !== 'grafana_managed_receiver_configs' && key.endsWith('_configs')) // filter out only properties that are alertmanager notifier\n .filter(([_, value]) => Array.isArray(value) && !!value.length) // check that there are actually notifiers of this type configured\n .reduce<NotifierTypeCounts>((acc, [key, value]) => {\n const type = key.replace('_configs', ''); // remove the `_config` part from the key, making it intto a notifier name\n const name = receiverTypeNames[type] ?? capitalize(type);\n return {\n ...acc,\n [name]: (acc[name] ?? 0) + (Array.isArray(value) ? value.length : 1),\n };\n }, {});\n}\n\nfunction getGrafanaNotifierTypeCounts(\n configs: GrafanaManagedReceiverConfig[],\n grafanaNotifiers: NotifierDTO[]\n): NotifierTypeCounts {\n return configs\n .map((recv) => recv.type) // extract types from config\n .map((type) => grafanaNotifiers.find((r) => r.type === type)?.name ?? capitalize(type)) // get readable name from notifier cofnig, or if not available, just capitalize\n .reduce<NotifierTypeCounts>(\n (acc, type) => ({\n ...acc,\n [type]: (acc[type] ?? 0) + 1,\n }),\n {}\n );\n}\n","import { css, cx } from '@emotion/css';\nimport React, { FC } from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Button, useStyles2 } from '@grafana/ui';\n\ninterface Props {\n title: string;\n description: string;\n addButtonLabel: string;\n addButtonTo: string;\n className?: string;\n showButton?: boolean;\n}\n\nexport const ReceiversSection: FC<Props> = ({\n className,\n title,\n description,\n addButtonLabel,\n addButtonTo,\n children,\n showButton = true,\n}) => {\n const styles = useStyles2(getStyles);\n return (\n <>\n <div className={cx(styles.heading, className)}>\n <div>\n <h4>{title}</h4>\n <p className={styles.description}>{description}</p>\n </div>\n {showButton && (\n <Link to={addButtonTo}>\n <Button type=\"button\" icon=\"plus\">\n {addButtonLabel}\n </Button>\n </Link>\n )}\n </div>\n {children}\n </>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n heading: css`\n display: flex;\n justify-content: space-between;\n `,\n description: css`\n color: ${theme.colors.text.secondary};\n `,\n});\n","import { css } from '@emotion/css';\nimport React, { FC, useMemo, useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Button, ConfirmModal, Modal, useStyles2 } from '@grafana/ui';\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { Authorize } from '../../components/Authorize';\nimport { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';\nimport { deleteReceiverAction } from '../../state/actions';\nimport { getAlertTableStyles } from '../../styles/table';\nimport { getNotificationsPermissions } from '../../utils/access-control';\nimport { isReceiverUsed } from '../../utils/alertmanager';\nimport { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource';\nimport { makeAMLink } from '../../utils/misc';\nimport { extractNotifierTypeCounts } from '../../utils/receivers';\nimport { ActionIcon } from '../rules/ActionIcon';\n\nimport { ReceiversSection } from './ReceiversSection';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerName: string;\n}\n\nexport const ReceiversTable: FC<Props> = ({ config, alertManagerName }) => {\n const dispatch = useDispatch();\n const tableStyles = useStyles2(getAlertTableStyles);\n const styles = useStyles2(getStyles);\n const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName);\n const permissions = getNotificationsPermissions(alertManagerName);\n const grafanaNotifiers = useUnifiedAlertingSelector((state) => state.grafanaNotifiers);\n\n // receiver name slated for deletion. If this is set, a confirmation modal is shown. If user approves, this receiver is deleted\n const [receiverToDelete, setReceiverToDelete] = useState<string>();\n const [showCannotDeleteReceiverModal, setShowCannotDeleteReceiverModal] = useState(false);\n\n const onClickDeleteReceiver = (receiverName: string): void => {\n if (isReceiverUsed(receiverName, config)) {\n setShowCannotDeleteReceiverModal(true);\n } else {\n setReceiverToDelete(receiverName);\n }\n };\n\n const deleteReceiver = () => {\n if (receiverToDelete) {\n dispatch(deleteReceiverAction(receiverToDelete, alertManagerName));\n }\n setReceiverToDelete(undefined);\n };\n\n const rows = useMemo(\n () =>\n config.alertmanager_config.receivers?.map((receiver) => ({\n name: receiver.name,\n types: Object.entries(extractNotifierTypeCounts(receiver, grafanaNotifiers.result ?? [])).map(\n ([type, count]) => {\n if (count > 1) {\n return `${type} (${count})`;\n }\n return type;\n }\n ),\n })) ?? [],\n [config, grafanaNotifiers.result]\n );\n\n return (\n <ReceiversSection\n className={styles.section}\n title=\"Contact points\"\n description=\"Define where the notifications will be sent to, for example email or Slack.\"\n showButton={!isVanillaAM && contextSrv.hasPermission(permissions.create)}\n addButtonLabel=\"New contact point\"\n addButtonTo={makeAMLink('/alerting/notifications/receivers/new', alertManagerName)}\n >\n <table className={tableStyles.table} data-testid=\"receivers-table\">\n <colgroup>\n <col />\n <col />\n <Authorize actions={[permissions.update, permissions.delete]}>\n <col />\n </Authorize>\n </colgroup>\n <thead>\n <tr>\n <th>Contact point name</th>\n <th>Type</th>\n <Authorize actions={[permissions.update, permissions.delete]}>\n <th>Actions</th>\n </Authorize>\n </tr>\n </thead>\n <tbody>\n {!rows.length && (\n <tr className={tableStyles.evenRow}>\n <td colSpan={3}>No receivers defined.</td>\n </tr>\n )}\n {rows.map((receiver, idx) => (\n <tr key={receiver.name} className={idx % 2 === 0 ? tableStyles.evenRow : undefined}>\n <td>{receiver.name}</td>\n <td>{receiver.types.join(', ')}</td>\n <Authorize actions={[permissions.update, permissions.delete]}>\n <td className={tableStyles.actionsCell}>\n {!isVanillaAM && (\n <>\n <Authorize actions={[permissions.update]}>\n <ActionIcon\n aria-label=\"Edit\"\n data-testid=\"edit\"\n to={makeAMLink(\n `/alerting/notifications/receivers/${encodeURIComponent(receiver.name)}/edit`,\n alertManagerName\n )}\n tooltip=\"Edit contact point\"\n icon=\"pen\"\n />\n </Authorize>\n <Authorize actions={[permissions.delete]}>\n <ActionIcon\n onClick={() => onClickDeleteReceiver(receiver.name)}\n tooltip=\"Delete contact point\"\n icon=\"trash-alt\"\n />\n </Authorize>\n </>\n )}\n {isVanillaAM && (\n <Authorize actions={[permissions.update]}>\n <ActionIcon\n data-testid=\"view\"\n to={makeAMLink(\n `/alerting/notifications/receivers/${encodeURIComponent(receiver.name)}/edit`,\n alertManagerName\n )}\n tooltip=\"View contact point\"\n icon=\"file-alt\"\n />\n </Authorize>\n )}\n </td>\n </Authorize>\n </tr>\n ))}\n </tbody>\n </table>\n {!!showCannotDeleteReceiverModal && (\n <Modal\n isOpen={true}\n title=\"Cannot delete contact point\"\n onDismiss={() => setShowCannotDeleteReceiverModal(false)}\n >\n <p>\n Contact point cannot be deleted because it is used in more policies. Please update or delete these policies\n first.\n </p>\n <Modal.ButtonRow>\n <Button variant=\"secondary\" onClick={() => setShowCannotDeleteReceiverModal(false)} fill=\"outline\">\n Close\n </Button>\n </Modal.ButtonRow>\n </Modal>\n )}\n {!!receiverToDelete && (\n <ConfirmModal\n isOpen={true}\n title=\"Delete contact point\"\n body={`Are you sure you want to delete contact point \"${receiverToDelete}\"?`}\n confirmText=\"Yes, delete\"\n onConfirm={deleteReceiver}\n onDismiss={() => setReceiverToDelete(undefined)}\n />\n )}\n </ReceiversSection>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n section: css`\n margin-top: ${theme.spacing(4)};\n `,\n});\n","import React, { FC, Fragment, useMemo, useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { ConfirmModal, useStyles2 } from '@grafana/ui';\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\n\nimport { Authorize } from '../../components/Authorize';\nimport { deleteTemplateAction } from '../../state/actions';\nimport { getAlertTableStyles } from '../../styles/table';\nimport { getNotificationsPermissions } from '../../utils/access-control';\nimport { makeAMLink } from '../../utils/misc';\nimport { CollapseToggle } from '../CollapseToggle';\nimport { DetailsField } from '../DetailsField';\nimport { ActionIcon } from '../rules/ActionIcon';\n\nimport { ReceiversSection } from './ReceiversSection';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerName: string;\n}\n\nexport const TemplatesTable: FC<Props> = ({ config, alertManagerName }) => {\n const dispatch = useDispatch();\n const [expandedTemplates, setExpandedTemplates] = useState<Record<string, boolean>>({});\n const tableStyles = useStyles2(getAlertTableStyles);\n const permissions = getNotificationsPermissions(alertManagerName);\n\n const templateRows = useMemo(() => Object.entries(config.template_files), [config]);\n const [templateToDelete, setTemplateToDelete] = useState<string>();\n\n const deleteTemplate = () => {\n if (templateToDelete) {\n dispatch(deleteTemplateAction(templateToDelete, alertManagerName));\n }\n setTemplateToDelete(undefined);\n };\n\n return (\n <ReceiversSection\n title=\"Message templates\"\n description=\"Templates construct the messages that get sent to the contact points.\"\n addButtonLabel=\"New template\"\n addButtonTo={makeAMLink('/alerting/notifications/templates/new', alertManagerName)}\n showButton={contextSrv.hasPermission(permissions.create)}\n >\n <table className={tableStyles.table} data-testid=\"templates-table\">\n <colgroup>\n <col className={tableStyles.colExpand} />\n <col />\n <col />\n </colgroup>\n <thead>\n <tr>\n <th></th>\n <th>Template</th>\n <Authorize actions={[permissions.update, permissions.delete]}>\n <th>Actions</th>\n </Authorize>\n </tr>\n </thead>\n <tbody>\n {!templateRows.length && (\n <tr className={tableStyles.evenRow}>\n <td colSpan={3}>No templates defined.</td>\n </tr>\n )}\n {templateRows.map(([name, content], idx) => {\n const isExpanded = !!expandedTemplates[name];\n return (\n <Fragment key={name}>\n <tr key={name} className={idx % 2 === 0 ? tableStyles.evenRow : undefined}>\n <td>\n <CollapseToggle\n isCollapsed={!expandedTemplates[name]}\n onToggle={() => setExpandedTemplates({ ...expandedTemplates, [name]: !isExpanded })}\n />\n </td>\n <td>{name}</td>\n <Authorize actions={[permissions.update, permissions.delete]}>\n <td className={tableStyles.actionsCell}>\n <Authorize actions={[permissions.update]}>\n <ActionIcon\n to={makeAMLink(\n `/alerting/notifications/templates/${encodeURIComponent(name)}/edit`,\n alertManagerName\n )}\n tooltip=\"edit template\"\n icon=\"pen\"\n />\n </Authorize>\n <Authorize actions={[permissions.delete]}>\n <ActionIcon\n onClick={() => setTemplateToDelete(name)}\n tooltip=\"delete template\"\n icon=\"trash-alt\"\n />\n </Authorize>\n </td>\n </Authorize>\n </tr>\n {isExpanded && (\n <tr className={idx % 2 === 0 ? tableStyles.evenRow : undefined}>\n <td></td>\n <td colSpan={2}>\n <DetailsField label=\"Description\" horizontal={true}>\n <pre>{content}</pre>\n </DetailsField>\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n\n {!!templateToDelete && (\n <ConfirmModal\n isOpen={true}\n title=\"Delete template\"\n body={`Are you sure you want to delete template \"${templateToDelete}\"?`}\n confirmText=\"Yes, delete\"\n onConfirm={deleteTemplate}\n onDismiss={() => setTemplateToDelete(undefined)}\n />\n )}\n </ReceiversSection>\n );\n};\n","import { css } from '@emotion/css';\nimport React, { FC } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Alert, LinkButton, useStyles2 } from '@grafana/ui';\nimport { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';\nimport { AccessControlAction } from 'app/types';\n\nimport { GRAFANA_RULES_SOURCE_NAME, isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource';\nimport { makeAMLink } from '../../utils/misc';\nimport { Authorize } from '../Authorize';\n\nimport { ReceiversTable } from './ReceiversTable';\nimport { TemplatesTable } from './TemplatesTable';\n\ninterface Props {\n config: AlertManagerCortexConfig;\n alertManagerName: string;\n}\n\nexport const ReceiversAndTemplatesView: FC<Props> = ({ config, alertManagerName }) => {\n const isCloud = alertManagerName !== GRAFANA_RULES_SOURCE_NAME;\n const styles = useStyles2(getStyles);\n const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName);\n return (\n <>\n {!isVanillaAM && <TemplatesTable config={config} alertManagerName={alertManagerName} />}\n <ReceiversTable config={config} alertManagerName={alertManagerName} />\n {isCloud && (\n <Authorize actions={[AccessControlAction.AlertingNotificationsExternalWrite]}>\n <Alert className={styles.section} severity=\"info\" title=\"Global config for contact points\">\n <p>\n For each external Alertmanager you can define global settings, like server addresses, usernames and\n password, for all the supported contact points.\n </p>\n <LinkButton href={makeAMLink('alerting/notifications/global-config', alertManagerName)} variant=\"secondary\">\n {isVanillaAM ? 'View global config' : 'Edit global config'}\n </LinkButton>\n </Alert>\n </Authorize>\n )}\n </>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n section: css`\n margin-top: ${theme.spacing(4)};\n `,\n});\n","import React, { FC, useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Redirect, Route, RouteChildrenProps, Switch, useLocation } from 'react-router-dom';\n\nimport { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui';\n\nimport { AlertManagerPicker } from './components/AlertManagerPicker';\nimport { AlertingPageWrapper } from './components/AlertingPageWrapper';\nimport { NoAlertManagerWarning } from './components/NoAlertManagerWarning';\nimport { EditReceiverView } from './components/receivers/EditReceiverView';\nimport { EditTemplateView } from './components/receivers/EditTemplateView';\nimport { GlobalConfigForm } from './components/receivers/GlobalConfigForm';\nimport { NewReceiverView } from './components/receivers/NewReceiverView';\nimport { NewTemplateView } from './components/receivers/NewTemplateView';\nimport { ReceiversAndTemplatesView } from './components/receivers/ReceiversAndTemplatesView';\nimport { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName';\nimport { useAlertManagersByPermission } from './hooks/useAlertManagerSources';\nimport { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector';\nimport { fetchAlertManagerConfigAction, fetchGrafanaNotifiersAction } from './state/actions';\nimport { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';\nimport { initialAsyncRequestState } from './utils/redux';\n\nconst Receivers: FC = () => {\n const alertManagers = useAlertManagersByPermission('notification');\n const [alertManagerSourceName, setAlertManagerSourceName] = useAlertManagerSourceName(alertManagers);\n const dispatch = useDispatch();\n\n const location = useLocation();\n const isRoot = location.pathname.endsWith('/alerting/notifications');\n\n const configRequests = useUnifiedAlertingSelector((state) => state.amConfigs);\n\n const {\n result: config,\n loading,\n error,\n } = (alertManagerSourceName && configRequests[alertManagerSourceName]) || initialAsyncRequestState;\n const receiverTypes = useUnifiedAlertingSelector((state) => state.grafanaNotifiers);\n\n const shouldLoadConfig = isRoot || !config;\n\n useEffect(() => {\n if (alertManagerSourceName && shouldLoadConfig) {\n dispatch(fetchAlertManagerConfigAction(alertManagerSourceName));\n }\n }, [alertManagerSourceName, dispatch, shouldLoadConfig]);\n\n useEffect(() => {\n if (\n alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME &&\n !(receiverTypes.result || receiverTypes.loading || receiverTypes.error)\n ) {\n dispatch(fetchGrafanaNotifiersAction());\n }\n }, [alertManagerSourceName, dispatch, receiverTypes]);\n\n const disableAmSelect = !isRoot;\n\n if (!alertManagerSourceName) {\n return isRoot ? (\n <AlertingPageWrapper pageId=\"receivers\">\n <NoAlertManagerWarning availableAlertManagers={alertManagers} />\n </AlertingPageWrapper>\n ) : (\n <Redirect to=\"/alerting/notifications\" />\n );\n }\n\n return (\n <AlertingPageWrapper pageId=\"receivers\">\n <AlertManagerPicker\n current={alertManagerSourceName}\n disabled={disableAmSelect}\n onChange={setAlertManagerSourceName}\n dataSources={alertManagers}\n />\n {error && !loading && (\n <Alert severity=\"error\" title=\"Error loading Alertmanager config\">\n {error.message || 'Unknown error.'}\n </Alert>\n )}\n {loading && !config && <LoadingPlaceholder text=\"loading configuration...\" />}\n {config && !error && (\n <Switch>\n <Route exact={true} path=\"/alerting/notifications\">\n <ReceiversAndTemplatesView config={config} alertManagerName={alertManagerSourceName} />\n </Route>\n <Route exact={true} path=\"/alerting/notifications/templates/new\">\n <NewTemplateView config={config} alertManagerSourceName={alertManagerSourceName} />\n </Route>\n <Route exact={true} path=\"/alerting/notifications/templates/:name/edit\">\n {({ match }: RouteChildrenProps<{ name: string }>) =>\n match?.params.name && (\n <EditTemplateView\n alertManagerSourceName={alertManagerSourceName}\n config={config}\n templateName={decodeURIComponent(match?.params.name)}\n />\n )\n }\n </Route>\n <Route exact={true} path=\"/alerting/notifications/receivers/new\">\n <NewReceiverView config={config} alertManagerSourceName={alertManagerSourceName} />\n </Route>\n <Route exact={true} path=\"/alerting/notifications/receivers/:name/edit\">\n {({ match }: RouteChildrenProps<{ name: string }>) =>\n match?.params.name && (\n <EditReceiverView\n alertManagerSourceName={alertManagerSourceName}\n config={config}\n receiverName={decodeURIComponent(match?.params.name)}\n />\n )\n }\n </Route>\n <Route exact={true} path=\"/alerting/notifications/global-config\">\n <GlobalConfigForm config={config} alertManagerSourceName={alertManagerSourceName} />\n </Route>\n </Switch>\n )}\n </AlertingPageWrapper>\n );\n};\n\nexport default withErrorBoundary(Receivers, { style: 'page' });\n","import React, { FC } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport Page from 'app/core/components/Page/Page';\nimport { getNavModel } from 'app/core/selectors/navModel';\nimport { StoreState } from 'app/types/store';\n\ninterface Props {\n pageId: string;\n isLoading?: boolean;\n}\n\nexport const AlertingPageWrapper: FC<Props> = ({ children, pageId, isLoading }) => {\n const navModel = getNavModel(\n useSelector((state: StoreState) => state.navIndex),\n pageId\n );\n\n return (\n <Page navModel={navModel}>\n <Page.Contents isLoading={isLoading}>{children}</Page.Contents>\n </Page>\n );\n};\n","import React, { FC } from 'react';\n\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { AccessControlAction } from 'app/types';\n\ntype Props = {\n actions: AccessControlAction[];\n fallback?: boolean;\n};\n\nexport const Authorize: FC<Props> = ({ actions, children, fallback = true }) => {\n if (actions.some((action) => contextSrv.hasAccess(action, fallback))) {\n return <>{children}</>;\n } else {\n return null;\n }\n};\n","import React from 'react';\n\nimport { Alert } from '@grafana/ui';\n\nimport { useAlertManagerSourceName } from '../hooks/useAlertManagerSourceName';\nimport { AlertManagerDataSource } from '../utils/datasource';\n\nimport { AlertManagerPicker } from './AlertManagerPicker';\n\ninterface Props {\n availableAlertManagers: AlertManagerDataSource[];\n}\n\nconst NoAlertManagersAvailable = () => (\n <Alert title=\"No Alertmanager found\" severity=\"warning\">\n We could not find any external Alertmanagers and you may not have access to the built-in Grafana Alertmanager.\n </Alert>\n);\n\nconst OtherAlertManagersAvailable = () => (\n <Alert title=\"Selected Alertmanager not found. Select a different Alertmanager.\" severity=\"warning\">\n Selected Alertmanager no longer exists or you may not have permission to access it.\n </Alert>\n);\n\nexport const NoAlertManagerWarning = ({ availableAlertManagers }: Props) => {\n const [_, setAlertManagerSourceName] = useAlertManagerSourceName(availableAlertManagers);\n const hasOtherAMs = availableAlertManagers.length > 0;\n\n return (\n <div>\n {hasOtherAMs ? (\n <>\n <AlertManagerPicker onChange={setAlertManagerSourceName} dataSources={availableAlertManagers} />\n <OtherAlertManagersAvailable />\n </>\n ) : (\n <NoAlertManagersAvailable />\n )}\n </div>\n );\n};\n","import React, { FC, useMemo } from 'react';\n\nimport { SelectableValue } from '@grafana/data';\n\nimport { Annotation, annotationLabels } from '../../utils/constants';\n\nimport { SelectWithAdd } from './SelectWIthAdd';\n\ninterface Props {\n onChange: (value: string) => void;\n existingKeys: string[];\n\n value?: string;\n width?: number;\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const AnnotationKeyInput: FC<Props> = ({ value, existingKeys, 'aria-label': ariaLabel, ...rest }) => {\n const annotationOptions = useMemo(\n (): SelectableValue[] =>\n Object.values(Annotation)\n .filter((key) => !existingKeys.includes(key)) // remove keys already taken in other annotations\n .map((key) => ({ value: key, label: annotationLabels[key] })),\n [existingKeys]\n );\n\n return (\n <SelectWithAdd\n aria-label={ariaLabel}\n value={value}\n options={annotationOptions}\n custom={!!value && !(Object.values(Annotation) as string[]).includes(value)}\n {...rest}\n />\n );\n};\n","import { css, cx } from '@emotion/css';\nimport React, { FC, useCallback } from 'react';\nimport { useFormContext } from 'react-hook-form';\n\nimport { GrafanaTheme } from '@grafana/data';\nimport { Button, Field, FieldArray, Input, InputControl, Label, TextArea, useStyles } from '@grafana/ui';\n\nimport { RuleFormValues } from '../../types/rule-form';\n\nimport { AnnotationKeyInput } from './AnnotationKeyInput';\n\nconst AnnotationsField: FC = () => {\n const styles = useStyles(getStyles);\n const {\n control,\n register,\n watch,\n formState: { errors },\n } = useFormContext();\n const annotations = watch('annotations') as RuleFormValues['annotations'];\n\n const existingKeys = useCallback(\n (index: number): string[] => annotations.filter((_, idx: number) => idx !== index).map(({ key }) => key),\n [annotations]\n );\n\n return (\n <>\n <Label>Summary and annotations</Label>\n <FieldArray name={'annotations'} control={control}>\n {({ fields, append, remove }) => {\n return (\n <div className={styles.flexColumn}>\n {fields.map((field, index) => {\n const isUrl = annotations[index]?.key?.toLocaleLowerCase().endsWith('url');\n const ValueInputComponent = isUrl ? Input : TextArea;\n return (\n <div key={field.id} className={styles.flexRow}>\n <Field\n className={styles.field}\n invalid={!!errors.annotations?.[index]?.key?.message}\n error={errors.annotations?.[index]?.key?.message}\n data-testid={`annotation-key-${index}`}\n >\n <InputControl\n name={`annotations[${index}].key`}\n render={({ field: { ref, ...field } }) => (\n <AnnotationKeyInput\n {...field}\n aria-label={`Annotation detail ${index + 1}`}\n existingKeys={existingKeys(index)}\n width={18}\n />\n )}\n control={control}\n rules={{ required: { value: !!annotations[index]?.value, message: 'Required.' } }}\n />\n </Field>\n <Field\n className={cx(styles.flexRowItemMargin, styles.field)}\n invalid={!!errors.annotations?.[index]?.value?.message}\n error={errors.annotations?.[index]?.value?.message}\n >\n <ValueInputComponent\n data-testid={`annotation-value-${index}`}\n className={cx(styles.annotationValueInput, { [styles.textarea]: !isUrl })}\n {...register(`annotations[${index}].value`)}\n placeholder={isUrl ? 'https://' : `Text`}\n defaultValue={field.value}\n />\n </Field>\n <Button\n type=\"button\"\n className={styles.flexRowItemMargin}\n aria-label=\"delete annotation\"\n icon=\"trash-alt\"\n variant=\"secondary\"\n onClick={() => remove(index)}\n />\n </div>\n );\n })}\n <Button\n className={styles.addAnnotationsButton}\n icon=\"plus-circle\"\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n append({ key: '', value: '' });\n }}\n >\n Add info\n </Button>\n </div>\n );\n }}\n </FieldArray>\n </>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme) => ({\n annotationValueInput: css`\n width: 426px;\n `,\n textarea: css`\n height: 76px;\n `,\n addAnnotationsButton: css`\n flex-grow: 0;\n align-self: flex-start;\n margin-left: 148px;\n `,\n flexColumn: css`\n display: flex;\n flex-direction: column;\n `,\n field: css`\n margin-bottom: ${theme.spacing.xs};\n `,\n flexRow: css`\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n `,\n flexRowItemMargin: css`\n margin-left: ${theme.spacing.xs};\n `,\n});\n\nexport default AnnotationsField;\n","import { css, cx } from '@emotion/css';\nimport React, { FC } from 'react';\nimport { useFormContext } from 'react-hook-form';\n\nimport { GrafanaTheme } from '@grafana/data';\nimport { Button, Field, FieldArray, Input, InlineLabel, Label, useStyles } from '@grafana/ui';\n\ninterface Props {\n className?: string;\n}\n\nconst LabelsField: FC<Props> = ({ className }) => {\n const styles = useStyles(getStyles);\n const {\n register,\n control,\n watch,\n formState: { errors },\n } = useFormContext();\n const labels = watch('labels');\n return (\n <div className={cx(className, styles.wrapper)}>\n <Label>Custom Labels</Label>\n <FieldArray control={control} name=\"labels\">\n {({ fields, append, remove }) => {\n return (\n <>\n <div className={styles.flexRow}>\n <InlineLabel width={18}>Labels</InlineLabel>\n <div className={styles.flexColumn}>\n {fields.map((field, index) => {\n return (\n <div key={field.id}>\n <div className={cx(styles.flexRow, styles.centerAlignRow)}>\n <Field\n className={styles.labelInput}\n invalid={!!errors.labels?.[index]?.key?.message}\n error={errors.labels?.[index]?.key?.message}\n >\n <Input\n {...register(`labels[${index}].key`, {\n required: { value: !!labels[index]?.value, message: 'Required.' },\n })}\n placeholder=\"key\"\n data-testid={`label-key-${index}`}\n defaultValue={field.key}\n />\n </Field>\n <InlineLabel className={styles.equalSign}>=</InlineLabel>\n <Field\n className={styles.labelInput}\n invalid={!!errors.labels?.[index]?.value?.message}\n error={errors.labels?.[index]?.value?.message}\n >\n <Input\n {...register(`labels[${index}].value`, {\n required: { value: !!labels[index]?.key, message: 'Required.' },\n })}\n placeholder=\"value\"\n data-testid={`label-value-${index}`}\n defaultValue={field.value}\n />\n </Field>\n <Button\n className={styles.deleteLabelButton}\n aria-label=\"delete label\"\n icon=\"trash-alt\"\n variant=\"secondary\"\n onClick={() => {\n remove(index);\n }}\n />\n </div>\n </div>\n );\n })}\n <Button\n className={styles.addLabelButton}\n icon=\"plus-circle\"\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n append({});\n }}\n >\n Add label\n </Button>\n </div>\n </div>\n </>\n );\n }}\n </FieldArray>\n </div>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme) => {\n return {\n wrapper: css`\n margin-bottom: ${theme.spacing.xl};\n `,\n flexColumn: css`\n display: flex;\n flex-direction: column;\n `,\n flexRow: css`\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n\n & + button {\n margin-left: ${theme.spacing.xs};\n }\n `,\n deleteLabelButton: css`\n margin-left: ${theme.spacing.xs};\n align-self: flex-start;\n `,\n addLabelButton: css`\n flex-grow: 0;\n align-self: flex-start;\n `,\n centerAlignRow: css`\n align-items: baseline;\n `,\n equalSign: css`\n align-self: flex-start;\n width: 28px;\n justify-content: center;\n margin-left: ${theme.spacing.xs};\n `,\n labelInput: css`\n width: 175px;\n margin-bottom: ${theme.spacing.sm};\n & + & {\n margin-left: ${theme.spacing.sm};\n }\n `,\n };\n};\n\nexport default LabelsField;\n","import React, { FC, useEffect, useMemo, useState } from 'react';\n\nimport { SelectableValue } from '@grafana/data';\nimport { Input, Select } from '@grafana/ui';\n\ninterface Props {\n onChange: (value: string) => void;\n options: Array<SelectableValue<string>>;\n value?: string;\n addLabel?: string;\n className?: string;\n placeholder?: string;\n custom?: boolean;\n onCustomChange?: (custom: boolean) => void;\n width?: number;\n disabled?: boolean;\n 'aria-label'?: string;\n}\n\nexport const SelectWithAdd: FC<Props> = ({\n value,\n onChange,\n options,\n className,\n placeholder,\n width,\n custom,\n onCustomChange,\n disabled = false,\n addLabel = '+ Add new',\n 'aria-label': ariaLabel,\n}) => {\n const [isCustom, setIsCustom] = useState(custom);\n\n useEffect(() => {\n if (custom) {\n setIsCustom(custom);\n }\n }, [custom]);\n\n const _options = useMemo(\n (): Array<SelectableValue<string>> => [...options, { value: '__add__', label: addLabel }],\n [options, addLabel]\n );\n\n if (isCustom) {\n return (\n <Input\n aria-label={ariaLabel}\n width={width}\n autoFocus={!custom}\n value={value || ''}\n placeholder={placeholder}\n className={className}\n disabled={disabled}\n onChange={(e) => onChange((e.target as HTMLInputElement).value)}\n />\n );\n } else {\n return (\n <Select\n aria-label={ariaLabel}\n width={width}\n options={_options}\n value={value}\n className={className}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(val: SelectableValue) => {\n const value = val?.value;\n if (value === '__add__') {\n setIsCustom(true);\n if (onCustomChange) {\n onCustomChange(true);\n }\n onChange('');\n } else {\n onChange(value);\n }\n }}\n />\n );\n }\n};\n","import React, { FC } from 'react';\n\nimport { IconName, Tooltip, LinkButton, Button } from '@grafana/ui';\nimport { PopoverContent, TooltipPlacement } from '@grafana/ui/src/components/Tooltip';\n\ninterface Props {\n tooltip: PopoverContent;\n icon: IconName;\n className?: string;\n tooltipPlacement?: TooltipPlacement;\n to?: string;\n target?: string;\n onClick?: () => void;\n 'data-testid'?: string;\n}\n\nexport const ActionIcon: FC<Props> = ({\n tooltip,\n icon,\n to,\n target,\n onClick,\n className,\n tooltipPlacement = 'top',\n ...rest\n}) => {\n const ariaLabel = typeof tooltip === 'string' ? tooltip : undefined;\n\n return (\n <Tooltip content={tooltip} placement={tooltipPlacement}>\n {to ? (\n <LinkButton\n variant=\"secondary\"\n fill=\"text\"\n icon={icon}\n href={to}\n size=\"sm\"\n target={target}\n {...rest}\n aria-label={ariaLabel}\n />\n ) : (\n <Button\n className={className}\n variant=\"secondary\"\n fill=\"text\"\n size=\"sm\"\n icon={icon}\n type=\"button\"\n onClick={onClick}\n {...rest}\n aria-label={ariaLabel}\n />\n )}\n </Tooltip>\n );\n};\n","import { useCallback } from 'react';\n\nimport { useQueryParams } from 'app/core/hooks/useQueryParams';\nimport store from 'app/core/store';\n\nimport { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from '../utils/constants';\nimport { AlertManagerDataSource, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';\n\nfunction useIsAlertManagerAvailable(availableAlertManagers: AlertManagerDataSource[]) {\n return useCallback(\n (alertManagerName: string) => {\n const availableAlertManagersNames = availableAlertManagers.map((am) => am.name);\n return availableAlertManagersNames.includes(alertManagerName);\n },\n [availableAlertManagers]\n );\n}\n\n/* This will return am name either from query params or from local storage or a default (grafana).\n * Due to RBAC permissions Grafana Managed Alert manager or external alert managers may not be available\n * In the worst case neihter GMA nor external alert manager is available\n */\nexport function useAlertManagerSourceName(\n availableAlertManagers: AlertManagerDataSource[]\n): [string | undefined, (alertManagerSourceName: string) => void] {\n const [queryParams, updateQueryParams] = useQueryParams();\n const isAlertManagerAvailable = useIsAlertManagerAvailable(availableAlertManagers);\n\n const update = useCallback(\n (alertManagerSourceName: string) => {\n if (!isAlertManagerAvailable(alertManagerSourceName)) {\n return;\n }\n if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME) {\n store.delete(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY);\n updateQueryParams({ [ALERTMANAGER_NAME_QUERY_KEY]: null });\n } else {\n store.set(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, alertManagerSourceName);\n updateQueryParams({ [ALERTMANAGER_NAME_QUERY_KEY]: alertManagerSourceName });\n }\n },\n [updateQueryParams, isAlertManagerAvailable]\n );\n\n const querySource = queryParams[ALERTMANAGER_NAME_QUERY_KEY];\n\n if (querySource && typeof querySource === 'string') {\n if (isAlertManagerAvailable(querySource)) {\n return [querySource, update];\n } else {\n // non existing alertmanager\n return [undefined, update];\n }\n }\n\n const storeSource = store.get(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY);\n if (storeSource && typeof storeSource === 'string' && isAlertManagerAvailable(storeSource)) {\n update(storeSource);\n return [storeSource, update];\n }\n\n if (isAlertManagerAvailable(GRAFANA_RULES_SOURCE_NAME)) {\n return [GRAFANA_RULES_SOURCE_NAME, update];\n }\n\n return [undefined, update];\n}\n","import { useMemo } from 'react';\n\nimport { getAlertManagerDataSourcesByPermission } from '../utils/datasource';\n\nexport function useAlertManagersByPermission(accessType: 'instance' | 'notification') {\n return useMemo(() => getAlertManagerDataSourcesByPermission(accessType), [accessType]);\n}\n","import { css } from '@emotion/css';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nexport const getAlertTableStyles = (theme: GrafanaTheme2) => ({\n table: css`\n width: 100%;\n border-radius: ${theme.shape.borderRadius()};\n border: solid 1px ${theme.colors.border.weak};\n background-color: ${theme.colors.background.secondary};\n\n th {\n padding: ${theme.spacing(1)};\n }\n\n td {\n padding: 0 ${theme.spacing(1)};\n }\n\n tr {\n height: 38px;\n }\n `,\n evenRow: css`\n background-color: ${theme.colors.background.primary};\n `,\n colExpand: css`\n width: 36px;\n `,\n actionsCell: css`\n text-align: right;\n width: 1%;\n white-space: nowrap;\n\n & > * + * {\n margin-left: ${theme.spacing(0.5)};\n }\n `,\n});\n"],"names":["useCleanup","stateSelector","dispatch","useDispatch","selectorRef","useRef","current","useEffect","cleanUpAction","useNavModel","id","navIndex","useSelector","state","getNavModel","navModel","notifications","setNotifications","useState","fetchNotifications","useAsyncFn","async","getBackendSrv","get","then","res","deleteNotificationConfirmed","delete","error","length","className","LinkButton","icon","href","style","minWidth","width","map","notification","name","type","HorizontalGroup","justify","isDefault","Button","disabled","variant","size","onClick","appEvents","ShowConfirmModalEvent","title","text","text2","confirmText","yesText","onConfirm","loading","buttonIcon","buttonLink","buttonTitle","proTip","proTipLink","proTipLinkTitle","proTipTarget","option","propertyName","label","description","rest","element","inputType","required","secure","placeholder","validationRule","showWhen","field","is","dependsOn","basicAuthOption","subformOptions","tlsConfigOption","httpConfigOption","cloudNotifierTypes","info","heading","options","globalConfigOptions","grafanaReceiverToFormValues","receiver","notifiers","channelMap","idCounter","items","grafana_managed_receiver_configs","channel","String","notifier","find","values","__id","secureSettings","settings","secureFields","disableResolveMessage","forEach","grafanaChannelConfigToFormChannelValues","cloudReceiverToFormValues","Object","entries","filter","endsWith","configs","replace","config","Error","sendResolved","send_resolved","cloudChannelConfigToFormChannelValues","flat","updateConfigWithReceiver","replaceReceiverName","oldReceivers","alertmanager_config","receivers","updated","existingReceiver","route","renameReceiverInRoute","oldName","newName","routes","formChannelValuesToGrafanaChannelConfig","defaults","existing","omitEmptyValues","uid","obj","isArray","key","value","CloudCommonChannelSettings","pathPrefix","readOnly","register","useFormContext","Field","Checkbox","EMPTY_ARRAY","useControlledFieldArray","formAPI","softDelete","watch","getValues","reset","setValue","fields","update","useCallback","updateFn","JSON","parse","stringify","newItems","set","append","remove","index","slice","splice","KeyValueMapInput","onChange","styles","useStyles2","getStyles","pairs","setPairs","recordToPairs","emitChange","pairsToRecord","updatePair","old","newPairs","pair","i","table","Input","e","currentTarget","ActionIcon","A","tooltip","removed","deleteItem","addButton","theme","css","spacing","record","StringArrayInput","v","row","itemValue","updateValue","deleteIcon","newValue","CollapsibleSection","children","isCollapsed","setIsCollapsed","toggleCollapse","cx","wrapper","CollapseToggle","caret","onToggle","hidden","undefined","colors","secondary","typography","sm","fontWeightRegular","getReceiverFormFieldStyles","collapsibleSection","border","medium","shape","borderRadius","SubformArrayField","errors","defaultValues","path","itemIndex","OptionField","defaultValue","Math","random","SubformField","_watchValue","show","setShow","subOption","invalid","pathSuffix","optionPath","message","OptionInput","pathIndex","control","unregister","keepValue","checkbox","determineReadOnly","determineRequired","validate","validateOption","InputControl","render","Select","selectOptions","TextArea","console","RegExp","test","isEmpty","dependentOn","Boolean","ChannelOptions","selectedChannelOptions","onResetSecureField","currentFormValues","selectedOptionValue","suffix","fill","ChannelSubForm","onDuplicate","onDelete","onTest","commonSettingsComponent","CommonSettingsComponent","fieldName","trigger","formState","selectedType","testingReceiver","useUnifiedAlertingSelector","testReceivers","_secureFields","setSecureFields","updatedSecureFields","typeOptions","useMemo","sort","a","b","localeCompare","mandatoryOptions","o","optionalOptions","contactPointTypeInputId","topRow","htmlFor","inputId","rules","buttons","keys","handleTest","innerContent","Alert","severity","breakpoints","xl","unit","channelSettingsHeader","DeletedSubForm","ReceiverForm","initialValues","defaultItem","alertManagerSourceName","onSubmit","onTestChannel","takenReceiverNames","notifyApp","useAppNotification","isVanillaPrometheusAlertManagerDataSource","useForm","unifiedAlerting","saveAMConfig","handleSubmit","validateNameIsAvailable","trim","toLowerCase","includes","item","__deleted","nameIsAvailable","initialItem","currentValues","makeAMLink","defaultChannelValues","freeze","CloudReceiverForm","isVanillaAM","existingValue","newReceiver","recv","configsKey","push","formValuesToCloudReceiver","updateAlertManagerConfigAction","newConfig","oldConfig","successMessage","redirectPath","GrafanaCommonChannelSettings","NotificationType","notificationOptions","annotations","labels","TestContactPointModal","isOpen","onDismiss","notificationType","setNotificationType","predefined","formMethods","mode","Modal","section","Label","RadioButtonGroup","data","custom","alert","reduce","acc","AnnotationsField","LabelsField","flexRow","GrafanaReceiverForm","grafanaNotifiers","testChannelValues","setTestChannelValues","result","fetchGrafanaNotifiersAction","id2original","channelValues","formValuesToGrafanaReceiver","GRAFANA_RULES_SOURCE_NAME","chan","payload","testReceiversAction","testNotification","LoadingPlaceholder","EditReceiverView","receiverName","InfoBox","content","TemplateForm","templateName","templateContent","match","indentedContent","split","line","join","ensureDefine","template_files","templates","nameIsUnique","autoFocus","target","rel","externalLink","textarea","rows","EditTemplateView","template","smtp_require_tls","GlobalConfigForm","global","NewReceiverView","NewTemplateView","receiverTypeNames","pagerduty","pushover","slack","opsgenie","webhook","victorops","wechat","extractNotifierTypeCounts","r","capitalize","getGrafanaNotifierTypeCounts","_","Array","getCortexAlertManagerNotifierTypeCounts","ReceiversSection","addButtonLabel","addButtonTo","showButton","Link","to","ReceiversTable","alertManagerName","tableStyles","getAlertTableStyles","permissions","getNotificationsPermissions","receiverToDelete","setReceiverToDelete","showCannotDeleteReceiverModal","setShowCannotDeleteReceiverModal","types","count","contextSrv","create","Authorize","actions","evenRow","colSpan","idx","actionsCell","encodeURIComponent","onClickDeleteReceiver","isReceiverUsed","ConfirmModal","body","deleteReceiverAction","TemplatesTable","expandedTemplates","setExpandedTemplates","templateRows","templateToDelete","setTemplateToDelete","colExpand","isExpanded","Fragment","DetailsField","horizontal","deleteTemplateAction","ReceiversAndTemplatesView","isCloud","AccessControlAction","withErrorBoundary","alertManagers","useAlertManagersByPermission","setAlertManagerSourceName","useAlertManagerSourceName","isRoot","useLocation","pathname","configRequests","amConfigs","initialAsyncRequestState","receiverTypes","shouldLoadConfig","fetchAlertManagerConfigAction","disableAmSelect","AlertingPageWrapper","pageId","AlertManagerPicker","dataSources","exact","params","decodeURIComponent","NoAlertManagerWarning","availableAlertManagers","isLoading","fallback","some","action","NoAlertManagersAvailable","OtherAlertManagersAvailable","hasOtherAMs","AnnotationKeyInput","existingKeys","ariaLabel","annotationOptions","Annotation","annotationLabels","annotationValueInput","addAnnotationsButton","flexColumn","xs","flexRowItemMargin","useStyles","FieldArray","isUrl","toLocaleLowerCase","ValueInputComponent","deleteLabelButton","addLabelButton","centerAlignRow","equalSign","labelInput","InlineLabel","SelectWithAdd","onCustomChange","addLabel","isCustom","setIsCustom","_options","val","tooltipPlacement","Tooltip","placement","queryParams","updateQueryParams","useQueryParams","isAlertManagerAvailable","am","useIsAlertManagerAvailable","store","ALERTMANAGER_NAME_LOCAL_STORAGE_KEY","ALERTMANAGER_NAME_QUERY_KEY","querySource","storeSource","accessType","getAlertManagerDataSourcesByPermission","weak","background","primary"],"sourceRoot":""}