Skip to content

Commit

Permalink
feat: [DHIS2-16204] make opt-in to new dashboard the default (#3508)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonadomnisoru authored Jan 25, 2024
1 parent 09b1989 commit 5407d7c
Show file tree
Hide file tree
Showing 26 changed files with 121 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ Feature: User interacts with the Enrollment New Event Workspace
Then the input should throw an error with error-message Please provide a positive integer

Scenario: User should be asked to create new event after completing a stage and choose to cancel
Given you open the main page with Ngelehun and Malaria focus investigation context
And you opt in to use the new enrollment Dashboard for Malaria focus investigation
Then you land on the enrollment new event page by having typed #/enrollmentEventNew?enrollmentId=zRfAPUpjoG3&orgUnitId=DiszpKrYNg8&programId=M3xtLkYBlKI&stageId=CWaAcQYKVpq&teiId=S3JjTA4QMNe
Given you land on the enrollment new event page by having typed #/enrollmentEventNew?enrollmentId=zRfAPUpjoG3&orgUnitId=DiszpKrYNg8&programId=M3xtLkYBlKI&stageId=CWaAcQYKVpq&teiId=S3JjTA4QMNe
And the data store is clean
Then you see the following Enrollment: New Event
And you see the widget header Foci investigation & classification
And you type 2022-01-01 in the input number 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor';
import '../sharedSteps';
import '../../sharedSteps';

const showAllEventsInProgramStage = () => {
cy.get('[data-test="dhis2-uicore-tablefoot"]')
Expand All @@ -16,16 +17,6 @@ Given('you open the main page with Ngelehun and Malaria focus investigation cont
cy.visit('/#/?orgUnitId=DiszpKrYNg8&programId=M3xtLkYBlKI');
});

When(/^you opt in to use the new enrollment Dashboard for (.*)$/, (program) => {
cy.get('[data-test="main-page-working-list"]').then(($wrapper) => {
if ($wrapper.find('[data-test="opt-in"]').length > 0) {
cy.contains('[data-test="dhis2-uicore-button"]', `Opt in for ${program}`).click();
cy.contains('[data-test="dhis2-uicore-button"]', 'Yes, opt in').click();
cy.contains('[data-test="dhis2-uicore-button"]', `Opt out for ${program}`);
}
});
});

Given(/^you land on the enrollment new event page by having typed (.*)$/, (url) => {
cy.visit(url);
});
Expand Down
3 changes: 1 addition & 2 deletions cypress/e2e/EnrollmentPage/BreakingTheGlass.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ Feature: Breaking the glass page
@skip
Scenario: User with search scope access tries to access an enrollment in a protected program
Given the tei created by this test is cleared from the database
And you opt temporarily in on new enrollment dashboard in Child programme and WHO RMNCH Tracker
And the data store is clean
And you create a new tei in Child programme from Ngelehun CHC
And you change program to WHO RMNCH Tracker
And you enroll the tei from Njandama MCHP
And you log out
And you log in as tracker2 user
And you opt temporarily in on new enrollment dashboard in Child programme and WHO RMNCH Tracker
And you select the new tei
And you change program to WHO RMNCH Tracker
Then you see the breaking the glass page
Expand Down
5 changes: 1 addition & 4 deletions cypress/e2e/EnrollmentPage/BreakingTheGlass/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor';
import '../sharedSteps';
import '../../sharedSteps';

Given('the tei created by this test is cleared from the database', () => {
cy.buildApiUrl('tracker', 'trackedEntities?filter=w75KJ2mc4zz:like:Breaking&filter=zDhUuAYrxNC:like:TheGlass&trackedEntityType=nEenWmSyUEp&page=1&pageSize=5&ouMode=ACCESSIBLE')
Expand All @@ -12,10 +13,6 @@ Given('the tei created by this test is cleared from the database', () => {
));
});

And('you opt temporarily in on new enrollment dashboard in Child programme and WHO RMNCH Tracker', () => {
cy.visit('/#/?newDashboard=IpHINAT79UW,WSGAb5XwJ3Y');
});

And('you create a new tei in Child programme from Ngelehun CHC', () => {
cy.visit('/#/new?orgUnitId=DiszpKrYNg8&programId=IpHINAT79UW');
cy.get('[data-test="capture-ui-input"]')
Expand Down
9 changes: 5 additions & 4 deletions cypress/e2e/MainPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ Feature: User interacts with Main page
Then the current url is /#/?orgUnitId=DiszpKrYNg8&programId=uy2gU8kT1jF&selectedTemplateId=uy2gU8kT1jF-default
And the TEI working list is displayed

Scenario: The admin user can optin to use the new Enrollment Dashboard
Scenario: The admin user can optout from using the new Enrollment Dashboard
Given you open the main page with Ngelehun and child programme context
And you see the opt in component for Child Programme
When you opt in to use the new enrollment Dashboard for Child Programme
Then you see the opt out component for Child Programme
And the data store is clean
And you see the opt out component for Child Programme
When you opt out to use the new enrollment Dashboard for Child Programme
Then you see the opt in component for Child Programme
When you opt in to use the new enrollment Dashboard for Child Programme
Then you see the opt out component for Child Programme

@v<41
Scenario: The icon is rendered as an svg
Expand Down
24 changes: 12 additions & 12 deletions cypress/e2e/NewPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ Feature: User creates a new entries from the registration page
@v>=41
Scenario: New person in Tracker Program > Filling the Allergies with multiple options
Given you are in the WHO RMNCH program registration page
And the data store is clean
When you fill in multiple Allergies options
Then you can see the multiple selections in the form
And you fill the WHO RMNCH program registration form with its required unique values
And you click the save person submit button
Then you are navigated to the WHO RMNCH program in Tracker Capture app
Then you see the enrollment event Edit page

Scenario: Viewing the registration page with incomplete program categories selection
Given you are in the main page with no selections made
Expand Down Expand Up @@ -126,17 +127,19 @@ Feature: User creates a new entries from the registration page

Scenario: New person > Submitting the form with unique name navigates you to the user dashboard
Given you are in the Person registration page
And the data store is clean
When you fill in a unique first name
And you click the save person submit button
Then you are navigated to the Tracker Capture
Then you are navigated to the enrollment dashboard page without enrollment

Scenario: New person > Submitting the form from the duplicates modal navigates you to the user dashboard
Given you are in the Person registration page
And the data store is clean
When you fill in the first name with value that has duplicates
And you click the save person submit button
And you see the possible duplicates modal
And you submit the form again from the duplicates modal
Then you are navigated to the Tracker Capture
Then you are navigated to the enrollment dashboard page without enrollment

Scenario: New person > Submitting the form shows a list with duplicates
Given you are in the Person registration page
Expand Down Expand Up @@ -171,17 +174,19 @@ Feature: User creates a new entries from the registration page

Scenario: New person in Tracker Program > Submitting the form with unique values navigates you to the user dashboard
Given you are in the WHO RMNCH program registration page
And the data store is clean
When you fill the WHO RMNCH program registration form with its required unique values
And you click the save person submit button
Then you are navigated to the WHO RMNCH program in Tracker Capture app
Then you see the enrollment event Edit page

Scenario: New person in Tracker Program > Submitting the form from the duplicates modal navigates you to the user dashboard
Given you are in the WHO RMNCH program registration page
And the data store is clean
When you fill the WHO RMNCH program registration form with its required values
And you click the save person submit button
And you see the possible duplicates modal
When you submit the form again from the duplicates modal
Then you are navigated to the WHO RMNCH program in Tracker Capture app
Then you see the enrollment event Edit page


Scenario: New person in Tracker Program > Submitting the form shows a list with duplicates
Expand All @@ -201,16 +206,11 @@ Feature: User creates a new entries from the registration page
Then you see validation errors on the WHO RMNCH program registration page

Scenario: Go to enrollment event when Open data entry form after enrollment is checked
Given you open the main page with Ngelehun and Malaria case diagnosis, treatment and investigation context
And you opt in to use the new enrollment Dashboard for Malaria case diagnosis, treatment and investigation
And you see the opt out component for Malaria case diagnosis, treatment and investigation
When you are in the Malaria case diagnosis, treatment and investigation program registration page
Given you are in the Malaria case diagnosis, treatment and investigation program registration page
And the data store is clean
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 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

## New enrollment of existing TEI

Expand Down
4 changes: 0 additions & 4 deletions cypress/e2e/NewPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,6 @@ And('you fill in child programme first name with value that has duplicates', ()
.blur();
});

Then('you are navigated to the WHO RMNCH program in Tracker Capture app', () => {
cy.url().should('include', 'dashboard?tei=');
cy.url().should('include', 'ou=DiszpKrYNg8&program=WSGAb5XwJ3Y');
});

And('you fill the Child programme registration form with a first name with value that has duplicates', () => {
cy.get('[data-test="capture-ui-input"]')
Expand Down
12 changes: 8 additions & 4 deletions cypress/e2e/SearchPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ Feature: User interacts with Search page

Scenario: Searching using unique identifier returns results
Given you are on the default search page
And the data store is clean
When you select the search domain WHO RMNCH Tracker
And you fill in the unique identifier field with values that will return a tracked entity instance
And you click find
Then you are navigated to the Tracker Capture
Then you are navigated to the enrollment dashboard page

# Scenario: Searching using attributes in Tracker Program returns no results
# Given you are on the default search page
Expand Down Expand Up @@ -96,23 +97,25 @@ Feature: User interacts with Search page

Scenario: Searching using attributes in Tracker Program navigates user to the dashboard view
Given you are on the default search page
And the data store is clean
When you select the search domain WHO RMNCH Tracker
And you expand the attributes search area
And you fill in the last name with values that will return results
And you click search
And you can see the first page of the results
And you click the view dashboard button
Then you are navigated to the Tracker Capture
Then you are navigated to the enrollment dashboard page

Scenario: Searching using attributes in TEType navigates user to dashboard view
Given you are on the default search page
And the data store is clean
When you select the search domain Person
And you expand the attributes search area
And you fill in the the form with first name value: Cla
And you click search
And you can see the first page of the results
And you click the view dashboard button
Then you are navigated to the Tracker Capture without program
Then you are navigated to the enrollment dashboard page without enrollment

Scenario: Searching using attributes in Tracker Program domain has disabled pagination
Given you are on the default search page
Expand Down Expand Up @@ -162,9 +165,10 @@ Feature: User interacts with Search page

Scenario: Pressing enter should trigger search unique identifier returns results
Given you are on the default search page
And the data store is clean
When you select the search domain WHO RMNCH Tracker
And you press enter after filling in the unique identifier field with values that will return a tracked entity instance
Then you are navigated to the Tracker Capture
Then you are navigated to the enrollment dashboard page

Scenario: Pressing enter should trigger search attributes returns results
Given you are in the search page with the Child Programme being preselected from the url
Expand Down
13 changes: 0 additions & 13 deletions cypress/e2e/SearchPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,6 @@ When('you fill in the unique identifier field with values that will return a tra
.blur();
});

Then('you are navigated to the Tracker Capture', () => {
cy.url()
.should('include', 'dhis-web-tracker-capture/')
.should('include', 'dashboard?tei=')
.should('include', 'program=WSGAb5XwJ3Y');
});

Then('you are navigated to the Tracker Capture without program', () => {
cy.url()
.should('include', 'dhis-web-tracker-capture/')
.should('include', 'dashboard?tei=')
.should('include', 'tracked_entity_type=nEenWmSyUEp');
});

When('you fill in the first name with values that will return no results', () => {
cy.get('[data-test="form-attributes"]')
Expand Down
17 changes: 13 additions & 4 deletions cypress/e2e/sharedSteps.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,15 @@ Then(/^the user ?(.*) see the following text: (.*)$/, (not, message) =>
cy.contains(message).should(not ? 'not.exist' : 'exist'),
);

And('you navigated to the enrollment dashboard page', () => {
cy.url().should('include', 'enrollment?enrollmentId');
And('you are navigated to the enrollment dashboard page', () => {
cy.url().should('include', 'enrollment?');
cy.url().should('include', 'enrollmentId');
});

And('you navigated to the enrollment dashboard page without enrollment', () => {
cy.url().should('include', 'enrollment?orgUnit');
And('you are navigated to the enrollment dashboard page without enrollment', () => {
cy.url().should('include', 'enrollment?');
cy.url().should('not.include', 'enrollmentId');
cy.url().should('include', 'teiId');
});

Then('you should see no results found', () => {
Expand Down Expand Up @@ -209,3 +212,9 @@ When(/^you opt out to use the new enrollment Dashboard for (.*)$/, (program) =>
Then(/^you see the opt in component for (.*)$/, (program) => {
cy.contains('[data-test="dhis2-uicore-button"]', `Opt in for ${program}`);
});

And('the data store is clean', () => {
cy.buildApiUrl('dataStore/capture/useNewDashboard')
.then(dataStoreUrl =>
cy.request({ method: 'DELETE', url: dataStoreUrl, failOnStatusCode: false }));
});
10 changes: 2 additions & 8 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: 2024-01-22T13:52:51.172Z\n"
"PO-Revision-Date: 2024-01-22T13:52:51.172Z\n"
"POT-Creation-Date: 2024-01-25T12:12:47.253Z\n"
"PO-Revision-Date: 2024-01-25T12:12:47.253Z\n"

msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
Expand Down Expand Up @@ -1092,12 +1092,6 @@ msgstr "New {{trackedEntityName}} in {{programName}}"
msgid "Search for a {{trackedEntityName}} in {{programName}}"
msgstr "Search for a {{trackedEntityName}} in {{programName}}"

msgid "To work with the selected program,"
msgstr "To work with the selected program,"

msgid "open the Tracker Capture app"
msgstr "open the Tracker Capture app"

msgid "Assigned to"
msgstr "Assigned to"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@ export const actionTypes = Object.freeze({
NAVIGATE_TO_ENROLLMENT_OVERVIEW: 'enrollmentNavigation.navigateToEnrollmentOverview',
});

export const navigateToEnrollmentOverview = ({ teiId, programId, orgUnitId, enrollmentId }: NavigateToEnrollmentOverviewProps) =>
export const navigateToEnrollmentOverview = ({
teiId,
programId,
orgUnitId,
enrollmentId,
}: NavigateToEnrollmentOverviewProps) =>
actionCreator(actionTypes.NAVIGATE_TO_ENROLLMENT_OVERVIEW)({ teiId, programId, orgUnitId, enrollmentId });
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ export const navigateToEnrollmentOverviewEpic = (action$: InputObservable, store
switchMap((action) => {
const { teiId, programId, orgUnitId } = action.payload;
const enrollmentId = programId && (action.payload?.enrollmentId || 'AUTO');
const { dataStore, userDataStore, temp } = store.value.useNewDashboard;
const { dataStore, userDataStore } = store.value.useNewDashboard;

if (dataStore || userDataStore) {
const shouldRedirectToEnrollmentDashboard = shouldUseNewDashboard(userDataStore, dataStore, temp, programId);
const shouldRedirectToEnrollmentDashboard = shouldUseNewDashboard({
userDataStore,
dataStore,
programId,
teiId,
});
if (shouldRedirectToEnrollmentDashboard) {
redirectToEnrollmentDashboard({ dependencies, teiId, programId, orgUnitId, enrollmentId });
return EMPTY;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
// @flow
import { ofType } from 'redux-observable';
import { mergeMap, catchError } from 'rxjs/operators';
import { flatMap, catchError } from 'rxjs/operators';
import { EMPTY } from 'rxjs';
import { saveDataStore } from './DataStore.actions';
import { type UseNewDashboard } from './DataStore.types';
import { appStartActionTypes } from '../../../../components/AppStart';
import { programCollection } from '../../metaDataMemoryStores';

const setNewDashboardByDefault = (key: string, dataStoreValues) => {
if (!dataStoreValues) {
return {};
}
const programs = [...programCollection.keys()];
const valuesWithDefault = programs.reduce((acc, program) => {
const dataStoreValue = dataStoreValues[program];
acc[program] = dataStoreValue === undefined ? true : dataStoreValue;
return acc;
}, {});

return { [key]: valuesWithDefault };
};

const getDataStoreFromApi = async querySingleResource =>
querySingleResource({
Expand All @@ -19,21 +34,27 @@ const getUserDataStoreFromApi = async querySingleResource =>
export const fetchDataStoreEpic = (action$: InputObservable, _: ReduxStore, { querySingleResource }: ApiUtils) =>
action$.pipe(
ofType(appStartActionTypes.APP_LOAD_SUCESS),
mergeMap(async () => {
const apiDataStore: UseNewDashboard = await getDataStoreFromApi(querySingleResource);
// $FlowFixMe
return saveDataStore({ dataStore: apiDataStore });
flatMap(async () => {
const apiDataStore: ?UseNewDashboard = await getDataStoreFromApi(querySingleResource)
.catch((error) => {
if (error.details.httpStatusCode === 404) {
return {};
}
return undefined;
});

return saveDataStore(setNewDashboardByDefault('dataStore', apiDataStore));
}),
catchError(() => EMPTY),
);

export const fetchUserDataStoreEpic = (action$: InputObservable, _: ReduxStore, { querySingleResource }: ApiUtils) =>
action$.pipe(
ofType(appStartActionTypes.APP_LOAD_SUCESS),
mergeMap(async () => {
flatMap(async () => {
const apiUserDataStore: UseNewDashboard = await getUserDataStoreFromApi(querySingleResource);
// $FlowFixMe
return saveDataStore({ userDataStore: apiUserDataStore });
return saveDataStore(setNewDashboardByDefault('userDataStore', apiUserDataStore));
}),
catchError(() => EMPTY),
);
Expand Down
Loading

0 comments on commit 5407d7c

Please sign in to comment.