Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [DHIS2-13343] hidden program stage rule effect #3406

Merged
merged 6 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions cypress/integration/EnrollmentPage/HiddenProgramStage/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
import moment from 'moment';
import '../../sharedSteps';

const cleanUp = () => {
cy.visit(
'/#/enrollment?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&teiId=uW8Y7AIcRKA',
);

cy.get('[data-test="enrollment-page-content"]').contains('Enrollment Dashboard');

cy.get('[data-test="stages-and-events-widget"]')
.find('[data-test="stage-content"]')
.eq(3)
.click();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we run into trouble if there are no events in the program stage (which is initially the case?). Is it possible to do an early return if the program stage is empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion! I updated to code to handle the case of no events in the program stage. Thanks


cy.contains('WHOMCH Pregnancy outcome').should('exist');
cy.contains('[data-test="dhis2-uicore-button"]', 'Edit event').click();
cy.contains('[data-test="dhis2-uicore-button"]', 'Delete').click();
cy.contains('[data-test="dhis2-uicore-button"]', 'Yes, delete event').click();
};

Given('you add an enrollment event that will result in a rule effect to hide a program stage', () => {
cleanUp();
cy.visit(
'/#/enrollmentEventNew?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&stageId=PFDfvmGpsR3&teiId=uW8Y7AIcRKA',
);
Expand All @@ -22,20 +40,19 @@ Given('you add an enrollment event that will result in a rule effect to hide a p
});

Then('the New Postpartum care visit event button is disabled in the stages and events widget', () => {
cy.get('[data-test="create-new-button"]')
.contains('New Postpartum care visit event')
cy.contains('[data-test="create-new-button"]', 'New Postpartum care visit event')
.should('be.disabled');
});

Then('and an error is show in the Postpartum care visit stage', () => {
cy.visit(
'/#/enrollmentEventNew?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&teiId=uW8Y7AIcRKA&stageId=bbKtnxRZKEP',
);

cy.contains('[data-test="dhis2-uicore-button"]', 'Complete').should('be.disabled');
cy.contains('[data-test="dhis2-uicore-button"]', 'Save without completing').should('be.disabled');

cy.contains('[data-test="dhis2-uicore-noticebox-content"]', 'You cant add any more Postpartum care visit events')
cy.contains('[data-test="dhis2-uicore-button"]', 'Complete')
.should('be.disabled');
cy.contains('[data-test="dhis2-uicore-button"]', 'Save without completing')
.should('be.disabled');
cy.contains('[data-test="dhis2-uicore-noticebox-content"]', 'You can\'t add any more Postpartum care visit events')
.should('exist');
});

Expand All @@ -45,21 +62,4 @@ Then('the Postpartum care visit button is disabled in the enrollmentEventNew pag
);

cy.contains('[data-test="program-stage-selector-button"]', 'Postpartum care visit').should('be.disabled');

// clean up
cy.visit(
'/#/enrollment?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&teiId=uW8Y7AIcRKA',
);

cy.get('[data-test="enrollment-page-content"]').contains('Enrollment Dashboard');

cy.get('[data-test="stages-and-events-widget"]')
.find('[data-test="stage-content"]')
.eq(3)
.click();

cy.contains('WHOMCH Pregnancy outcome').should('exist');
cy.contains('[data-test="dhis2-uicore-button"]', 'Edit event').click();
cy.contains('[data-test="dhis2-uicore-button"]', 'Delete').click();
cy.contains('[data-test="dhis2-uicore-button"]', 'Yes, delete event').click();
});
7 changes: 2 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-08-24T08:48:29.672Z\n"
"PO-Revision-Date: 2023-08-24T08:48:29.672Z\n"
"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n"
"PO-Revision-Date: 2023-09-04T07:07:59.195Z\n"

msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
Expand Down Expand Up @@ -1191,9 +1191,6 @@ msgstr "Write a comment about this enrollment"
msgid "This enrollment doesn't have any comments"
msgstr "This enrollment doesn't have any comments"

msgid "You can’t add any more {{ programStageName }} events"
msgstr "You can’t add any more {{ programStageName }} events"

msgid "organisation unit could not be retrieved. Please try again later."
msgstr "organisation unit could not be retrieved. Please try again later."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const ErrorText = ({ stageName }: Props) => (
<br />
<NoticeBox error>
<span>
{i18n.t('You cant add any more {{ programStageName }} events', {
{i18n.t("You can't add any more {{ programStageName }} events", {
programStageName: stageName,
interpolation: { escapeValue: false },
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { type ComponentType } from 'react';
import i18n from '@dhis2/d2-i18n';
import { withStyles } from '@material-ui/core';
import { Button, spacersNum } from '@dhis2/ui';
import { ConditionalTooltip } from 'capture-core/components/ConditionalTooltip';
import { withCancelButton } from '../../DataEntry/withCancelButton';
import { addEventSaveTypes } from '../DataEntry/addEventSaveTypes';
import type { InputProps, Props } from './finishButtons.types';
Expand All @@ -17,28 +18,43 @@ const styles = {
},
};

const FinishButtonsPlain = ({ onSave, cancelButton, hiddenProgramStage, classes }: Props) => (
const FinishButtonsPlain = ({ onSave, cancelButton, hiddenProgramStage, stageName, classes }: Props) => (
<div className={classes.container}>
<div className={classes.button}>
<Button
disabled={hiddenProgramStage}
onClick={() => onSave(addEventSaveTypes.COMPLETE)}
primary
<ConditionalTooltip
content={i18n.t("You can't add any more {{ programStageName }} events", {
programStageName: stageName,
interpolation: { escapeValue: false },
})}
enabled={hiddenProgramStage}
>
{i18n.t('Complete')}
</Button>
<Button
disabled={hiddenProgramStage}
onClick={() => onSave(addEventSaveTypes.COMPLETE)}
primary
>
{i18n.t('Complete')}
</Button>
</ConditionalTooltip>
</div>
<div className={classes.button}>
<Button
disabled={hiddenProgramStage}
onClick={() => onSave(addEventSaveTypes.SAVE_WITHOUT_COMPLETING)}
<ConditionalTooltip
content={i18n.t("You can't add any more {{ programStageName }} events", {
programStageName: stageName,
interpolation: { escapeValue: false },
})}
enabled={hiddenProgramStage}
>
{i18n.t('Save without completing')}
</Button>
<Button
disabled={hiddenProgramStage}
onClick={() => onSave(addEventSaveTypes.SAVE_WITHOUT_COMPLETING)}
>
{i18n.t('Save without completing')}
</Button>
</ConditionalTooltip>
</div>
{cancelButton}
</div>
);

export const FinishButtons: ComponentType<InputProps> =
withCancelButton()(withStyles(styles)(FinishButtonsPlain));
export const FinishButtons: ComponentType<InputProps> = withCancelButton()(withStyles(styles)(FinishButtonsPlain));
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ export type InputProps = {|
onCancel: () => void,
id: string,
hiddenProgramStage: boolean,
stageName: string,
|};

export type Props = {|
onSave: (saveType: $Keys<addEventSaveTypes>) => void,
cancelButton: Element<any>,
hiddenProgramStage: boolean,
stageName: string,
...CssClasses,
|};
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const ValidatedPlain = ({
onCancel={onCancel}
id={id}
hiddenProgramStage={hiddenProgramStage}
stageName={stage.name}
/>
{hiddenProgramStage ? (
<ErrorText stageName={stage.name} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cx from 'classnames';
import i18n from '@dhis2/d2-i18n';
import { withStyles } from '@material-ui/core';
import { spacersNum, colors, IconAdd16, Button } from '@dhis2/ui';
import { ConditionalTooltip } from 'capture-core/components/ConditionalTooltip';
import { StageOverview } from './StageOverview';
import type { Props } from './stage.types';
import { Widget } from '../../../Widget';
Expand Down Expand Up @@ -59,17 +60,30 @@ export const StagePlain = ({ stage, events, classes, className, onCreateNew, rul
onCreateNew={onCreateNew}
hiddenProgramStage={hiddenProgramStage}
{...passOnProps}
/> : <Button
small
secondary
disabled={hiddenProgramStage}
icon={<IconAdd16 />}
className={classes.button}
dataTest="create-new-button"
onClick={() => onCreateNew(id)}
>
{i18n.t('New {{ eventName }} event', { eventName: name, interpolation: { escapeValue: false } })}
</Button>}
/> : (
<ConditionalTooltip
content={i18n.t("You can't add any more {{ programStageName }} events", {
programStageName: name,
interpolation: { escapeValue: false },
})}
enabled={hiddenProgramStage}
>
<Button
small
secondary
disabled={hiddenProgramStage}
icon={<IconAdd16 />}
className={classes.button}
dataTest="create-new-button"
onClick={() => onCreateNew(id)}
>
{i18n.t('New {{ eventName }} event', {
eventName: name,
interpolation: { escapeValue: false },
})}
</Button>
</ConditionalTooltip>
)}
</Widget>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,16 @@ const StageDetailPlain = (props: Props) => {
const renderCreateNewButton = () => {
const shouldDisableCreateNew = (!repeatable && events.length > 0) || hiddenProgramStage;

const tooltipContent = hiddenProgramStage
? i18n.t("You can't add any more {{ programStageName }} events", {
programStageName: eventName,
interpolation: { escapeValue: false },
})
: i18n.t('This stage can only have one event');

return (
<ConditionalTooltip
content={i18n.t('This stage can only have one event')}
content={tooltipContent}
enabled={shouldDisableCreateNew}
closeDelay={50}
>
Expand Down