From ab3c5326b66c680c43a12183e02a2a5b1462f646 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 14 Oct 2024 15:50:08 +0200 Subject: [PATCH 1/5] chore: [DHIS2-17915] remove opt-in functionality (#3796) --- .../EnrollmentAddEventPageForm.feature | 1 - .../BreakingTheGlass/BreakingTheGlass.feature | 1 - cypress/e2e/MainPage/MainPage.feature | 9 --- cypress/e2e/NewPage/NewPage.feature | 6 -- cypress/e2e/SearchPage/SearchPage.feature | 4 -- .../step_definitions/common/baseSteps.js | 30 -------- docs/user/using-the-capture-app.md | 14 ---- i18n/en.pot | 48 ------------- .../navigateToEnrollmentOverview.constants.js | 6 -- .../navigateToEnrollmentOverview.epics.js | 54 +++----------- .../components/DataStore/DataStore.actions.js | 6 -- .../components/DataStore/DataStore.epics.js | 61 ---------------- .../components/DataStore/DataStore.types.js | 9 --- .../components/DataStore/index.js | 1 - .../OptInOut/OptIn/OptIn.component.js | 71 ------------------- .../OptInOut/OptIn/OptIn.container.js | 57 --------------- .../components/OptInOut/OptIn/index.js | 2 - .../components/OptInOut/OptIn/optIn.types.js | 12 ---- .../OptInOut/OptOut/OptOut.component.js | 44 ------------ .../OptInOut/OptOut/OptOut.container.js | 36 ---------- .../components/OptInOut/OptOut/index.js | 2 - .../OptInOut/OptOut/optOut.types.js | 12 ---- .../capture-core/components/OptInOut/index.js | 3 - .../WorkingListsType.component.js | 3 - .../RegistrationDataEntry.epics.js | 6 +- .../getStageWithOpenAfterEnrollment.js | 3 +- .../ConnectedEntity/TrackedEntityInstance.js | 39 +++------- .../useNewDashboard.reducerDescription.js | 17 ----- .../capture-core/utils/routing/index.js | 1 - .../utils/routing/newDashboard.js | 16 ----- src/epics/trackerCapture.epics.js | 7 -- .../trackerCapture.reducerDescriptions.js | 2 - 32 files changed, 19 insertions(+), 564 deletions(-) delete mode 100644 src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.constants.js delete mode 100644 src/core_modules/capture-core/components/DataStore/DataStore.actions.js delete mode 100644 src/core_modules/capture-core/components/DataStore/DataStore.epics.js delete mode 100644 src/core_modules/capture-core/components/DataStore/DataStore.types.js delete mode 100644 src/core_modules/capture-core/components/DataStore/index.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.component.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.container.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptIn/index.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptIn/optIn.types.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.component.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.container.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptOut/index.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/OptOut/optOut.types.js delete mode 100644 src/core_modules/capture-core/components/OptInOut/index.js delete mode 100644 src/core_modules/capture-core/reducers/descriptions/useNewDashboard.reducerDescription.js delete mode 100644 src/core_modules/capture-core/utils/routing/newDashboard.js diff --git a/cypress/e2e/EnrollmentAddEventPage/EnrollmentAddEventPageForm/EnrollmentAddEventPageForm.feature b/cypress/e2e/EnrollmentAddEventPage/EnrollmentAddEventPageForm/EnrollmentAddEventPageForm.feature index 47bacdbe8a..869b837615 100644 --- a/cypress/e2e/EnrollmentAddEventPage/EnrollmentAddEventPageForm/EnrollmentAddEventPageForm.feature +++ b/cypress/e2e/EnrollmentAddEventPage/EnrollmentAddEventPageForm/EnrollmentAddEventPageForm.feature @@ -50,7 +50,6 @@ Feature: User interacts with the Enrollment New Event Workspace Scenario: User should be asked to create new event after completing a stage and choose to cancel 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 diff --git a/cypress/e2e/EnrollmentPage/BreakingTheGlass/BreakingTheGlass.feature b/cypress/e2e/EnrollmentPage/BreakingTheGlass/BreakingTheGlass.feature index 8f20612a24..40ed7aac7c 100644 --- a/cypress/e2e/EnrollmentPage/BreakingTheGlass/BreakingTheGlass.feature +++ b/cypress/e2e/EnrollmentPage/BreakingTheGlass/BreakingTheGlass.feature @@ -4,7 +4,6 @@ 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 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 diff --git a/cypress/e2e/MainPage/MainPage.feature b/cypress/e2e/MainPage/MainPage.feature index cb10b479fb..8f29db3697 100644 --- a/cypress/e2e/MainPage/MainPage.feature +++ b/cypress/e2e/MainPage/MainPage.feature @@ -35,15 +35,6 @@ 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 optout from using the new Enrollment Dashboard - Given you open the main page with Ngelehun and child programme context - 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 Given you are in the main page with no selections made diff --git a/cypress/e2e/NewPage/NewPage.feature b/cypress/e2e/NewPage/NewPage.feature index b6a7907dee..29b5ffc199 100644 --- a/cypress/e2e/NewPage/NewPage.feature +++ b/cypress/e2e/NewPage/NewPage.feature @@ -7,7 +7,6 @@ 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 @@ -103,14 +102,12 @@ 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 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 @@ -152,7 +149,6 @@ 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 see the enrollment event Edit page @@ -166,7 +162,6 @@ Feature: User creates a new entries from the registration 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 @@ -192,7 +187,6 @@ Feature: User creates a new entries from the registration page Scenario: Go to enrollment event when Open data entry form after enrollment is checked 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 diff --git a/cypress/e2e/SearchPage/SearchPage.feature b/cypress/e2e/SearchPage/SearchPage.feature index b1a2a58741..afc2f9e035 100644 --- a/cypress/e2e/SearchPage/SearchPage.feature +++ b/cypress/e2e/SearchPage/SearchPage.feature @@ -24,7 +24,6 @@ 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 @@ -97,7 +96,6 @@ 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 @@ -108,7 +106,6 @@ Feature: User interacts with Search 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 @@ -165,7 +162,6 @@ 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 enrollment dashboard page diff --git a/cypress/support/step_definitions/common/baseSteps.js b/cypress/support/step_definitions/common/baseSteps.js index 42c19ad164..a4db6e4a30 100644 --- a/cypress/support/step_definitions/common/baseSteps.js +++ b/cypress/support/step_definitions/common/baseSteps.js @@ -181,33 +181,3 @@ When(/^the user selects the org unit (.*)$/, (orgUnit) => { cy.contains(orgUnit) .click(); }); - -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="dhis2-uicore-button"]').length > 0) { - cy.contains('[data-test="dhis2-uicore-button"]', `Opt in for ${program}`).click(); - cy.contains('[data-test="opt-in-button"]', 'Yes, opt in').click(); - cy.contains('[data-test="opt-out-button"]', `Opt out for ${program}`); - } - }); -}); - -Then(/^you see the opt out component for (.*)$/, (program) => { - cy.contains('[data-test="opt-out-button"]', `Opt out for ${program}`); -}); - -When(/^you opt out to use the new enrollment Dashboard for (.*)$/, (program) => { - cy.intercept('PUT', '**/dataStore/capture/useNewDashboard').as('optOutEnrollmentDashboard'); - cy.contains('[data-test="opt-out-button"]', `Opt out for ${program}`).click(); - cy.wait('@optOutEnrollmentDashboard', { timeout: 30000 }); -}); - -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 })); -}); diff --git a/docs/user/using-the-capture-app.md b/docs/user/using-the-capture-app.md index 651e9f7eb0..fab4c41175 100644 --- a/docs/user/using-the-capture-app.md +++ b/docs/user/using-the-capture-app.md @@ -821,20 +821,6 @@ For performance reasons the Capture app caches metadata in the client browser. W ## Enrollment dashboard -### Enabling the enrollment dashboard - -#### Opt in - -Enable the enrollment dashboard for a Tracker program for all the users. The dialog is visible for users with program write access. - -![](resources/images/enrollment-dash-opt-in.png) - -#### Opt out - -Disable the enrollment dashboard for a Tracker program for all the users. - -![](resources/images/enrollment-dash-opt-out.png) - ### Reaching the enrollment dashboard via url You reach the enrollment dashboard either by typing in the address bar of your browser or using the user interface of the capture app. diff --git a/i18n/en.pot b/i18n/en.pot index d299bcedcf..c098e29ad6 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -616,54 +616,6 @@ msgstr "Notice" msgid "Close the notice" msgstr "Close the notice" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "Use new Enrollment dashboard for {{programName}}" - -msgid "Opt in for {{programName}}" -msgstr "Opt in for {{programName}}" - -msgid "" -"By clicking opt-in below, you will start using the new enrollment dashboard " -"in the Capture app for this Tracker program. At the moment, there is " -"certain functionality from Tracker Capture that has not yet been added, " -"including relationship and referral functionality. The work on including " -"this Tracker functionality in Capture is ongoing and will be added in " -"upcoming app releases." -msgstr "" -"By clicking opt-in below, you will start using the new enrollment dashboard " -"in the Capture app for this Tracker program. At the moment, there is " -"certain functionality from Tracker Capture that has not yet been added, " -"including relationship and referral functionality. The work on including " -"this Tracker functionality in Capture is ongoing and will be added in " -"upcoming app releases." - -msgid "" -"The core team appreciates any feedback on this new functionality which is " -"currently being beta tested, please report any issues and feedback in the " -"DHIS2 JIRA project." -msgstr "" -"The core team appreciates any feedback on this new functionality which is " -"currently being beta tested, please report any issues and feedback in the " -"DHIS2 JIRA project." - -msgid "" -"Click the button below to opt-in to the new enrollment dashboard " -"functionality in the Capture app (beta) for this Tracker program for all " -"users." -msgstr "" -"Click the button below to opt-in to the new enrollment dashboard " -"functionality in the Capture app (beta) for this Tracker program for all " -"users." - -msgid "Yes, opt in" -msgstr "Yes, opt in" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "Stop using new Enrollment dashboard for {{programName}}" - -msgid "Opt out for {{programName}}" -msgstr "Opt out for {{programName}}" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "Enrollment with id \"{{enrollmentId}}\" does not exist" diff --git a/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.constants.js b/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.constants.js deleted file mode 100644 index 435c2824ac..0000000000 --- a/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.constants.js +++ /dev/null @@ -1,6 +0,0 @@ -// @flow - -export const scopeHierarchyTypes = { - PROGRAM: 'PROGRAM', - TRACKED_ENTITY_TYPE: 'TRACKED_ENTITY_TYPE', -}; diff --git a/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.epics.js b/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.epics.js index 32f7d066e2..8b413b70a4 100644 --- a/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.epics.js +++ b/src/core_modules/capture-core/actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.epics.js @@ -4,58 +4,22 @@ import { ofType } from 'redux-observable'; import { switchMap } from 'rxjs/operators'; import { EMPTY } from 'rxjs'; import { actionTypes as NavigateToEnrollmentOverviewActionTypes } from './navigateToEnrollmentOverview.actions'; -import { buildUrlQueryString, getLocationQuery, shouldUseNewDashboard } from '../../utils/routing'; -import { scopeHierarchyTypes } from './navigateToEnrollmentOverview.constants'; +import { buildUrlQueryString } from '../../utils/routing'; -// TODO This will be removed when the link between capture and tracker capture is not relevant -const redirectToTracker = ({ teiId, orgUnitId, dependencies }) => { - const baseUrl = dependencies.absoluteApiPath; - const { search, pathname } = dependencies.history.location; - const { programId: queryProgramId, trackedEntityTypeId: queryTrackedEntityTypeId } = getLocationQuery(); - - const instanceBaseUrl = baseUrl.split('/api')[0]; - const scopeHierarchy = queryProgramId ? scopeHierarchyTypes.PROGRAM : scopeHierarchyTypes.TRACKED_ENTITY_TYPE; - const selectedScopeId = queryTrackedEntityTypeId || queryProgramId; - const scopeSearchParam = `${scopeHierarchy.toLowerCase()}=${selectedScopeId}`; - const base64Url = btoa(`/dhis-web-capture/#${pathname}${search}`); - setTimeout(() => { - window.location.href = `${instanceBaseUrl}/dhis-web-tracker-capture/#/dashboard?tei=${teiId}&ou=${orgUnitId}&${scopeSearchParam}&returnUrl=${base64Url}`; - }, 50); -}; - -const redirectToEnrollmentDashboard = ({ dependencies, teiId, programId, orgUnitId, enrollmentId }) => { - dependencies.history.push( - `/enrollment?${buildUrlQueryString({ - teiId, - programId, - orgUnitId, - enrollmentId, - })}`, - ); -}; - -export const navigateToEnrollmentOverviewEpic = (action$: InputObservable, store: ReduxStore, dependencies: any) => +export const navigateToEnrollmentOverviewEpic = (action$: InputObservable, store: ReduxStore, { history }: ApiUtils) => action$.pipe( ofType(NavigateToEnrollmentOverviewActionTypes.NAVIGATE_TO_ENROLLMENT_OVERVIEW), switchMap((action) => { const { teiId, programId, orgUnitId } = action.payload; const enrollmentId = programId && (action.payload?.enrollmentId || 'AUTO'); - const { dataStore, userDataStore } = store.value.useNewDashboard; - - if (dataStore || userDataStore) { - const shouldRedirectToEnrollmentDashboard = shouldUseNewDashboard({ - userDataStore, - dataStore, - programId, + history.push( + `/enrollment?${buildUrlQueryString({ teiId, - }); - if (shouldRedirectToEnrollmentDashboard) { - redirectToEnrollmentDashboard({ dependencies, teiId, programId, orgUnitId, enrollmentId }); - return EMPTY; - } - } - - redirectToTracker({ dependencies, store, teiId, orgUnitId }); + programId, + orgUnitId, + enrollmentId, + })}`, + ); return EMPTY; }), ); diff --git a/src/core_modules/capture-core/components/DataStore/DataStore.actions.js b/src/core_modules/capture-core/components/DataStore/DataStore.actions.js deleted file mode 100644 index a06c83561d..0000000000 --- a/src/core_modules/capture-core/components/DataStore/DataStore.actions.js +++ /dev/null @@ -1,6 +0,0 @@ -// @flow -import { actionCreator } from '../../actions/actions.utils'; -import { type UseNewDashboard, actionTypes as dataStoreActionTypes } from './DataStore.types'; - -export const saveDataStore = ({ dataStore, userDataStore }: UseNewDashboard) => - actionCreator(dataStoreActionTypes.SAVE_DATA_STORE)({ dataStore, userDataStore }); diff --git a/src/core_modules/capture-core/components/DataStore/DataStore.epics.js b/src/core_modules/capture-core/components/DataStore/DataStore.epics.js deleted file mode 100644 index 71c1cee90c..0000000000 --- a/src/core_modules/capture-core/components/DataStore/DataStore.epics.js +++ /dev/null @@ -1,61 +0,0 @@ -// @flow -import { ofType } from 'redux-observable'; -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({ - resource: 'dataStore/capture/useNewDashboard', - }); - -const getUserDataStoreFromApi = async querySingleResource => - querySingleResource({ - resource: 'userDataStore/capture/useNewDashboard', - }); - -export const fetchDataStoreEpic = (action$: InputObservable, _: ReduxStore, { querySingleResource }: ApiUtils) => - action$.pipe( - ofType(appStartActionTypes.APP_LOAD_SUCESS), - 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), - flatMap(async () => { - const apiUserDataStore: UseNewDashboard = await getUserDataStoreFromApi(querySingleResource); - // $FlowFixMe - return saveDataStore(setNewDashboardByDefault('userDataStore', apiUserDataStore)); - }), - catchError(() => EMPTY), - ); - diff --git a/src/core_modules/capture-core/components/DataStore/DataStore.types.js b/src/core_modules/capture-core/components/DataStore/DataStore.types.js deleted file mode 100644 index ffa2641abb..0000000000 --- a/src/core_modules/capture-core/components/DataStore/DataStore.types.js +++ /dev/null @@ -1,9 +0,0 @@ -// @flow - -export const actionTypes = { - SAVE_DATA_STORE: 'useNewDashboard.SaveDataStore', -}; - -export type UseNewDashboard = {| - [key: string]: string, -|} diff --git a/src/core_modules/capture-core/components/DataStore/index.js b/src/core_modules/capture-core/components/DataStore/index.js deleted file mode 100644 index e6359f21f1..0000000000 --- a/src/core_modules/capture-core/components/DataStore/index.js +++ /dev/null @@ -1 +0,0 @@ -export { saveDataStore } from './DataStore.actions'; diff --git a/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.component.js b/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.component.js deleted file mode 100644 index 81a541bf82..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.component.js +++ /dev/null @@ -1,71 +0,0 @@ -// @flow -import React, { useState, type ComponentType } from 'react'; -import { NoticeBox, Button, Modal, ModalTitle, ModalContent, ModalActions, ButtonStrip } from '@dhis2/ui'; -import i18n from '@dhis2/d2-i18n'; -import { withStyles } from '@material-ui/core'; -import type { PlainProps } from './optIn.types'; - -const styles = { - container: { - width: '80%', - margin: '0 auto', - }, -}; - -export const OptInPlain = ({ classes, programName, handleOptIn, loading }: PlainProps) => { - const [toggle, setToggle] = useState(false); - - const title = i18n.t('Use new Enrollment dashboard for {{programName}}', { - programName, - interpolation: { escapeValue: false }, - }); - const button = i18n.t('Opt in for {{programName}}', { - programName, - interpolation: { escapeValue: false }, - }); - - const modalContent = i18n.t('By clicking opt-in below, you will start using the new enrollment dashboard in the Capture app for this Tracker program. At the moment, there is certain functionality from Tracker Capture that has not yet been added, including relationship and referral functionality. The work on including this Tracker functionality in Capture is ongoing and will be added in upcoming app releases.'); - - const modalContentFeedback = i18n.t('The core team appreciates any feedback on this new functionality which is currently being beta tested, please report any issues and feedback in the DHIS2 JIRA project.'); - - return ( -
- -

- {i18n.t('Click the button below to opt-in to the new enrollment dashboard functionality in the Capture app (beta) for this Tracker program for all users.')} -

- -
-
- {toggle && ( - setToggle(false)} dataTest="opt-in-modal"> - {title} - -

{modalContent}

-

{modalContentFeedback}

-
- - - - - - -
- )} -
- ); -}; - -export const OptIn: ComponentType<$Diff> = withStyles(styles)(OptInPlain); diff --git a/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.container.js b/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.container.js deleted file mode 100644 index 7bea988d28..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptIn/OptIn.container.js +++ /dev/null @@ -1,57 +0,0 @@ -// @flow -import React, { useCallback } from 'react'; -import { useDataMutation } from '@dhis2/app-runtime'; -import { useSelector, useDispatch } from 'react-redux'; -import { OptIn as OptInComponent } from './OptIn.component'; -import type { Props } from './optIn.types'; -import { useTrackerProgram } from '../../../hooks/useTrackerProgram'; -import { saveDataStore } from '../../DataStore'; - -const dataStoreUpdate = { - resource: 'dataStore/capture/useNewDashboard', - type: 'update', - data: ({ data }) => data, -}; - -const dataStoreCreate = { - resource: 'dataStore/capture/useNewDashboard', - type: 'create', - data: ({ data }) => data, -}; - -export const OptIn = ({ programId }: Props) => { - const dispatch = useDispatch(); - const program = useTrackerProgram(programId); - const newDashboard = useSelector(({ useNewDashboard }) => useNewDashboard); - const { dataStore } = newDashboard; - const showOptIn = program?.access?.write && !dataStore?.[programId]; - - const [updateMutation, { loading: loadingUpdate }] = useDataMutation(dataStoreUpdate, { - onComplete: () => { - dispatch(saveDataStore({ dataStore: { ...dataStore, [programId]: true } })); - }, - }); - const [createMutation, { loading: loadingCreate }] = useDataMutation(dataStoreCreate, { - onComplete: () => { - dispatch(saveDataStore({ dataStore: { ...dataStore, [programId]: true } })); - }, - }); - - const handleOptIn = useCallback(() => { - if (dataStore) { - const data = { ...dataStore, [programId]: true }; - updateMutation({ data }); - } else { - const data = { [programId]: true }; - createMutation({ data }); - } - }, [programId, updateMutation, createMutation, dataStore]); - - return showOptIn ? ( - - ) : null; -}; diff --git a/src/core_modules/capture-core/components/OptInOut/OptIn/index.js b/src/core_modules/capture-core/components/OptInOut/OptIn/index.js deleted file mode 100644 index 3d26d28715..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptIn/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// @flow -export { OptIn } from './OptIn.container'; diff --git a/src/core_modules/capture-core/components/OptInOut/OptIn/optIn.types.js b/src/core_modules/capture-core/components/OptInOut/OptIn/optIn.types.js deleted file mode 100644 index e105d399ce..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptIn/optIn.types.js +++ /dev/null @@ -1,12 +0,0 @@ -// @flow - -export type Props = {| - programId: string, -|}; - -export type PlainProps = {| - handleOptIn: () => void, - programName: string, - loading: boolean, - ...CssClasses -|}; diff --git a/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.component.js b/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.component.js deleted file mode 100644 index 3639694228..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.component.js +++ /dev/null @@ -1,44 +0,0 @@ -// @flow -import React, { type ComponentType } from 'react'; -import { NoticeBox, Button } from '@dhis2/ui'; -import i18n from '@dhis2/d2-i18n'; -import { withStyles } from '@material-ui/core'; -import type { PlainProps } from './optOut.types'; - -const styles = { - container: { - width: '80%', - margin: '0 auto', - }, -}; - -export const OptOutPlain = ({ classes, programName, handleOptOut, loading }: PlainProps) => { - const title = i18n.t('Stop using new Enrollment dashboard for {{programName}}', { - programName, - interpolation: { escapeValue: false }, - }); - const button = i18n.t('Opt out for {{programName}}', { - programName, - interpolation: { escapeValue: false }, - }); - - return ( -
-
- -

- {i18n.t( - 'This program uses the new enrollment dashboard functionality ' + - 'in the Capture app (beta). Click this button to opt-out and direct ' + - 'all users to the Tracker capture app for this program.', - )} -

- -
-
- ); -}; - -export const OptOut: ComponentType<$Diff> = withStyles(styles)(OptOutPlain); diff --git a/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.container.js b/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.container.js deleted file mode 100644 index c9ba767866..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptOut/OptOut.container.js +++ /dev/null @@ -1,36 +0,0 @@ -// @flow -import React, { useCallback } from 'react'; -import { useDataMutation } from '@dhis2/app-runtime'; -import { useSelector, useDispatch } from 'react-redux'; -import { OptOut as OptOutComponent } from './OptOut.component'; -import type { Props } from './optOut.types'; -import { useTrackerProgram } from '../../../hooks/useTrackerProgram'; -import { saveDataStore } from '../../DataStore'; - -const dataStoreUpdate = { - resource: 'dataStore/capture/useNewDashboard', - type: 'update', - data: ({ data }) => data, -}; - -export const OptOut = ({ programId }: Props) => { - const dispatch = useDispatch(); - const program = useTrackerProgram(programId); - const newDashboard = useSelector(({ useNewDashboard }) => useNewDashboard); - const { dataStore } = newDashboard; - - const [updateMutation, { loading: loadingUpdate }] = useDataMutation(dataStoreUpdate, { - onComplete: () => { - dispatch(saveDataStore({ dataStore: { ...dataStore, [programId]: false } })); - }, - }); - const handleOptOut = useCallback(() => { - const data = { ...dataStore, [programId]: false }; - updateMutation({ data }); - }, [programId, updateMutation, dataStore]); - const showOptOut = program?.access?.write && dataStore?.[programId]; - - return showOptOut ? ( - - ) : null; -}; diff --git a/src/core_modules/capture-core/components/OptInOut/OptOut/index.js b/src/core_modules/capture-core/components/OptInOut/OptOut/index.js deleted file mode 100644 index b89207bf49..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptOut/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// @flow -export { OptOut } from './OptOut.container'; diff --git a/src/core_modules/capture-core/components/OptInOut/OptOut/optOut.types.js b/src/core_modules/capture-core/components/OptInOut/OptOut/optOut.types.js deleted file mode 100644 index 3f4a4c244e..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/OptOut/optOut.types.js +++ /dev/null @@ -1,12 +0,0 @@ -// @flow - -export type Props = {| - programId: string, -|}; - -export type PlainProps = {| - handleOptOut: () => void, - programName: string, - loading: boolean, - ...CssClasses, -|}; diff --git a/src/core_modules/capture-core/components/OptInOut/index.js b/src/core_modules/capture-core/components/OptInOut/index.js deleted file mode 100644 index cc2949649c..0000000000 --- a/src/core_modules/capture-core/components/OptInOut/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// @flow -export { OptIn } from './OptIn'; -export { OptOut } from './OptOut'; diff --git a/src/core_modules/capture-core/components/Pages/MainPage/WorkingListsType/WorkingListsType.component.js b/src/core_modules/capture-core/components/Pages/MainPage/WorkingListsType/WorkingListsType.component.js index dea90e1485..732f0d07d5 100644 --- a/src/core_modules/capture-core/components/Pages/MainPage/WorkingListsType/WorkingListsType.component.js +++ b/src/core_modules/capture-core/components/Pages/MainPage/WorkingListsType/WorkingListsType.component.js @@ -3,7 +3,6 @@ import React from 'react'; import { useProgramInfo, programTypes } from '../../../../hooks/useProgramInfo'; import { EventWorkingListsInit } from '../EventWorkingListsInit'; import { TeiWorkingLists } from '../../../WorkingLists/TeiWorkingLists'; -import { OptIn, OptOut } from '../../../OptInOut'; import type { Props } from './workingListsType.types'; export const WorkingListsType = ({ programId, orgUnitId, selectedTemplateId, onChangeTemplate }: Props) => { @@ -15,14 +14,12 @@ export const WorkingListsType = ({ programId, orgUnitId, selectedTemplateId, onC if (programType === programTypes.TRACKER_PROGRAM) { return ( <> - - ); } diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js index d14df1119e..4ee21bd46c 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js @@ -12,7 +12,7 @@ import { getTrackerProgramThrowIfNotFound } from '../../../../metaData'; import { navigateToEnrollmentOverview, } from '../../../../actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.actions'; -import { buildUrlQueryString, shouldUseNewDashboard } from '../../../../utils/routing'; +import { buildUrlQueryString } from '../../../../utils/routing'; import { getStageWithOpenAfterEnrollment, PAGES, @@ -54,15 +54,11 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_START), map((action) => { const { currentSelections: { programId } } = store.value; - const { dataStore, userDataStore } = store.value.useNewDashboard; const { enrollmentPayload, uid } = action.payload; const { stages, useFirstStageDuringRegistration } = getTrackerProgramThrowIfNotFound(programId); - - const shouldRedirect = shouldUseNewDashboard({ userDataStore, dataStore, programId }); const { stageWithOpenAfterEnrollment, redirectTo } = getStageWithOpenAfterEnrollment( stages, useFirstStageDuringRegistration, - shouldRedirect, ); const eventIndex = enrollmentPayload.enrollments[0]?.events.findIndex( diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js index 23d9d1a610..3688d29b4c 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js @@ -13,13 +13,12 @@ export const PAGES = { export const getStageWithOpenAfterEnrollment = ( stages: Map, useFirstStageDuringRegistration: boolean, - shouldRedirect: boolean, ) => { const stagesArray = [...stages.values()]; const [firstStageWithOpenAfterEnrollment] = stagesArray.filter(({ openAfterEnrollment }) => openAfterEnrollment); const redirectTo = (() => { - if (shouldRedirect && firstStageWithOpenAfterEnrollment) { + if (firstStageWithOpenAfterEnrollment) { // event will be created during first stage registration if ( useFirstStageDuringRegistration diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RelationshipsSection/ConnectedEntity/TrackedEntityInstance.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RelationshipsSection/ConnectedEntity/TrackedEntityInstance.js index e02de9b1e9..16f0197068 100644 --- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RelationshipsSection/ConnectedEntity/TrackedEntityInstance.js +++ b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RelationshipsSection/ConnectedEntity/TrackedEntityInstance.js @@ -1,10 +1,6 @@ // @flow import React, { useCallback } from 'react'; -import { useConfig } from '@dhis2/app-runtime'; -import { useSelector } from 'react-redux'; -import { buildUrl } from 'capture-core-utils'; -import { systemSettingsStore } from '../../../../../../metaDataMemoryStores'; -import { buildUrlQueryString, shouldUseNewDashboard } from '../../../../../../utils/routing'; +import { buildUrlQueryString } from '../../../../../../utils/routing'; type Props = { name: string, @@ -14,39 +10,20 @@ type Props = { }; export const TrackedEntityInstance = ({ name, id, orgUnitId, linkProgramId }: Props) => { - const { baseUrl } = useConfig(); - const { dataStore, userDataStore } = useSelector(({ useNewDashboard }) => useNewDashboard); - - const getUrl = useCallback(() => { - if (shouldUseNewDashboard({ userDataStore, dataStore, programId: linkProgramId, teiId: id })) { - return `/#/enrollment?${buildUrlQueryString({ + const getUrl = useCallback( + () => + `/#/enrollment?${buildUrlQueryString({ teiId: id, programId: linkProgramId, orgUnitId, enrollmentId: 'AUTO', - })}`; - } - const trackerBaseUrl = buildUrl(baseUrl, systemSettingsStore.get().trackerAppRelativePath, '/#/dashboard?'); - const baseParams = `tei=${id}&ou=${orgUnitId}`; - const params = linkProgramId ? `${baseParams}&program=${linkProgramId}` : baseParams; - return trackerBaseUrl + params; - }, [ - baseUrl, - id, - orgUnitId, - linkProgramId, - dataStore, - userDataStore, - ]); + })}`, + [id, orgUnitId, linkProgramId], + ); return ( - + {name} ); }; - diff --git a/src/core_modules/capture-core/reducers/descriptions/useNewDashboard.reducerDescription.js b/src/core_modules/capture-core/reducers/descriptions/useNewDashboard.reducerDescription.js deleted file mode 100644 index a2bd768063..0000000000 --- a/src/core_modules/capture-core/reducers/descriptions/useNewDashboard.reducerDescription.js +++ /dev/null @@ -1,17 +0,0 @@ -// @flow -import { createReducerDescription } from '../../trackerRedux/trackerReducer'; -import { actionTypes as dataStoreActionTypes } from '../../components/DataStore/DataStore.types'; - -export const useNewDashboardDesc = createReducerDescription({ - [dataStoreActionTypes.SAVE_DATA_STORE]: (state, action) => { - const newState = { ...state }; - const { dataStore, userDataStore } = action.payload; - newState.dataStore = dataStore; - newState.userDataStore = userDataStore; - - return newState; - }, -}, 'useNewDashboard', { - dataStore: undefined, - userDataStore: undefined, -}); diff --git a/src/core_modules/capture-core/utils/routing/index.js b/src/core_modules/capture-core/utils/routing/index.js index 3b533bc3cd..3131c7c491 100644 --- a/src/core_modules/capture-core/utils/routing/index.js +++ b/src/core_modules/capture-core/utils/routing/index.js @@ -2,4 +2,3 @@ export { useLocationQuery } from './useLocationQuery'; export { getLocationQuery } from './getLocationQuery'; export { buildUrlQueryString } from './buildUrlQueryString'; -export { shouldUseNewDashboard } from './newDashboard'; diff --git a/src/core_modules/capture-core/utils/routing/newDashboard.js b/src/core_modules/capture-core/utils/routing/newDashboard.js deleted file mode 100644 index c81265f93e..0000000000 --- a/src/core_modules/capture-core/utils/routing/newDashboard.js +++ /dev/null @@ -1,16 +0,0 @@ -// @flow - -export const shouldUseNewDashboard = ({ - userDataStore, - dataStore, - programId, - teiId, -}: { - userDataStore: any, - dataStore: any, - programId: ?string, - teiId?: ?string, -}): boolean => - Boolean(!programId && teiId) || // Check for when a TEI is created/searched without being enrolled in any program. In this case the URL has the enrollmentId set to 'AUTO'. - userDataStore?.[programId] || - (userDataStore?.[programId] !== false && dataStore?.[programId]); diff --git a/src/epics/trackerCapture.epics.js b/src/epics/trackerCapture.epics.js index f0bdf3bc7e..48836ddc46 100644 --- a/src/epics/trackerCapture.epics.js +++ b/src/epics/trackerCapture.epics.js @@ -35,11 +35,6 @@ import { deleteTemplateEpic, } from 'capture-core/components/WorkingLists/EventWorkingLists'; -import { - fetchDataStoreEpic, - fetchUserDataStoreEpic, -} from 'capture-core/components/DataStore/DataStore.epics'; - import { getEventFromUrlEpic, } from 'capture-core/components/Pages/ViewEvent/epics/editEvent.epics'; @@ -245,8 +240,6 @@ export const epics = combineEpics( resetProgramAfterSettingOrgUnitIfApplicableEpic, calculateSelectionsCompletenessEpic, triggerLoadCoreEpic, - fetchDataStoreEpic, - fetchUserDataStoreEpic, loadAppEpic, initEventListEpic, initTeiViewEpic, diff --git a/src/reducers/descriptions/trackerCapture.reducerDescriptions.js b/src/reducers/descriptions/trackerCapture.reducerDescriptions.js index 6f6ad63d84..ac35a29082 100644 --- a/src/reducers/descriptions/trackerCapture.reducerDescriptions.js +++ b/src/reducers/descriptions/trackerCapture.reducerDescriptions.js @@ -40,7 +40,6 @@ import { workingListsListRecordsDesc, } from 'capture-core/reducers/descriptions/workingLists'; import { mainPageDesc } from 'capture-core/reducers/descriptions/mainPage.reducerDescription'; -import { useNewDashboardDesc } from 'capture-core/reducers/descriptions/useNewDashboard.reducerDescription'; import { newEventPageDesc } from 'capture-core/reducers/descriptions/newEvent.reducerDescription'; import { editEventPageDesc } from 'capture-core/reducers/descriptions/editEvent.reducerDescription'; import { viewEventPageDesc } from 'capture-core/reducers/descriptions/viewEvent.reducerDescription'; @@ -129,7 +128,6 @@ export const reducerDescriptions = [ searchDomainDesc, teiSearchDesc, trackedEntityInstanceDesc, - useNewDashboardDesc, viewEventPageDesc, workingListsDesc, workingListsMetaDesc, From 599b2c1e29c94fd0258844aadb7eef20e03024eb Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Mon, 14 Oct 2024 15:54:46 +0200 Subject: [PATCH 2/5] fix: [DHIS2-18215] selected working list not persisted on navigate (#3838) * fix: persist working list on navigate * fix: allow navigate back despite displayFrontPageList * chore: review --- .../TeiWorkingListsUser.feature | 619 +++++++++--------- .../TeiWorkingListsUser.js | 21 +- i18n/en.pot | 7 +- .../Pages/MainPage/MainPage.container.js | 25 +- 4 files changed, 358 insertions(+), 314 deletions(-) diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature index 3bf9fbfaf8..db142862ee 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature @@ -8,311 +8,316 @@ Feature: User interacts with tei working lists When you change the sharing settings Then you see the new sharing settings -Scenario: User opens the default working list for a tracker program -Given you open the main page with Ngelehun and child programe context -Then the default working list should be displayed -And rows per page should be set to 15 -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show only teis with completed enrollments using the predefined working list -Given you open the main page with Ngelehun and child programe context -When you select the working list called completed enrollments -Then the enrollment status filter button should show that the completed filter is in effect -And the list should display teis with a completed enrollment -And rows per page should be set to 15 -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show only teis with completed enrollments using the filter -Given you open the main page with Ngelehun and child programe context -When you set the enrollment status filter to completed -And you apply the current filter -Then the enrollment status filter button should show that the completed filter is in effect -And the list should display teis with a completed enrollment -And rows per page should be set to 15 -And for a tracker program the page navigation should show that you are on the first page - -# DHIS2-13960: /trackedEntities filter by assignee results are not consistent -@skip -Scenario: Show only teis with active enrollments and unassinged events using the filter -Given you open the main page with Ngelehun and Malaria focus investigation context -When you set the enrollment status filter to active -And you apply the current filter -And you set the assginee filter to None -And you apply the current filter -Then the enrollment status filter button should show that the active filter is in effect -And the assignee filter button should show that None filter is in effect -And the list should display teis with an active enrollment and unassinged events -And rows per page should be set to 15 -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show only teis with first name containig John using the filter -Given you open the main page with Ngelehun and child programe context -When you set the first name filter to John -And you apply the current filter -Then the first name filter button should show that the filter is in effect -And the list should display teis with John as the first name -And rows per page should be set to 15 -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show the registering unit column -Given you open the main page with Ngelehun and child programe context -When you open the column selector -And you select the organisation unit and save from the column selector -Then the organisation unit should display in the list - -Scenario: Show next page -Given you open the main page with Ngelehun and child programe context -When you click the next page button -Then the list should display data for the second page -And the pagination for the tei working list should show the second page - -Scenario: Show next page then previous page -Given you open the main page with Ngelehun and child programe context -When you click the next page button -Then the list should display data for the second page -And the pagination for the tei working list should show the second page -When you click the previous page button -Then the default working list should be displayed -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show next page then first page -Given you open the main page with Ngelehun and child programe context -When you click the next page button -Then the list should display data for the second page -And the pagination for the tei working list should show the second page -When you click the first page button -Then the default working list should be displayed -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show 10 rows per page -Given you open the main page with Ngelehun and child programe context -When you change rows per page to 10 -Then the list should display 10 rows of data -And for a tracker program the page navigation should show that you are on the first page - -Scenario: Show teis ordered ascendingly by first name -Given you open the main page with Ngelehun and child programe context -When you click the first name column header -Then the sort arrow should indicate ascending order -And the list should display data ordered ascendingly by first name -And for a tracker program the page navigation should show that you are on the first page - -Scenario: The TEI custom working lists is loaded -Given you open the main page with Ngelehun and Malaria focus investigation context -Then you see the custom TEI working lists -And you can load the view with the name Events assigned to me - - - -Scenario: The user creates, updates and deletes a TEI custom working list -Given you open the main page with Ngelehun and Malaria case diagnosis context -And you set the enrollment status filter to completed -And you apply the current filter -And you set the enrollment date to a relative range -And you apply the current filter -When you save the list with the name My custom list -Then the new My custom list is created -And the enrollment status filter button should show that the completed filter is in effect -When you set the enrollment status filter to active -And you apply the current filter -When you update the list with the name My custom list -Then the enrollment status filter button should show that the active filter is in effect -And you delete the name My custom list -Then the My custom list is deleted - -Scenario: The user can delete a TEI working list right immediately after creating it. -Given you open the main page with Ngelehun and Malaria case diagnosis context -And you set the enrollment status filter to completed -And you apply the current filter -And you set the enrollment date to a relative range -And you apply the current filter -When you save the list with the name My custom list -Then the new My custom list is created -When you delete the name My custom list -Then the My custom list is deleted - -Scenario: The user can open and select a program stage filter -Given you open the main page with Ngelehun and Malaria focus investigation context -When you open the program stage filters from the more filters dropdown menu -When you select the Foci response program stage -And you apply the current filter -And you open the column selector -And you select a data element columns and save from the column selector -Then you see data elements specific filters and columns - -Scenario: While in a program stage working list, the user can filter by both TEA and data elements -Given you open the main page with Ngelehun, WHO RMNCH Tracker and First antenatal care visit context -When you set the enrollment status filter to active -And you apply the current filter -And you set the event status filter to completed -And you apply the current filter -And you set the first name filter to Urzula -And you apply the current filter -And you set the WHOMCH Smoking filter to No -And you apply the current filter -Then the list should display 1 row of data - -Scenario: While in a program stage working list, the user can sort by both TEA and data elements -Given you open the main page with Ngelehun, WHO RMNCH Tracker and First antenatal care visit context -And you set the first name filter to u -And you apply the current filter -When you click the last name column header -Then the sort arrow should indicate ascending order -And the list should display data ordered ascendingly by last name -When you click the WHOMCH Hemoglobin value column header -Then the sort arrow should indicate descending order -And the list should display data ordered descending by WHOMCH Hemoglobin - -Scenario: The user can remove the program stage filter -Given you open the main page with Ngelehun and WHO RMNCH Tracker context -When you open the program stage filters from the more filters dropdown menu -And you select the First antenatal care visit program stage -And you apply the current filter -Then you see program stage working list events -When you remove the program stage filter -Then you don't see program stage working list events - -Scenario: The user can filter the events by scheduledAt date -Given you open the main page with Ngelehun and WHO RMNCH Tracker context -When you open the program stage filters from the more filters dropdown menu -And you select the First antenatal care visit program stage -And you apply the current filter -Then you see scheduledAt filter -And you open the column selector -When you select a scheduledAt column and save from the column selector -And you select the events scheduled today -And you apply the current filter -Then you see the selected option in the scheduledAt filter - -Scenario: The program stage working list configureation is kept when navigating -Given you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list -When you open an enrollment event from the working list -And you go back using the browser button -Then the program stage working list is loaded - -Scenario: The program stage working list without a orgUnit selected redirects to a tracker event -Given you open the main page with all accesible records in the WHO RMNCH Tracker context and configure a program stage working list -When you open an enrollment event from the working list -Then the tracker event URL contains the orgUnitId - -Scenario: The user can open a program stage list without events -Given you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list -And you set the event visit date to Today -And you apply the current filter -Then the working list is empty - -Scenario: The user can filter the Foci response assigned events -Given you open the main page with Ngelehun and Malaria focus investigation context -When you open the program stage filters from the more filters dropdown menu -And you select the Foci response program stage -And you apply the current filter -And you set the assginee filter to Anyone -And you apply the current filter -Then the assignee filter button should show that Anyone filter is in effect -And the assignee column is displayed - -Scenario: The assigned user data is kept when switching between working list types -Given you open the main page with Ngelehun and Malaria focus investigation context -And you filter by assigned Foci investigation & classification events -And the assignee filter button should show that Anyone filter is in effect -When you remove the program stage filter -Then you don't see program stage working list events -And the assignee filter button should show that Anyone filter is in effect -When you set the assginee filter to None -And you apply the current filter -Then the assignee filter button should show that None filter is in effect -When you open the program stage filters from the more filters dropdown menu -And you select the Foci response program stage -And you apply the current filter -Then the assignee filter button should show that None filter is in effect - -@v>=40 -Scenario: The user can create and delete a program stage working list for Foci investigation & classification assigned events -Given you open the main page with Ngelehun and Malaria focus investigation context -And you filter by assigned Foci investigation & classification events -When you save the list with the name Custom Program stage list -Then the new Custom Program stage list is created -And you delete the name Custom Program stage list -Then the Custom Program stage list is deleted - -@v>=40 -Scenario: The user creates, updates and deletes a Program stage custom working list -Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context -And you set the enrollment status filter to completed -And you apply the current filter -And you set the enrollment date to a relative range -And you apply the current filter -When you save the list with the name Custom Program stage list -Then the new Custom Program stage list is created -And the enrollment status filter button should show that the completed filter is in effect -When you set the enrollment status filter to active -And you apply the current filter -When you update the list with the name Custom Program stage list -Then the enrollment status filter button should show that the active filter is in effect -And you delete the name Custom Program stage list -Then the Custom Program stage list is deleted - -@v>=40 -Scenario: The user can delete a Program stage working list right immediately after creating it. -Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context -When you save the list with the name Custom Program stage list -Then the new Custom Program stage list is created -And you delete the name Custom Program stage list -Then the Custom Program stage list is deleted - -# For the program stage WL scenarios I need to create/delete my own because there are no program stage working lists in the demo database. -@v>=40 -Scenario: The Program stage custom working can be shared -Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context -And you save the list with the name Custom Program stage list -When you change the sharing settings -Then you see the new sharing settings - -@v>=40 -Scenario: The Program stage working list configuration is kept when changing the org unit -Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context -And you save the list with the name Custom Program stage list -Then the new Custom Program stage list is created -And you set the event status filter to completed -And you apply the current filter -And you change the org unit -Then the working list configuration was kept -And you delete the name Custom Program stage list -And the Custom Program stage list is deleted - -@v>=40 -Scenario: The user can save a program stage working list, based on a TEI working list configuration -Given you open a clean main page with Ngelehun and Malaria focus investigation context -Then you see the custom TEI working lists -And you can load the view with the name Ongoing foci responses -And you open the program stage filters from the more filters dropdown menu -And you select the Foci response program stage -And you apply the current filter -Then you are redirect to the default templete -When you save the list with the name Custom Program stage list -Then the new Custom Program stage list is created -And the TEI working list initial configuration was kept -And you delete the name Custom Program stage list -Then the Custom Program stage list is deleted - -@v>=40 -Scenario: The user can download the tracked entity working list -Given you open the main page with Ngelehun and child programe context -And you open the menu and click the "Download data..." button -Then the download dialog opens -Then the CSV button exists -Then the JSON button exists - -@v<40 -Scenario: The user can download the tracked entity working list -Given you open the main page with Ngelehun and child programe context -And you open the menu and click the "Download data..." button -Then the download dialog opens -Then the JSON button exists - -Scenario: The user cannot download the tracked entity working list when no orgUnit is selected -Given you open the main page with child programe context -And the user clicks the element containing the text: Or see all records accessible to you in Child Programme -And you open the menu -Then the "Download data..." button is hidden + Scenario: User opens the default working list for a tracker program + Given you open the main page with Ngelehun and child programe context + Then the default working list should be displayed + And rows per page should be set to 15 + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show only teis with completed enrollments using the predefined working list + Given you open the main page with Ngelehun and child programe context + When you select the working list called completed enrollments + Then the enrollment status filter button should show that the completed filter is in effect + And the list should display teis with a completed enrollment + And rows per page should be set to 15 + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show only teis with completed enrollments using the filter + Given you open the main page with Ngelehun and child programe context + When you set the enrollment status filter to completed + And you apply the current filter + Then the enrollment status filter button should show that the completed filter is in effect + And the list should display teis with a completed enrollment + And rows per page should be set to 15 + And for a tracker program the page navigation should show that you are on the first page + + # DHIS2-13960: /trackedEntities filter by assignee results are not consistent + @skip + Scenario: Show only teis with active enrollments and unassinged events using the filter + Given you open the main page with Ngelehun and Malaria focus investigation context + When you set the enrollment status filter to active + And you apply the current filter + And you set the assginee filter to None + And you apply the current filter + Then the enrollment status filter button should show that the active filter is in effect + And the assignee filter button should show that None filter is in effect + And the list should display teis with an active enrollment and unassinged events + And rows per page should be set to 15 + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show only teis with first name containig John using the filter + Given you open the main page with Ngelehun and child programe context + When you set the first name filter to John + And you apply the current filter + Then the first name filter button should show that the filter is in effect + And the list should display teis with John as the first name + And rows per page should be set to 15 + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show the registering unit column + Given you open the main page with Ngelehun and child programe context + When you open the column selector + And you select the organisation unit and save from the column selector + Then the organisation unit should display in the list + + Scenario: Show next page + Given you open the main page with Ngelehun and child programe context + When you click the next page button + Then the list should display data for the second page + And the pagination for the tei working list should show the second page + + Scenario: Show next page then previous page + Given you open the main page with Ngelehun and child programe context + When you click the next page button + Then the list should display data for the second page + And the pagination for the tei working list should show the second page + When you click the previous page button + Then the default working list should be displayed + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show next page then first page + Given you open the main page with Ngelehun and child programe context + When you click the next page button + Then the list should display data for the second page + And the pagination for the tei working list should show the second page + When you click the first page button + Then the default working list should be displayed + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show 10 rows per page + Given you open the main page with Ngelehun and child programe context + When you change rows per page to 10 + Then the list should display 10 rows of data + And for a tracker program the page navigation should show that you are on the first page + + Scenario: Show teis ordered ascendingly by first name + Given you open the main page with Ngelehun and child programe context + When you click the first name column header + Then the sort arrow should indicate ascending order + And the list should display data ordered ascendingly by first name + And for a tracker program the page navigation should show that you are on the first page + + Scenario: The TEI custom working lists is loaded + Given you open the main page with Ngelehun and Malaria focus investigation context + Then you see the custom TEI working lists + And you can load the view with the name Events assigned to me + + Scenario: The user creates, updates and deletes a TEI custom working list + Given you open the main page with Ngelehun and Malaria case diagnosis context + And you set the enrollment status filter to completed + And you apply the current filter + And you set the enrollment date to a relative range + And you apply the current filter + When you save the list with the name My custom list + Then the new My custom list is created + And the enrollment status filter button should show that the completed filter is in effect + When you set the enrollment status filter to active + And you apply the current filter + When you update the list with the name My custom list + Then the enrollment status filter button should show that the active filter is in effect + And you delete the name My custom list + Then the My custom list is deleted + + Scenario: The user is navigated back to the selected working list after closing a TEI + Given you open the main page with Ngelehun and child programe context + And you select the working list called completed enrollments + When you open a tei from the working list + And you deselect the tracked entity from the context selector + Then the working list called completed enrollments should be selected + + Scenario: The user can delete a TEI working list right immediately after creating it. + Given you open the main page with Ngelehun and Malaria case diagnosis context + And you set the enrollment status filter to completed + And you apply the current filter + And you set the enrollment date to a relative range + And you apply the current filter + When you save the list with the name My custom list + Then the new My custom list is created + When you delete the name My custom list + Then the My custom list is deleted + + Scenario: The user can open and select a program stage filter + Given you open the main page with Ngelehun and Malaria focus investigation context + When you open the program stage filters from the more filters dropdown menu + When you select the Foci response program stage + And you apply the current filter + And you open the column selector + And you select a data element columns and save from the column selector + Then you see data elements specific filters and columns + + Scenario: While in a program stage working list, the user can filter by both TEA and data elements + Given you open the main page with Ngelehun, WHO RMNCH Tracker and First antenatal care visit context + When you set the enrollment status filter to active + And you apply the current filter + And you set the event status filter to completed + And you apply the current filter + And you set the first name filter to Urzula + And you apply the current filter + And you set the WHOMCH Smoking filter to No + And you apply the current filter + Then the list should display 1 row of data + + Scenario: While in a program stage working list, the user can sort by both TEA and data elements + Given you open the main page with Ngelehun, WHO RMNCH Tracker and First antenatal care visit context + And you set the first name filter to u + And you apply the current filter + When you click the last name column header + Then the sort arrow should indicate ascending order + And the list should display data ordered ascendingly by last name + When you click the WHOMCH Hemoglobin value column header + Then the sort arrow should indicate descending order + And the list should display data ordered descending by WHOMCH Hemoglobin + + Scenario: The user can remove the program stage filter + Given you open the main page with Ngelehun and WHO RMNCH Tracker context + When you open the program stage filters from the more filters dropdown menu + And you select the First antenatal care visit program stage + And you apply the current filter + Then you see program stage working list events + When you remove the program stage filter + Then you don't see program stage working list events + + Scenario: The user can filter the events by scheduledAt date + Given you open the main page with Ngelehun and WHO RMNCH Tracker context + When you open the program stage filters from the more filters dropdown menu + And you select the First antenatal care visit program stage + And you apply the current filter + Then you see scheduledAt filter + And you open the column selector + When you select a scheduledAt column and save from the column selector + And you select the events scheduled today + And you apply the current filter + Then you see the selected option in the scheduledAt filter + + Scenario: The program stage working list configureation is kept when navigating + Given you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list + When you open an enrollment event from the working list + And you go back using the browser button + Then the program stage working list is loaded + + Scenario: The program stage working list without a orgUnit selected redirects to a tracker event + Given you open the main page with all accesible records in the WHO RMNCH Tracker context and configure a program stage working list + When you open an enrollment event from the working list + Then the tracker event URL contains the orgUnitId + + Scenario: The user can open a program stage list without events + Given you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list + And you set the event visit date to Today + And you apply the current filter + Then the working list is empty + + Scenario: The user can filter the Foci response assigned events + Given you open the main page with Ngelehun and Malaria focus investigation context + When you open the program stage filters from the more filters dropdown menu + And you select the Foci response program stage + And you apply the current filter + And you set the assginee filter to Anyone + And you apply the current filter + Then the assignee filter button should show that Anyone filter is in effect + And the assignee column is displayed + + Scenario: The assigned user data is kept when switching between working list types + Given you open the main page with Ngelehun and Malaria focus investigation context + And you filter by assigned Foci investigation & classification events + And the assignee filter button should show that Anyone filter is in effect + When you remove the program stage filter + Then you don't see program stage working list events + And the assignee filter button should show that Anyone filter is in effect + When you set the assginee filter to None + And you apply the current filter + Then the assignee filter button should show that None filter is in effect + When you open the program stage filters from the more filters dropdown menu + And you select the Foci response program stage + And you apply the current filter + Then the assignee filter button should show that None filter is in effect + + @v>=40 + Scenario: The user can create and delete a program stage working list for Foci investigation & classification assigned events + Given you open the main page with Ngelehun and Malaria focus investigation context + And you filter by assigned Foci investigation & classification events + When you save the list with the name Custom Program stage list + Then the new Custom Program stage list is created + And you delete the name Custom Program stage list + Then the Custom Program stage list is deleted + + @v>=40 + Scenario: The user creates, updates and deletes a Program stage custom working list + Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context + And you set the enrollment status filter to completed + And you apply the current filter + And you set the enrollment date to a relative range + And you apply the current filter + When you save the list with the name Custom Program stage list + Then the new Custom Program stage list is created + And the enrollment status filter button should show that the completed filter is in effect + When you set the enrollment status filter to active + And you apply the current filter + When you update the list with the name Custom Program stage list + Then the enrollment status filter button should show that the active filter is in effect + And you delete the name Custom Program stage list + Then the Custom Program stage list is deleted + + @v>=40 + Scenario: The user can delete a Program stage working list right immediately after creating it. + Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context + When you save the list with the name Custom Program stage list + Then the new Custom Program stage list is created + And you delete the name Custom Program stage list + Then the Custom Program stage list is deleted + + # For the program stage WL scenarios I need to create/delete my own because there are no program stage working lists in the demo database. + @v>=40 + Scenario: The Program stage custom working can be shared + Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context + And you save the list with the name Custom Program stage list + When you change the sharing settings + Then you see the new sharing settings + + @v>=40 + Scenario: The Program stage working list configuration is kept when changing the org unit + Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context + And you save the list with the name Custom Program stage list + Then the new Custom Program stage list is created + And you set the event status filter to completed + And you apply the current filter + And you change the org unit + Then the working list configuration was kept + And you delete the name Custom Program stage list + And the Custom Program stage list is deleted + + @v>=40 + Scenario: The user can save a program stage working list, based on a TEI working list configuration + Given you open a clean main page with Ngelehun and Malaria focus investigation context + Then you see the custom TEI working lists + And you can load the view with the name Ongoing foci responses + And you open the program stage filters from the more filters dropdown menu + And you select the Foci response program stage + And you apply the current filter + Then you are redirect to the default templete + When you save the list with the name Custom Program stage list + Then the new Custom Program stage list is created + And the TEI working list initial configuration was kept + And you delete the name Custom Program stage list + Then the Custom Program stage list is deleted + + @v>=40 + Scenario: The user can download the tracked entity working list + Given you open the main page with Ngelehun and child programe context + And you open the menu and click the "Download data..." button + Then the download dialog opens + Then the CSV button exists + Then the JSON button exists + + @v<40 + Scenario: The user can download the tracked entity working list + Given you open the main page with Ngelehun and child programe context + And you open the menu and click the "Download data..." button + Then the download dialog opens + Then the JSON button exists + + Scenario: The user cannot download the tracked entity working list when no orgUnit is selected + Given you open the main page with child programe context + And the user clicks the element containing the text: Or see all records accessible to you in Child Programme + And you open the menu + Then the "Download data..." button is hidden diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js index 260e312422..0ea736c26a 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js @@ -1,4 +1,4 @@ -import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor'; +import { defineStep as And, Given, Then, When } from '@badeball/cypress-cucumber-preprocessor'; import { v4 as uuid } from 'uuid'; import '../sharedSteps'; @@ -654,6 +654,25 @@ When('you remove the program stage filter', () => { .click(); }); +When('you open a tei from the working list', () => { + cy.get('[data-test="tei-working-lists"]') + .contains('Filona') + .click(); +}); + +When('you deselect the tracked entity from the context selector', () => { + cy.get('[data-test="person-selector-container-clear-icon"]') + .click(); +}); + +// the working list called completed enrollments should be selected +Then('the working list called completed enrollments should be selected', () => { + cy.get('[data-test="workinglist-template-selector-chip"]') + .contains('Completed enrollments') + .parent() + .should('have.class', 'selected'); +}); + Then('you see scheduledAt filter', () => { cy.get('[data-test="tei-working-lists"]') .contains('Appointment date') diff --git a/i18n/en.pot b/i18n/en.pot index c098e29ad6..9b56b6db68 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-09-02T11:08:16.281Z\n" -"PO-Revision-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-10T14:29:59.249Z\n" +"PO-Revision-Date: 2024-10-10T14:29:59.249Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." @@ -1071,6 +1071,9 @@ msgstr "Create new event" msgid "Search for a {{trackedEntityName}} in {{programName}}" msgstr "Search for a {{trackedEntityName}} in {{programName}}" +msgid "Back to list" +msgstr "Back to list" + msgid "No tracked entity types available" msgstr "No tracked entity types available" diff --git a/src/core_modules/capture-core/components/Pages/MainPage/MainPage.container.js b/src/core_modules/capture-core/components/Pages/MainPage/MainPage.container.js index 52a10ab4e4..32ac19a65b 100644 --- a/src/core_modules/capture-core/components/Pages/MainPage/MainPage.container.js +++ b/src/core_modules/capture-core/components/Pages/MainPage/MainPage.container.js @@ -1,7 +1,7 @@ // @flow -import React, { useEffect, useMemo, useCallback } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; // $FlowFixMe -import { connect, useSelector, shallowEqual, useDispatch } from 'react-redux'; +import { connect, shallowEqual, useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { programCollection } from 'capture-core/metaDataMemoryStores/programCollection/programCollection'; import { MainPageComponent } from './MainPage.component'; @@ -68,9 +68,11 @@ const useMainPageStatus = ({ const useSelectorMainPage = () => useSelector( - ({ currentSelections, activePage }) => ({ + ({ currentSelections, activePage, workingListsTemplates, workingListsContext }) => ({ categories: currentSelections.categories, selectedCategories: currentSelections.categoriesMeta, + reduxSelectedTemplateId: workingListsTemplates.teiList?.selectedTemplateId, + workingListProgramId: workingListsContext.teiList?.programIdView, ready: !activePage.isLoading && !activePage.lockedSelectorLoads, error: activePage.selectionsError && activePage.selectionsError.error, }), @@ -103,6 +105,8 @@ const MainPageContainer = () => { const { categories, selectedCategories, + reduxSelectedTemplateId, + workingListProgramId, error, ready, } = useSelectorMainPage(); @@ -131,7 +135,18 @@ const MainPageContainer = () => { }, [showAllAccessible, dispatch]); useEffect(() => { - if (programId && trackedEntityTypeId && displayFrontPageList && selectedTemplateId === undefined) { + if (programId && trackedEntityTypeId && selectedTemplateId === undefined) { + if (reduxSelectedTemplateId && workingListProgramId === programId) { + handleChangeTemplateUrl({ + programId, + orgUnitId, + selectedTemplateId: reduxSelectedTemplateId, + showAllAccessible, + history, + }); + return; + } + if (!displayFrontPageList) return; handleChangeTemplateUrl({ programId, orgUnitId, @@ -148,6 +163,8 @@ const MainPageContainer = () => { trackedEntityTypeId, displayFrontPageList, history, + reduxSelectedTemplateId, + workingListProgramId, ]); return ( From cd63f877772ae5f6e943371c19791b9495085904 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 14 Oct 2024 14:12:33 +0000 Subject: [PATCH 3/5] chore(release): cut 101.10.2 [skip release] ## [101.10.2](https://github.com/dhis2/capture-app/compare/v101.10.1...v101.10.2) (2024-10-14) ### Bug Fixes * [DHIS2-18215] selected working list not persisted on navigate ([#3838](https://github.com/dhis2/capture-app/issues/3838)) ([599b2c1](https://github.com/dhis2/capture-app/commit/599b2c1e29c94fd0258844aadb7eef20e03024eb)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1897fba86d..0656efb4df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.10.2](https://github.com/dhis2/capture-app/compare/v101.10.1...v101.10.2) (2024-10-14) + + +### Bug Fixes + +* [DHIS2-18215] selected working list not persisted on navigate ([#3838](https://github.com/dhis2/capture-app/issues/3838)) ([599b2c1](https://github.com/dhis2/capture-app/commit/599b2c1e29c94fd0258844aadb7eef20e03024eb)) + ## [101.10.1](https://github.com/dhis2/capture-app/compare/v101.10.0...v101.10.1) (2024-10-14) diff --git a/package.json b/package.json index 437c545d18..6221901040 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.10.1", + "version": "101.10.2", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.10.1", + "@dhis2/rules-engine-javascript": "101.10.2", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index a922df4111..594bb9704e 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.10.1", + "version": "101.10.2", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From de06f8b1b5480ba7315ca648784ef414f8473e06 Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:53:05 +0200 Subject: [PATCH 4/5] feat: [DHIS2-17970] Auto-select orgUnit if there is only one available (#3798) * feat: pre select * feat: review changes * fix: remove children check * fix: review change * feat: merge hooks for auto select * Revert "feat: merge hooks for auto select" This reverts commit 9b97d2e6499e9d3ba4b99068659495a355d83ddf. * fix: review changes --- .../hooks/useMetadataAutoSelect.js | 20 +++----------- .../WidgetRelatedStages.component.js | 20 ++++++++++---- .../capture-core/dataQueries/index.js | 1 + .../dataQueries/useOrgUnitsForAutoSelect.js | 26 +++++++++++++++++++ 4 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 src/core_modules/capture-core/dataQueries/useOrgUnitsForAutoSelect.js diff --git a/src/core_modules/capture-core/components/MetadataAutoSelectInitializer/hooks/useMetadataAutoSelect.js b/src/core_modules/capture-core/components/MetadataAutoSelectInitializer/hooks/useMetadataAutoSelect.js index 90be846e65..e85322f939 100644 --- a/src/core_modules/capture-core/components/MetadataAutoSelectInitializer/hooks/useMetadataAutoSelect.js +++ b/src/core_modules/capture-core/components/MetadataAutoSelectInitializer/hooks/useMetadataAutoSelect.js @@ -1,9 +1,10 @@ // @flow import { useCallback, useEffect, useState } from 'react'; import { useHistory } from 'react-router-dom'; -import { useApiMetadataQuery, useIndexedDBQuery } from '../../../utils/reactQueryHelpers'; +import { useIndexedDBQuery } from '../../../utils/reactQueryHelpers'; import { getUserStorageController, userStores } from '../../../storageControllers'; import { buildUrlQueryString, useLocationQuery } from '../../../utils/routing'; +import { useOrgUnitAutoSelect } from '../../../dataQueries'; const getAllPrograms = () => { const userStorageController = getUserStorageController(); @@ -28,21 +29,8 @@ export const useMetadataAutoSelect = () => { }, ); - const { data: searchOrgUnits, isLoading: loadingOrgUnits } = useApiMetadataQuery( - ['searchOrgUnitsForAutoSelect'], - { - resource: 'organisationUnits', - params: { - fields: 'id', - withinUserSearchHierarchy: true, - pageSize: 2, - }, - }, - { - enabled: Object.keys(urlParams).length === 0 && !mounted, - select: ({ organisationUnits }) => organisationUnits, - }, - ); + const queryOptions = { enabled: Object.keys(urlParams).length === 0 && !mounted }; + const { isLoading: loadingOrgUnits, data: searchOrgUnits } = useOrgUnitAutoSelect(queryOptions); const updateUrlIfApplicable = useCallback(() => { const paramsToAdd = { diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js b/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js index 7ac5068e44..722515d992 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js @@ -1,6 +1,7 @@ // @flow import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react'; import { useRelatedStages } from './useRelatedStages'; +import { useOrgUnitAutoSelect } from '../../dataQueries'; import type { Props, RelatedStageDataValueStates } from './WidgetRelatedStages.types'; import type { ErrorMessagesForRelatedStages } from './RelatedStagesActions'; import { RelatedStagesActions } from './RelatedStagesActions'; @@ -36,6 +37,15 @@ const WidgetRelatedStagesPlain = ({ orgUnit: undefined, linkedEventId: undefined, }); + const { isLoading: orgUnitLoading, data } = useOrgUnitAutoSelect(); + useEffect(() => { + if (!orgUnitLoading && data?.length === 1) { + setRelatedStageDataValues(prev => ({ + ...prev, + orgUnit: data[0], + })); + } + }, [data, orgUnitLoading, setRelatedStageDataValues]); const addErrorMessage = (message: ErrorMessagesForRelatedStages) => { setErrorMessages((prevMessages: Object) => ({ @@ -81,7 +91,7 @@ const WidgetRelatedStagesPlain = ({ } }, [formIsValid, relatedStageDataValues]); - if (!currentRelatedStagesStatus || !selectedRelationshipType || isLoadingEvents) { + if (!currentRelatedStagesStatus || !selectedRelationshipType || isLoadingEvents || orgUnitLoading) { return null; } @@ -104,8 +114,8 @@ const WidgetRelatedStagesPlain = ({ ); }; -export const WidgetRelatedStages = forwardRef(WidgetRelatedStagesPlain); + formIsValidOnSave: Function, + getLinkedStageValues: Function + |}>(WidgetRelatedStagesPlain); diff --git a/src/core_modules/capture-core/dataQueries/index.js b/src/core_modules/capture-core/dataQueries/index.js index 913bca576a..c77469ff0c 100644 --- a/src/core_modules/capture-core/dataQueries/index.js +++ b/src/core_modules/capture-core/dataQueries/index.js @@ -1 +1,2 @@ export { useOrganisationUnit } from './useOrganisationUnit'; +export { useOrgUnitAutoSelect } from './useOrgUnitsForAutoSelect'; diff --git a/src/core_modules/capture-core/dataQueries/useOrgUnitsForAutoSelect.js b/src/core_modules/capture-core/dataQueries/useOrgUnitsForAutoSelect.js new file mode 100644 index 0000000000..a2e57ed10a --- /dev/null +++ b/src/core_modules/capture-core/dataQueries/useOrgUnitsForAutoSelect.js @@ -0,0 +1,26 @@ +// @flow +import { useApiMetadataQuery } from '../utils/reactQueryHelpers'; + +export const useOrgUnitAutoSelect = (customQueryOptions: Object) => { + const queryKey = ['organisationUnits']; + const queryFn = { + resource: 'organisationUnits', + params: { + fields: ['id, displayName~rename(name), path'], + withinUserHierarchy: true, + pageSize: 2, + }, + }; + const defaultQueryOptions = { + select: ({ organisationUnits }) => organisationUnits, + }; + + const queryOptions = { ...defaultQueryOptions, ...customQueryOptions }; + + const { data, isLoading } = useApiMetadataQuery(queryKey, queryFn, queryOptions); + + return { + isLoading, + data, + }; +}; From 5444ac70ac5635db674e2dee1475b604ef004bdb Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 14 Oct 2024 14:57:09 +0000 Subject: [PATCH 5/5] chore(release): cut 101.11.0 [skip release] # [101.11.0](https://github.com/dhis2/capture-app/compare/v101.10.2...v101.11.0) (2024-10-14) ### Features * [DHIS2-17970] Auto-select orgUnit if there is only one available ([#3798](https://github.com/dhis2/capture-app/issues/3798)) ([de06f8b](https://github.com/dhis2/capture-app/commit/de06f8b1b5480ba7315ca648784ef414f8473e06)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0656efb4df..08e6811337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.11.0](https://github.com/dhis2/capture-app/compare/v101.10.2...v101.11.0) (2024-10-14) + + +### Features + +* [DHIS2-17970] Auto-select orgUnit if there is only one available ([#3798](https://github.com/dhis2/capture-app/issues/3798)) ([de06f8b](https://github.com/dhis2/capture-app/commit/de06f8b1b5480ba7315ca648784ef414f8473e06)) + ## [101.10.2](https://github.com/dhis2/capture-app/compare/v101.10.1...v101.10.2) (2024-10-14) diff --git a/package.json b/package.json index 6221901040..2ca3ec5672 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.10.2", + "version": "101.11.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.10.2", + "@dhis2/rules-engine-javascript": "101.11.0", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 594bb9704e..ac2c2f545a 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.10.2", + "version": "101.11.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": {