Skip to content

Commit

Permalink
feat: [DHIS2-9661][DHIS2-14830] first stage on registration page (#3267)
Browse files Browse the repository at this point in the history
Co-authored-by: jasminenguyennn <jasmine@dhis2.org>
Co-authored-by: Joakim Storløkken Melseth <joakim.melseth@gmail.com>
  • Loading branch information
3 people authored and superskip committed Oct 27, 2023
1 parent 0b46d20 commit 1cdef22
Show file tree
Hide file tree
Showing 70 changed files with 1,334 additions and 272 deletions.
4 changes: 4 additions & 0 deletions cypress/integration/EnrollmentPage/BreakingTheGlass/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ And('you create a new tei in Child programme from Ngelehun CHC', () => {
.eq(1)
.type('TheGlass')
.blur();
cy.get('[data-test="capture-ui-input"]')
.eq(7)
.type('2023-09-01')
.blur();

clickSave();
});
Expand Down
7 changes: 6 additions & 1 deletion cypress/integration/NewPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ Feature: User creates a new entries from the registration page
Scenario: New person in Tracker Program > Submitting the form shows a list with duplicates
Given you are in Child programme registration page
When you fill the Child programme registration form with a first name with value that has duplicates
And you fill in the birth report date
And you click the save person submit button
And you see the possible duplicates modal
When you click the next page button
Expand All @@ -197,7 +198,7 @@ Feature: User creates a new entries from the registration page
When you are in the Malaria case diagnosis, treatment and investigation program registration page
And you fill the Malaria case diagnosis registration form with values
And you click the save malaria entity submit button
Then you see the enrollment event New page
Then you see the enrollment event Edit page
When you open the main page with Ngelehun and Malaria case diagnosis, treatment and investigation context
And you opt out to use the new enrollment Dashboard for Malaria case diagnosis, treatment and investigation
Then you see the opt in component for Malaria case diagnosis, treatment and investigation
Expand All @@ -208,3 +209,7 @@ Feature: User creates a new entries from the registration page
Given you are in Child programme reenrollment page
Then you see the form prefield with existing TEI attributes values
And the scope selector has the TEI context

Scenario: First stage appears on registration page
Given you are in Child programme registration page
Then the first stage appears on registration page
23 changes: 19 additions & 4 deletions cypress/integration/NewPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,13 @@ And('you fill the Child programme registration form with a first name with value
.blur();
});

And('you fill in the birth report date', () => {
cy.get('[data-test="capture-ui-input"]')
.eq(7)
.type('2023-01-01')
.blur();
});

And('you are in the WNCH PNC program registration page', () => {
cy.visit('/#/new?programId=uy2gU8kT1jF&orgUnitId=DiszpKrYNg8');
});
Expand Down Expand Up @@ -561,12 +568,10 @@ And('you fill the Malaria case diagnosis registration form with values', () => {
.blur();
});

Then('you see the enrollment event New page', () => {
cy.url().should('include', '/#/enrollmentEventNew?');
cy.url().should('include', 'stageId=hYyB7FUS5eR');
Then('you see the enrollment event Edit page', () => {
cy.url().should('include', '/#/enrollmentEventEdit?');
});


And('you fill in multiple Allergies options', () => {
cy.get('[data-test="registration-page-content"]').within(() => {
cy.contains('Allergies').should('exist');
Expand All @@ -585,3 +590,13 @@ Then('you can see the multiple selections in the form', () => {
cy.contains('Other').should('exist');
});
});

Then('the first stage appears on registration page', () => {
cy.get('[data-test="registration-page-content"]').within(() => {
cy.contains('Birth - Basic info').should('exist');
cy.contains('Birth - Details').should('exist');
cy.contains('Birth - Status').should('exist');
cy.contains('Report date').should('exist');
cy.contains('Apgar Score').should('exist');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { v4 as uuid } from 'uuid';
import '../../sharedSteps';
import '../../../sharedSteps';

const cleanUpIfApplicable = () => {
cy.buildApiUrl('programStageWorkingLists?filter=program.id:eq:qDkgAbB5Jlk&fields=id,displayName')
const cleanUpIfApplicable = (programId) => {
cy.buildApiUrl(`programStageWorkingLists?filter=program.id:eq:${programId}&fields=id,displayName`)
.then(url => cy.request(url))
.then(({ body }) => {
const workingList = body.programStageWorkingLists?.find(e => e.displayName === 'Custom Program stage list');
Expand Down Expand Up @@ -55,7 +55,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis context',
});

Given('you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context', () => {
cleanUpIfApplicable();
cleanUpIfApplicable('qDkgAbB5Jlk');
cy.visit('#/?programId=qDkgAbB5Jlk&orgUnitId=DiszpKrYNg8');

cy.get('[data-test="tei-working-lists"]')
Expand All @@ -75,7 +75,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis and House
});

Given('you open a clean main page with Ngelehun and Malaria focus investigation context', () => {
cleanUpIfApplicable();
cleanUpIfApplicable('M3xtLkYBlKI');
cy.visit('#/?programId=M3xtLkYBlKI&orgUnitId=DiszpKrYNg8');
});

Expand Down
22 changes: 17 additions & 5 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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: 2023-09-04T07:07:59.195Z\n"
"PO-Revision-Date: 2023-09-04T07:07:59.195Z\n"
"POT-Creation-Date: 2023-09-29T14:14:34.330Z\n"
"PO-Revision-Date: 2023-09-29T14:14:34.330Z\n"

msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
Expand Down Expand Up @@ -149,6 +149,15 @@ msgstr "Coordinate"
msgid "Enrollment"
msgstr "Enrollment"

msgid "Complete event"
msgstr "Complete event"

msgid "{{ stageName }} - Basic info"
msgstr "{{ stageName }} - Basic info"

msgid "{{ stageName }} - Status"
msgstr "{{ stageName }} - Status"

msgid "Please select {{categoryName}}"
msgstr "Please select {{categoryName}}"

Expand All @@ -167,15 +176,18 @@ msgstr "Cancel"
msgid "Metadata error. see log for details"
msgstr "Metadata error. see log for details"

msgid "{{ stageName }} - Details"
msgstr "{{ stageName }} - Details"

msgid "{{ stageName }} - {{ sectionName }}"
msgstr "{{ stageName }} - {{ sectionName }}"

msgid "Assigned user"
msgstr "Assigned user"

msgid "Search for user"
msgstr "Search for user"

msgid "Complete event"
msgstr "Complete event"

msgid "Basic info"
msgstr "Basic info"

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "capture-app",
"homepage": ".",
"version": "100.40.1",
"cacheVersion": "5",
"cacheVersion": "6",
"serverVersion": "38",
"license": "BSD-3-Clause",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,21 @@ class D2Form extends React.PureComponent<PropsForPureComponent> {
id,
classes,
isFormInReduxStore,
getCustomContent,
...passOnProps
} = this.props;
const metaDataSectionsAsArray = Array.from(formFoundation.sections.entries()).map(entry => entry[1]);

const sections = metaDataSectionsAsArray.map(section => (passOnProps.formHorizontal ? this.renderHorizontal(section, passOnProps) : this.renderVertical(section, passOnProps)));
const sections = metaDataSectionsAsArray.map(section => (
passOnProps.formHorizontal
? this.renderHorizontal(section, passOnProps)
: (
<>
{getCustomContent && getCustomContent(section.id) }
{this.renderVertical(section, passOnProps)}
</>
)
));

return (
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow

import * as React from 'react';
import type { RenderFoundation } from '../../metaData';

export type FormRef = $ReadOnly<{|
Expand All @@ -10,6 +10,7 @@ export type OwnProps = $ReadOnly<{|
formFoundation: RenderFoundation,
id: string,
formHorizontal?: boolean,
getCustomContent?: (beforeSectionId: string) => React.Node,
...FormRef
|}>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ import {
getIncidentDateValidatorContainer,
} from './fieldValidators';
import { sectionKeysForEnrollmentDataEntry } from './constants/sectionKeys.const';
import { type Enrollment, getProgramThrowIfNotFound } from '../../../metaData';
import { type Enrollment, ProgramStage, RenderFoundation, getProgramThrowIfNotFound } from '../../../metaData';
import { EnrollmentWithFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry';
import {
getCategoryOptionsValidatorContainers,
attributeOptionsKey,
AOCsectionKey,
withAOCFieldBuilder,
withDataEntryFields,
} from '../../DataEntryDhis2Helpers';
import { shouldUseNewDashboard } from '../../../utils/routing';

const overrideMessagePropNames = {
errorMessage: 'validationError',
Expand Down Expand Up @@ -290,40 +290,35 @@ const getCategoryOptionsSettingsFn = () => {
getPropName: (props: Object, fieldId?: string) => (fieldId ? `${attributeOptionsKey}-${fieldId}` : attributeOptionsKey),
getFieldIds: (props: Object) => props.categories?.map(category => category.id),
getValidatorContainers: (props: Object, fieldId?: string) => getCategoryOptionsValidatorContainers(props, fieldId),
getMeta: (props: Object) => ({
section: AOCsectionKey,
placement: placements.BOTTOM,
sectionName: props.programCategory?.displayName,
}),
getMeta: (props: Object) => {
const { firstStageMetaData, programCategory } = props;

return {
section: AOCsectionKey,
placement: placements.BOTTOM,
sectionName: firstStageMetaData
? `${firstStageMetaData.stage.name} - ${programCategory?.displayName}`
: programCategory?.displayName,
};
},
};

return categoryOptionsSettings;
};

const getAOCSettingsFn = () => ({
hideAOC: ({ programId, newDashboardConfig }) => {
const { stages: stagesMap } = getProgramThrowIfNotFound(programId);
hideAOC: ({ programId }) => {
const { stages: stagesMap, useFirstStageDuringRegistration } = getProgramThrowIfNotFound(programId);

/*
Show AOC selection if:
- There are any program stages in the program with “Auto-generate" event and NOT “Open data entry form after enrollment”.
- There are multiple program stages with "Auto-generate" event and "Open data entry form after enrollment"
(in this scenario we are currently generating events for the program stages that are not the first one)
- Using the old dashboard and we have a stage with auto generate event.
- There are any program stages in the program with “Auto-generate"
- The "Show first stage on registration page" is selected for the program
*/

const stages = [...stagesMap.values()];

const usingNewDashboardForProgram = shouldUseNewDashboard(
newDashboardConfig.userDataStore,
newDashboardConfig.dataStore,
newDashboardConfig.temp,
programId,
);

const shouldShowAOC = (!usingNewDashboardForProgram && stages.some(stage => stage.autoGenerateEvent)) ||
stages.some(stage => stage.autoGenerateEvent && !stage.openAfterEnrollment) ||
stages.filter(stage => stage.autoGenerateEvent && stage.openAfterEnrollment).length > 1;
const shouldShowAOC = stages.some(stage => stage.autoGenerateEvent) || useFirstStageDuringRegistration;

return !shouldShowAOC;
},
Expand All @@ -336,7 +331,9 @@ type FinalTeiDataEntryProps = {
orgUnitId: string,
onUpdateDataEntryField: Function,
onUpdateFormFieldAsync: Function,
onUpdateFormField: Function
onUpdateFormField: Function,
firstStageMetaData?: ?{ stage: ProgramStage },
formFoundation: RenderFoundation,
};
// final step before the generic dataEntry is inserted
class FinalEnrollmentDataEntry extends React.Component<FinalTeiDataEntryProps> {
Expand All @@ -355,14 +352,21 @@ class FinalEnrollmentDataEntry extends React.Component<FinalTeiDataEntryProps> {
};

render() {
const { enrollmentMetadata, ...passOnProps } = this.props;
const { enrollmentMetadata, firstStageMetaData, ...passOnProps } = this.props;

return (
// $FlowFixMe[cannot-spread-inexact] automated comment
<DataEntry
{...passOnProps}
dataEntrySections={FinalEnrollmentDataEntry.dataEntrySectionDefinitions}
formFoundation={enrollmentMetadata.enrollmentForm}
/>
firstStageMetaData ? (
<EnrollmentWithFirstStageDataEntry
{...passOnProps}
firstStageMetaData={firstStageMetaData}
/>
) : (
<DataEntry
{...passOnProps}
dataEntrySections={FinalEnrollmentDataEntry.dataEntrySectionDefinitions}
/>
)
);
}
}
Expand All @@ -385,6 +389,8 @@ type PreEnrollmentDataEntryProps = {
onStartAsyncUpdateField: Function,
onGetUnsavedAttributeValues?: ?Function,
teiId?: ?string,
firstStageMetaData?: ?{ stage: ProgramStage },
formFoundation: RenderFoundation,
};

class PreEnrollmentDataEntryPure extends React.PureComponent<Object> {
Expand All @@ -409,18 +415,18 @@ export class EnrollmentDataEntryComponent extends React.Component<PreEnrollmentD
}

handleUpdateField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onUpdateField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props;
this.props.onUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation);
}

handleUpdateDataEntryField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onUpdateDataEntryField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props;
this.props.onUpdateDataEntryField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation);
}

handleStartAsyncUpdateField = (...args: Array<any>) => {
const { programId, orgUnit } = this.props;
this.props.onStartAsyncUpdateField(...args, programId, orgUnit);
const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props;
this.props.onStartAsyncUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation);
}

render() {
Expand All @@ -432,6 +438,7 @@ export class EnrollmentDataEntryComponent extends React.Component<PreEnrollmentD
onGetUnsavedAttributeValues,
...passOnProps
} = this.props;

return (
// $FlowFixMe[cannot-spread-inexact] automated comment
<PreEnrollmentDataEntryPure
Expand Down
Loading

0 comments on commit 1cdef22

Please sign in to comment.