diff --git a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
index 2c63abf9e8..7fe6865f44 100644
--- a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
+++ b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
@@ -15,7 +15,6 @@ import { FormSelect, FormSelectOption } from '@patternfly/react-core';
function AnsibleSelect({
id,
data,
-
isValid,
onBlur,
value,
diff --git a/awx/ui_next/src/components/DetailList/ArrayDetail.jsx b/awx/ui_next/src/components/DetailList/ArrayDetail.jsx
index a946a5976f..0b7df17d6a 100644
--- a/awx/ui_next/src/components/DetailList/ArrayDetail.jsx
+++ b/awx/ui_next/src/components/DetailList/ArrayDetail.jsx
@@ -25,7 +25,7 @@ function ArrayDetail({ label, value, dataCy }) {
{vals.map(v => (
- {v}
+ {v}
))}
diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.jsx
index 236ec0b656..2d6164a79c 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.jsx
@@ -1,7 +1,12 @@
import React, { useCallback } from 'react';
import { Link, useHistory } from 'react-router-dom';
-
-import { Button } from '@patternfly/react-core';
+import {
+ Button,
+ TextList,
+ TextListItem,
+ TextListItemVariants,
+ TextListVariants,
+} from '@patternfly/react-core';
import { t } from '@lingui/macro';
import AlertModal from '../../../components/AlertModal';
import { CardBody, CardActionsRow } from '../../../components/Card';
@@ -31,6 +36,23 @@ function NotificationTemplateDetail({ template, defaultMessages }) {
messages,
} = template;
+ const renderOptionsField = configuration.use_ssl || configuration.use_tls;
+
+ const renderOptions = (
+
+ {configuration.use_ssl && (
+
+ {t`Use SSL`}
+
+ )}
+ {configuration.use_tls && (
+
+ {t`Use TLS`}
+
+ )}
+
+ );
+
const { request: deleteTemplate, isLoading, error: deleteError } = useRequest(
useCallback(async () => {
await NotificationTemplatesAPI.destroy(template.id);
@@ -104,11 +126,9 @@ function NotificationTemplateDetail({ template, defaultMessages }) {
value={configuration.timeout}
dataCy="nt-detail-timeout"
/>
-
+ {renderOptionsField && (
+
+ )}
>
)}
{template.notification_type === 'grafana' && (
diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.test.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.test.jsx
new file mode 100644
index 0000000000..3f4bd34fb3
--- /dev/null
+++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateDetail/NotificationTemplateDetail.test.jsx
@@ -0,0 +1,102 @@
+import React from 'react';
+import { act } from 'react-dom/test-utils';
+import {
+ mountWithContexts,
+ waitForElement,
+} from '../../../../testUtils/enzymeHelpers';
+import NotificationTemplateDetail from './NotificationTemplateDetail';
+import defaultMessages from '../shared/notification-template-default-messages.json';
+
+jest.mock('../../../api');
+
+const mockTemplate = {
+ id: 1,
+ type: 'notification_template',
+ url: '/api/v2/notification_templates/1/',
+ related: {
+ named_url: '/api/v2/notification_templates/abc++Default/',
+ created_by: '/api/v2/users/2/',
+ modified_by: '/api/v2/users/2/',
+ test: '/api/v2/notification_templates/1/test/',
+ notifications: '/api/v2/notification_templates/1/notifications/',
+ copy: '/api/v2/notification_templates/1/copy/',
+ organization: '/api/v2/organizations/1/',
+ },
+ summary_fields: {
+ organization: {
+ id: 1,
+ name: 'Default',
+ description: '',
+ },
+ created_by: {
+ id: 2,
+ username: 'test',
+ first_name: '',
+ last_name: '',
+ },
+ modified_by: {
+ id: 2,
+ username: 'test',
+ first_name: '',
+ last_name: '',
+ },
+ user_capabilities: {
+ edit: true,
+ delete: true,
+ copy: true,
+ },
+ recent_notifications: [],
+ },
+ created: '2021-06-16T18:52:23.811374Z',
+ modified: '2021-06-16T18:53:37.631371Z',
+ name: 'abc',
+ description: 'foo description',
+ organization: 1,
+ notification_type: 'email',
+ notification_configuration: {
+ username: '',
+ password: '',
+ host: 'https://localhost',
+ recipients: ['foo@ansible.com'],
+ sender: 'bar@ansible.com',
+ port: 324,
+ timeout: 11,
+ use_ssl: true,
+ use_tls: true,
+ },
+ messages: null,
+};
+
+describe('', () => {
+ let wrapper;
+
+ beforeEach(async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('should render Details', () => {
+ function assertDetail(label, value) {
+ expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label);
+ expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value);
+ }
+ assertDetail('Name', mockTemplate.name);
+ assertDetail('Description', mockTemplate.description);
+ expect(
+ wrapper
+ .find('Detail[label="Email Options"]')
+ .containsAllMatchingElements([
Use SSL, Use TLS])
+ ).toEqual(true);
+ });
+});
diff --git a/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.jsx b/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.jsx
index 6edaa4e97d..dc3535526f 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.jsx
@@ -118,10 +118,6 @@ function NotificationTemplateForm({
);
};
- let emailOptions = '';
- if (template.notification_type === 'email') {
- emailOptions = template.notification_configuration?.use_ssl ? 'ssl' : 'tls';
- }
const messages = template.messages || { workflow_approval: {} };
const defs = defaultMessages[template.notification_type || 'email'];
const mergeDefaultMessages = (templ = {}, def) => {
@@ -144,7 +140,6 @@ function NotificationTemplateForm({
...template.notification_configuration,
headers: headers ? JSON.stringify(headers, null, 2) : null,
},
- emailOptions,
organization: template.summary_fields?.organization,
messages: {
started: { ...mergeDefaultMessages(messages.started, defs.started) },
@@ -235,10 +230,6 @@ function normalizeTypeFields(values) {
stripped[fieldName] = values.notification_configuration[fieldName];
}
});
- if (values.notification_type === 'email') {
- stripped.use_ssl = values.emailOptions === 'ssl';
- stripped.use_tls = !stripped.use_ssl;
- }
if (values.notification_type === 'webhook') {
stripped.headers = stripped.headers ? JSON.parse(stripped.headers) : {};
}
diff --git a/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.test.jsx b/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.test.jsx
index 5b90fd5e8d..5d5825a110 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.test.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/shared/NotificationTemplateForm.test.jsx
@@ -4,6 +4,7 @@ import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import NotificationTemplateForm from './NotificationTemplateForm';
jest.mock('../../../api/models/NotificationTemplates');
+jest.mock('../../../api/models/Organizations');
const template = {
id: 3,
@@ -50,16 +51,19 @@ const defaultMessages = {
};
describe('', () => {
- test('should render form fields', () => {
- const wrapper = mountWithContexts(
-
- );
+ let wrapper;
+ test('should render form fields', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
expect(wrapper.find('input#notification-name').prop('value')).toEqual(
'Test Notification'
@@ -77,26 +81,48 @@ describe('', () => {
expect(
wrapper.find('CustomMessagesSubForm').prop('defaultMessages')
).toEqual(defaultMessages);
+
+ expect(wrapper.find('input#option-use-ssl').length).toBe(0);
+ expect(wrapper.find('input#option-use-tls').length).toBe(0);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect#notification-type').invoke('onChange')(
+ {
+ target: {
+ name: 'notification_type',
+ value: 'email',
+ },
+ },
+ 'email'
+ );
+ });
+
+ wrapper.update();
+
+ expect(wrapper.find('input#option-use-ssl').length).toBe(1);
+ expect(wrapper.find('input#option-use-tls').length).toBe(1);
});
- test('should render custom messages fields', () => {
- const wrapper = mountWithContexts(
- {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
- );
+ }}
+ defaultMessages={defaultMessages}
+ detailUrl="/notification_templates/3/detail"
+ onSubmit={jest.fn()}
+ onCancel={jest.fn()}
+ />
+ );
+ });
expect(
wrapper
@@ -108,21 +134,23 @@ describe('', () => {
test('should submit', async () => {
const handleSubmit = jest.fn();
- const wrapper = mountWithContexts(
-
- );
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
await act(async () => {
wrapper.find('FormActionGroup').invoke('onSubmit')();
diff --git a/awx/ui_next/src/screens/NotificationTemplate/shared/TypeInputsSubForm.jsx b/awx/ui_next/src/screens/NotificationTemplate/shared/TypeInputsSubForm.jsx
index b7f8b4a1be..e6f7393139 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/shared/TypeInputsSubForm.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/shared/TypeInputsSubForm.jsx
@@ -4,6 +4,7 @@ import { t } from '@lingui/macro';
import { useField } from 'formik';
import { FormGroup, Title } from '@patternfly/react-core';
import {
+ FormCheckboxLayout,
FormColumnLayout,
FormFullWidthLayout,
SubFormLayout,
@@ -56,10 +57,6 @@ TypeInputsSubForm.propTypes = {
export default TypeInputsSubForm;
function EmailFields() {
- const [optionsField, optionsMeta] = useField({
- name: 'emailOptions',
- validate: required(t`Select a value for this field`),
- });
return (
<>
-
-
+
+
+
+
+
>
);
diff --git a/awx/ui_next/src/screens/NotificationTemplate/shared/notification-template-default-messages.json b/awx/ui_next/src/screens/NotificationTemplate/shared/notification-template-default-messages.json
new file mode 100644
index 0000000000..e2bd0ccaed
--- /dev/null
+++ b/awx/ui_next/src/screens/NotificationTemplate/shared/notification-template-default-messages.json
@@ -0,0 +1,302 @@
+{
+ "type": "json",
+ "required": false,
+ "label": "Messages",
+ "help_text": "Optional custom messages for notification template.",
+ "filterable": true,
+ "default": {
+ "started": null,
+ "success": null,
+ "error": null,
+ "workflow_approval": null
+ },
+ "email": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_friendly_name }} #{{ job.id }} had status {{ job.status }}, view details at {{ url }}\n\n{{ job_metadata }}"
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_friendly_name }} #{{ job.id }} had status {{ job.status }}, view details at {{ url }}\n\n{{ job_metadata }}"
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_friendly_name }} #{{ job.id }} had status {{ job.status }}, view details at {{ url }}\n\n{{ job_metadata }}"
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" needs review. This approval node can be viewed at: {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}\n\n{{ job_metadata }}"
+ }
+ }
+ },
+ "slack": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": null
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": null
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": null
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": null
+ }
+ }
+ },
+ "twilio": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": null
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": null
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": null
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": null
+ }
+ }
+ },
+ "pagerduty": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_metadata }}"
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_metadata }}"
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": "{{ job_metadata }}"
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" needs review. This approval node can be viewed at: {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}\n\n{{ job_metadata }}"
+ }
+ }
+ },
+ "grafana": {
+ "started": {
+ "body": "{{ job_metadata }}",
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}"
+ },
+ "success": {
+ "body": "{{ job_metadata }}",
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}"
+ },
+ "error": {
+ "body": "{{ job_metadata }}",
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}"
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" needs review. This approval node can be viewed at: {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}\n\n{{ job_metadata }}"
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}\n\n{{ job_metadata }}"
+ }
+ }
+ },
+ "webhook": {
+ "started": {
+ "body": "{{ job_metadata }}"
+ },
+ "success": {
+ "body": "{{ job_metadata }}"
+ },
+ "error": {
+ "body": "{{ job_metadata }}"
+ },
+ "workflow_approval": {
+ "running": {
+ "body": {
+ "body": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}"
+ }
+ },
+ "approved": {
+ "body": {
+ "body": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}"
+ }
+ },
+ "timed_out": {
+ "body": {
+ "body": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}"
+ }
+ },
+ "denied": {
+ "body": {
+ "body": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}"
+ }
+ }
+ }
+ },
+ "mattermost": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": null
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": null
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": null
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": null
+ }
+ }
+ },
+ "rocketchat": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": null
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": null
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": null
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": null
+ }
+ }
+ },
+ "irc": {
+ "started": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "success": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "error": {
+ "message": "{{ job_friendly_name }} #{{ job.id }} '{{ job.name }}' {{ job.status }}: {{ url }}",
+ "body": null
+ },
+ "workflow_approval": {
+ "running": {
+ "message": "The approval node \"{{ approval_node_name }}\" needs review. This node can be viewed at: {{ workflow_url }}",
+ "body": null
+ },
+ "approved": {
+ "message": "The approval node \"{{ approval_node_name }}\" was approved. {{ workflow_url }}",
+ "body": null
+ },
+ "timed_out": {
+ "message": "The approval node \"{{ approval_node_name }}\" has timed out. {{ workflow_url }}",
+ "body": null
+ },
+ "denied": {
+ "message": "The approval node \"{{ approval_node_name }}\" was denied. {{ workflow_url }}",
+ "body": null
+ }
+ }
+ }
+}
diff --git a/awx/ui_next/src/screens/NotificationTemplate/shared/typeFieldNames.js b/awx/ui_next/src/screens/NotificationTemplate/shared/typeFieldNames.js
index 4dd991cfa9..6d4d3046a6 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/shared/typeFieldNames.js
+++ b/awx/ui_next/src/screens/NotificationTemplate/shared/typeFieldNames.js
@@ -7,6 +7,8 @@ const typeFieldNames = {
'sender',
'port',
'timeout',
+ 'use_ssl',
+ 'use_tls',
],
grafana: [
'grafana_url',