From 6ccc3278bc282fdb95523a0075349f7c08c5fd5c Mon Sep 17 00:00:00 2001 From: ismay Date: Wed, 21 Feb 2024 11:00:54 +0100 Subject: [PATCH] feat: add run queue menu item --- i18n/en.pot | 10 ++++- src/components/JobTable/QueueActions.js | 8 +++- src/components/JobTable/QueueTableRow.js | 7 ++- src/components/JobTable/RunQueueAction.js | 43 +++++++++++++++++++ .../JobTable/RunQueueAction.test.js | 23 ++++++++++ src/components/Modal/RunJobModal.js | 27 ++++++++++-- 6 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 src/components/JobTable/RunQueueAction.js create mode 100644 src/components/JobTable/RunQueueAction.test.js diff --git a/i18n/en.pot b/i18n/en.pot index ce1daa3a7..41d86b9f0 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-02-15T11:19:20.108Z\n" -"PO-Revision-Date: 2024-02-15T11:19:20.108Z\n" +"POT-Creation-Date: 2024-02-21T09:54:31.937Z\n" +"PO-Revision-Date: 2024-02-21T09:54:31.937Z\n" msgid "Something went wrong" msgstr "Something went wrong" @@ -252,9 +252,15 @@ msgstr "Yes, discard changes" msgid "Error running job" msgstr "Error running job" +msgid "Error running queue" +msgstr "Error running queue" + msgid "Are you sure you want to run this job?" msgstr "Are you sure you want to run this job?" +msgid "Are you sure you want to run this queue?" +msgstr "Are you sure you want to run this queue?" + msgid "Run" msgstr "Run" diff --git a/src/components/JobTable/QueueActions.js b/src/components/JobTable/QueueActions.js index 5ff911ffa..b4b57f97f 100644 --- a/src/components/JobTable/QueueActions.js +++ b/src/components/JobTable/QueueActions.js @@ -3,14 +3,16 @@ import PropTypes from 'prop-types' import { FlyoutMenu, DropdownButton } from '@dhis2/ui' import i18n from '@dhis2/d2-i18n' import EditQueueAction from './EditQueueAction' +import RunQueueAction from './RunQueueAction' import DeleteQueueAction from './DeleteQueueAction' -const QueueActions = ({ name, refetch }) => ( +const QueueActions = ({ name, refetch, id, enabled }) => ( + } @@ -19,9 +21,11 @@ const QueueActions = ({ name, refetch }) => ( ) -const { string, func } = PropTypes +const { string, func, bool } = PropTypes QueueActions.propTypes = { + enabled: bool.isRequired, + id: string.isRequired, name: string.isRequired, refetch: func.isRequired, } diff --git a/src/components/JobTable/QueueTableRow.js b/src/components/JobTable/QueueTableRow.js index bdd10a3f6..e046a42c0 100644 --- a/src/components/JobTable/QueueTableRow.js +++ b/src/components/JobTable/QueueTableRow.js @@ -69,7 +69,12 @@ const QueueTableRow = ({ /> - + {showJobs diff --git a/src/components/JobTable/RunQueueAction.js b/src/components/JobTable/RunQueueAction.js new file mode 100644 index 000000000..e4848593b --- /dev/null +++ b/src/components/JobTable/RunQueueAction.js @@ -0,0 +1,43 @@ +import React, { useState } from 'react' +import PropTypes from 'prop-types' +import { MenuItem } from '@dhis2/ui' +import i18n from '@dhis2/d2-i18n' +import { RunJobModal } from '../Modal' + +const RunQueueAction = ({ id, enabled, onComplete }) => { + const [showModal, setShowModal] = useState(false) + + return ( + + { + setShowModal(true) + }} + disabled={!enabled} + label={i18n.t('Run manually')} + /> + {showModal && ( + setShowModal(false) + } + onComplete={onComplete} + isQueue + /> + )} + + ) +} + +const { string, bool, func } = PropTypes + +RunQueueAction.propTypes = { + id: string.isRequired, + onComplete: func.isRequired, + enabled: bool, +} + +export default RunQueueAction diff --git a/src/components/JobTable/RunQueueAction.test.js b/src/components/JobTable/RunQueueAction.test.js new file mode 100644 index 000000000..a00e6c082 --- /dev/null +++ b/src/components/JobTable/RunQueueAction.test.js @@ -0,0 +1,23 @@ +import React from 'react' +import { mount } from 'enzyme' +import RunQueueAction from './RunQueueAction' + +describe('', () => { + it('shows the modal when MenuItem is clicked and the job is enabled', () => { + const wrapper = mount( + {}} /> + ) + + expect(wrapper.find('RunJobModal')).toHaveLength(0) + wrapper.find('a').simulate('click') + expect(wrapper.find('RunJobModal')).toHaveLength(1) + }) + + it('does not show the modal when MenuItem is clicked and the job is disabled', () => { + const wrapper = mount( {}} />) + + expect(wrapper.find('RunJobModal')).toHaveLength(0) + wrapper.find('a').simulate('click') + expect(wrapper.find('RunJobModal')).toHaveLength(0) + }) +}) diff --git a/src/components/Modal/RunJobModal.js b/src/components/Modal/RunJobModal.js index e18d18b08..36303f523 100644 --- a/src/components/Modal/RunJobModal.js +++ b/src/components/Modal/RunJobModal.js @@ -11,7 +11,23 @@ import { } from '@dhis2/ui' import i18n from '@dhis2/d2-i18n' -const RunJobModal = ({ id, hideModal, onComplete }) => { +const messages = { + error: { + job: i18n.t('Error running job'), + queue: i18n.t('Error running queue'), + }, + confirm: { + job: i18n.t('Are you sure you want to run this job?'), + queue: i18n.t('Are you sure you want to run this queue?'), + }, +} + +/** + * This modal can be used to trigger a job or a queue. To start + * a queue, pass the id of the first job of that queue. + */ + +const RunJobModal = ({ id, hideModal, onComplete, isQueue }) => { const [mutation] = useState({ resource: `jobConfigurations/${id}/execute`, type: 'create', @@ -22,16 +38,18 @@ const RunJobModal = ({ id, hideModal, onComplete }) => { onComplete() }, }) + const errorTitle = isQueue ? messages.error.queue : messages.error.job + const confirmation = isQueue ? messages.confirm.queue : messages.confirm.job return ( {error && ( - + {error.message} )} -

{i18n.t('Are you sure you want to run this job?')}

+

{confirmation}

@@ -57,12 +75,13 @@ const RunJobModal = ({ id, hideModal, onComplete }) => { ) } -const { func, string } = PropTypes +const { func, string, bool } = PropTypes RunJobModal.propTypes = { hideModal: func.isRequired, id: string.isRequired, onComplete: func.isRequired, + isQueue: bool, } export default RunJobModal