Skip to content

Commit

Permalink
fix: add skipprograms field
Browse files Browse the repository at this point in the history
  • Loading branch information
ismay authored and ismay committed Mar 18, 2024
1 parent a05bfa6 commit b8fb409
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 20 deletions.
12 changes: 12 additions & 0 deletions cypress/integration/add-job/create-parameter-jobs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ Given('the user enters the parameters for analytics table', () => {
// Close the select by clicking layer
cy.get('[data-test="dhis2-uicore-layer"]').click()

cy.findByText('Skip programs')
.parents('[data-test="dhis2-uiwidgets-multiselectfield"]')
.within(() => {
cy.get('[data-test="dhis2-uicore-multiselect"]').click()
})

cy.findByText('Antenatal care visit').click()

// Close the select by clicking layer
cy.get('[data-test="dhis2-uicore-layer"]').click()

cy.findByLabelText('Skip resource tables').click()
})

Expand Down Expand Up @@ -184,6 +195,7 @@ Then(
jobParameters: {
lastYears: '1',
skipTableTypes: ['DATA_VALUE'],
skipPrograms: ['lxAQ7Zs9VYR'],
skipResourceTables: true,
},
})
Expand Down
12 changes: 12 additions & 0 deletions cypress/integration/edit-job/edit-parameter-jobs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ Given('the user enters the parameters for analytics table', () => {
// Close the select by clicking layer
cy.get('[data-test="dhis2-uicore-layer"]').click()

cy.findByText('Skip programs')
.parents('[data-test="dhis2-uiwidgets-multiselectfield"]')
.within(() => {
cy.get('[data-test="dhis2-uicore-multiselect"]').click()
})

cy.findByText('Antenatal care visit').click()

// Close the select by clicking layer
cy.get('[data-test="dhis2-uicore-layer"]').click()

cy.findByLabelText('Skip resource tables').click()
})

Expand Down Expand Up @@ -201,6 +212,7 @@ Then('the job is updated when the user saves the analytics table job', () =>
jobParameters: {
lastYears: '1',
skipTableTypes: ['DATA_VALUE'],
skipPrograms: ['lxAQ7Zs9VYR'],
skipResourceTables: true,
},
})
Expand Down
64 changes: 64 additions & 0 deletions src/components/FormFields/ListFieldMulti.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import PropTypes from 'prop-types'
import { MultiSelectFieldFF, ReactFinalForm, MultiSelectField } from '@dhis2/ui'
import i18n from '@dhis2/d2-i18n'
import { useParameterOption } from '../../hooks/parameter-options'

const { Field } = ReactFinalForm

// This field has options that have both an id and a label.
const ListFieldMulti = ({ label, name, parameterName }) => {
const { loading, error, data } = useParameterOption(parameterName)
const disabledProps = { disabled: true, label }

if (loading) {
return (
<MultiSelectField
{...disabledProps}
helpText={i18n.t('Loading options')}
/>
)
}

if (error) {
return (
<MultiSelectField
{...disabledProps}
helpText={i18n.t('Something went wrong whilst loading options')}
/>
)
}

if (data.length === 0) {
return (
<MultiSelectField
{...disabledProps}
helpText={i18n.t('No options available')}
/>
)
}

const labeledOptions = data.map(({ id, displayName }) => ({
value: id,
label: displayName,
}))

return (
<Field
name={name}
component={MultiSelectFieldFF}
options={labeledOptions}
label={label}
/>
)
}

const { string } = PropTypes

ListFieldMulti.propTypes = {
label: string.isRequired,
name: string.isRequired,
parameterName: string.isRequired,
}

export default ListFieldMulti
73 changes: 73 additions & 0 deletions src/components/FormFields/ListFieldMulti.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react'
import { mount } from 'enzyme'
import { ReactFinalForm } from '@dhis2/ui'
import { useParameterOption } from '../../hooks/parameter-options'
import ListFieldMulti from './ListFieldMulti'

const { Form } = ReactFinalForm

jest.mock('../../hooks/parameter-options', () => ({
useParameterOption: jest.fn(),
}))

afterEach(() => {
jest.resetAllMocks()
})

describe('<ListFieldMulti>', () => {
it('shows a message when there are no options', () => {
useParameterOption.mockImplementation(() => ({
loading: false,
error: undefined,
data: [],
}))
const props = {
label: 'label',
name: 'name',
parameterName: 'parameterName',
}
const wrapper = mount(
<Form onSubmit={() => {}}>
{() => (
<form>
<ListFieldMulti {...props} />
</form>
)}
</Form>
)

const actual = wrapper
.find({
'data-test': 'dhis2-uiwidgets-multiselectfield-help',
})
.text()

expect(actual).toEqual(expect.stringContaining('No options available'))
})

it('renders the field when there are options', () => {
useParameterOption.mockImplementation(() => ({
loading: false,
error: undefined,
data: [{ id: 'id', displayName: 'displayName' }],
}))
const props = {
label: 'label',
name: 'fieldName',
parameterName: 'parameterName',
}
const wrapper = mount(
<Form onSubmit={() => {}}>
{() => (
<form>
<ListFieldMulti {...props} />
</form>
)}
</Form>
)

const actual = wrapper.find('ListFieldMulti')

expect(actual).toHaveLength(1)
})
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import {
MultiSelectFieldFF,
SingleSelectFieldFF,
ReactFinalForm,
SingleSelectField,
Expand All @@ -11,8 +10,8 @@ import { useParameterOption } from '../../hooks/parameter-options'

const { Field } = ReactFinalForm

// A labeled options field has options that have both an id and a label.
const LabeledOptionsField = ({ label, name, parameterName, multiple }) => {
// This field has options that have both an id and a label.
const ListFieldSingle = ({ label, name, parameterName }) => {
const { loading, error, data } = useParameterOption(parameterName)
const disabledProps = { disabled: true, label }

Expand Down Expand Up @@ -51,20 +50,19 @@ const LabeledOptionsField = ({ label, name, parameterName, multiple }) => {
return (
<Field
name={name}
component={multiple ? MultiSelectFieldFF : SingleSelectFieldFF}
component={SingleSelectFieldFF}
options={labeledOptions}
label={label}
/>
)
}

const { string, bool } = PropTypes
const { string } = PropTypes

LabeledOptionsField.propTypes = {
ListFieldSingle.propTypes = {
label: string.isRequired,
name: string.isRequired,
parameterName: string.isRequired,
multiple: bool,
}

export default LabeledOptionsField
export default ListFieldSingle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { mount } from 'enzyme'
import { ReactFinalForm } from '@dhis2/ui'
import { useParameterOption } from '../../hooks/parameter-options'
import LabeledOptionsField from './LabeledOptionsField'
import ListFieldSingle from './ListFieldSingle'

const { Form } = ReactFinalForm

Expand All @@ -14,7 +14,7 @@ afterEach(() => {
jest.resetAllMocks()
})

describe('<LabeledOptionsField>', () => {
describe('<ListFieldSingle>', () => {
it('shows a message when there are no options', () => {
useParameterOption.mockImplementation(() => ({
loading: false,
Expand All @@ -30,7 +30,7 @@ describe('<LabeledOptionsField>', () => {
<Form onSubmit={() => {}}>
{() => (
<form>
<LabeledOptionsField {...props} />
<ListFieldSingle {...props} />
</form>
)}
</Form>
Expand Down Expand Up @@ -60,13 +60,13 @@ describe('<LabeledOptionsField>', () => {
<Form onSubmit={() => {}}>
{() => (
<form>
<LabeledOptionsField {...props} />
<ListFieldSingle {...props} />
</form>
)}
</Form>
)

const actual = wrapper.find('LabeledOptionsField')
const actual = wrapper.find('ListFieldSingle')

expect(actual).toHaveLength(1)
})
Expand Down
17 changes: 12 additions & 5 deletions src/components/FormFields/ParameterFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import DataIntegrityReportTypeField from './Custom/DataIntegrityReportTypeField'
import AggregatedDataExchangeField from './Custom/AggregatedDataExchangeField'
import PushAnalyticsModeField from './Custom/PushAnalyticsModeField'
import styles from './ParameterFields.module.css'
import LabeledOptionsField from './LabeledOptionsField'
import ListFieldSingle from './ListFieldSingle'
import ListFieldMulti from './ListFieldMulti'
import { formatToString } from './formatters'

const { Field } = ReactFinalForm
Expand All @@ -41,6 +42,13 @@ const getCustomComponent = (jobType, parameterName) => {

return null
case 'ANALYTICS_TABLE':
if (parameterName === 'skipTableTypes') {
return SkipTableTypesField
} else if (parameterName === 'skipPrograms') {
return ListFieldMulti
}

return null
case 'CONTINUOUS_ANALYTICS_TABLE':
if (parameterName === 'skipTableTypes') {
return SkipTableTypesField
Expand All @@ -49,9 +57,9 @@ const getCustomComponent = (jobType, parameterName) => {
return null
case 'HTML_PUSH_ANALYTICS':
if (parameterName === 'dashboard') {
return LabeledOptionsField
return ListFieldSingle
} else if (parameterName === 'receivers') {
return LabeledOptionsField
return ListFieldSingle
} else if (parameterName === 'mode') {
return PushAnalyticsModeField
}
Expand Down Expand Up @@ -145,10 +153,9 @@ const ParameterFields = ({ jobType }) => {
break
case 'java.util.List':
parameterComponent = (
<LabeledOptionsField
<ListFieldMulti
{...defaultProps}
parameterName={name}
multiple
/>
)
break
Expand Down
2 changes: 1 addition & 1 deletion src/components/FormFields/ParameterFields.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ describe('<ParameterFields>', () => {
</Form>
)

const component = wrapper.find('LabeledOptionsField')
const component = wrapper.find('ListFieldMulti')

expect(component).toHaveLength(1)
})
Expand Down
1 change: 1 addition & 0 deletions src/hooks/parameter-options/use-parameter-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('useParameterOption', () => {
dataIntegrity: 'dataIntegrityChecks',
dashboards: { dashboards: 'dashboard' },
userGroups: { userGroups: 'receivers' },
programs: { programs: 'programs' },
}
const wrapper = ({ children }) => (
<CustomDataProvider data={data}>{children}</CustomDataProvider>
Expand Down
8 changes: 7 additions & 1 deletion src/hooks/parameter-options/use-parameter-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const query = {
receivers: {
resource: 'userGroups',
},
programs: {
resource: 'programs',
},
}

const useParameterOptions = () => {
Expand All @@ -53,6 +56,7 @@ const useParameterOptions = () => {
const dataIntegrityChecks = fetch.data?.dataIntegrityChecks
const dashboard = fetch.data?.dashboard?.dashboards
const receivers = fetch.data?.receivers?.userGroups
const skipPrograms = fetch.data?.programs?.programs

if (
!skipTableTypes ||
Expand All @@ -62,7 +66,8 @@ const useParameterOptions = () => {
!predictorGroups ||
!dataIntegrityChecks ||
!dashboard ||
!receivers
!receivers ||
!skipPrograms
) {
const error = new Error(
'Did not receive the expected parameter options'
Expand All @@ -79,6 +84,7 @@ const useParameterOptions = () => {
dataIntegrityChecks,
dashboard,
receivers,
skipPrograms,
}

return { ...fetch, data }
Expand Down
Loading

0 comments on commit b8fb409

Please sign in to comment.