From 77da8c6994219e262c72a0313ebe9bef6d47749b Mon Sep 17 00:00:00 2001 From: mabashian Date: Tue, 20 Oct 2020 14:47:44 -0400 Subject: [PATCH 1/6] Adds copy button to notification templates list rows --- .../NotificationTemplateList.jsx | 1 + .../NotificationTemplateListItem.jsx | 33 +++++++++++- .../NotificationTemplateListItem.test.jsx | 53 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx index 258cd7cbb6..67588fc267 100644 --- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx +++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx @@ -166,6 +166,7 @@ function NotificationTemplatesList({ i18n }) { renderItem={template => ( row.id === template.id)} diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.jsx index 59d9fb748d..5f3d0a2a10 100644 --- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.jsx +++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.jsx @@ -14,9 +14,11 @@ import { Tooltip, } from '@patternfly/react-core'; import { PencilAltIcon, BellIcon } from '@patternfly/react-icons'; +import { timeOfDay } from '../../../util/dates'; import { NotificationTemplatesAPI, NotificationsAPI } from '../../../api'; import DataListCell from '../../../components/DataListCell'; import StatusLabel from '../../../components/StatusLabel'; +import CopyButton from '../../../components/CopyButton'; import useRequest from '../../../util/useRequest'; import { NOTIFICATION_TYPES } from '../constants'; @@ -24,7 +26,7 @@ const DataListAction = styled(_DataListAction)` align-items: center; display: grid; grid-gap: 16px; - grid-template-columns: 40px 40px; + grid-template-columns: repeat(3, 40px); `; const NUM_RETRIES = 25; @@ -33,6 +35,7 @@ const RETRY_TIMEOUT = 5000; function NotificationTemplateListItem({ template, detailUrl, + fetchTemplates, isSelected, onSelect, i18n, @@ -42,6 +45,22 @@ function NotificationTemplateListItem({ ? recentNotifications[0]?.status : null; const [status, setStatus] = useState(latestStatus); + const [isCopyDisabled, setIsCopyDisabled] = useState(false); + + const copyTemplate = useCallback(async () => { + await NotificationTemplatesAPI.copy(template.id, { + name: `${template.name} @ ${timeOfDay()}`, + }); + await fetchTemplates(); + }, [template.id, template.name, fetchTemplates]); + + const handleCopyStart = useCallback(() => { + setIsCopyDisabled(true); + }, []); + + const handleCopyFinish = useCallback(() => { + setIsCopyDisabled(false); + }, []); useEffect(() => { setStatus(latestStatus); @@ -136,6 +155,18 @@ function NotificationTemplateListItem({ ) : (
)} + {template.summary_fields.user_capabilities.copy && ( + + )} diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.test.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.test.jsx index 58878d3b96..65f959522c 100644 --- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.test.jsx +++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateListItem.test.jsx @@ -13,6 +13,7 @@ const template = { summary_fields: { user_capabilities: { edit: true, + copy: true, }, recent_notifications: [ { @@ -63,4 +64,56 @@ describe('', () => { .text() ).toEqual('Running'); }); + + test('should call api to copy inventory', async () => { + NotificationTemplatesAPI.copy.mockResolvedValue(); + + const wrapper = mountWithContexts( + + ); + + await act(async () => + wrapper.find('Button[aria-label="Copy"]').prop('onClick')() + ); + expect(NotificationTemplatesAPI.copy).toHaveBeenCalled(); + jest.clearAllMocks(); + }); + + test('should render proper alert modal on copy error', async () => { + NotificationTemplatesAPI.copy.mockRejectedValue(new Error()); + + const wrapper = mountWithContexts( + + ); + await act(async () => + wrapper.find('Button[aria-label="Copy"]').prop('onClick')() + ); + wrapper.update(); + expect(wrapper.find('Modal').prop('isOpen')).toBe(true); + jest.clearAllMocks(); + }); + + test('should not render copy button', async () => { + const wrapper = mountWithContexts( + + ); + expect(wrapper.find('CopyButton').length).toBe(0); + }); }); From ad20d6c93f279930f5a33109784489f0770e2c70 Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 7 Dec 2020 16:15:48 -0500 Subject: [PATCH 2/6] Configure advanced search on notification templates list --- .../NotificationTemplateList.jsx | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx index 67588fc267..a722f8fe6b 100644 --- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx +++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx @@ -29,27 +29,41 @@ function NotificationTemplatesList({ i18n }) { const addUrl = `${match.url}/add`; const { - result: { templates, count, actions }, + result: { + templates, + count, + actions, + relatedSearchableKeys, + searchableKeys, + }, error: contentError, isLoading: isTemplatesLoading, request: fetchTemplates, } = useRequest( useCallback(async () => { const params = parseQueryString(QS_CONFIG, location.search); - const responses = await Promise.all([ + const [response, actionsResponse] = await Promise.all([ NotificationTemplatesAPI.read(params), NotificationTemplatesAPI.readOptions(), ]); return { - templates: responses[0].data.results, - count: responses[0].data.count, - actions: responses[1].data.actions, + templates: response.data.results, + count: response.data.count, + actions: actionsResponse.data.actions, + relatedSearchableKeys: ( + actionsResponse.data?.related_search_fields || [] + ).map(val => val.slice(0, -8)), + searchableKeys: Object.keys( + actionsResponse.data.actions?.GET || {} + ).filter(key => actionsResponse.data.actions?.GET[key].filterable), }; }, [location]), { templates: [], count: 0, actions: {}, + relatedSearchableKeys: [], + searchableKeys: [], } ); @@ -133,6 +147,8 @@ function NotificationTemplatesList({ i18n }) { key: 'modified_by__username__icontains', }, ]} + toolbarSearchableKeys={searchableKeys} + toolbarRelatedSearchableKeys={relatedSearchableKeys} toolbarSortColumns={[ { name: i18n._(t`Name`), From d58b4807d9ee219c2f608d58f1c28e35250eb20e Mon Sep 17 00:00:00 2001 From: mabashian Date: Wed, 16 Dec 2020 08:52:38 -0500 Subject: [PATCH 3/6] Disable copy button while copy request is outstanding --- awx/ui_next/src/components/CopyButton/CopyButton.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/ui_next/src/components/CopyButton/CopyButton.jsx b/awx/ui_next/src/components/CopyButton/CopyButton.jsx index f8eeda7626..fe4580f4bf 100644 --- a/awx/ui_next/src/components/CopyButton/CopyButton.jsx +++ b/awx/ui_next/src/components/CopyButton/CopyButton.jsx @@ -34,7 +34,7 @@ function CopyButton({ <> From 3d03c473d6a69106e17a6de31e1f440bffdad076 Mon Sep 17 00:00:00 2001 From: mabashian Date: Wed, 16 Dec 2020 14:55:19 -0500 Subject: [PATCH 6/6] Change `Type` to `Notification type` since this endpoint has both type and notification_type attributes. --- .../src/components/NotificationList/NotificationList.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/ui_next/src/components/NotificationList/NotificationList.jsx b/awx/ui_next/src/components/NotificationList/NotificationList.jsx index 35a77b52f3..4bdba17027 100644 --- a/awx/ui_next/src/components/NotificationList/NotificationList.jsx +++ b/awx/ui_next/src/components/NotificationList/NotificationList.jsx @@ -187,7 +187,7 @@ function NotificationList({ key: 'description__icontains', }, { - name: i18n._(t`Type`), + name: i18n._(t`Notification type`), key: 'or__notification_type', options: [ ['email', i18n._(t`Email`)],