From cd06e414fc2162397f3844887e1b3f902d18a874 Mon Sep 17 00:00:00 2001 From: Tony Valle <79843014+superskip@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:54:06 +0200 Subject: [PATCH 01/91] fix: [DHIS2-17971] trigger program stage specific rules on opening new event page (#3776) --- .../common/ProgramStage/buildProgramStageMetadata.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core_modules/capture-core/components/DataEntries/common/ProgramStage/buildProgramStageMetadata.js b/src/core_modules/capture-core/components/DataEntries/common/ProgramStage/buildProgramStageMetadata.js index 8c3977382e..dbebc546bb 100644 --- a/src/core_modules/capture-core/components/DataEntries/common/ProgramStage/buildProgramStageMetadata.js +++ b/src/core_modules/capture-core/components/DataEntries/common/ProgramStage/buildProgramStageMetadata.js @@ -28,6 +28,9 @@ export const buildProgramStageMetadata = async ({ const storageController = getUserStorageController(); const cachedRelationshipTypes = await storageController.getAll(userStores.RELATIONSHIP_TYPES); + const cachedProgramRules = await storageController.getAll(userStores.PROGRAM_RULES, { + predicate: rule => rule.programStageId === cachedProgramStage.id, + }); const programStageFactory = new ProgramStageFactory({ cachedOptionSets: new Map(cachedOptionSets.map(optionSet => [optionSet.id, optionSet])), @@ -41,5 +44,8 @@ export const buildProgramStageMetadata = async ({ return programStageFactory.build( cachedProgramStage, programId, - ); + ).then((stage) => { + stage.programRules = cachedProgramRules; + return stage; + }); }; From 325c63887f7e6cddd35944f0a70ea494042f4634 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 2 Sep 2024 10:59:29 +0000 Subject: [PATCH 02/91] chore(release): cut 101.3.3 [skip release] ## [101.3.3](https://github.com/dhis2/capture-app/compare/v101.3.2...v101.3.3) (2024-09-02) ### Bug Fixes * [DHIS2-17971] trigger program stage specific rules on opening new event page ([#3776](https://github.com/dhis2/capture-app/issues/3776)) ([cd06e41](https://github.com/dhis2/capture-app/commit/cd06e414fc2162397f3844887e1b3f902d18a874)) --- 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 3ce973047b..5182a15d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.3.3](https://github.com/dhis2/capture-app/compare/v101.3.2...v101.3.3) (2024-09-02) + + +### Bug Fixes + +* [DHIS2-17971] trigger program stage specific rules on opening new event page ([#3776](https://github.com/dhis2/capture-app/issues/3776)) ([cd06e41](https://github.com/dhis2/capture-app/commit/cd06e414fc2162397f3844887e1b3f902d18a874)) + ## [101.3.2](https://github.com/dhis2/capture-app/compare/v101.3.1...v101.3.2) (2024-09-01) diff --git a/package.json b/package.json index d392f8367a..dc54a5992a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.3.2", + "version": "101.3.3", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.3.2", + "@dhis2/rules-engine-javascript": "101.3.3", "@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 c31500497a..fd771bc637 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.3.2", + "version": "101.3.3", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From fb793cc695c6ac28ee6c8e7de6a670503f8b2394 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:02:46 +0200 Subject: [PATCH 03/91] chore(deps): bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows (#3784) chore(deps): bump actions/download-artifact in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/verify-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify-app.yml b/.github/workflows/verify-app.yml index c8a7d22379..6b577c7a87 100644 --- a/.github/workflows/verify-app.yml +++ b/.github/workflows/verify-app.yml @@ -214,7 +214,7 @@ jobs: with: node-version: 18.x - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4.1.7 with: name: app-build From 12af1384f4ab4e9c6eeef2460bee7d53bfb6b8cc Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Fri, 6 Sep 2024 09:18:58 +0200 Subject: [PATCH 04/91] feat: [DHIS2-17878][DHIS2-17048] Add overflow menu with actions to stages&events (#3756) * feat: add overflow menu with actions * fix: review comments * fix: pr-comments * chore: cypress tests --- .../StagesAndEventsWidget.feature | 29 ++++- .../StagesAndEventsWidget.js | 88 +++++++++++++- i18n/en.pot | 19 +++ .../Buttons/OverflowButton.component.js | 7 +- .../EnrollmentPageDefault.container.js | 27 +++++ .../LayoutComponentConfig.js | 6 + .../enrollment.actions.js | 12 ++ .../useCommonEnrollmentDomainData.js | 44 +++---- .../DeleteActionButton/DeleteActionButton.js | 30 +++++ .../EventRow/DeleteActionButton/index.js | 3 + .../DeleteActionModal/DeleteActionModal.js | 114 ++++++++++++++++++ .../EventRow/DeleteActionModal/index.js | 3 + .../Stage/StageDetail/EventRow/EventRow.js | 111 +++++++++++++++++ .../StageDetail/EventRow/EventRow.types.js | 17 +++ .../EventRow/SkipAction/SkipAction.js | 89 ++++++++++++++ .../StageDetail/EventRow/SkipAction/index.js | 3 + .../Stage/StageDetail/EventRow/index.js | 3 + .../StageDetail/StageDetail.component.js | 40 ++++-- .../Stage/StageDetail/stageDetail.types.js | 6 +- .../Stages/Stage/stage.types.js | 3 + .../Stages/stages.types.js | 6 + .../stagesAndEvents.types.js | 3 + .../enrollmentDomain.reducerDescription.js | 15 +++ 23 files changed, 633 insertions(+), 45 deletions(-) create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionButton/DeleteActionButton.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionButton/index.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionModal/DeleteActionModal.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionModal/index.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.types.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/index.js create mode 100644 src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/index.js diff --git a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature index 07387fcde5..e944741b2f 100644 --- a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature +++ b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature @@ -1,9 +1,5 @@ Feature: User interacts with Stages and Events Widget - @user:trackerAutoTestRestricted - Scenario: Create new event button is disabled if no data write access - Given you open the enrollment page by typing #enrollment?enrollmentId=WKPoiZxZxNG&orgUnitId=DiszpKrYNg8&programId=WSGAb5XwJ3Y&teiId=PgmUFEQYZdt - Then you should see the disabled button New Previous deliveries event Scenario: User can view program stages Given you open the enrollment page @@ -57,13 +53,36 @@ Feature: User interacts with Stages and Events Widget When you click New First antenatal care visit event Then you should navigate to Add new page #/enrollmentEventNew?enrollmentId=ek4WWAgXX5i&orgUnitId=DwpbWkiqjMy&programId=WSGAb5XwJ3Y&stageId=WZbXY0S00lP&teiId=yFcOhsM1Yoa - Scenario: User can not go to Add new page if stage is not repeatable and there is event in the stage Given you open the enrollment page by typing #enrollment?programId=IpHINAT79UW&orgUnitId=UgYg0YW7ZIh&teiId=fhFQhO0xILJ&enrollmentId=gPDueU02tn8 Then you should see the disabled button New Birth event + Scenario: User can skip a scheduled event + Given you open the enrollment page by typing #/enrollment?enrollmentId=gL8BooqKhdX&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=RABlFsj5Omi + And there is an Overdue event in the TB visit stage + When you click the Skip event overflow button on the Overdue event + Then the event should be skipped + + Scenario: User can unskip a scheduled event + Given you open the enrollment page by typing #/enrollment?enrollmentId=gL8BooqKhdX&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=RABlFsj5Omi + And there is an Skipped event in the TB visit stage + When you click the Unskip event overflow button on the Skipped event + Then there is an Overdue event in the TB visit stage + + @with-restore-deleted-event + Scenario: User can delete an event + Given you open the enrollment page by typing #/enrollment?enrollmentId=ikYMpSKXik1&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=Trc1H9T5C6f + And there is an Active event in the TB visit stage + When you click the Delete event overflow button on the Active event + And you confirm you want to delete the event + Then the TB visit stage should be empty + @user:trackerAutoTestRestricted Scenario: Program stage is hidden if no data read access And you open the enrollment page by typing #enrollment?enrollmentId=iNEq9d22Nyp&orgUnitId=DiszpKrYNg8&programId=WSGAb5XwJ3Y&teiId=k4ODejBytgv Then the Care at birth program stage should be hidden + @user:trackerAutoTestRestricted + Scenario: Create new event button is disabled if no data write access + Given you open the enrollment page by typing #enrollment?enrollmentId=WKPoiZxZxNG&orgUnitId=DiszpKrYNg8&programId=WSGAb5XwJ3Y&teiId=PgmUFEQYZdt + Then you should see the disabled button New Previous deliveries event diff --git a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js index d772f41034..d4771a8876 100644 --- a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js +++ b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js @@ -1,7 +1,38 @@ -import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor'; +import { Given, When, Then, defineStep as And, After } from '@badeball/cypress-cucumber-preprocessor'; import { getCurrentYear } from '../../../support/date'; import '../sharedSteps'; +After({ tags: '@with-restore-deleted-event' }, () => { + cy.visit('#/enrollment?enrollmentId=ikYMpSKXik1&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=Trc1H9T5C6f'); + + cy.get('[data-test="stages-and-events-widget"]') + .find('[data-test="widget-contents"]') + .contains('[data-test="stage-content"]', 'TB visit') + .find('[data-test="create-new-button"]') + .click(); + + cy.get('[data-test="capture-ui-input"]') + .first() + .type('2023-01-26') + .blur(); + + cy.get('[data-test="virtualized-select"]') + .eq(0) + .click() + .contains('P+') + .click(); + + cy.get('[data-test="virtualized-select"]') + .eq(1) + .click() + .contains('New') + .click(); + + cy.get('[data-test="dhis2-uicore-button"]') + .contains('Save without completing') + .click(); +}); + Then('the program stages should be displayed', () => { cy.get('[data-test="stages-and-events-widget"]') .within(() => { @@ -162,3 +193,58 @@ Then('the Care at birth program stage should be hidden', () => { cy.contains('[data-test="stages-and-events-widget"]', 'Postpartum care visit').should('exist'); cy.contains('[data-test="stages-and-events-widget"]', 'Care at birth').should('not.exist'); }); + +Given(/there is an (.*) event in the TB visit stage$/, (eventStatus) => { + cy.get('[data-test="stages-and-events-widget"]') + .find('[data-test="widget-contents"]') + .contains('[data-test="stage-content"]', 'TB visit') + .within(() => { + cy.get('[data-test="dhis2-uicore-datatablerow"]') + .contains(eventStatus); + }); +}); + +When(/you click the (.*) event overflow button on the (.*) event$/, (buttonName, eventStatus) => { + cy.get('[data-test="stages-and-events-widget"]') + .find('[data-test="widget-contents"]') + .contains('[data-test="stage-content"]', 'TB visit') + .find('[data-test="dhis2-uicore-tablebody"]') + .contains('tr', eventStatus) + .find('[data-test="overflow-button"]') + .click({ force: true }); + + cy.get('[data-test="overflow-menu"]') + .contains(buttonName) + .click(); +}); + +Then('the event should be skipped', () => { + cy.get('[data-test="stages-and-events-widget"]') + .find('[data-test="widget-contents"]') + .contains('[data-test="stage-content"]', 'TB visit') + .find('[data-test="dhis2-uicore-datatablerow"]') + .contains('Skipped'); +}); + +Then('the TB visit stage should be empty', () => { + cy.get('[data-test="stages-and-events-widget"]') + .find('[data-test="widget-contents"]') + .contains('[data-test="stage-content"]', 'TB visit') + .find('[data-test="dhis2-uicore-datatablerow"]') + .should('not.exist'); +}); + +When('you confirm you want to delete the event', () => { + cy.intercept('POST', '**/tracker?async=false&importStrategy=DELETE') + .as('deleteEvent'); + + cy.get('[data-test="dhis2-uicore-modal"]').within(() => { + cy.contains('button', 'Yes, delete event') + .click(); + }); + + cy.wait('@deleteEvent') + .its('response.statusCode') + .should('eq', 200); +}); + diff --git a/i18n/en.pot b/i18n/en.pot index 25f3a5987a..cae303cf0b 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -1508,6 +1508,25 @@ msgstr "This stage can only have one event" msgid "New {{ eventName }} event" msgstr "New {{ eventName }} event" +msgid "An error occurred while deleting the event" +msgstr "An error occurred while deleting the event" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" + +msgid "An error occurred when updating event status" +msgstr "An error occurred when updating event status" + +msgid "Unskip" +msgstr "Unskip" + +msgid "Skip" +msgstr "Skip" + msgid "To open this event, please wait until saving is complete" msgstr "To open this event, please wait until saving is complete" diff --git a/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js b/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js index 5f20a47c92..57e99a125e 100644 --- a/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js +++ b/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react'; -import i18n from '@dhis2/d2-i18n'; import { useRef, useState } from 'react'; +import i18n from '@dhis2/d2-i18n'; import { Button, Layer, Popper } from '@dhis2/ui'; type Props = { @@ -15,6 +15,7 @@ type Props = { dataTest?: string, small?: boolean, large?: boolean, + disabled?: boolean, }; export const OverflowButton = ({ @@ -23,6 +24,7 @@ export const OverflowButton = ({ secondary, small, large, + disabled, onClick: handleClick, open: propsOpen, icon, @@ -43,10 +45,11 @@ export const OverflowButton = ({ return (
+ + + + + ); +}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionModal/index.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionModal/index.js new file mode 100644 index 0000000000..f288fff5b2 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/DeleteActionModal/index.js @@ -0,0 +1,3 @@ +// @flow + +export { DeleteActionModal } from './DeleteActionModal'; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.js new file mode 100644 index 0000000000..1f8ba00e56 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.js @@ -0,0 +1,111 @@ +// @flow +import React, { useState } from 'react'; +import { withStyles } from '@material-ui/core/'; +import { + DataTableCell, + DataTableRow, + FlyoutMenu, + IconMore16, +} from '@dhis2/ui'; +import { OverflowButton } from '../../../../../Buttons'; +import type { EventRowProps } from './EventRow.types'; +import { DeleteActionButton } from './DeleteActionButton'; +import { SkipAction } from './SkipAction'; +import { DeleteActionModal } from './DeleteActionModal'; + +const styles = { + row: { + maxWidth: '100%', + whiteSpace: 'nowrap', + cursor: 'pointer', + }, + rowDisabled: { + cursor: 'not-allowed', + opacity: 0.5, + }, +}; + +export const EventStatuses = { + ACTIVE: 'ACTIVE', + COMPLETED: 'COMPLETED', + SKIPPED: 'SKIPPED', + SCHEDULE: 'SCHEDULE', +}; + +const EventRowPlain = ({ + id, + pendingApiResponse, + eventDetails, + cells, + stageWriteAccess, + onDeleteEvent, + onRollbackDeleteEvent, + onUpdateEventStatus, + teiId, + programId, + enrollmentId, + classes, +}: EventRowProps) => { + const [actionsOpen, setActionsOpen] = useState(false); + const [deleteModalOpen, setDeleteModalOpen] = useState(false); + + return ( + + {cells} + + + <> + setActionsOpen(prev => !prev)} + dataTest={'overflow-button'} + secondary + small + icon={} + disabled={pendingApiResponse || !stageWriteAccess} + component={( + + {(eventDetails.status === EventStatuses.SCHEDULE || eventDetails.status === EventStatuses.SKIPPED) && ( + + )} + + + + )} + /> + + {deleteModalOpen && ( + + )} + + + + ); +}; + +export const EventRow = withStyles(styles)(EventRowPlain); diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.types.js new file mode 100644 index 0000000000..d47cc386fc --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/EventRow.types.js @@ -0,0 +1,17 @@ +// @flow + +export type EventRowProps = {| + id: string, + pendingApiResponse: boolean, + eventDetails: ApiEnrollmentEvent, + cells: Array>, + onEventClick: (id: string, options: ?Object) => void, + onDeleteEvent: (id: string) => void, + onUpdateEventStatus: (id: string, status: string) => void, + onRollbackDeleteEvent: (event: ApiEnrollmentEvent) => void, + stageWriteAccess: boolean, + teiId: string, + programId: string, + enrollmentId: string, + ...CssClasses, +|}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.js new file mode 100644 index 0000000000..70cd1068b4 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.js @@ -0,0 +1,89 @@ +// @flow +import React from 'react'; +import i18n from '@dhis2/d2-i18n'; +import log from 'loglevel'; +import { + MenuItem, + IconArrowRight16, IconRedo16, +} from '@dhis2/ui'; +import { useMutation } from 'react-query'; +import { useAlert, useDataEngine } from '@dhis2/app-runtime'; +import { EventStatuses } from '../EventRow'; +import { errorCreator } from '../../../../../../../../capture-core-utils'; + +type Props = {| + eventId: string, + eventDetails: ApiEnrollmentEvent, + pendingApiResponse: boolean, + onUpdateEventStatus: (eventId: string, status: string) => void, + setActionsOpen: (open: boolean) => void, +|} + +export const SkipAction = ({ + eventId, + eventDetails, + pendingApiResponse, + setActionsOpen, + onUpdateEventStatus, +}: Props) => { + const dataEngine = useDataEngine(); + const { show: showError } = useAlert( + ({ message }) => message, + { critical: true }, + ); + const { mutate: updateEventStatus } = useMutation( + ({ status }) => dataEngine.mutate({ + resource: 'tracker?async=false&importStrategy=UPDATE', + type: 'create', + data: { + events: [ + { + ...eventDetails, + event: eventId, + status, + }, + ], + }, + }), + { + onMutate: (payload) => { + const status = EventStatuses[payload.status]; + const previousStatus = eventDetails.status; + + status && onUpdateEventStatus(eventId, status); + + return { previousStatus }; + }, + onError: (error, payload, context) => { + showError({ message: i18n.t('An error occurred when updating event status') }); + log.error(errorCreator('An error occurred when updating event status')({ error, payload, context })); + context && onUpdateEventStatus(eventId, context.previousStatus); + }, + }, + ); + + const handleMenuItemClick = (status) => { + setActionsOpen(false); + !pendingApiResponse && updateEventStatus({ status }); + }; + + if (eventDetails.status === EventStatuses.SKIPPED) { + return ( + } + label={i18n.t('Unskip')} + onClick={() => handleMenuItemClick(EventStatuses.SCHEDULE)} + /> + ); + } + + return ( + } + label={i18n.t('Skip')} + onClick={() => handleMenuItemClick(EventStatuses.SKIPPED)} + /> + ); +}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/index.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/index.js new file mode 100644 index 0000000000..860c3a51f5 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/index.js @@ -0,0 +1,3 @@ +// @flow + +export { SkipAction } from './SkipAction'; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/index.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/index.js new file mode 100644 index 0000000000..acea1793f8 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/index.js @@ -0,0 +1,3 @@ +// @flow + +export { EventRow } from './EventRow'; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js index 2d1f6dd06d..e36d5f4b16 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js @@ -18,12 +18,15 @@ import { Button, Tooltip, } from '@dhis2/ui'; +import log from 'loglevel'; import { sortDataFromEvent } from './hooks/sortFuntions'; import { StageCreateNewButton } from '../StageCreateNewButton'; import { useComputeDataFromEvent, useComputeHeaderColumn, formatRowForView } from './hooks/useEventList'; import { DEFAULT_NUMBER_OF_ROW, SORT_DIRECTION } from './hooks/constants'; import { getProgramAndStageForProgram } from '../../../../../metaData/helpers'; import type { Props } from './stageDetail.types'; +import { EventRow } from './EventRow'; +import { errorCreator } from '../../../../../../capture-core-utils'; const styles = { @@ -32,10 +35,6 @@ const styles = { whiteSpace: 'nowrap', cursor: 'pointer', }, - rowDisabled: { - cursor: 'not-allowed', - opacity: 0.5, - }, container: { display: 'flex', flexDirection: 'column', @@ -100,10 +99,14 @@ const StageDetailPlain = (props: Props) => { repeatable = false, enableUserAssignment = false, onEventClick, + onDeleteEvent, + onUpdateEventStatus, + onRollbackDeleteEvent, onViewAll, onCreateNew, hiddenProgramStage, - classes } = props; + classes, + } = props; const defaultSortState = { columnName: 'status', sortDirection: SORT_DIRECTION.DESC, @@ -158,6 +161,8 @@ const StageDetailPlain = (props: Props) => { className={classes.row} > {headerCells} + + ); } @@ -205,15 +210,28 @@ const StageDetailPlain = (props: Props) => { )} )); + const eventDetails = events.find(event => event.event === row.id); + if (!eventDetails) { + log.error(errorCreator('Event details not found')({ row })); + return null; + } return ( - - {cells} - + ); }); } diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/stageDetail.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/stageDetail.types.js index 31d8c79dea..d5a07514d3 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/stageDetail.types.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/stageDetail.types.js @@ -1,7 +1,7 @@ // @flow import type { StageDataElement, StageCommonProps } from '../../../types/common.types'; - type ExtractedProps = {| +type ExtractedProps = {| events: Array, dataElements: Array, eventName: string, @@ -9,6 +9,10 @@ import type { StageDataElement, StageCommonProps } from '../../../types/common.t repeatable?: boolean, enableUserAssignment?: boolean, stageId: string, + onCreateNew: (stageId: string) => void, + onDeleteEvent: (eventId: string) => void, + onUpdateEventStatus: (eventId: string, status: string) => void, + onRollbackDeleteEvent: (eventId: ApiEnrollmentEvent) => void, hiddenProgramStage?: boolean, ...CssClasses, |}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/stage.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/stage.types.js index d8ce73c7e6..10be4ac00d 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/stage.types.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/stage.types.js @@ -7,6 +7,9 @@ type ExtractedProps = {| events: Array, className?: string, onEventClick: (eventId: string) => void, + onDeleteEvent: (eventId: string) => void, + onUpdateEventStatus: (eventId: string, status: string) => void, + onRollbackDeleteEvent: (eventId: ApiEnrollmentEvent) => void, ...CssClasses, |}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/stages.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/stages.types.js index 82208aa356..c4ca0b8fd6 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/stages.types.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/stages.types.js @@ -5,6 +5,9 @@ export type PlainProps = {| stages: Array, events: Array, onEventClick: (eventId: string) => void, + onDeleteEvent: (eventId: string) => void, + onUpdateEventStatus: (eventId: string, status: string) => void, + onRollbackDeleteEvent: (eventId: ApiEnrollmentEvent) => void, ...StageCommonProps, ...CssClasses, |}; @@ -13,5 +16,8 @@ export type InputProps = {| stages?: Array, events?: ?Array, onEventClick: (eventId: string) => void, + onDeleteEvent: (eventId: string) => void, + onUpdateEventStatus: (eventId: string, status: string) => void, + onRollbackDeleteEvent: (eventId: ApiEnrollmentEvent) => void, ...StageCommonProps, |}; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/stagesAndEvents.types.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/stagesAndEvents.types.js index c7e2453f24..5dce9859fb 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/stagesAndEvents.types.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/stagesAndEvents.types.js @@ -6,6 +6,9 @@ type ExtractedProps = {| stages?: Array, events: ?Array, onEventClick: (eventId: string) => void, + onDeleteEvent: (eventId: string) => void, + onUpdateEventStatus: (eventId: string, status: string) => void, + onRollbackDeleteEvent: (eventId: ApiEnrollmentEvent) => void, className?: string, |}; diff --git a/src/core_modules/capture-core/reducers/descriptions/enrollmentDomain.reducerDescription.js b/src/core_modules/capture-core/reducers/descriptions/enrollmentDomain.reducerDescription.js index 2eecc8429a..f7ca795289 100644 --- a/src/core_modules/capture-core/reducers/descriptions/enrollmentDomain.reducerDescription.js +++ b/src/core_modules/capture-core/reducers/descriptions/enrollmentDomain.reducerDescription.js @@ -23,6 +23,8 @@ const { COMMIT_ENROLLMENT_EVENTS, ADD_PERSISTED_ENROLLMENT_EVENTS, COMMIT_ENROLLMENT_AND_EVENTS, + DELETE_ENROLLMENT_EVENT, + UPDATE_ENROLLMENT_EVENT_STATUS, } = enrollmentSiteActionTypes; const setAssignee = (state, action) => { @@ -98,6 +100,19 @@ export const enrollmentDomainDesc = createReducerDescription( return { ...state, enrollment: { ...state.enrollment, events } }; }, + [DELETE_ENROLLMENT_EVENT]: (state, { payload: { eventId } }) => { + const events = state.enrollment.events?.filter(event => event.event !== eventId); + return { ...state, enrollment: { ...state.enrollment, events } }; + }, + [UPDATE_ENROLLMENT_EVENT_STATUS]: (state, { payload: { eventId, status, updatedAt } }) => { + const events = state.enrollment.events?.map(event => + (event.event === eventId + ? { ...event, status, updatedAt } + : event), + ); + + return { ...state, enrollment: { ...state.enrollment, events } }; + }, [UPDATE_OR_ADD_ENROLLMENT_EVENTS]: ( state, { payload: { events } }, From 526c2bddbe58b95b4b4c66b262a6fd71f050f3f8 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 9 Sep 2024 09:34:03 +0200 Subject: [PATCH 05/91] chore(deps): revert actions/download-artifact from 4.1.7 to 2 in /.github/workflows (#3785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "chore(deps): bump actions/download-artifact from 2 to 4.1.7 in /.gith…" This reverts commit fb793cc695c6ac28ee6c8e7de6a670503f8b2394. --- .github/workflows/verify-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify-app.yml b/.github/workflows/verify-app.yml index 6b577c7a87..c8a7d22379 100644 --- a/.github/workflows/verify-app.yml +++ b/.github/workflows/verify-app.yml @@ -214,7 +214,7 @@ jobs: with: node-version: 18.x - - uses: actions/download-artifact@v4.1.7 + - uses: actions/download-artifact@v2 with: name: app-build From f6b7f3d89d5d24928a3a8c8c609611950820e272 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 9 Sep 2024 07:39:10 +0000 Subject: [PATCH 06/91] chore(release): cut 101.4.0 [skip release] # [101.4.0](https://github.com/dhis2/capture-app/compare/v101.3.3...v101.4.0) (2024-09-09) ### Features * [DHIS2-17878][DHIS2-17048] Add overflow menu with actions to stages&events ([#3756](https://github.com/dhis2/capture-app/issues/3756)) ([12af138](https://github.com/dhis2/capture-app/commit/12af1384f4ab4e9c6eeef2460bee7d53bfb6b8cc)) --- 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 5182a15d63..0eb9a40a3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.4.0](https://github.com/dhis2/capture-app/compare/v101.3.3...v101.4.0) (2024-09-09) + + +### Features + +* [DHIS2-17878][DHIS2-17048] Add overflow menu with actions to stages&events ([#3756](https://github.com/dhis2/capture-app/issues/3756)) ([12af138](https://github.com/dhis2/capture-app/commit/12af1384f4ab4e9c6eeef2460bee7d53bfb6b8cc)) + ## [101.3.3](https://github.com/dhis2/capture-app/compare/v101.3.2...v101.3.3) (2024-09-02) diff --git a/package.json b/package.json index dc54a5992a..8e93ee83a0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.3.3", + "version": "101.4.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.3.3", + "@dhis2/rules-engine-javascript": "101.4.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 fd771bc637..f4cb98057a 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.3.3", + "version": "101.4.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From bce1dc485bacc28061d87bdaf6ecd1ef3c237683 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Thu, 19 Sep 2024 09:07:30 +0200 Subject: [PATCH 07/91] refactor: bump download-artifact and upload-artifact version (#3800) --- .github/workflows/verify-app.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-app.yml b/.github/workflows/verify-app.yml index c8a7d22379..c0623e4d64 100644 --- a/.github/workflows/verify-app.yml +++ b/.github/workflows/verify-app.yml @@ -193,7 +193,7 @@ jobs: - name: Build run: yarn build - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: app-build path: | @@ -214,7 +214,7 @@ jobs: with: node-version: 18.x - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: name: app-build From a4464f431618200853772cc2546ea9adff515840 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Thu, 19 Sep 2024 09:29:12 +0200 Subject: [PATCH 08/91] fix(translations): sync translations from transifex (master) (#3805) --- i18n/ar.po | 23 ++++++- i18n/cs.po | 17 +++++ i18n/es.po | 38 +++++++--- i18n/es_419.po | 17 +++++ i18n/fr.po | 21 +++++- i18n/id.po | 21 +++++- i18n/lo.po | 25 +++++-- i18n/nb.po | 168 +++++++++++++++++++++++++++------------------ i18n/nl.po | 17 +++++ i18n/prs.po | 17 +++++ i18n/ps.po | 17 +++++ i18n/pt.po | 17 +++++ i18n/pt_BR.po | 21 +++++- i18n/ru.po | 21 +++++- i18n/uk.po | 17 +++++ i18n/ur.po | 17 +++++ i18n/uz_UZ_Cyrl.po | 17 +++++ i18n/uz_UZ_Latn.po | 17 +++++ i18n/vi.po | 17 +++++ i18n/zh.po | 17 +++++ i18n/zh_CN.po | 17 +++++ 21 files changed, 471 insertions(+), 88 deletions(-) diff --git a/i18n/ar.po b/i18n/ar.po index 4bb4146a90..b619c664e0 100644 --- a/i18n/ar.po +++ b/i18n/ar.po @@ -1316,6 +1316,9 @@ msgstr "" msgid "Event completed" msgstr "الحدث مكتمل" +msgid "The event cannot be edited after it has been completed" +msgstr "" + msgid "Back to all stages and events" msgstr "" @@ -1484,13 +1487,27 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" -msgid "To open this event, please wait until saving is complete" +msgid "An error occurred while deleting the event" msgstr "" -msgid "Show {{ rest }} more" +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" msgstr "" -msgid "Reset list" +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "تخطى" + +msgid "To open this event, please wait until saving is complete" +msgstr "" + +msgid "Show {{ rest }} more" msgstr "" msgid "Go to full {{ eventName }}" diff --git a/i18n/cs.po b/i18n/cs.po index 62ef1badcc..798be3e276 100644 --- a/i18n/cs.po +++ b/i18n/cs.po @@ -1535,6 +1535,23 @@ msgstr "Tato fáze může mít pouze jednu událost" msgid "New {{ eventName }} event" msgstr "Nová událost {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Přeskočit" + msgid "To open this event, please wait until saving is complete" msgstr "Chcete-li otevřít tuto událost, počkejte na dokončení ukládání" diff --git a/i18n/es.po b/i18n/es.po index 1b377c622d..6dd93902ff 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -3,7 +3,6 @@ # Sergio Valenzuela , 2020 # ericbp , 2021 # Jaime Bosque , 2021 -# Marta Vila , 2022 # Pablo Pajuelo Cabezas , 2022 # Prabhjot Singh, 2023 # Christian Atavillos, 2023 @@ -13,13 +12,15 @@ # Janeth Cruz, 2024 # Enzo Nicolas Rossi , 2024 # Viktor Varland , 2024 +# Marta Vila , 2024 +# Juan M Alcantara Acosta , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Juan M Alcantara Acosta , 2024\n" "Language-Team: Spanish (https://app.transifex.com/hisp-uio/teams/100509/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -848,6 +849,8 @@ msgid "" "The category option is not valid for the selected organisation unit. Please " "select a valid combination." msgstr "" +"La opción de categoría no es válida para la unidad organizativa " +"seleccionada. Seleccione una combinación válida." msgid "Please select {{category}}." msgstr "Seleccione {{category}}." @@ -1027,7 +1030,7 @@ msgid "Loading" msgstr "Cargando" msgid "An error occurred while loading the form" -msgstr "" +msgstr "Ocurrió un error al cargar el formulario" msgid "Possible duplicates found" msgstr "Posibles duplicados encontrados" @@ -1394,7 +1397,7 @@ msgid "Event completed" msgstr "Evento completado" msgid "The event cannot be edited after it has been completed" -msgstr "" +msgstr "El evento no admite cambios después de haber sido completado" msgid "Back to all stages and events" msgstr "Volver a todas las etapas y eventos" @@ -1560,7 +1563,7 @@ msgid "Enter details now" msgstr "Introducir datos ahora" msgid "Link to an existing" -msgstr "" +msgstr "Relacionar con ..." msgid "Scheduled date" msgstr "Fecha planificada" @@ -1572,7 +1575,7 @@ msgid "Please select a valid event" msgstr "Seleccione un evento válido" msgid "You do not have access to create events in this stage" -msgstr "" +msgstr "No cuenta con acceso para crear eventos en esta etapa" msgid "This stage can only have one event" msgstr "Esta etapa solo puede tener un evento" @@ -1580,6 +1583,25 @@ msgstr "Esta etapa solo puede tener un evento" msgid "New {{ eventName }} event" msgstr "Nuevo evento {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "Se produjo un error eliminando el evento" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" +"La eliminación de un evento es permanente y no se puede deshacer. ¿Está " +"seguro de que desea eliminar este evento?" + +msgid "An error occurred when updating event status" +msgstr "Ocurrió un error al actualizar el estado del evento" + +msgid "Unskip" +msgstr "des omitir" + +msgid "Skip" +msgstr "Omitir" + msgid "To open this event, please wait until saving is complete" msgstr "Para abrir este evento, espere hasta que se complete el guardado." @@ -1610,10 +1632,10 @@ msgid "Stages and Events" msgstr "Etapas y eventos" msgid "An error occurred while loading the widget." -msgstr "" +msgstr "Ha ocurrido un error al cargar el componente" msgid "View linked event" -msgstr "" +msgstr "Ver eventos relacionados" msgid "Scheduled" msgstr "Planificado" diff --git a/i18n/es_419.po b/i18n/es_419.po index 8bc4508cd5..1007032b9c 100644 --- a/i18n/es_419.po +++ b/i18n/es_419.po @@ -1518,6 +1518,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "Nuevo evento {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Omitir" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/fr.po b/i18n/fr.po index 894d0c288e..d8952a4af7 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -7,16 +7,16 @@ # Gabriela Rodriguez , 2024 # Yao Selom SAKA (HISP WCA) , 2024 # Elise Desailly, 2024 -# Bram Piot , 2024 # Viktor Varland , 2024 # Yayra Gomado , 2024 +# Bram Piot , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Yayra Gomado , 2024\n" +"Last-Translator: Bram Piot , 2024\n" "Language-Team: French (https://app.transifex.com/hisp-uio/teams/100509/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1548,6 +1548,23 @@ msgstr "Ce stade ne peut avoir qu'un seul événement" msgid "New {{ eventName }} event" msgstr "Nouvel événement {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Ignorer" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/id.po b/i18n/id.po index e251484c4c..450489bebe 100644 --- a/i18n/id.po +++ b/i18n/id.po @@ -8,15 +8,15 @@ # ratih syabrina, 2024 # Yusuf Setiawan , 2024 # Guardian Sanjaya , 2024 -# Aprisa Chrysantina , 2024 # Viktor Varland , 2024 +# Aprisa Chrysantina , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Aprisa Chrysantina , 2024\n" "Language-Team: Indonesian (https://app.transifex.com/hisp-uio/teams/100509/id/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1493,6 +1493,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Lewati" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/lo.po b/i18n/lo.po index b2da06a4c5..cb86ea18bc 100644 --- a/i18n/lo.po +++ b/i18n/lo.po @@ -4,15 +4,15 @@ # Saysamone Sibounma, 2023 # Somkhit Bouavong , 2024 # Thuy Nguyen , 2024 -# Viktor Varland , 2024 # Namwan Chanthavisouk, 2024 +# Viktor Varland , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Namwan Chanthavisouk, 2024\n" +"Last-Translator: Viktor Varland , 2024\n" "Language-Team: Lao (https://app.transifex.com/hisp-uio/teams/100509/lo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1336,7 +1336,7 @@ msgid "Event completed" msgstr "ກິດຈະກຳສຳເລັດແລ້ວ" msgid "The event cannot be edited after it has been completed" -msgstr "" +msgstr "ເຫດການດັ່ງກ່າວບໍ່ສາມາດແກ້ໄຂໄດ້ຫຼັງຈາກສໍາເລັດແລ້ວ" msgid "Back to all stages and events" msgstr "ກັບໄປທຸກຂັ້ນຕອນ ແລະ ເຫດການ" @@ -1497,7 +1497,7 @@ msgid "Please select a valid event" msgstr "ກະລຸນາເລືອກເຫດການທີ່ຖືກຕ້ອງ" msgid "You do not have access to create events in this stage" -msgstr "" +msgstr "ທ່ານບໍ່ມີສິດເຂົ້າເຖິງເພື່ອສ້າງເຫດການໃນຂັ້ນຕອນນີ້" msgid "This stage can only have one event" msgstr "ຂັ້ນຕອນນີ້ສາມາດມີເຫດການດຽວເທົ່ານັ້ນ" @@ -1505,6 +1505,23 @@ msgstr "ຂັ້ນຕອນນີ້ສາມາດມີເຫດການດ msgid "New {{ eventName }} event" msgstr "ເຫດການໃໝ່ {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "ຂ້າມ" + msgid "To open this event, please wait until saving is complete" msgstr "ເພື່ອເປີດເຫດການນີ້, ກະລຸນາລໍຖ້າຈົນກວ່າການບັນທຶກຈະສຳເລັດ" diff --git a/i18n/nb.po b/i18n/nb.po index 12080b29b7..2e64114b50 100644 --- a/i18n/nb.po +++ b/i18n/nb.po @@ -2,13 +2,14 @@ # Translators: # Karoline Tufte Lien , 2024 # Caroline Hesthagen Holen , 2024 +# Merethe Wollan Blisten, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Caroline Hesthagen Holen , 2024\n" +"Last-Translator: Merethe Wollan Blisten, 2024\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/hisp-uio/teams/100509/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -47,7 +48,7 @@ msgid "More" msgstr "Mer" msgid "View {{programName}} dashboard" -msgstr "Vis {{programName}} dashbord" +msgstr "Vis {{programName}} dashbord" msgid "View dashboard" msgstr "Vis dashbord" @@ -240,7 +241,7 @@ msgid "Completed" msgstr "Fullført" msgid "Please add or cancel note before saving the event" -msgstr "" +msgstr "Legg til eller avbryt notat før lagring" msgid "Save and add another" msgstr "Lagre og legg til en til" @@ -325,25 +326,25 @@ msgid "An error has occurred. See log for details" msgstr "Det har oppstått en feil. Se logg for detaljer" msgid "{{programStageName}} completed" -msgstr "" +msgstr "{{programStageName}} fullført" msgid "" "Would you like to complete the enrollment and all active events as well?" -msgstr "" +msgstr "Ønsker du å fullføre registreringen og alle aktive hendelser?" msgid "{{count}} event in {{programStageName}}" msgid_plural "{{count}} event in {{programStageName}}" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{{count}}hendelse i {{programStageName}}" +msgstr[1] "{{count}} hendelser i {{programStageName}}" msgid "Yes, complete enrollment and events" -msgstr "" +msgstr "Ja, fullfør registreringen og hendelsen. " msgid "Complete enrollment only" -msgstr "" +msgstr "Fullfør bare registreringen" msgid "Would you like to complete the enrollment?" -msgstr "" +msgstr "Ønsker du å fullføre registreringen?" msgid "Complete enrollment" msgstr "Fullfør registrering" @@ -378,10 +379,10 @@ msgid "validation failed" msgstr "validering mislyktes" msgid "No feedback for this event yet" -msgstr "" +msgstr "Det er ingen tilbakemeldinger på denne hendelsen " msgid "No indicator output for this event yet" -msgstr "" +msgstr "Det er ingen indikatorresulater for denne hendelsen " msgid "Generate new event" msgstr "Generer en ny hendelse" @@ -563,7 +564,7 @@ msgid "Column" msgstr "Kolonne" msgid "Visible" -msgstr "" +msgstr "Synlig" msgid "Update" msgstr "Oppdater" @@ -605,7 +606,7 @@ msgid "Program doesn't exist" msgstr "Programmet finnes ikke" msgid "Selected program is invalid for selected organisation unit" -msgstr "" +msgstr "Valgt program er ugyldig for valgt organisajonsenhet" msgid "Online" msgstr "Påkoblet" @@ -620,10 +621,10 @@ msgid "Add note" msgstr "Legg til notat" msgid "You don't have access to write notes" -msgstr "" +msgstr "Du har ikke tilgang til å skrive notater" msgid "Write note" -msgstr "" +msgstr "Skriv notat" msgid "was blanked out and hidden by your last action" msgstr "ble tømt og skjult av den siste handlingen din" @@ -790,7 +791,7 @@ msgid "There was an error loading the page" msgstr "Det oppsto en feil under lasting av siden" msgid "Choose an organisation unit to start reporting" -msgstr "" +msgstr "Velg en organisasjonsenhet for å starte rapportering" msgid "Program stage is invalid" msgstr "Programfase er ugyldig" @@ -805,7 +806,7 @@ msgid "Refer" msgstr "Henvis" msgid "You can't add any more {{ programStageName }} events" -msgstr "Du kan ikke legge til flere {{ programStageName }}-hendelser" +msgstr "Du kan ikke legge til flere {{ programStageName }} hendelser" msgid "Cancel without saving" msgstr "Avbryt uten å lagre" @@ -826,6 +827,8 @@ msgid "" "The category option is not valid for the selected organisation unit. Please " "select a valid combination." msgstr "" +"Valgt kategori er ikke gyldig for valgt organisasjonsenhet. Velg en gyldig " +"kombinasjon. " msgid "Please select {{category}}." msgstr "Velg {{category}}." @@ -842,7 +845,7 @@ msgstr "Vennligst velg en organisasjonsenhet" msgid "" "You don't have access to create a {{trackedEntityName}} in the current " "selections" -msgstr "" +msgstr "Du har ikke tilgang til å lage en {{trackedEntityName}} her" msgid "Choose the {{missingCategories}} to start reporting" msgstr "Velg {{missingCategories}} for å starte rapportering" @@ -931,7 +934,7 @@ msgid "Edit event" msgstr "Rediger hendelse" msgid "View changelog" -msgstr "" +msgstr "Vis endringslogg" msgid "Event details" msgstr "Hendelsesdetaljer" @@ -987,8 +990,8 @@ msgstr "Søk etter attributter" msgid "Fill in at least {{count}} attribute to search" msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Fyll inn minst {{count}}attributt for å søke" +msgstr[1] "Fyll inn minst {{count}} attributter for å søke" msgid "Could not retrieve metadata. Please try again later." msgstr "Kunne ikke hente metadata. Prøv igjen senere." @@ -1000,7 +1003,7 @@ msgid "Loading" msgstr "Laster" msgid "An error occurred while loading the form" -msgstr "" +msgstr "Det oppsto en feil ved åpning av skjemaet" msgid "Possible duplicates found" msgstr "Mulige duplikater funnet" @@ -1021,7 +1024,7 @@ msgid "No results found for " msgstr "Ingen resultater funnet for" msgid "Choose an organisation unit" -msgstr "" +msgstr "Velg en organisasjonsenhet" msgid "Clear selection" msgstr "Fjern valg" @@ -1033,7 +1036,7 @@ msgid "Search for a program" msgstr "Søk for et program" msgid "Some programs are being filtered by the chosen organisation unit" -msgstr "" +msgstr "Filtreringen av programmer påvirkes av valgt organisasjonsenhet" msgid "Show all programs" msgstr "Vis alle programmer" @@ -1086,8 +1089,8 @@ msgid "" "Fill in at least {{minAttributesRequiredToSearch}} of these fields to " "search{{escape}} {{searchableAttributes}}" msgstr "" -"Fyll ut minst {{minAttributesRequiredToSearch}} av disse feltene for å " -"søke{{escape}} {{searchableAttributes}}" +"Fyll ut minst {{minAttributesRequiredToSearch}} av disse feltene for å søke " +"{{escape}} {{searchableAttributes}}" msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" msgstr "Fyll ut dette feltet for å søke {{escape}} {{searchableAttributes}}" @@ -1133,7 +1136,7 @@ msgid "Create saved list" msgstr "Lag lagret liste" msgid "Create new in another program" -msgstr "" +msgstr "Opprett ny i et annet program" msgid "Create new event" msgstr "Opprett ny hendelse" @@ -1142,7 +1145,7 @@ msgid "Search for a {{trackedEntityName}} in {{programName}}" msgstr "Søk etter {{trackedEntityName}} i {{programName}}" msgid "No tracked entity types available" -msgstr "" +msgstr "Det er ingen sporbare enhetstyper tilgjengelig" msgid "Assigned to" msgstr "Tildelt til" @@ -1226,10 +1229,10 @@ msgid "Mark for follow-up" msgstr "Merk for oppfølging" msgid "Transfer" -msgstr "" +msgstr "Overfør " msgid "An error occurred while transferring ownership" -msgstr "" +msgstr "En feil oppsto ved overføring av eierskapet " msgid "Existing dates for auto-generated events will not be updated." msgstr "" @@ -1264,19 +1267,25 @@ msgid "" "Transferring enrollment ownership from {{ownerOrgUnit}} to " "{{newOrgUnit}}{{escape}}" msgstr "" +"Overfør eierskapet til registreringen fra {{ownerOrgUnit}} til " +"{{newOrgUnit}} {{escape}}" msgid "" "You will lose access to the enrollment when transferring ownership to " "{{organisationUnit}}." msgstr "" +"Du vil miste tilgangen til hendelsen når eierskapet overføres til " +"{{organisationUnit}}." msgid "Transfer Ownership" -msgstr "" +msgstr "Overfør eierskap" msgid "" "Choose the organisation unit to which enrollment ownership should be " "transferred." msgstr "" +"Velg hvilke organisajonsenhet som skal overta eierskapet til denne " +"registreringen. " msgid "Enrollment date" msgstr "Registreringsdato" @@ -1307,6 +1316,8 @@ msgstr "Legg til område" msgid "Please add or cancel the note before saving the event" msgstr "" +"Du må legge til eller avbryt registreringen i notatet før hendelsen kan " +"lagres. " msgid "organisation unit could not be retrieved. Please try again later." msgstr "organisasjonsenheten kunne ikke hentes. Prøv igjen senere." @@ -1318,13 +1329,13 @@ msgid "program or stage is invalid" msgstr "program eller fase er ugyldig" msgid "Notes about this enrollment" -msgstr "" +msgstr "Notater om denne registreringen" msgid "Write a note about this enrollment" -msgstr "" +msgstr "Skriv et notat om denne registreringen" msgid "This enrollment doesn't have any notes" -msgstr "" +msgstr "Denne registreringen har ingen notater" msgid "Error" msgstr "Feil" @@ -1351,19 +1362,19 @@ msgid "Event completed" msgstr "Hendelse fullført" msgid "The event cannot be edited after it has been completed" -msgstr "" +msgstr "Hendelsen kan ikke redigeres etter at den er fullført" msgid "Back to all stages and events" msgstr "Tilbake til alle faser og hendelser" msgid "Notes about this event" -msgstr "" +msgstr "Notater om denne hendelsen" msgid "Write a note about this event" -msgstr "" +msgstr "Skriv et notat om denne hendelsen" msgid "This event doesn't have any notes" -msgstr "" +msgstr "Denne hendelsen har ingen notater" msgid "Schedule date info" msgstr "Informasjon for planlagt dato" @@ -1410,10 +1421,10 @@ msgid "Schedule date / Due date" msgstr "Planlagt dato / Forfallsdato" msgid "Event notes" -msgstr "" +msgstr "Hendelsesnotater" msgid "Write a note about this scheduled event" -msgstr "" +msgstr "Skriv et notat om denne planlagte hendelsen" msgid "Save note" msgstr "Lagre notat" @@ -1452,57 +1463,62 @@ msgid "Fix errors in the form to continue." msgstr "Rett opp feil i skjemaet for å fortsette." msgid "You do not have access to delete this {{trackedEntityTypeName}}" -msgstr "" +msgstr "Du har ikke tilgang til å slette denne {{trackedEntityTypeName}}" msgid "Delete {{trackedEntityTypeName}}" -msgstr "" +msgstr "Slett {{trackedEntityTypeName}}" msgid "" "Are you sure you want to delete this {{trackedEntityTypeName}}? This will " "permanently remove the {{trackedEntityTypeName}} and all its associated " "enrollments and events in all programs." msgstr "" +"Er du sikker på at du vil slette {{trackedEntityTypeName}}? Sletting vil " +"permanent fjerne {{trackedEntityTypeName}} og alle tilhørende " +"registreringer og hendelser i alle programmer. " msgid "There was a problem deleting the {{trackedEntityTypeName}}" -msgstr "" +msgstr "Det oppsto et problem ved sletting av {{trackedEntityTypeName}}" msgid "Yes, delete {{trackedEntityTypeName}}" -msgstr "" +msgstr "Ja, slett {{trackedEntityTypeName}}" msgid "Profile widget could not be loaded. Please try again later" msgstr "Profil -widgeten kunne ikke lastes inn. Prøv igjen senere" msgid "{{trackedEntityTypeName}} profile" -msgstr "" +msgstr "{{trackedEntityTypeName}} profil" msgid "tracked entity instance" msgstr "Sporet enhetforekomst" msgid "Link to an existing {{linkableStageLabel}}" -msgstr "" +msgstr "Link til eksisterende {{linkableStageLabel}}" msgid "Choose a {{linkableStageLabel}}" -msgstr "" +msgstr "Velg en {{linkableStageLabel}}" msgid "{{ linkableStageLabel }} is not repeatable" -msgstr "" +msgstr "{{ linkableStageLabel }} er ikke repiterbar" msgid "{{ linkableStageLabel }} has no linkable events" -msgstr "" +msgstr "{{ linkableStageLabel }} har ingen hendelser som kan kobles til" msgid "Ambiguous relationships, contact system administrator" -msgstr "" +msgstr "Uklare relasjoner, kontakt din systemadministrator" msgid "" "Enter {{linkableStageLabel}} details in the next step after completing this " "{{currentStageLabel}}." msgstr "" +"Skriv inn {{linkableStageLabel}}detaljer i neste trinn etter du har fullført" +" dette {{currentStageLabel}}." msgid "Enter details now" -msgstr "" +msgstr "Skriv inn detaljer " msgid "Link to an existing" -msgstr "" +msgstr "Koble til en eksisterende" msgid "Scheduled date" msgstr "Planlagt dato" @@ -1511,10 +1527,11 @@ msgid "Report date" msgstr "Rapporteringsdato" msgid "Please select a valid event" -msgstr "" +msgstr "Velg en gyldig hendelse" msgid "You do not have access to create events in this stage" msgstr "" +"Du har ikke rettigheter til å opprette en hendelse i dette programsteget. " msgid "This stage can only have one event" msgstr "Denne fasen kan bare ha en hendelse" @@ -1522,6 +1539,25 @@ msgstr "Denne fasen kan bare ha en hendelse" msgid "New {{ eventName }} event" msgstr "Ny {{ eventName }} hendelse" +msgid "An error occurred while deleting the event" +msgstr "Det oppstå en feil ved sletting av hendelsen. " + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" +"Sletting av hendelsen er permanent og kan ikke angres. Er du sikker på at du" +" vil slette denne hendelsen?" + +msgid "An error occurred when updating event status" +msgstr "En feil oppsto ved oppdatering av status på hendelsen. " + +msgid "Unskip" +msgstr "Ikke hoppe over" + +msgid "Skip" +msgstr "Hopp over" + msgid "To open this event, please wait until saving is complete" msgstr "For å åpne denne hendelsen, vennligst vent til lagringen er fullført" @@ -1536,8 +1572,8 @@ msgstr "Hendelser kunne ikke hentes. Prøv igjen senere." msgid "{{ count }} event" msgid_plural "{{ count }} event" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{{ count }} hendelse" +msgstr[1] "{{count}} hendelse" msgid "{{ overdueEvents }} overdue" msgstr "{{ overdueEvents }} forfalt" @@ -1549,19 +1585,19 @@ msgid "Stages and Events" msgstr "Faser og hendelser" msgid "An error occurred while loading the widget." -msgstr "" +msgstr "En feil oppstå ved lasting av widget. " msgid "View linked event" -msgstr "" +msgstr "Vis knyttede hendelser" msgid "Scheduled" msgstr "Planlagt" msgid "Changelog" -msgstr "" +msgstr "Endringslogg" msgid "No changes to display" -msgstr "" +msgstr "Ingen endringer å vise" msgid "Created" msgstr "Opprettet" @@ -1579,10 +1615,10 @@ msgid "Data item" msgstr "Datapunkt" msgid "Change" -msgstr "" +msgstr "Endre" msgid "New {{trackedEntityTypeName}} relationship" -msgstr "Ny {{trackedEntityTypeName}}relasjon" +msgstr "Ny {{trackedEntityTypeName}} relasjon" msgid "Missing implementation step" msgstr "Manglende implementeringstrinn" @@ -1604,7 +1640,7 @@ msgid "" msgstr "Noe gikk galt under innlasting av relasjoner. Prøv igjen senere." msgid "{{trackedEntityTypeName}} relationships" -msgstr "{{trackedEntityTypeName}}-relasjoner" +msgstr "{{trackedEntityTypeName}} relasjoner" msgid "Delete relationship" msgstr "Slett relasjon" @@ -1613,12 +1649,14 @@ msgid "" "Deleting the relationship is permanent and cannot be undone. Are you sure " "you want to delete this relationship?" msgstr "" +"Sletting av relasjonen er permanent og kan ikke angres. Er du sikker på at " +"du vil slette relasjonen?" msgid "Yes, delete relationship" -msgstr "" +msgstr "Slett relasjon" msgid "An error occurred while deleting the relationship." -msgstr "" +msgstr "Det oppsto en feil ved sletting av relasjonen. " msgid "To open this relationship, please wait until saving is complete" msgstr "For å åpne denne relasjonen, vennligst vent til lagringen er fullført" diff --git a/i18n/nl.po b/i18n/nl.po index 05303720b5..31991c9398 100644 --- a/i18n/nl.po +++ b/i18n/nl.po @@ -1548,6 +1548,23 @@ msgstr "Deze fase kan maar één evenement hebben" msgid "New {{ eventName }} event" msgstr "Nieuwe {{ eventName }} evenement" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Overslaan" + msgid "To open this event, please wait until saving is complete" msgstr "Wacht tot het opslaan is voltooid om dit evenement te openen" diff --git a/i18n/prs.po b/i18n/prs.po index e8fcb7ddf2..89f3234f12 100644 --- a/i18n/prs.po +++ b/i18n/prs.po @@ -1456,6 +1456,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "اسکیپ" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/ps.po b/i18n/ps.po index ada1358d93..31f1707af2 100644 --- a/i18n/ps.po +++ b/i18n/ps.po @@ -1457,6 +1457,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "ترې تېر شئ" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/pt.po b/i18n/pt.po index c7c2353c06..306edb6cbd 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -1543,6 +1543,23 @@ msgstr "Esta etapa só pode ter um evento" msgid "New {{ eventName }} event" msgstr "Novo evento de {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Saltar" + msgid "To open this event, please wait until saving is complete" msgstr "" "Para abrir este evento, aguarde até que o processo de gravar seja concluído" diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po index b968595bfc..00cd51c882 100644 --- a/i18n/pt_BR.po +++ b/i18n/pt_BR.po @@ -2,15 +2,15 @@ # Translators: # Oscar Mesones Lapouble , 2021 # Philip Larsen Donnelly, 2024 -# Thiago Rocha, 2024 # Viktor Varland , 2024 +# Thiago Rocha, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Thiago Rocha, 2024\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/hisp-uio/teams/100509/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1463,6 +1463,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Pular" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/ru.po b/i18n/ru.po index cfd4926b7f..ff0df86178 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -3,15 +3,15 @@ # Ulanbek Abakirov , 2020 # Wanda , 2021 # Yury Rogachev , 2024 -# Philip Larsen Donnelly, 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Russian (https://app.transifex.com/hisp-uio/teams/100509/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1578,6 +1578,23 @@ msgstr "Данный этап позволяет создать только о msgid "New {{ eventName }} event" msgstr "Новое событие {{ eventName }} " +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Пропустить" + msgid "To open this event, please wait until saving is complete" msgstr "Чтобы открыть это событие, дождитесь завершения сохранения" diff --git a/i18n/uk.po b/i18n/uk.po index dd5ad8b73b..c51bff2210 100644 --- a/i18n/uk.po +++ b/i18n/uk.po @@ -1468,6 +1468,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Пропустити" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/ur.po b/i18n/ur.po index 69cec58a92..ce4b3021c3 100644 --- a/i18n/ur.po +++ b/i18n/ur.po @@ -1457,6 +1457,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "چھوڑ دو" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/uz_UZ_Cyrl.po b/i18n/uz_UZ_Cyrl.po index 96a05d6a51..6ca571beea 100644 --- a/i18n/uz_UZ_Cyrl.po +++ b/i18n/uz_UZ_Cyrl.po @@ -1491,6 +1491,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Ўтказиб юбориш" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/uz_UZ_Latn.po b/i18n/uz_UZ_Latn.po index 217bfb6e90..0379eb17c6 100644 --- a/i18n/uz_UZ_Latn.po +++ b/i18n/uz_UZ_Latn.po @@ -1479,6 +1479,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Oʼtkazib yuborish" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/vi.po b/i18n/vi.po index 6df6022cce..8e1ac63a89 100644 --- a/i18n/vi.po +++ b/i18n/vi.po @@ -1477,6 +1477,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "Bỏ qua" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/zh.po b/i18n/zh.po index a5216b482f..70a175384c 100644 --- a/i18n/zh.po +++ b/i18n/zh.po @@ -1464,6 +1464,23 @@ msgstr "这个阶段只能有一个事件" msgid "New {{ eventName }} event" msgstr "新的 {{ eventName }} 事件" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "跳过" + msgid "To open this event, please wait until saving is complete" msgstr "要打开此活动,请等待保存完成" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po index a23db1a424..2216a33b29 100644 --- a/i18n/zh_CN.po +++ b/i18n/zh_CN.po @@ -1461,6 +1461,23 @@ msgstr "这个阶段只能有一个事件" msgid "New {{ eventName }} event" msgstr "新的 {{ eventName }} 事件" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "跳过" + msgid "To open this event, please wait until saving is complete" msgstr "要打开此活动,请等待保存完成" From c256a1293339f4dd33f49acc49f350cb0fb42688 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Thu, 19 Sep 2024 07:38:37 +0000 Subject: [PATCH 09/91] chore(release): cut 101.4.1 [skip release] ## [101.4.1](https://github.com/dhis2/capture-app/compare/v101.4.0...v101.4.1) (2024-09-19) ### Bug Fixes * **translations:** sync translations from transifex (master) ([#3805](https://github.com/dhis2/capture-app/issues/3805)) ([a4464f4](https://github.com/dhis2/capture-app/commit/a4464f431618200853772cc2546ea9adff515840)) --- 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 0eb9a40a3c..95e021f34b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.4.1](https://github.com/dhis2/capture-app/compare/v101.4.0...v101.4.1) (2024-09-19) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([#3805](https://github.com/dhis2/capture-app/issues/3805)) ([a4464f4](https://github.com/dhis2/capture-app/commit/a4464f431618200853772cc2546ea9adff515840)) + # [101.4.0](https://github.com/dhis2/capture-app/compare/v101.3.3...v101.4.0) (2024-09-09) diff --git a/package.json b/package.json index 8e93ee83a0..efb07db0ef 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.4.0", + "version": "101.4.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.4.0", + "@dhis2/rules-engine-javascript": "101.4.1", "@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 f4cb98057a..e4e1b00d9d 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.4.0", + "version": "101.4.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 562b03a1cf2cb5cff5382bd433943f289c860095 Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:51:05 +0200 Subject: [PATCH 10/91] feat: [DHIS2-17770] Org unit contextualization in self contained widgets (#3720) * feat: org unit context in Stages and Events widget * feat: orgunit in enrollment widget completed * fix: lint * feat: profile widget org unit tooltip completed * fix: remove unused component * fix: error in getOrgUnitNames * fix: cache * fix: disabled value * fix: review changes * fix: restructure cache * fix: set back to right cache * fix: cache structure for useorgunitnames * feat: follow cache standard for all functions * fix: move full path hook * fix: change cache name * fix: undefined value for ancestor * fix: remove level * feat: use recursion * fix: remove console log * fix: changes on recursion * fix: remove unnecessary function from recursion * fix: code clean up * feat: change to clienttolist for widgetenrollment * fix: missing orgunitname in chip component * fix: change to orgunitname * fix: change to clienttolist in widgetprofile * fix: set back to name * feat: change from orgunitname to name * fix: set back to cleint to view * fix: review changes for orgunitname file * feat: remove id from ancestors * feat: change tooltip component * feat: clean up for tooltip * fix: merge with master * fix: after review changes * fix: cy test --- .../WidgetEnrollment/index.js | 8 +- i18n/en.pot | 10 +- .../CardList/CardListItem.component.js | 4 +- .../TeiRegistrationEntry.component.js | 4 +- .../ScopeSelector/ScopeSelector.container.js | 4 +- .../TooltipOrgUnit.component.js | 18 +++ .../Tooltips/TooltipOrgUnit/index.js | 1 + .../InfoBoxes/InfoBoxes.component.js | 6 +- .../WidgetEnrollment.component.js | 21 +-- .../WidgetEnrollment.container.js | 4 +- .../WidgetEventSchedule.container.js | 4 +- .../WidgetProfile/WidgetProfile.component.js | 4 +- .../WidgetProfile/hooks/getSubValueForTei.js | 11 +- .../FlatListOrgUnitField.js | 4 +- .../capture-core/converters/clientToView.js | 26 ++- .../metadataRetrieval/orgUnitName/index.js | 2 +- .../orgUnitName/orgUnitName.js | 152 +++++++++++------- .../capture-ui/FlatList/flatList.types.js | 4 +- 18 files changed, 179 insertions(+), 108 deletions(-) create mode 100644 src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js create mode 100644 src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/index.js diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js b/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js index 7ad8539f77..ca5bef0b08 100644 --- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js +++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js @@ -66,7 +66,7 @@ Then('the user sees the enrollment organisation unit', () => { cy.get('[data-test="widget-enrollment"]').within(() => { cy.get('[data-test="widget-enrollment-icon-orgunit"]').should('exist'); cy.get('[data-test="widget-enrollment-orgunit"]') - .contains('Started at Ngelehun CHC') + .contains('Started at: Ngelehun CHC') .should('exist'); }); }); @@ -77,7 +77,7 @@ Then('the user sees the owner organisation unit', () => { 'exist', ); cy.get('[data-test="widget-enrollment-owner-orgunit"]') - .contains('Owned by Ngelehun CHC') + .contains('Owned by: Ngelehun CHC') .should('exist'); }); }); @@ -232,7 +232,7 @@ Then(/^the user successfully transfers the enrollment/, () => { cy.get('[data-test="widget-enrollment"]').within(() => { cy.get('[data-test="widget-enrollment-owner-orgunit"]') - .contains('Owned by Njandama MCHP') + .contains('Owned by: Njandama MCHP') .should('exist'); }); }); @@ -246,7 +246,7 @@ Then(/^the user types in (.*)/, (orgunit) => { Given(/^the enrollment owner organisation unit is (.*)/, (orgunit) => { cy.get('[data-test="widget-enrollment"]').within(() => { cy.get('[data-test="widget-enrollment-owner-orgunit"]') - .contains(`Owned by ${orgunit}`) + .contains(`Owned by: ${orgunit}`) .should('exist'); }); }); diff --git a/i18n/en.pot b/i18n/en.pot index cae303cf0b..5d63ac1048 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-08-10T10:42:21.141Z\n" -"PO-Revision-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"PO-Revision-Date: 2024-09-02T11:08:16.281Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." @@ -1281,12 +1281,6 @@ msgstr "Enrollment widget could not be loaded. Please try again later" msgid "Follow-up" msgstr "Follow-up" -msgid "Started at {{orgUnitName}}" -msgstr "Started at {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Owned by {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Cancelled" diff --git a/src/core_modules/capture-core/components/CardList/CardListItem.component.js b/src/core_modules/capture-core/components/CardList/CardListItem.component.js index d411d1a933..17b7513ce8 100644 --- a/src/core_modules/capture-core/components/CardList/CardListItem.component.js +++ b/src/core_modules/capture-core/components/CardList/CardListItem.component.js @@ -15,7 +15,7 @@ import { searchScopes } from '../SearchBox'; import { enrollmentTypes } from './CardList.constants'; import { ListEntry } from './ListEntry.component'; import { dataElementTypes, getTrackerProgramThrowIfNotFound } from '../../metaData'; -import { useOrgUnitName } from '../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../metadataRetrieval/orgUnitName'; import type { ListItem, RenderCustomCardActions } from './CardList.types'; type OwnProps = $ReadOnly<{| @@ -144,7 +144,7 @@ const CardListItemIndex = ({ const enrollments = item.tei ? item.tei.enrollments : []; const enrollmentType = deriveEnrollmentType(enrollments, currentProgramId); const { orgUnitId, enrolledAt } = deriveEnrollmentOrgUnitIdAndDate(enrollments, enrollmentType, currentProgramId); - const { displayName: orgUnitName } = useOrgUnitName(orgUnitId); + const { displayName: orgUnitName } = useOrgUnitNameWithAncestors(orgUnitId); const program = enrollments && enrollments.length ? deriveProgramFromEnrollment(enrollments, currentSearchScopeType) : undefined; diff --git a/src/core_modules/capture-core/components/DataEntries/TeiRegistrationEntry/TeiRegistrationEntry.component.js b/src/core_modules/capture-core/components/DataEntries/TeiRegistrationEntry/TeiRegistrationEntry.component.js index 457fe3a112..14d9395f29 100644 --- a/src/core_modules/capture-core/components/DataEntries/TeiRegistrationEntry/TeiRegistrationEntry.component.js +++ b/src/core_modules/capture-core/components/DataEntries/TeiRegistrationEntry/TeiRegistrationEntry.component.js @@ -8,7 +8,7 @@ import { useScopeInfo } from '../../../hooks/useScopeInfo'; import { scopeTypes } from '../../../metaData'; import { TrackedEntityInstanceDataEntry } from '../TrackedEntityInstance'; import { useCurrentOrgUnitId } from '../../../hooks/useCurrentOrgUnitId'; -import { useOrgUnitName } from '../../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../../metadataRetrieval/orgUnitName'; import type { Props, PlainProps } from './TeiRegistrationEntry.types'; import { DiscardDialog } from '../../Dialogs/DiscardDialog.component'; import { withSaveHandler } from '../../DataEntry'; @@ -54,7 +54,7 @@ const TeiRegistrationEntryPlain = const { scopeType } = useScopeInfo(selectedScopeId); const { formId, formFoundation } = useMetadataForRegistrationForm({ selectedScopeId }); const orgUnitId = useCurrentOrgUnitId(); - const { displayName: orgUnitName } = useOrgUnitName(orgUnitId); + const { displayName: orgUnitName } = useOrgUnitNameWithAncestors(orgUnitId); const handleOnCancel = () => { if (!isUserInteractionInProgress) { diff --git a/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.container.js b/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.container.js index 0fdb374e16..6199295503 100644 --- a/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.container.js +++ b/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.container.js @@ -3,7 +3,7 @@ import React, { type ComponentType, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { ScopeSelectorComponent } from './ScopeSelector.component'; import type { OwnProps } from './ScopeSelector.types'; -import { useOrgUnitName } from '../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../metadataRetrieval/orgUnitName'; import { resetOrgUnitIdFromScopeSelector } from './ScopeSelector.actions'; @@ -34,7 +34,7 @@ export const ScopeSelector: ComponentType = ({ }) => { const dispatch = useDispatch(); const [selectedOrgUnit, setSelectedOrgUnit] = useState({ name: undefined, id: selectedOrgUnitId }); - const { displayName, error: ouNameError } = useOrgUnitName(selectedOrgUnit.id); + const { displayName, error: ouNameError } = useOrgUnitNameWithAncestors(selectedOrgUnit.id); useEffect(() => { if (displayName && selectedOrgUnit.name !== displayName) { diff --git a/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js new file mode 100644 index 0000000000..8b756f7e9c --- /dev/null +++ b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js @@ -0,0 +1,18 @@ +// @flow +import React from 'react'; +import { Tooltip } from '@dhis2/ui'; + +type Props = { + orgUnitName: string, + ancestors?: Array, +}; + +export const TooltipOrgUnit = ({ orgUnitName, ancestors = [] }: Props) => { + const fullPath = [...ancestors, orgUnitName].join(' / '); + + return ( + + {orgUnitName} + + ); +}; diff --git a/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/index.js b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/index.js new file mode 100644 index 0000000000..046747ddff --- /dev/null +++ b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/index.js @@ -0,0 +1 @@ +export { TooltipOrgUnit } from './TooltipOrgUnit.component'; diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/TransferModal/InfoBoxes/InfoBoxes.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/TransferModal/InfoBoxes/InfoBoxes.component.js index 3c91794004..2cb21e6f98 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollment/TransferModal/InfoBoxes/InfoBoxes.component.js +++ b/src/core_modules/capture-core/components/WidgetEnrollment/TransferModal/InfoBoxes/InfoBoxes.component.js @@ -4,7 +4,7 @@ import cx from 'classnames'; import { withStyles } from '@material-ui/core/styles'; import { colors, IconInfo16, IconWarning16 } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; -import { useOrgUnitName } from '../../../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../../../metadataRetrieval/orgUnitName'; import { OrgUnitScopes } from '../hooks/useTransferValidation'; import { ProgramAccessLevels } from '../hooks/useProgramAccessLevel'; @@ -48,8 +48,8 @@ const InfoBoxesPlain = ({ orgUnitScopes, classes, }: Props) => { - const { displayName: ownerOrgUnitName } = useOrgUnitName(ownerOrgUnitId); - const { displayName: newOrgUnitName } = useOrgUnitName(validOrgUnitId); + const { displayName: ownerOrgUnitName } = useOrgUnitNameWithAncestors(ownerOrgUnitId); + const { displayName: newOrgUnitName } = useOrgUnitNameWithAncestors(validOrgUnitId); const showWarning = [ProgramAccessLevels.PROTECTED, ProgramAccessLevels.CLOSED].includes(programAccessLevel) && orgUnitScopes.destination === OrgUnitScopes.SEARCH; diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js index 1bbeed7d79..3bec583e85 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js +++ b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js @@ -17,7 +17,8 @@ import { Widget } from '../Widget'; import type { PlainProps } from './enrollment.types'; import { Status } from './Status'; import { dataElementTypes } from '../../metaData'; -import { useOrgUnitName } from '../../metadataRetrieval/orgUnitName'; +import { convertValue } from '../../converters/clientToView'; +import { useOrgUnitNameWithAncestors } from '../../metadataRetrieval/orgUnitName'; import { Date } from './Date'; import { Actions } from './Actions'; import { MiniMap } from './MiniMap'; @@ -69,11 +70,16 @@ export const WidgetEnrollmentPlain = ({ onUpdateEnrollmentStatusError, onUpdateEnrollmentStatusSuccess, onAccessLostFromTransfer, + type = dataElementTypes.ORGANISATION_UNIT, }: PlainProps) => { const [open, setOpenStatus] = useState(true); const { fromServerDate } = useTimeZoneConversion(); const geometryType = getGeometryType(enrollment?.geometry?.type); - const { displayName: orgUnitName } = useOrgUnitName(enrollment?.orgUnit); + const { displayName: orgUnitName, ancestors } = useOrgUnitNameWithAncestors(enrollment?.orgUnit); + const { displayName: ownerOrgUnitName, ancestors: ownerAncestors } = useOrgUnitNameWithAncestors(ownerOrgUnit?.id); + + const orgUnitClientValue = { name: orgUnitName, ancestors }; + const ownerOrgUnitClientValue = { name: ownerOrgUnitName, ancestors: ownerAncestors }; return (
@@ -130,19 +136,16 @@ export const WidgetEnrollmentPlain = ({ - {i18n.t('Started at {{orgUnitName}}', { - orgUnitName, - interpolation: { escapeValue: false }, - })} + {i18n.t('Started at: ')} + {convertValue(orgUnitClientValue, type)}
- {i18n.t('Owned by {{ownerOrgUnit}}', { - ownerOrgUnit: ownerOrgUnit.displayName, - })} + {i18n.t('Owned by: ')} + {convertValue(ownerOrgUnitClientValue, type)}
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.container.js b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.container.js index f46827f52b..dba0dc0954 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.container.js +++ b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.container.js @@ -3,7 +3,7 @@ import React, { useMemo } from 'react'; import { errorCreator } from 'capture-core-utils'; import log from 'loglevel'; import { WidgetEnrollment as WidgetEnrollmentNote } from './WidgetEnrollment.component'; -import { useOrgUnitName } from '../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../metadataRetrieval/orgUnitName'; import { useTrackedEntityInstances } from './hooks/useTrackedEntityInstances'; import { useEnrollment } from './hooks/useEnrollment'; import { useProgram } from './hooks/useProgram'; @@ -68,7 +68,7 @@ export const WidgetEnrollment = ({ enrollments, refetch: refetchTEI, } = useTrackedEntityInstances(teiId, programId); - const { error: errorOrgUnit, displayName } = useOrgUnitName( + const { error: errorOrgUnit, displayName } = useOrgUnitNameWithAncestors( typeof ownerOrgUnit === 'string' ? ownerOrgUnit : undefined, ); const { error: errorLocale, locale } = useUserLocale(); diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js index 24bfdc0016..843e40d96a 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js @@ -4,7 +4,7 @@ import i18n from '@dhis2/d2-i18n'; import { useDispatch } from 'react-redux'; import moment from 'moment'; import { getProgramAndStageForProgram, TrackerProgram, getProgramEventAccess, dataElementTypes } from '../../metaData'; -import { useOrgUnitName } from '../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../metadataRetrieval/orgUnitName'; import { useLocationQuery } from '../../utils/routing'; import type { ContainerProps } from './widgetEventSchedule.types'; import { WidgetEventScheduleComponent } from './WidgetEventSchedule.component'; @@ -37,7 +37,7 @@ export const WidgetEventSchedule = ({ }: ContainerProps) => { const { program, stage } = useMemo(() => getProgramAndStageForProgram(programId, stageId), [programId, stageId]); const dispatch = useDispatch(); - const orgUnit = { id: orgUnitId, name: useOrgUnitName(orgUnitId).displayName }; + const orgUnit = { id: orgUnitId, name: useOrgUnitNameWithAncestors(orgUnitId).displayName }; const { programStageScheduleConfig } = useScheduleConfigFromProgramStage(stageId); const { programConfig } = useScheduleConfigFromProgram(programId); const suggestedScheduleDate = useDetermineSuggestedScheduleDate({ diff --git a/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.js b/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.js index f14f5fb3ec..0204ac19a7 100644 --- a/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.js +++ b/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.js @@ -97,10 +97,10 @@ const WidgetProfilePlain = ({ const displayInListAttributes = useMemo(() => clientAttributesWithSubvalues .filter(item => item.displayInList) .map((clientAttribute) => { - const { attribute, key } = clientAttribute; + const { attribute, key, valueType } = clientAttribute; const value = convertClientToView(clientAttribute); return { - attribute, key, value, reactKey: attribute, + attribute, key, value, valueType, reactKey: attribute, }; }), [clientAttributesWithSubvalues]); diff --git a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js index 241316d4eb..89a9e819cf 100644 --- a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js +++ b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js @@ -51,10 +51,17 @@ const getOrganisationUnitSubvalue = async ({ attribute, querySingleResource }: S resource: 'organisationUnits', id: attribute.value, params: { - fields: 'id,name', + fields: 'id,name,ancestors[displayName]', }, }); - return { ...organisationUnit }; + + const orgUnitClientValue = { + id: organisationUnit.id, + name: organisationUnit.name, + ancestors: organisationUnit.ancestors.map(ancestor => ancestor.displayName), + }; + + return orgUnitClientValue; }; export const subValueGetterByElementType = { diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js index c8a1652a76..aaf3ffdf3c 100644 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js +++ b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js @@ -1,6 +1,6 @@ // @flow import React from 'react'; -import { useOrgUnitName } from '../../../metadataRetrieval/orgUnitName'; +import { useOrgUnitNameWithAncestors } from '../../../metadataRetrieval/orgUnitName'; type Props = { orgUnitId: string, @@ -9,7 +9,7 @@ type Props = { export const FlatListOrgUnitField = ({ orgUnitId, }: Props) => { - const { displayName } = useOrgUnitName(orgUnitId); + const { displayName } = useOrgUnitNameWithAncestors(orgUnitId); return ( diff --git a/src/core_modules/capture-core/converters/clientToView.js b/src/core_modules/capture-core/converters/clientToView.js index a1301e6836..115bcbeb69 100644 --- a/src/core_modules/capture-core/converters/clientToView.js +++ b/src/core_modules/capture-core/converters/clientToView.js @@ -7,36 +7,39 @@ import { dataElementTypes, type DataElement } from '../metaData'; import { convertMomentToDateFormatString } from '../utils/converters/date'; import { stringifyNumber } from './common/stringifyNumber'; import { MinimalCoordinates } from '../components/MinimalCoordinates'; +import { TooltipOrgUnit } from '../components/Tooltips/TooltipOrgUnit'; function convertDateForView(rawValue: string): string { const momentDate = moment(rawValue); return convertMomentToDateFormatString(momentDate); } - function convertDateTimeForView(rawValue: string): string { const momentDate = moment(rawValue); const dateString = convertMomentToDateFormatString(momentDate); const timeString = momentDate.format('HH:mm'); return `${dateString} ${timeString}`; } - function convertTimeForView(rawValue: string): string { const momentDate = moment(rawValue, 'HH:mm', true); return momentDate.format('HH:mm'); } - type FileClientValue = { name: string, url: string, value: string, }; - type ImageClientValue = { ...FileClientValue, previewUrl: string, }; +type OrgUnitClientValue = { + name: string, + ancestors?: Array, + tooltip?: string, +}; + function convertFileForDisplay(clientValue: FileClientValue) { return ( ; } +function convertOrgUnitForDisplay(clientValue: OrgUnitClientValue) { + return ( + + ); +} + const valueConvertersForType = { [dataElementTypes.NUMBER]: stringifyNumber, [dataElementTypes.INTEGER]: stringifyNumber, @@ -70,7 +83,7 @@ const valueConvertersForType = { [dataElementTypes.AGE]: convertDateForView, [dataElementTypes.FILE_RESOURCE]: convertFileForDisplay, [dataElementTypes.IMAGE]: convertImageForDisplay, - [dataElementTypes.ORGANISATION_UNIT]: (rawValue: Object) => rawValue.name, + [dataElementTypes.ORGANISATION_UNIT]: convertOrgUnitForDisplay, [dataElementTypes.POLYGON]: () => 'Polygon', }; @@ -78,18 +91,15 @@ export function convertValue(value: any, type: $Keys, d if (!value && value !== 0 && value !== false) { return value; } - if (dataElement && dataElement.optionSet) { if (dataElement.type === dataElementTypes.MULTI_TEXT) { return dataElement.optionSet.getMultiOptionsText(value); } return dataElement.optionSet.getOptionText(value); } - // $FlowFixMe dataElementTypes flow error return valueConvertersForType[type] ? valueConvertersForType[type](value) : value; } - export function convertDateWithTimeForView(rawValue?: ?string): string { if (!rawValue) { return ''; } if (!moment(rawValue).hours() && !moment(rawValue).minutes()) { diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js index f254f83a12..21e8b84212 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js @@ -1,6 +1,6 @@ // @flow export { - useOrgUnitName, + useOrgUnitNameWithAncestors, useOrgUnitNames, getOrgUnitNames, getCachedOrgUnitName, diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js index ca45d9de40..56d222c119 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js @@ -14,13 +14,43 @@ const displayNamesQuery = { organisationUnits: { resource: 'organisationUnits', params: ({ filter }) => ({ - fields: 'id,displayName', + fields: 'id,displayName,ancestors[id,displayName]', filter: `id:in:[${filter}]`, pageSize: maxBatchSize, }), }, }; +const updateCacheWithOrgUnits = (organisationUnits) => { + organisationUnits.forEach(({ id, displayName, ancestors }) => { + if (ancestors.length > 0) { + displayNameCache[id] = { + displayName, + ancestor: ancestors[ancestors.length - 1].id, + }; + + ancestors.findLast((ancestor, index) => { + if (displayNameCache[ancestor.id]) { + // Ancestors already cached + return true; + } else if (index > 0) { + // Add orgunit WITH ancestor to cache + displayNameCache[ancestor.id] = { + displayName: ancestor.displayName, + ancestor: ancestors[index - 1].id, + }; + return false; + } + // Add orgunit WITHOUT ancestor to cache + displayNameCache[ancestor.id] = { displayName: ancestor.displayName }; + return true; + }); + } else { + displayNameCache[id] = { displayName }; + } + }); +}; + const createBatches = (orgUnitIds: Array): Array> => { const reducedOrgUnitIds = Array.from(orgUnitIds .filter(id => id) @@ -39,6 +69,17 @@ const createBatches = (orgUnitIds: Array): Array> => { return batches; }; +const getAncestors = (orgUnitId) => { + const orgUnit = displayNameCache[orgUnitId]; + + if (!orgUnit) return []; + + const ancestors = getAncestors(orgUnit.ancestor); + ancestors.push(orgUnit.displayName); + + return ancestors; +}; + // Works best with memoized input arrays. export const useOrgUnitNames = (orgUnitIds: Array): { loading: boolean, @@ -54,28 +95,19 @@ export const useOrgUnitNames = (orgUnitIds: Array): { const ready = !fetching && orgUnitIds === requestedArray; - const batches = useMemo( - () => createBatches(orgUnitIds), - [orgUnitIds], - ); - const filter = useMemo( - () => (fetching ? currentBatches[completedBatches].join(',') : ''), - [fetching, currentBatches, completedBatches], - ); - const result = useMemo( - () => (ready ? orgUnitIds.reduce((acc, id) => { - acc[id] = displayNameCache[id]; - return acc; - }, {}) : null), - [ready, orgUnitIds], - ); + const batches = useMemo(() => createBatches(orgUnitIds), [orgUnitIds]); + const filter = useMemo(() => (fetching ? currentBatches[completedBatches].join(',') : ''), [fetching, currentBatches, completedBatches]); + const result = useMemo(() => (ready ? orgUnitIds.reduce((acc, id) => { + acc[id] = displayNameCache[id] ? displayNameCache[id].displayName : null; + return acc; + }, {}) : null), [ready, orgUnitIds]); const onComplete = useCallback(({ organisationUnits }) => { - for (const { id, displayName } of organisationUnits.organisationUnits) { - displayNameCache[id] = displayName; - } + updateCacheWithOrgUnits(organisationUnits.organisationUnits); + const completeCount = completedBatches + 1; setCompletedBatches(completeCount); + if (completeCount === currentBatches.length) { setFetching(false); } else { @@ -83,22 +115,17 @@ export const useOrgUnitNames = (orgUnitIds: Array): { } }, [completedBatches, setCompletedBatches, currentBatches, setFetching, setFetchNextBatch]); - const onError = useCallback( - (fetchError) => { - setFetching(false); - setError(fetchError); - }, - [setFetching, setError], - ); + const onError = useCallback((fetchError) => { + setFetching(false); + setError(fetchError); + }, [setFetching, setError]); - const { refetch } = useDataQuery( - displayNamesQuery, { - variables: { filter }, - onComplete, - onError, - lazy: true, - }, - ); + const { refetch } = useDataQuery(displayNamesQuery, { + variables: { filter }, + onComplete, + onError, + lazy: true, + }); useEffect(() => { if (!fetching && orgUnitIds !== requestedArray) { @@ -111,7 +138,7 @@ export const useOrgUnitNames = (orgUnitIds: Array): { setCompletedBatches(0); } } - }, [fetching, orgUnitIds, requestedArray, batches, setRequestedArray, setCurrentBatches, setCompletedBatches, setFetching, setError]); + }, [fetching, orgUnitIds, requestedArray, batches]); useEffect(() => { if (fetchNextBatch) { @@ -120,7 +147,7 @@ export const useOrgUnitNames = (orgUnitIds: Array): { refetch({ filter }); } } - }, [fetchNextBatch, setFetchNextBatch, completedBatches, currentBatches, refetch, filter]); + }, [fetchNextBatch, completedBatches, currentBatches, refetch, filter]); return { loading: !ready && !error, @@ -130,44 +157,57 @@ export const useOrgUnitNames = (orgUnitIds: Array): { }; export async function getOrgUnitNames(orgUnitIds: Array, querySingleResource: QuerySingleResource): Promise<{| - [orgUnitId: string]: {| - id: string, +[orgUnitId: string]: {| + id: string, displayName: string, |} |}> { await Promise.all(createBatches(orgUnitIds) .map(batch => querySingleResource(displayNamesQuery.organisationUnits, { filter: batch.join(',') }) .then(({ organisationUnits }) => { - for (const { id, displayName } of organisationUnits) { - displayNameCache[id] = displayName; - } - }))); + updateCacheWithOrgUnits(organisationUnits); + }), + ), + ); return orgUnitIds.reduce((acc, orgUnitId) => { acc[orgUnitId] = { id: orgUnitId, - name: displayNameCache[orgUnitId], + name: displayNameCache[orgUnitId]?.displayName, }; return acc; }, {}); } -export const useOrgUnitName = (orgUnitId: ?string): { +export const useOrgUnitNameWithAncestors = (orgUnitId: ?string): { displayName?: string, - error?: any, + ancestors?: Array, + error: any, } => { - const cachedOrgUnitName = orgUnitId && displayNameCache[orgUnitId]; - const fetchId = cachedOrgUnitName ? undefined : orgUnitId; - const { orgUnit, error } = useOrganisationUnit(fetchId, 'displayName'); - if (cachedOrgUnitName) { - return { displayName: cachedOrgUnitName }; - } else if (orgUnit && fetchId) { - displayNameCache[orgUnit.id] = orgUnit.displayName; - if (orgUnit.id === fetchId) { - return { displayName: orgUnit.displayName, error }; - } + const cachedOrgUnit = orgUnitId && displayNameCache[orgUnitId]; + const fetchId = cachedOrgUnit ? undefined : orgUnitId; + const { orgUnit: fetchedOrgUnit, error } = useOrganisationUnit(fetchId, 'displayName,ancestors[id,displayName]'); + + if (orgUnitId && cachedOrgUnit) { + const ancestors = getAncestors(cachedOrgUnit.ancestor); + + return { + displayName: cachedOrgUnit.displayName, + ancestors, + error, + }; + } else if (fetchedOrgUnit && fetchId) { + updateCacheWithOrgUnits([fetchedOrgUnit]); + const ancestors = fetchedOrgUnit.ancestors.map(ancestor => ancestor.displayName); + + return { + displayName: fetchedOrgUnit.displayName, + ancestors, + error, + }; } + return { error }; }; -export const getCachedOrgUnitName = (orgUnitId: string): ?string => displayNameCache[orgUnitId]; +export const getCachedOrgUnitName = (orgUnitId: string): ?string => displayNameCache[orgUnitId]?.displayName; diff --git a/src/core_modules/capture-ui/FlatList/flatList.types.js b/src/core_modules/capture-ui/FlatList/flatList.types.js index 94dc5a5b47..4159c32e1d 100644 --- a/src/core_modules/capture-ui/FlatList/flatList.types.js +++ b/src/core_modules/capture-ui/FlatList/flatList.types.js @@ -1,8 +1,6 @@ // @flow -import { type Node } from 'react'; - export type Props = {| - list: { reactKey: string, key: string, value: Node }[], + list: { reactKey: string, key: string, value: Object, valueType?: string }[], dataTest?: string, ...CssClasses, |}; From f11b35b7a490107bc2e1ef2340497cdd5f0c76d3 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 24 Sep 2024 07:55:27 +0000 Subject: [PATCH 11/91] chore(release): cut 101.5.0 [skip release] # [101.5.0](https://github.com/dhis2/capture-app/compare/v101.4.1...v101.5.0) (2024-09-24) ### Features * [DHIS2-17770] Org unit contextualization in self contained widgets ([#3720](https://github.com/dhis2/capture-app/issues/3720)) ([562b03a](https://github.com/dhis2/capture-app/commit/562b03a1cf2cb5cff5382bd433943f289c860095)) --- 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 95e021f34b..a001555d3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.5.0](https://github.com/dhis2/capture-app/compare/v101.4.1...v101.5.0) (2024-09-24) + + +### Features + +* [DHIS2-17770] Org unit contextualization in self contained widgets ([#3720](https://github.com/dhis2/capture-app/issues/3720)) ([562b03a](https://github.com/dhis2/capture-app/commit/562b03a1cf2cb5cff5382bd433943f289c860095)) + ## [101.4.1](https://github.com/dhis2/capture-app/compare/v101.4.0...v101.4.1) (2024-09-19) diff --git a/package.json b/package.json index efb07db0ef..40c639584b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.4.1", + "version": "101.5.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.4.1", + "@dhis2/rules-engine-javascript": "101.5.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 e4e1b00d9d..cf91147ca2 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.4.1", + "version": "101.5.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 7b3485b6c364758d1d03e039508d62564b295a96 Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Fri, 27 Sep 2024 09:39:50 +0200 Subject: [PATCH 12/91] docs: [DHIS2-18052] Rebuild developer docs when there are changes (#3797) --- .github/workflows/rebuild-docs.yml | 19 +++++++++++++++++++ .../enrollment-plugins/manual-setup.mdx | 8 ++++---- 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/rebuild-docs.yml diff --git a/.github/workflows/rebuild-docs.yml b/.github/workflows/rebuild-docs.yml new file mode 100644 index 0000000000..a5c86d59e0 --- /dev/null +++ b/.github/workflows/rebuild-docs.yml @@ -0,0 +1,19 @@ +name: 'dhis2: rebuild developer docs' + +on: + push: + branches: + - master + paths: + - 'docs/developer/**' + - 'CHANGELOG.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rebuild-docs: + runs-on: ubuntu-latest + steps: + - run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_DEVELOPER_DOCS_TOKEN }} diff --git a/docs/developer/enrollment-plugins/manual-setup.mdx b/docs/developer/enrollment-plugins/manual-setup.mdx index 895973f25b..bae6afbe0f 100644 --- a/docs/developer/enrollment-plugins/manual-setup.mdx +++ b/docs/developer/enrollment-plugins/manual-setup.mdx @@ -76,7 +76,7 @@ You can also have different layouts for the three different enrollment pages. }, { "type": "component", - "name": "EnrollmentComment" + "name": "EnrollmentNote" }, { "type": "component", @@ -188,7 +188,7 @@ You can also have different layouts for the three different enrollment pages. }, { "type": "component", - "name": "EventComment" + "name": "EventNote" }, { "type": "component", @@ -229,8 +229,8 @@ type DefaultComponents = 'QuickActions' | 'AssigneeWidget' | 'NewEventWorkspace' | 'EditEventWorkspace' - | 'EnrollmentComment' - | 'EventComment' + | 'EnrollmentNote' + | 'EventNote' | 'TrackedEntityRelationship' | 'ErrorWidget' | 'WarningWidget' From 22cfe585b6b044c7d6b146c1449ccddb85d8abb4 Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Fri, 27 Sep 2024 11:20:33 +0200 Subject: [PATCH 13/91] feat: support custom background color (#3814) --- .../DefaultEnrollmentLayout.types.js | 1 + .../EnrollmentPageLayout/EnrollmentPageLayout.js | 11 ++++++++++- .../components/Widget/WidgetCollapsible.component.js | 6 +++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/DefaultEnrollmentLayout.types.js b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/DefaultEnrollmentLayout.types.js index 218d77fa41..922a2071fc 100644 --- a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/DefaultEnrollmentLayout.types.js +++ b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/DefaultEnrollmentLayout.types.js @@ -34,6 +34,7 @@ export type ColumnConfig = DefaultWidgetColumnConfig | PluginWidgetColumnConfig; export type PageLayoutConfig = { title?: ?string, + backgroundColor?: ?string, leftColumn: ?Array, rightColumn: ?Array, } diff --git a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/EnrollmentPageLayout.js b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/EnrollmentPageLayout.js index d3f18557ff..f6d821e872 100644 --- a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/EnrollmentPageLayout.js +++ b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/EnrollmentPageLayout.js @@ -10,6 +10,7 @@ import { DefaultPageTitle, EnrollmentPageKeys } from './DefaultEnrollmentLayout. const getEnrollmentPageStyles = () => ({ container: { + minHeight: '90vh', padding: '16px 24px 16px 24px', }, contentContainer: { @@ -44,6 +45,9 @@ const getEnrollmentPageStyles = () => ({ }, }); +// Function to validate hex color +const isValidHex = (color: string) => /^#[0-9A-F]{6}$/i.test(color); + const getTitle = (inputTitle, page) => { const title = inputTitle || i18n.t('Enrollment'); const titles = { @@ -83,8 +87,13 @@ const EnrollmentPageLayoutPlain = ({ props: allProps, }); + const containerStyle = useMemo(() => { + if (!pageLayout.backgroundColor || !isValidHex(pageLayout.backgroundColor)) return undefined; + return { backgroundColor: pageLayout.backgroundColor }; + }, [pageLayout.backgroundColor]); + return ( -
+
+
Date: Fri, 27 Sep 2024 09:25:00 +0000 Subject: [PATCH 14/91] chore(release): cut 101.6.0 [skip release] # [101.6.0](https://github.com/dhis2/capture-app/compare/v101.5.0...v101.6.0) (2024-09-27) ### Features * support custom background color ([#3814](https://github.com/dhis2/capture-app/issues/3814)) ([22cfe58](https://github.com/dhis2/capture-app/commit/22cfe585b6b044c7d6b146c1449ccddb85d8abb4)) --- 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 a001555d3b..05d1af531c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.6.0](https://github.com/dhis2/capture-app/compare/v101.5.0...v101.6.0) (2024-09-27) + + +### Features + +* support custom background color ([#3814](https://github.com/dhis2/capture-app/issues/3814)) ([22cfe58](https://github.com/dhis2/capture-app/commit/22cfe585b6b044c7d6b146c1449ccddb85d8abb4)) + # [101.5.0](https://github.com/dhis2/capture-app/compare/v101.4.1...v101.5.0) (2024-09-24) diff --git a/package.json b/package.json index 40c639584b..09a9938fef 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.5.0", + "version": "101.6.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.5.0", + "@dhis2/rules-engine-javascript": "101.6.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 cf91147ca2..c5c79526fe 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.5.0", + "version": "101.6.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From cbeb1022bf45b241a91dcfb8c3e49956b28b1c44 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 29 Sep 2024 03:44:52 +0200 Subject: [PATCH 15/91] fix(translations): sync translations from transifex (master) Automatically merged. --- i18n/cs.po | 8 +------- i18n/es.po | 8 +------- i18n/fr.po | 8 +------- i18n/id.po | 8 +------- i18n/lo.po | 20 ++++++++------------ i18n/nb.po | 8 +------- i18n/nl.po | 8 +------- i18n/pt.po | 8 +------- i18n/ro.po | 25 ++++++++++++++++++------- i18n/ru.po | 8 +------- i18n/uz_UZ_Cyrl.po | 9 +-------- i18n/vi.po | 14 ++++---------- i18n/zh.po | 8 +------- i18n/zh_CN.po | 8 +------- 14 files changed, 41 insertions(+), 107 deletions(-) diff --git a/i18n/cs.po b/i18n/cs.po index 798be3e276..61c3bef8ce 100644 --- a/i18n/cs.po +++ b/i18n/cs.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Jiří Podhorecký , 2024\n" "Language-Team: Czech (https://app.transifex.com/hisp-uio/teams/100509/cs/)\n" @@ -1294,12 +1294,6 @@ msgstr "Widget pro zápis nelze načíst. Prosím zkuste to znovu později" msgid "Follow-up" msgstr "Následovat" -msgid "Started at {{orgUnitName}}" -msgstr "Zahájeno v {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Vlastník: {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Zrušeno" diff --git a/i18n/es.po b/i18n/es.po index 6dd93902ff..534e4de691 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Juan M Alcantara Acosta , 2024\n" "Language-Team: Spanish (https://app.transifex.com/hisp-uio/teams/100509/es/)\n" @@ -1333,12 +1333,6 @@ msgstr "" msgid "Follow-up" msgstr "Seguimiento" -msgid "Started at {{orgUnitName}}" -msgstr "Comenzó en {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Propiedad de {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Cancelar" diff --git a/i18n/fr.po b/i18n/fr.po index d8952a4af7..c9418fa104 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Bram Piot , 2024\n" "Language-Team: French (https://app.transifex.com/hisp-uio/teams/100509/fr/)\n" @@ -1304,12 +1304,6 @@ msgstr "" msgid "Follow-up" msgstr "Suivi" -msgid "Started at {{orgUnitName}}" -msgstr "Commencé à {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Propriété de {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Annulé" diff --git a/i18n/id.po b/i18n/id.po index 450489bebe..a4124e8e01 100644 --- a/i18n/id.po +++ b/i18n/id.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Aprisa Chrysantina , 2024\n" "Language-Team: Indonesian (https://app.transifex.com/hisp-uio/teams/100509/id/)\n" @@ -1272,12 +1272,6 @@ msgstr "Widget pendaftaran tidak dapat dimuat. Silakan coba lagi nanti" msgid "Follow-up" msgstr "Mengikuti" -msgid "Started at {{orgUnitName}}" -msgstr "Dimulai di {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Dimiliki oleh {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Dibatalkan" diff --git a/i18n/lo.po b/i18n/lo.po index cb86ea18bc..b12cc74fe7 100644 --- a/i18n/lo.po +++ b/i18n/lo.po @@ -4,15 +4,15 @@ # Saysamone Sibounma, 2023 # Somkhit Bouavong , 2024 # Thuy Nguyen , 2024 -# Namwan Chanthavisouk, 2024 # Viktor Varland , 2024 +# Namwan Chanthavisouk, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Namwan Chanthavisouk, 2024\n" "Language-Team: Lao (https://app.transifex.com/hisp-uio/teams/100509/lo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1275,12 +1275,6 @@ msgstr "ບໍ່ສາມາດໂຫຼດລາຍການການລົງ msgid "Follow-up" msgstr "ຕິດຕາມ" -msgid "Started at {{orgUnitName}}" -msgstr "ເລີ່ມຈາກ {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "ເປັນເຈົ້າຂອງໂດຍ {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "ຍົກເລີກແລ້ວ" @@ -1506,18 +1500,20 @@ msgid "New {{ eventName }} event" msgstr "ເຫດການໃໝ່ {{ eventName }}" msgid "An error occurred while deleting the event" -msgstr "" +msgstr "ພົບຂໍ້ຜິດພາດໃນລະຫວ່າງລົບເຫດການ" msgid "" "Deleting an event is permanent and cannot be undone. Are you sure you want " "to delete this event?" msgstr "" +"ການລົບເຫດການແມ່ນຖາວອນ ແລະ ບໍ່ສາມາດຍົກເລີກໄດ້. " +"ທ່ານແນ່ໃຈບໍ່ວ່າຕ້ອງການລົບເຫດການນີ້?" msgid "An error occurred when updating event status" -msgstr "" +msgstr "ພົບຂໍ້ຜິດພາດໃນລະຫວ່າງອັບເດດສະຖານະເຫດການ" msgid "Unskip" -msgstr "" +msgstr "ຍົກເລີກ" msgid "Skip" msgstr "ຂ້າມ" diff --git a/i18n/nb.po b/i18n/nb.po index 2e64114b50..e14d1e2e25 100644 --- a/i18n/nb.po +++ b/i18n/nb.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Merethe Wollan Blisten, 2024\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/hisp-uio/teams/100509/nb/)\n" @@ -1299,12 +1299,6 @@ msgstr "Registreringsmodulen kunne ikke lastes inn. Prøv igjen senere" msgid "Follow-up" msgstr "Oppfølging" -msgid "Started at {{orgUnitName}}" -msgstr "Begynt på {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Eid av {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Kansellert" diff --git a/i18n/nl.po b/i18n/nl.po index 31991c9398..1ab637a352 100644 --- a/i18n/nl.po +++ b/i18n/nl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Charel van den Elsen, 2024\n" "Language-Team: Dutch (https://app.transifex.com/hisp-uio/teams/100509/nl/)\n" @@ -1310,12 +1310,6 @@ msgstr "" msgid "Follow-up" msgstr "Opvolgen" -msgid "Started at {{orgUnitName}}" -msgstr "Gestart bij {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Eigendom van {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Geannuleerd" diff --git a/i18n/pt.po b/i18n/pt.po index 306edb6cbd..7531dccfa4 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Portuguese (https://app.transifex.com/hisp-uio/teams/100509/pt/)\n" @@ -1306,12 +1306,6 @@ msgstr "" msgid "Follow-up" msgstr "Acompanhamento" -msgid "Started at {{orgUnitName}}" -msgstr "Iniciado em {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Propriedade de {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Cancelado" diff --git a/i18n/ro.po b/i18n/ro.po index 310d3bc638..5c64022113 100644 --- a/i18n/ro.po +++ b/i18n/ro.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Valeriu Plesca , 2024\n" "Language-Team: Romanian (https://app.transifex.com/hisp-uio/teams/100509/ro/)\n" @@ -1255,12 +1255,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Deținut de {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Anulat" @@ -1481,6 +1475,23 @@ msgstr "Această etapă poate avea un singur eveniment" msgid "New {{ eventName }} event" msgstr "Eveniment nou {{ eventName }}" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/ru.po b/i18n/ru.po index ff0df86178..01896cce66 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Russian (https://app.transifex.com/hisp-uio/teams/100509/ru/)\n" @@ -1320,12 +1320,6 @@ msgstr "" msgid "Follow-up" msgstr "Наблюдать" -msgid "Started at {{orgUnitName}}" -msgstr "Первоначальная регистрация в {{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "Принадлежит {{ownerOrgUnit}}" - msgid "Cancelled" msgstr "Отменен/а/о" diff --git a/i18n/uz_UZ_Cyrl.po b/i18n/uz_UZ_Cyrl.po index 6ca571beea..32a8d2e932 100644 --- a/i18n/uz_UZ_Cyrl.po +++ b/i18n/uz_UZ_Cyrl.po @@ -1,12 +1,11 @@ # # Translators: -# Philip Larsen Donnelly, 2024 # Khurshid Ibatov , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Khurshid Ibatov , 2024\n" "Language-Team: Uzbek (Cyrillic) (https://app.transifex.com/hisp-uio/teams/100509/uz@Cyrl/)\n" @@ -1269,12 +1268,6 @@ msgstr "" msgid "Follow-up" msgstr "Кузатиш" -msgid "Started at {{orgUnitName}}" -msgstr " {{orgUnitName}} да бошланган" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr " {{ownerOrgUnit}} эгалиги асосида" - msgid "Cancelled" msgstr "Бекор қилинди" diff --git a/i18n/vi.po b/i18n/vi.po index 8e1ac63a89..10dc9f241e 100644 --- a/i18n/vi.po +++ b/i18n/vi.po @@ -2,15 +2,15 @@ # Translators: # Philip Larsen Donnelly, 2024 # Mai Nguyen , 2024 -# Thuy Nguyen , 2024 # Viktor Varland , 2024 +# Thuy Nguyen , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Thuy Nguyen , 2024\n" "Language-Team: Vietnamese (https://app.transifex.com/hisp-uio/teams/100509/vi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1256,12 +1256,6 @@ msgstr "" msgid "Follow-up" msgstr "Theo dõi sau" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Đã hủy" @@ -1314,7 +1308,7 @@ msgid "Scheduled date cannot be changed for {{ eventStatus }} events" msgstr "" msgid "Event completed" -msgstr "" +msgstr "Sự kiện đã hoàn tất" msgid "The event cannot be edited after it has been completed" msgstr "" diff --git a/i18n/zh.po b/i18n/zh.po index 70a175384c..559372ca30 100644 --- a/i18n/zh.po +++ b/i18n/zh.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: easylin , 2024\n" "Language-Team: Chinese (https://app.transifex.com/hisp-uio/teams/100509/zh/)\n" @@ -1241,12 +1241,6 @@ msgstr "无法加载报名的小部件。请稍后再试" msgid "Follow-up" msgstr "后续" -msgid "Started at {{orgUnitName}}" -msgstr "始于{{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "由{{ownerOrgUnit}}拥有" - msgid "Cancelled" msgstr "已取消" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po index 2216a33b29..d370cc02a6 100644 --- a/i18n/zh_CN.po +++ b/i18n/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: 晓东 林 <13981924470@126.com>, 2024\n" "Language-Team: Chinese (China) (https://app.transifex.com/hisp-uio/teams/100509/zh_CN/)\n" @@ -1240,12 +1240,6 @@ msgstr "无法加载报名的小部件。请稍后再试" msgid "Follow-up" msgstr "后续" -msgid "Started at {{orgUnitName}}" -msgstr "始于{{orgUnitName}}" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "由{{ownerOrgUnit}}拥有" - msgid "Cancelled" msgstr "已取消" From 380f6b6f15dfd8e1d1137e2c8ff93e0d335c22b5 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 29 Sep 2024 01:49:39 +0000 Subject: [PATCH 16/91] chore(release): cut 101.6.1 [skip release] ## [101.6.1](https://github.com/dhis2/capture-app/compare/v101.6.0...v101.6.1) (2024-09-29) ### Bug Fixes * **translations:** sync translations from transifex (master) ([cbeb102](https://github.com/dhis2/capture-app/commit/cbeb1022bf45b241a91dcfb8c3e49956b28b1c44)) --- 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 05d1af531c..f91bf84b79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.6.1](https://github.com/dhis2/capture-app/compare/v101.6.0...v101.6.1) (2024-09-29) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([cbeb102](https://github.com/dhis2/capture-app/commit/cbeb1022bf45b241a91dcfb8c3e49956b28b1c44)) + # [101.6.0](https://github.com/dhis2/capture-app/compare/v101.5.0...v101.6.0) (2024-09-27) diff --git a/package.json b/package.json index 09a9938fef..0af7250c62 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.6.0", + "version": "101.6.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.6.0", + "@dhis2/rules-engine-javascript": "101.6.1", "@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 c5c79526fe..d869454032 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.6.0", + "version": "101.6.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 2bb485e0927e9137874131a982fe690b9f6c5361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Storl=C3=B8kken=20Melseth?= Date: Tue, 1 Oct 2024 12:37:24 +0200 Subject: [PATCH 17/91] =?UTF-8?q?fix:=20[DHIS2-18004]=C2=A0sort=20events?= =?UTF-8?q?=20in=20rules=20engine=20by=20occurredAt=20and=20createdAt=20(#?= =?UTF-8?q?3788)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VariableService/VariableService.js | 2 +- .../helpers/structureEvents.js | 30 +++++++++---------- .../VariableService/variableService.types.js | 3 ++ .../rules/converters/dateUtils.js | 16 ++++------ 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/packages/rules-engine/src/services/VariableService/VariableService.js b/packages/rules-engine/src/services/VariableService/VariableService.js index 193de2677e..9b596a8190 100644 --- a/packages/rules-engine/src/services/VariableService/VariableService.js +++ b/packages/rules-engine/src/services/VariableService/VariableService.js @@ -85,7 +85,7 @@ export class VariableService { this.defaultValues = defaultValues; - this.structureEvents = getStructureEvents(dateUtils.compareDates); + this.structureEvents = getStructureEvents(dateUtils.compareDates, onProcessValue); } getVariables({ diff --git a/packages/rules-engine/src/services/VariableService/helpers/structureEvents.js b/packages/rules-engine/src/services/VariableService/helpers/structureEvents.js index 7c4fcab7f8..9660397845 100644 --- a/packages/rules-engine/src/services/VariableService/helpers/structureEvents.js +++ b/packages/rules-engine/src/services/VariableService/helpers/structureEvents.js @@ -1,9 +1,11 @@ // @flow +import { typeKeys } from '../../../constants'; import { eventStatuses } from '../constants'; import type { EventData, EventsData, CompareDates, + ProcessValue, } from '../variableService.types'; const createEventsContainer = (events: EventsData) => { @@ -16,20 +18,16 @@ const createEventsContainer = (events: EventsData) => { return { all: events, byStage: eventsDataByStage }; }; -export const getStructureEvents = (compareDates: CompareDates) => { - const compareEvents = (first: EventData, second: EventData): number => { - let result; - if (!first.occurredAt && !second.occurredAt) { - result = 0; - } else if (!first.occurredAt) { - result = 1; - } else if (!second.occurredAt) { - result = -1; - } else { - result = compareDates(first.occurredAt, second.occurredAt); - } - return result; - }; +export const getStructureEvents = (compareDates: CompareDates, processValue: ProcessValue) => { + const compareEvents = (first: EventData, second: EventData): number => + compareDates( + processValue(first.occurredAt, typeKeys.DATE), + processValue(second.occurredAt, typeKeys.DATE), + ) || + compareDates( + processValue(first.createdAt, typeKeys.DATETIME), + processValue(second.createdAt, typeKeys.DATETIME), + ); return (currentEvent: EventData = {}, otherEvents: EventsData = []) => { const otherEventsFiltered = otherEvents @@ -37,8 +35,8 @@ export const getStructureEvents = (compareDates: CompareDates) => { [eventStatuses.COMPLETED, eventStatuses.ACTIVE, eventStatuses.VISITED].includes(event.status) && event.eventId !== currentEvent.eventId, ); - - const events = Object.keys(currentEvent).length !== 0 ? otherEventsFiltered.concat(currentEvent) : otherEventsFiltered; + const events = Object.keys(currentEvent).length ? + otherEventsFiltered.concat(currentEvent) : otherEventsFiltered; const sortedEvents = events.sort(compareEvents); return createEventsContainer(sortedEvents); diff --git a/packages/rules-engine/src/services/VariableService/variableService.types.js b/packages/rules-engine/src/services/VariableService/variableService.types.js index f31caadc2f..9640354c46 100644 --- a/packages/rules-engine/src/services/VariableService/variableService.types.js +++ b/packages/rules-engine/src/services/VariableService/variableService.types.js @@ -1,4 +1,5 @@ // @flow +import { typeof typeKeys } from '../../constants'; import { typeof eventStatuses } from './constants'; import type { DataElements, TrackedEntityAttributes, OrgUnit } from '../../rulesEngine.types'; @@ -89,3 +90,5 @@ export type VariableServiceInput = {| |}; export type CompareDates = (firstRulesDate: ?string, secondRulesDate: ?string) => number; + +export type ProcessValue = (value: any, type: $Values) => any; diff --git a/src/core_modules/capture-core/rules/converters/dateUtils.js b/src/core_modules/capture-core/rules/converters/dateUtils.js index 674d82bcfc..9d4398635f 100644 --- a/src/core_modules/capture-core/rules/converters/dateUtils.js +++ b/src/core_modules/capture-core/rules/converters/dateUtils.js @@ -51,16 +51,10 @@ export const dateUtils: IDateUtils = { return momentToRulesDate(newDateMoment); }, compareDates: (firstRulesDate: ?string, secondRulesDate: ?string): number => { - const diff = dateUtils.daysBetween(secondRulesDate, firstRulesDate); - if (!diff) { - return 0; - } - if (diff < 0) { - return -1; - } - if (diff > 0) { - return 1; - } - return 0; + // Empty input dates will be replaced by "MAX_SAFE_INTEGER" when creating the timestamp. + // This ensures empty input will be bigger than any actual date + const firstDateTimestamp = firstRulesDate ? moment(firstRulesDate).valueOf() : Number.MAX_SAFE_INTEGER; + const secondDateTimestamp = secondRulesDate ? moment(secondRulesDate).valueOf() : Number.MAX_SAFE_INTEGER; + return firstDateTimestamp - secondDateTimestamp; }, }; From b8245ea6dc8f1ec5287e40190ab77b4173c28635 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 1 Oct 2024 10:41:56 +0000 Subject: [PATCH 18/91] chore(release): cut 101.6.2 [skip release] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [101.6.2](https://github.com/dhis2/capture-app/compare/v101.6.1...v101.6.2) (2024-10-01) ### Bug Fixes * [DHIS2-18004] sort events in rules engine by occurredAt and createdAt ([#3788](https://github.com/dhis2/capture-app/issues/3788)) ([2bb485e](https://github.com/dhis2/capture-app/commit/2bb485e0927e9137874131a982fe690b9f6c5361)) --- 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 f91bf84b79..65bc0a3ec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.6.2](https://github.com/dhis2/capture-app/compare/v101.6.1...v101.6.2) (2024-10-01) + + +### Bug Fixes + +* [DHIS2-18004] sort events in rules engine by occurredAt and createdAt ([#3788](https://github.com/dhis2/capture-app/issues/3788)) ([2bb485e](https://github.com/dhis2/capture-app/commit/2bb485e0927e9137874131a982fe690b9f6c5361)) + ## [101.6.1](https://github.com/dhis2/capture-app/compare/v101.6.0...v101.6.1) (2024-09-29) diff --git a/package.json b/package.json index 0af7250c62..ffe44ffb82 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.6.1", + "version": "101.6.2", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.6.1", + "@dhis2/rules-engine-javascript": "101.6.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 d869454032..d773ecb1fe 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.6.1", + "version": "101.6.2", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 7194e54a56bbfbcab5b3d39d597fabfa4d49daf7 Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:38:57 +0200 Subject: [PATCH 19/91] feat: [DHIS2-17874] replace remaining Material UI components (#3794) * feat: remove snackbar * feat: change menu components * feat: remove paper * feat: remove grow * feat: change popover * feat: remove icon button * feat: remove icons * fix: type error for open delay * fix: after review changes * feat: change to icon button * fix: data test prop * fix: increase max width --- i18n/en.pot | 9 - .../FeedbackBar/FeedbackBar.component.js | 136 +++------- .../UserField/SearchSuggestion.component.js | 38 +-- .../IncompleteSelectionsMessage/index.js | 26 +- .../ActiveFilterButton.component.js | 14 +- .../FilterButtonMain.component.js | 58 ++--- .../FilterRestMenu.component.js | 239 ++++-------------- .../ListView/Menu/ListViewMenu.component.js | 73 +++--- .../ListView/types/listView.types.js | 3 +- .../withEndColumnMenu/RowMenu.component.js | 208 ++++----------- .../NetworkStatusBadge.component.js | 155 ------------ .../Section/ViewEventSection.component.js | 173 ++++++++----- .../components/Popper/Popper.component.js | 107 -------- .../Relationships/Relationships.component.js | 15 +- .../WidgetError/WidgetErrorHeader.js | 5 +- .../WidgetWarning/WidgetWarningHeader.js | 5 +- .../StageOverview/StageOverview.component.js | 22 +- .../hooks/useAddRelationship.js | 4 +- ...EventWorkingListsRowMenuSetup.component.js | 26 +- .../eventWorkingListsRowMenuSetup.types.js | 1 - .../Icons/DropdownChevron.component.js | 35 +++ src/core_modules/capture-ui/Icons/index.js | 1 + 22 files changed, 410 insertions(+), 943 deletions(-) delete mode 100644 src/core_modules/capture-core/components/NetworkStatusBadge/NetworkStatusBadge.component.js delete mode 100644 src/core_modules/capture-core/components/Popper/Popper.component.js create mode 100644 src/core_modules/capture-ui/Icons/DropdownChevron.component.js diff --git a/i18n/en.pot b/i18n/en.pot index 5d63ac1048..d299bcedcf 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -598,15 +598,6 @@ msgstr "Program doesn't exist" msgid "Selected program is invalid for selected organisation unit" msgstr "Selected program is invalid for selected organisation unit" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "Syncing" - msgid "Add note" msgstr "Add note" diff --git a/src/core_modules/capture-core/components/FeedbackBar/FeedbackBar.component.js b/src/core_modules/capture-core/components/FeedbackBar/FeedbackBar.component.js index f4406742cc..166a351e1d 100644 --- a/src/core_modules/capture-core/components/FeedbackBar/FeedbackBar.component.js +++ b/src/core_modules/capture-core/components/FeedbackBar/FeedbackBar.component.js @@ -1,11 +1,8 @@ // @flow -import * as React from 'react'; -import SnackBar from '@material-ui/core/Snackbar'; +import React, { type Node } from 'react'; import { withStyles } from '@material-ui/core/styles'; -import { IconButton } from 'capture-ui'; -import { IconCross24, Button, Modal, ModalTitle, ModalContent, ModalActions } from '@dhis2/ui'; +import { Button, Modal, ModalTitle, ModalContent, ModalActions, AlertStack, AlertBar } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; -import isDefined from 'd2-utilizr/lib/isDefined'; const styles = () => ({ closeButton: { @@ -17,110 +14,43 @@ const styles = () => ({ }); type Feedback = { - message: string | { title: string, content: string}, - action?: ?React.Node, - displayType?: ?string, + message: string | { title: string, content: string }, + action?: Node, + displayType?: 'alert' | 'dialog', }; type Props = { feedback: Feedback, onClose: () => void, - classes: Object, }; -class Index extends React.Component { - static defaultProps = { - feedback: {}, - }; - - constructor(props: Props) { - super(props); - this.handleClose = this.handleClose.bind(this); - } - static CLICKAWAY_KEY = 'clickaway'; - - static ANCHOR_ORIGIN = { - vertical: 'bottom', - horizontal: 'center', - }; - - handleClose = (event?: ?Object, reason?: ?string) => { - if (reason !== Index.CLICKAWAY_KEY) { - this.props.onClose(); - } - } - - getAction() { - const { feedback, classes } = this.props; - - return ( - <> - { - (() => { - if (!feedback.action) { - return null; - } - - return ( - - {feedback.action} - - ); - })() - } - - - - - ); - } - - render() { - const { feedback } = this.props; - const { message, displayType } = feedback; - const isSnackBarOpen = isDefined(message) && !displayType; - const isDialogOpen = isDefined(message) && displayType === 'dialog'; - return ( - - {message}} - action={this.getAction()} - /> - {isDialogOpen && ( - - - { - // $FlowFixMe[prop-missing] automated comment - isDialogOpen ? message && message.title : ''} - - - { - // $FlowFixMe[prop-missing] automated comment - isDialogOpen ? message && message.content : ''} - - - - - +const FeedbackBarComponentPlain = ({ feedback = {}, onClose }: Props) => { + const { message, displayType } = feedback; + const isAlertBarOpen = typeof message === 'string' && !displayType; + const isDialogOpen = typeof message === 'object' && displayType === 'dialog'; + + return ( + <> + + {isAlertBarOpen && ( + + {message} + )} - - ); - } -} -Index.displayName = 'FeedbackBar'; + + {isDialogOpen && ( + + {message?.title || ''} + {message?.content || ''} + + + + + )} + + ); +}; -export const FeedbackBarComponent = withStyles(styles)(Index); +export const FeedbackBarComponent = withStyles(styles)(FeedbackBarComponentPlain); diff --git a/src/core_modules/capture-core/components/FormFields/UserField/SearchSuggestion.component.js b/src/core_modules/capture-core/components/FormFields/UserField/SearchSuggestion.component.js index 754b3a464e..6ebff0dea1 100644 --- a/src/core_modules/capture-core/components/FormFields/UserField/SearchSuggestion.component.js +++ b/src/core_modules/capture-core/components/FormFields/UserField/SearchSuggestion.component.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react'; import parse from 'autosuggest-highlight/parse'; -import MenuItem from '@material-ui/core/MenuItem'; +import { MenuItem } from '@dhis2/ui'; import classNames from 'classnames'; import { SearchContext } from './Search.context'; import defaultClasses from './searchSuggestion.module.css'; @@ -96,7 +96,6 @@ export const SearchSuggestion = (props: Props) => { onExitSearch(); } }, [onExitSearch, suggestionName, inputName]); - return (
{ onBlur={handleBlur} > -
- {parts.map((part, index) => (part.highlight ? ( - // eslint-disable-next-line react/no-array-index-key - - {part.text} - - ) : ( - // eslint-disable-next-line react/no-array-index-key - - {part.text} - - )))} -
-
+ active={isHighlighted} + label={( +
+ {parts.map((part, index) => (part.highlight ? ( + // eslint-disable-next-line react/no-array-index-key + + {part.text} + + ) : ( + // eslint-disable-next-line react/no-array-index-key + + {part.text} + + )))} +
+ )} + /> +
); }; diff --git a/src/core_modules/capture-core/components/IncompleteSelectionsMessage/index.js b/src/core_modules/capture-core/components/IncompleteSelectionsMessage/index.js index 6c206f72b6..411539110b 100644 --- a/src/core_modules/capture-core/components/IncompleteSelectionsMessage/index.js +++ b/src/core_modules/capture-core/components/IncompleteSelectionsMessage/index.js @@ -1,29 +1,23 @@ import React from 'react'; -import Paper from '@material-ui/core/Paper/Paper'; -import { withStyles } from '@material-ui/core'; import { colors } from '@dhis2/ui'; -const StyledPaper = withStyles({ - root: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - background: colors.grey200, - color: colors.grey700, - padding: '12px 16px', - }, -})(Paper); - const containerStyle = { display: 'flex', justifyContent: 'center', - width: '100%', +}; + +const messageBoxStyle = { + alignItems: 'center', + background: colors.grey200, + color: colors.grey700, + padding: '12px 16px', + borderRadius: '4px', }; export const IncompleteSelectionsMessage = ({ children, dataTest = 'informative-paper' }) => (
- +
{children} - +
); diff --git a/src/core_modules/capture-core/components/ListView/Filters/FilterButton/ActiveFilterButton.component.js b/src/core_modules/capture-core/components/ListView/Filters/FilterButton/ActiveFilterButton.component.js index f9fa85838f..fddd32eb76 100644 --- a/src/core_modules/capture-core/components/ListView/Filters/FilterButton/ActiveFilterButton.component.js +++ b/src/core_modules/capture-core/components/ListView/Filters/FilterButton/ActiveFilterButton.component.js @@ -1,16 +1,20 @@ // @flow import * as React from 'react'; import { withStyles } from '@material-ui/core/styles'; -import createSvgIcon from '@material-ui/icons/utils/createSvgIcon'; import { Tooltip, Button } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; import classNames from 'classnames'; -const ClearIcon = createSvgIcon( - +const ClearIcon = ({ className, ...props }) => ( + - , - 'CloseCircle', + ); const getStyles = (theme: Theme) => ({ diff --git a/src/core_modules/capture-core/components/ListView/Filters/FilterButton/FilterButtonMain.component.js b/src/core_modules/capture-core/components/ListView/Filters/FilterButton/FilterButtonMain.component.js index 8a1c83ddd1..c06d546ba2 100644 --- a/src/core_modules/capture-core/components/ListView/Filters/FilterButton/FilterButtonMain.component.js +++ b/src/core_modules/capture-core/components/ListView/Filters/FilterButton/FilterButtonMain.component.js @@ -1,9 +1,9 @@ // @flow import React, { Component } from 'react'; import { withStyles } from '@material-ui/core/styles'; -import Popover from '@material-ui/core/Popover'; -import { IconChevronDown16, IconChevronUp16, Button } from '@dhis2/ui'; +import { Button, Popover } from '@dhis2/ui'; import { ConditionalTooltip } from 'capture-core/components/Tooltips/ConditionalTooltip'; +import { ChevronDown, ChevronUp } from 'capture-ui/Icons'; import { ActiveFilterButton } from './ActiveFilterButton.component'; import { FilterSelectorContents } from '../Contents'; import type { UpdateFilter, ClearFilter, RemoveFilter } from '../../types'; @@ -11,8 +11,9 @@ import type { FilterData, Options } from '../../../FiltersForTypes'; const getStyles = (theme: Theme) => ({ icon: { - fontSize: theme.typography.pxToRem(20), - paddingLeft: theme.typography.pxToRem(5), + paddingLeft: theme.typography.pxToRem(12), + display: 'flex', + alignItems: 'center', }, inactiveFilterButton: { backgroundColor: '#f5f5f5', @@ -22,15 +23,6 @@ const getStyles = (theme: Theme) => ({ }, }); -const POPOVER_ANCHOR_ORIGIN = { - vertical: 'bottom', - horizontal: 'left', -}; -const POPOVER_TRANSFORM_ORIGIN = { - vertical: 'top', - horizontal: 'left', -}; - type Props = { itemId: string, type: string, @@ -142,11 +134,11 @@ class FilterButtonMainPlain extends Component { const arrowIconElement = selectorVisible ? ( - + ) : ( - + ); @@ -178,7 +170,7 @@ class FilterButtonMainPlain extends Component { > {title} - {selectorVisible ? : } + {selectorVisible ? : } @@ -199,22 +191,24 @@ class FilterButtonMainPlain extends Component { > {button}
- - { - (() => { - if (selectorVisible) { - return this.renderSelectorContents(); - } - return null; - })() - } - + {(selectorVisible && isMounted) && ( + + { + (() => { + if (selectorVisible) { + return this.renderSelectorContents(); + } + return null; + })() + } + + )} ); } diff --git a/src/core_modules/capture-core/components/ListView/Filters/FilterRestMenu/FilterRestMenu.component.js b/src/core_modules/capture-core/components/ListView/Filters/FilterRestMenu/FilterRestMenu.component.js index 97ca1b48e8..598911c49c 100644 --- a/src/core_modules/capture-core/components/ListView/Filters/FilterRestMenu/FilterRestMenu.component.js +++ b/src/core_modules/capture-core/components/ListView/Filters/FilterRestMenu/FilterRestMenu.component.js @@ -1,203 +1,52 @@ // @flow -import React from 'react'; -import { withStyles } from '@material-ui/core/styles'; -import { Card, IconChevronDown16, IconChevronUp16, Button, Layer } from '@dhis2/ui'; - -import { Manager, Popper, Reference } from 'react-popper'; -import Grow from '@material-ui/core/Grow'; -import MenuList from '@material-ui/core/MenuList'; -import MenuItem from '@material-ui/core/MenuItem'; +import React, { useState, useCallback } from 'react'; +import { FlyoutMenu, MenuItem, DropdownButton } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; - -import type { Column } from '../../types'; - -const getStyles = (theme: Theme) => ({ - icon: { - fontSize: theme.typography.pxToRem(20), - paddingLeft: theme.typography.pxToRem(5), - }, - restMenuButton: { - backgroundColor: '#f5f5f5', - }, - restMenuButtonLabel: { - textTransform: 'none', - }, - menuPaper: { - maxHeight: 280, - overflowY: 'auto', - }, - menuItemRoot: { - padding: 6, - paddingLeft: 24, - paddingRight: 24, - fontSize: theme.typography.pxToRem(14), - }, - popperContainerHidden: { - display: 'none', - }, - popper: { - zIndex: 1, - }, -}); +import type { Column, FilterOnly } from '../../types'; type Props = { - columns: Array, + columns: Array, onItemSelected: (id: string) => void, - classes: { - icon: string, - restMenuButton: string, - restMenuButtonLabel: string, - menuPaper: string, - menuItemRoot: string, - popperContainerHidden: string, - }, -}; - -type State = { - filterSelectorOpen: boolean, }; -class FilterRestMenuPlain extends React.Component { - menuClasses: Object; - menuItemClasses: Object; - managerRef: any; - menuReferenceInstance: ?HTMLDivElement; - constructor(props: Props) { - super(props); - this.state = { - filterSelectorOpen: false, - }; - this.setClassesOnMount(); - } - - setClassesOnMount() { - const classes = this.props.classes; - this.menuClasses = { - paper: classes.menuPaper, - }; - - this.menuItemClasses = { - root: classes.menuItemRoot, - }; - } - closeMenu() { - this.setState({ - filterSelectorOpen: false, - }); - } - - toggleMenu() { - this.setState({ - filterSelectorOpen: !this.state.filterSelectorOpen, - }); - } - - handleMenuButtonClick = () => { - this.toggleMenu(); - } - - handleClickAway = (event: any) => { - if (this.menuReferenceInstance && this.menuReferenceInstance.contains(event.target)) { - return; - } - this.closeMenu(); - } - - handleItemSelected = (id: string) => { - this.closeMenu(); - this.props.onItemSelected(id); - } - - renderMenuItems() { - const columns = this.props.columns; - return columns - .map(column => ( - { this.handleItemSelected(column.id); }} - classes={this.menuItemClasses} +export const FilterRestMenu = ({ columns, onItemSelected }: Props) => { + const [filterSelectorOpen, setFilterSelectorOpen] = useState(false); + + const toggleMenu = useCallback(() => { + setFilterSelectorOpen(prevState => !prevState); + }, []); + + const handleItemSelected = useCallback((id: string) => { + setFilterSelectorOpen(false); + onItemSelected(id); + }, [onItemSelected]); + + const renderMenuItems = useCallback(() => ( + columns.map(column => ( + handleItemSelected(column.id)} + label={column.header} + /> + )) + ), [columns, handleItemSelected]); + + return ( + - {column.header} - - )); - } - - handleReferenceInstanceRetrieved = (instance) => { - this.managerRef(instance); - this.menuReferenceInstance = instance; - } - - render() { - const { classes } = this.props; - - return ( - - - { - ({ ref }) => { - this.managerRef = ref; - return ( -
- -
- ); - } - } -
- {this.state.filterSelectorOpen && - - - { - ({ ref, style, placement }) => ( -
- - - - {this.renderMenuItems()} - - - -
- ) - } -
-
- } -
- ); - } -} - -export const FilterRestMenu = withStyles(getStyles)(FilterRestMenuPlain); + {renderMenuItems()} + + } + > + {i18n.t('More filters')} + + ); +}; diff --git a/src/core_modules/capture-core/components/ListView/Menu/ListViewMenu.component.js b/src/core_modules/capture-core/components/ListView/Menu/ListViewMenu.component.js index 07611adc28..8acb2bcf59 100644 --- a/src/core_modules/capture-core/components/ListView/Menu/ListViewMenu.component.js +++ b/src/core_modules/capture-core/components/ListView/Menu/ListViewMenu.component.js @@ -1,11 +1,9 @@ // @flow -import React, { useCallback, memo, type ComponentType } from 'react'; +import React, { useState, useRef, memo, useCallback, type ComponentType } from 'react'; import { IconButton } from 'capture-ui'; -import { withStyles } from '@material-ui/core/styles'; -import { Divider, IconMore24, Card } from '@dhis2/ui'; -import { MenuList, MenuItem } from '@material-ui/core'; +import { MenuItem, Layer, Popper, IconMore24, FlyoutMenu, Divider } from '@dhis2/ui'; +import { withStyles } from '@material-ui/core'; -import { MenuPopper } from '../../Popper/Popper.component'; import type { Props } from './listViewMenu.types'; const getStyles = () => ({ @@ -31,16 +29,15 @@ const getStyles = () => ({ }); const ListViewMenuPlain = ({ customMenuContents = [], classes }: Props) => { - const renderPopperAction = useCallback((togglePopper: Function) => ( - - - - ), []); + const anchorRef = useRef(null); + const [actionsIsOpen, setActionsIsOpen] = useState(false); - const renderMenuItems = useCallback((togglePopper: Function) => + const toggle = () => { + setActionsIsOpen(prev => !prev); + }; + + + const renderMenuItems = useCallback(() => customMenuContents .map((content) => { if (content.subHeader) { @@ -70,40 +67,42 @@ const ListViewMenuPlain = ({ customMenuContents = [], classes }: Props) => { if (!content.clickHandler) { return; } - togglePopper(); + setActionsIsOpen(false); // $FlowFixMe Using exact types, in my book this should work. Please tell me what I'm missing. content.clickHandler(); }} // $FlowFixMe Using exact types, in my book this should work. Please tell me what I'm missing. disabled={!content.clickHandler} - > - { - // $FlowFixMe Using exact types, in my book this should work. Please tell me what I'm missing. - content.element} -
+ // $FlowFixMe Using exact types, in my book this should work. Please tell me what I'm missing. + label={content.element} + /> ); }) .flat(1), [customMenuContents, classes]); - const renderPopperContent = useCallback((togglePopper: Function) => ( - - - {renderMenuItems(togglePopper)} - - - ), [renderMenuItems]); - - if (!customMenuContents.length) { - return null; - } - return ( - +
+ + + + {actionsIsOpen && ( + setActionsIsOpen(false)} transparent> + + + {renderMenuItems()} + + + + )} +
); }; export const ListViewMenu: ComponentType<$Diff> = - memo<$Diff>(withStyles(getStyles)(ListViewMenuPlain)); + memo < $Diff>(withStyles(getStyles)(ListViewMenuPlain)); diff --git a/src/core_modules/capture-core/components/ListView/types/listView.types.js b/src/core_modules/capture-core/components/ListView/types/listView.types.js index 011d70d6fb..96f98f4c90 100644 --- a/src/core_modules/capture-core/components/ListView/types/listView.types.js +++ b/src/core_modules/capture-core/components/ListView/types/listView.types.js @@ -60,7 +60,8 @@ export type CustomMenuContents = Array; export type CustomRowMenuContent = {| key: string, clickHandler?: ?(rowData: DataSourceItem) => any, - element: React$Node, + icon: React$Node, + label: string, |}; export type CustomRowMenuContents = Array; diff --git a/src/core_modules/capture-core/components/ListView/withEndColumnMenu/RowMenu.component.js b/src/core_modules/capture-core/components/ListView/withEndColumnMenu/RowMenu.component.js index 1ba6d043c5..68d0706fce 100644 --- a/src/core_modules/capture-core/components/ListView/withEndColumnMenu/RowMenu.component.js +++ b/src/core_modules/capture-core/components/ListView/withEndColumnMenu/RowMenu.component.js @@ -1,160 +1,58 @@ // @flow -import * as React from 'react'; -import { Manager, Popper, Reference } from 'react-popper'; -import { Card, spacers, IconMore24, colors, Layer } from '@dhis2/ui'; -import Grow from '@material-ui/core/Grow'; -import MenuList from '@material-ui/core/MenuList'; -import MenuItem from '@material-ui/core/MenuItem'; -import withStyles from '@material-ui/core/styles/withStyles'; -import type { Props, State } from './rowMenu.types'; - -const styles = theme => ({ - deleteIcon: { - fill: theme.palette.error.main, - }, - menuList: { - padding: 0, - }, - popperContainer: { - zIndex: 100, - }, - iconButton: { - display: 'flex', - borderRadius: '50%', - border: 'none', - cursor: 'pointer', - background: 'transparent', - padding: spacers.dp12, - marginTop: `-${spacers.dp12}`, - marginBottom: `-${spacers.dp12}`, - color: colors.grey600, - '&:hover': { - background: colors.grey400, - }, - }, -}); - -class Index extends React.Component { - managerRef: any; - menuReferenceInstance: ?HTMLDivElement; - - constructor(props: Props) { - super(props); - this.state = { menuOpen: false }; - } - - handleReferenceInstanceRetrieved = (instance) => { - this.managerRef(instance); - this.menuReferenceInstance = instance; - } - - toggleMenu = (event: any) => { - this.setState({ - menuOpen: !this.state.menuOpen, - }); - event.stopPropagation(); - } - - closeMenu = () => { - this.setState({ - menuOpen: false, - }); - } - - handleClickAway = (event: any) => { - if (this.menuReferenceInstance && this.menuReferenceInstance.contains(event.target)) { - return; - } - this.closeMenu(); - } - - renderMenuItems = () => { - const { customRowMenuContents = [], row, classes } = this.props; - - const menuItems = customRowMenuContents - .map(content => ( - ) => { - if (!content.clickHandler) { - return; - } - this.closeMenu(); - // $FlowFixMe common flow, I checked this 4 lines up - content.clickHandler(row); - event.stopPropagation(); - }} - disabled={!content.clickHandler} - > - {content.element} - - )); - - return ( - - {menuItems} - - ); - } - - render() { - const { classes } = this.props; - return ( - - - { - ({ ref }) => { - this.managerRef = ref; - return ( -
- -
- ); - } - } -
- {this.state.menuOpen && - +import React, { useState, useRef } from 'react'; +import { IconButton } from 'capture-ui'; +import { MenuItem, Layer, Popper, IconMore24, FlyoutMenu } from '@dhis2/ui'; +import type { Props } from './rowMenu.types'; + +export const RowMenu = (props: Props) => { + const { customRowMenuContents = [], row } = props; + + const anchorRef = useRef(null); + const [actionsIsOpen, setActionsIsOpen] = useState(false); + + const toggle = () => { + setActionsIsOpen(prev => !prev); + }; + + const renderMenuItems = () => customRowMenuContents.map(content => ( + { + if (!content.clickHandler) { + return; + } + setActionsIsOpen(false); + // $FlowFixMe common flow, I checked this 4 lines up + content.clickHandler(row); + }} + disabled={!content.clickHandler} + label={content.label} + icon={content.icon} + /> + )); + + return ( +
+ + + + {actionsIsOpen && ( + setActionsIsOpen(false)} transparent> - { - ({ ref, style, placement }) => ( -
- - - {this.renderMenuItems()} - - -
- ) - } + + {renderMenuItems()} +
- } - - ); - } -} - -export const RowMenu = withStyles(styles)(Index); + )} +
+ ); +}; diff --git a/src/core_modules/capture-core/components/NetworkStatusBadge/NetworkStatusBadge.component.js b/src/core_modules/capture-core/components/NetworkStatusBadge/NetworkStatusBadge.component.js deleted file mode 100644 index 2cdd4be23f..0000000000 --- a/src/core_modules/capture-core/components/NetworkStatusBadge/NetworkStatusBadge.component.js +++ /dev/null @@ -1,155 +0,0 @@ -import { connect } from 'react-redux'; -import React, { PureComponent } from 'react'; -import { IconSynk16 } from '@dhis2/ui'; -import Grow from '@material-ui/core/Grow'; -import { withStyles } from '@material-ui/core/styles'; -import moment from 'moment'; -import i18n from '@dhis2/d2-i18n'; - -const styles = () => ({ - offlineIcon: { - backgroundColor: '#9e9e9e', - width: '8px', - height: '8px', - borderRadius: '4px', - display: 'inline-block', - marginRight: '6px', - }, - onlineIcon: { - backgroundColor: '#48a999', - width: '8px', - height: '8px', - borderRadius: '4px', - display: 'inline-block', - marginRight: '6px', - }, - badgeContainer: { - backgroundColor: '#16486e', - color: 'white', - borderRadius: '4px', - whiteSpace: 'nowrap', - }, - badgeSection: { - padding: '8px', - }, - badgeSeparator: { - borderRight: '1px solid #0b3b60', - }, - flex: { - display: 'flex', - flexWrap: 'nowrap', - alignItems: 'center', - justifyContent: 'space-between', - }, - icon: { - animationName: 'Sync-spin', - animationDuration: '1.5s', - animationIterationCount: 'infinite', - animationDelay: '250ms', - animationDirection: 'reverse', - width: '16px', - height: '16px', - }, - text: { - margin: 0, - padding: 0, - }, - smallText: { - fontSize: '14px', - }, - '@keyframes Sync-spin': { - from: { transform: 'rotate(0deg)' }, - to: { transform: 'rotate(360deg)' }, - }, -}); - -const RightSection = props => - (
- -

{ props.status ? i18n.t('Online') : i18n.t('Offline') }

-
); - -class LeftSection extends PureComponent { - constructor(props) { - super(props); - this.state = { offlineTimer: moment(Date.now()).fromNow() }; - } - - componentDidUpdate() { - if (this.props.statusTimer === 0) { - clearInterval(this.timer); - this.timer = null; - // todo (eslint) - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ offlineTimer: moment(Date.now()).fromNow() }); - return; - } - - if (this.props.statusTimer > 0 && !this.timer) { - this.timer = setInterval(() => { - const t1 = moment(this.props.statusTimer).fromNow(); - this.setState({ offlineTimer: t1 }); - }, 60 * 1000); - } - } - - render() { - const props = this.props; - let content; - - if (props.status && props.syncList.length === 0) { - return null; - } - - if (props.status && props.syncList.length > 0) { - content = ( -
- - - -

{i18n.t('Syncing')}

-
- ); - } - - if (!props.status) { - content = {props.syncList.length} {i18n.t('offline events. Last synced:')} {this.state.offlineTimer}; - } - - const show = !!content; - - return ( - -
- {content} -
-
- ); - } -} - -const OnlineIcon = props => ; - -// eslint-disable-next-line react/no-multi-comp -class NetworkStatusBadgePlain extends PureComponent { - render() { - const status = this.props.offline || {}; - const classes = this.props.classes; - - const itemsToSync = status.outbox; - - return ( -
- - -
- ); - } -} - -const mapStateToProps = state => ({ - offline: state.offline, - networkStatus: state.networkStatus, -}); - -export const NetworkStatusBadge = connect(mapStateToProps)(withStyles(styles)(NetworkStatusBadgePlain)); diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/Section/ViewEventSection.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/Section/ViewEventSection.component.js index 36db5aebae..69eca570fc 100644 --- a/src/core_modules/capture-core/components/Pages/ViewEvent/Section/ViewEventSection.component.js +++ b/src/core_modules/capture-core/components/Pages/ViewEvent/Section/ViewEventSection.component.js @@ -1,10 +1,11 @@ // @flow +import React, { useState, useEffect, useRef } from 'react'; +import { withStyles } from '@material-ui/core'; +import { IconButton } from 'capture-ui'; +import cx from 'classnames'; +import { IconChevronUp24, colors, spacersNum } from '@dhis2/ui'; -import * as React from 'react'; -import { withStyles, IconButton } from '@material-ui/core'; -import { IconChevronDown24, IconChevronUp24, colors } from '@dhis2/ui'; - -const getStyles = (theme: Theme) => ({ +const getStyles = theme => ({ container: { background: colors.white, border: '1px solid', @@ -17,86 +18,132 @@ const getStyles = (theme: Theme) => ({ justifyContent: 'space-between', padding: theme.typography.pxToRem(5), minHeight: theme.typography.pxToRem(42), - }, toggleCollapseButton: { padding: 4, }, - contentContainer: { + children: { padding: theme.typography.pxToRem(10), borderTop: `1px solid ${theme.palette.grey.blueGrey}`, + '&.open': { + animation: 'slidein 200ms normal forwards ease-in-out', + transformOrigin: '50% 0%', + }, + '&.close': { + animation: 'slideout 200ms normal forwards ease-in-out', + transformOrigin: '100% 0%', + }, + }, + toggleButton: { + margin: `0 0 0 ${spacersNum.dp4}px`, + height: '24px', + borderRadius: '3px', + color: colors.grey600, + '&:hover': { + background: colors.grey200, + color: colors.grey800, + }, + '&.open': { + animation: 'flipOpen 200ms normal forwards linear', + }, + '&.close': { + animation: 'flipClose 200ms normal forwards linear', + }, + '&.closeinit': { + transform: 'rotateX(180deg)', + }, + }, + '@keyframes slidein': { + from: { transform: 'scaleY(0)' }, + to: { transform: 'scaleY(1)' }, + }, + '@keyframes slideout': { + from: { transform: 'scaleY(1)' }, + to: { transform: 'scaleY(0)' }, + }, + '@keyframes flipOpen': { + from: { transform: 'rotateX(180deg)' }, + to: { transform: 'rotateX(0)' }, + }, + '@keyframes flipClose': { + from: { transform: 'rotateX(0)' }, + to: { transform: 'rotateX(180deg)' }, }, }); type Props = { - header: React.Element, - children: React.Element, + header: React$Node, + children: React$Node, collapsable?: ?boolean, collapsed?: ?boolean, classes: Object, -} - -type State = { - collapsed: ?boolean, -} +}; -class ViewEventSectionPlain extends React.Component { - constructor(props) { - super(props); - this.state = { - collapsed: this.props.collapsed || false, - }; - } +const ViewEventSectionPlain = ({ + header, + collapsable = false, + collapsed: propsCollapsed = false, + children, + classes, +}: Props) => { + const [collapsed, setCollapsed] = useState(propsCollapsed); + const [childrenVisible, setChildrenVisibility] = useState(!propsCollapsed); + const [animationsReady, setAnimationsReadyStatus] = useState(false); + const hideChildrenTimeoutRef = useRef(null); + const initialRenderRef = useRef(true); - UNSAFE_componentWillReceiveProps(nextProps: Props) { - if (nextProps.collapsed !== this.props.collapsed) { - this.setState({ - collapsed: nextProps.collapsed, - }); + useEffect(() => { + if (initialRenderRef.current) { + initialRenderRef.current = false; + setAnimationsReadyStatus(false); + return; } - } - toggleCollapse = () => { - this.setState({ - collapsed: !this.state.collapsed, - }); - } + setAnimationsReadyStatus(true); - renderCollapsable = () => { - const classes = this.props.classes; + if (!collapsed) { + setChildrenVisibility(true); + } else { + hideChildrenTimeoutRef.current = setTimeout(() => { + setChildrenVisibility(false); + }, 200); + } + }, [collapsed]); - return ( - - {this.state.collapsed ? - : - - } - - ); - } + const toggleCollapse = () => { + setCollapsed(prev => !prev); + }; - renderContent = () => { - const { children, classes } = this.props; - return ( -
- {children} + return ( +
+
+ {header} + {collapsable && ( + + + + )}
- ); - } - - render() { - const { header, collapsable, classes } = this.props; - return ( -
-
- {header} - {collapsable && this.renderCollapsable()} + {childrenVisible && ( +
+ {children}
- {!this.state.collapsed && this.renderContent()} -
- ); - } -} + )} +
+ ); +}; export const ViewEventSection = withStyles(getStyles)(ViewEventSectionPlain); diff --git a/src/core_modules/capture-core/components/Popper/Popper.component.js b/src/core_modules/capture-core/components/Popper/Popper.component.js deleted file mode 100644 index 832de14135..0000000000 --- a/src/core_modules/capture-core/components/Popper/Popper.component.js +++ /dev/null @@ -1,107 +0,0 @@ -// @flow -import * as React from 'react'; -import { Manager, Popper, Reference } from 'react-popper'; -import type { Placement } from '@popperjs/core/lib'; -import { Layer } from '@dhis2/ui'; -import Grow from '@material-ui/core/Grow'; - -type Props = { - getPopperAction: (togglePopper: () => void) => React.Node, - getPopperContent: (togglePopper: Function) => React.Node, - placement: Placement, - classes?: ?Object, -} - -type State = { - popperOpen: ?boolean, -} - -export class MenuPopper extends React.Component { - managerRef: any; - menuReferenceInstance: ?HTMLDivElement; - - static defaultProps = { - placement: 'bottom-end', - } - - constructor(props: Props) { - super(props); - this.state = { popperOpen: false }; - } - - handleReferenceInstanceRetrieved = (instance: any) => { - this.managerRef(instance); - this.menuReferenceInstance = instance; - } - - toggleMenu = (event?: any) => { - this.setState({ - popperOpen: !this.state.popperOpen, - }); - event && event.stopPropagation(); - } - - closeMenu = () => { - this.setState({ - popperOpen: false, - }); - } - - handleClickAway = (event: any) => { - if (this.menuReferenceInstance && this.menuReferenceInstance.contains(event.target)) { - return; - } - this.closeMenu(); - } - - render() { - const { classes, getPopperAction, getPopperContent } = this.props; - - return ( - - - { - ({ ref }) => { - this.managerRef = ref; - return ( -
- {getPopperAction(this.toggleMenu)} -
- ); - } - } -
- {this.state.popperOpen && - - - { - ({ ref, style, placement }) => ( -
- - - {getPopperContent(this.toggleMenu)} - - -
- ) - } -
-
} -
- ); - } -} diff --git a/src/core_modules/capture-core/components/Relationships/Relationships.component.js b/src/core_modules/capture-core/components/Relationships/Relationships.component.js index 5e4b38fbf1..a0fe19e867 100644 --- a/src/core_modules/capture-core/components/Relationships/Relationships.component.js +++ b/src/core_modules/capture-core/components/Relationships/Relationships.component.js @@ -3,8 +3,9 @@ import * as React from 'react'; import classNames from 'classnames'; import i18n from '@dhis2/d2-i18n'; -import { IconButton, withStyles } from '@material-ui/core'; -import { IconArrowRight16, IconCross24, Button } from '@dhis2/ui'; +import { withStyles } from '@material-ui/core'; +import { IconButton } from 'capture-ui'; +import { IconArrowRight16, IconDelete16, Button, colors } from '@dhis2/ui'; import { ConditionalTooltip } from 'capture-core/components/Tooltips/ConditionalTooltip'; import type { RelationshipType } from '../../metaData'; import type { Relationship, Entity } from './relationships.types'; @@ -23,7 +24,7 @@ const getStyles = (theme: Theme) => ({ relationshipTypeName: { fontSize: 14, fontWeight: 600, - color: 'rgba(0,0,0,0.7)', + color: colors.grey700, }, relationshipsContainer: { }, @@ -84,6 +85,7 @@ type Props = { relationshipActions: string, relationshipHighlight: string, tooltip: string, + deleteButton: string, addButtonContainer: string, }, relationships: Array, @@ -145,12 +147,14 @@ class RelationshipsPlain extends React.Component { wrapperClassName={classes.tooltip} > { onRemoveRelationship(relationship.clientId); }} disabled={!canDelete} + secondary > - + +
@@ -203,6 +207,7 @@ class RelationshipsPlain extends React.Component { disabled={!canCreate} small={smallMainButton} dataTest="add-relationship-button" + secondary > {i18n.t('Add relationship')} diff --git a/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetError/WidgetErrorHeader.js b/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetError/WidgetErrorHeader.js index 1544fb4057..defa892c94 100644 --- a/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetError/WidgetErrorHeader.js +++ b/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetError/WidgetErrorHeader.js @@ -1,8 +1,7 @@ // @flow import React from 'react'; import { withStyles } from '@material-ui/core'; -import { ErrorRounded } from '@material-ui/icons'; -import { spacers, colors } from '@dhis2/ui'; +import { spacers, colors, IconErrorFilled24 } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; const styles = { @@ -20,7 +19,7 @@ const styles = { const WidgetErrorHeaderPlain = ({ classes }) => ( - +

{i18n.t('Error')}

); diff --git a/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetWarning/WidgetWarningHeader.js b/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetWarning/WidgetWarningHeader.js index 25eca6d680..9483be440f 100644 --- a/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetWarning/WidgetWarningHeader.js +++ b/src/core_modules/capture-core/components/WidgetErrorAndWarning/WidgetWarning/WidgetWarningHeader.js @@ -1,7 +1,6 @@ // @flow -import { colors, spacers } from '@dhis2/ui'; -import { WarningRounded } from '@material-ui/icons'; +import { colors, spacers, IconWarningFilled24 } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; import React from 'react'; import { withStyles } from '@material-ui/core'; @@ -20,7 +19,7 @@ const styles = { const WidgetWarningHeaderPlain = ({ classes }) => ( - +

{i18n.t('Warning')}

); diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageOverview/StageOverview.component.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageOverview/StageOverview.component.js index c2e7731421..907e049840 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageOverview/StageOverview.component.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageOverview/StageOverview.component.js @@ -76,7 +76,7 @@ const getLastUpdatedAt = (events, fromServerDate) => { <> {i18n.t('Last updated')}  - { moment(fromServerDate(updatedAt)).fromNow()} + {moment(fromServerDate(updatedAt)).fromNow()} ) @@ -111,15 +111,15 @@ export const StageOverviewPlain = ({ title, icon, description, events, classes }
{title}
- { description && - -
- -
-
+ {description && + +
+ +
+
}
@@ -141,7 +141,7 @@ export const StageOverviewPlain = ({ title, icon, description, events, classes }
{i18n.t('{{ scheduledEvents }} scheduled', { scheduledEvents })} -
: null } +
: null} {totalEvents > 0 &&
diff --git a/src/core_modules/capture-core/components/WidgetsRelationship/WidgetTrackedEntityRelationship/NewTrackedEntityRelationship/hooks/useAddRelationship.js b/src/core_modules/capture-core/components/WidgetsRelationship/WidgetTrackedEntityRelationship/NewTrackedEntityRelationship/hooks/useAddRelationship.js index 3342810e0b..b57a46e4f0 100644 --- a/src/core_modules/capture-core/components/WidgetsRelationship/WidgetTrackedEntityRelationship/NewTrackedEntityRelationship/hooks/useAddRelationship.js +++ b/src/core_modules/capture-core/components/WidgetsRelationship/WidgetTrackedEntityRelationship/NewTrackedEntityRelationship/hooks/useAddRelationship.js @@ -23,7 +23,7 @@ export const useAddRelationship = ({ teiId, onMutate, onSuccess }: Props) => { const queryClient = useQueryClient(); const queryKey: string = useFeature(FEATURES.exportablePayload) ? 'relationships' : 'instances'; const dataEngine = useDataEngine(); - const { show: showSnackbar } = useAlert( + const { show: showAlert } = useAlert( i18n.t('An error occurred while adding the relationship'), { critical: true }, ); @@ -37,7 +37,7 @@ export const useAddRelationship = ({ teiId, onMutate, onSuccess }: Props) => { }), { onError: (_, requestData) => { - showSnackbar(); + showAlert(); const apiRelationshipId = requestData.clientRelationship.relationship; const apiResponse = queryClient.getQueryData([ReactQueryAppNamespace, 'relationships', teiId]); const apiRelationships = handleAPIResponse(REQUESTED_ENTITIES.relationships, apiResponse); diff --git a/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/EventWorkingListsRowMenuSetup.component.js b/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/EventWorkingListsRowMenuSetup.component.js index 7044885784..fadcccb965 100644 --- a/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/EventWorkingListsRowMenuSetup.component.js +++ b/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/EventWorkingListsRowMenuSetup.component.js @@ -1,32 +1,19 @@ // @flow -import React, { useMemo, type ComponentType } from 'react'; +import React, { useMemo } from 'react'; import i18n from '@dhis2/d2-i18n'; -import { withStyles } from '@material-ui/core/styles'; import { IconDelete24, colors } from '@dhis2/ui'; import { EventWorkingListsUpdateTrigger } from '../UpdateTrigger'; import type { CustomRowMenuContents } from '../../WorkingListsBase'; import type { Props } from './eventWorkingListsRowMenuSetup.types'; -const getStyles = () => ({ - deleteContainer: { - display: 'flex', - }, -}); -export const EventWorkingListsRowMenuSetupPlain = ({ onDeleteEvent, classes, ...passOnProps }: Props) => { +export const EventWorkingListsRowMenuSetup = ({ onDeleteEvent, ...passOnProps }: Props) => { const customRowMenuContents: CustomRowMenuContents = useMemo(() => [{ key: 'deleteEventItem', clickHandler: ({ id }) => onDeleteEvent(id), - element: ( - - - {i18n.t('Delete event')} - - ), - }], [onDeleteEvent, classes.deleteContainer]); + icon: , + label: i18n.t('Delete event'), + }], [onDeleteEvent]); return ( ); }; - -export const EventWorkingListsRowMenuSetup: ComponentType<$Diff> = - withStyles(getStyles)(EventWorkingListsRowMenuSetupPlain); diff --git a/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/eventWorkingListsRowMenuSetup.types.js b/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/eventWorkingListsRowMenuSetup.types.js index 28331c6f0d..efd37756d4 100644 --- a/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/eventWorkingListsRowMenuSetup.types.js +++ b/src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/RowMenuSetup/eventWorkingListsRowMenuSetup.types.js @@ -4,7 +4,6 @@ import type { CustomRowMenuContents } from '../../WorkingListsBase'; type ExtractedProps = $ReadOnly<{| onDeleteEvent: Function, - classes: Object, |}>; type RestProps = $Rest; diff --git a/src/core_modules/capture-ui/Icons/DropdownChevron.component.js b/src/core_modules/capture-ui/Icons/DropdownChevron.component.js new file mode 100644 index 0000000000..d02d85e2d5 --- /dev/null +++ b/src/core_modules/capture-ui/Icons/DropdownChevron.component.js @@ -0,0 +1,35 @@ +// @flow +import React from 'react'; + +type Props = { + className?: string, +}; + +export function ChevronDown({ className }: Props) { + return ( + + + + ); +} + +export function ChevronUp({ className }: Props) { + return ( + + + + ); +} diff --git a/src/core_modules/capture-ui/Icons/index.js b/src/core_modules/capture-ui/Icons/index.js index 1f4dfc1f82..0bada9e901 100644 --- a/src/core_modules/capture-ui/Icons/index.js +++ b/src/core_modules/capture-ui/Icons/index.js @@ -6,5 +6,6 @@ export { MultiSelectionUncheckedIcon } from './MultiSelectionUncheckedIcon.compo export { SingleSelectionCheckedIcon } from './SingleSelectionCheckedIcon.component'; export { SingleSelectionUncheckedIcon } from './SingleSelectionUncheckedIcon.component'; export { BookmarkAddIcon } from './BookmarkAddIcon.component'; +export { ChevronDown, ChevronUp } from './DropdownChevron.component'; export { ChevronIcon } from './ChevronIcon.component'; From 2a1c7be7109be9d1f706436b9d12eb17059d1370 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Thu, 3 Oct 2024 11:43:00 +0000 Subject: [PATCH 20/91] chore(release): cut 101.7.0 [skip release] # [101.7.0](https://github.com/dhis2/capture-app/compare/v101.6.2...v101.7.0) (2024-10-03) ### Features * [DHIS2-17874] replace remaining Material UI components ([#3794](https://github.com/dhis2/capture-app/issues/3794)) ([7194e54](https://github.com/dhis2/capture-app/commit/7194e54a56bbfbcab5b3d39d597fabfa4d49daf7)) --- 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 65bc0a3ec3..2a5b490a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.7.0](https://github.com/dhis2/capture-app/compare/v101.6.2...v101.7.0) (2024-10-03) + + +### Features + +* [DHIS2-17874] replace remaining Material UI components ([#3794](https://github.com/dhis2/capture-app/issues/3794)) ([7194e54](https://github.com/dhis2/capture-app/commit/7194e54a56bbfbcab5b3d39d597fabfa4d49daf7)) + ## [101.6.2](https://github.com/dhis2/capture-app/compare/v101.6.1...v101.6.2) (2024-10-01) diff --git a/package.json b/package.json index ffe44ffb82..83604774ef 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.6.2", + "version": "101.7.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.6.2", + "@dhis2/rules-engine-javascript": "101.7.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 d773ecb1fe..b1d2a148b5 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.6.2", + "version": "101.7.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From a1626e02991501c09df6d52d177374dff5fe75fe Mon Sep 17 00:00:00 2001 From: Tony Valle <79843014+superskip@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:55:41 +0200 Subject: [PATCH 21/91] fix: [DHIS2-18116] check return value of `parseDate` (#3823) --- .../capture-core/converters/formToClient.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/core_modules/capture-core/converters/formToClient.js b/src/core_modules/capture-core/converters/formToClient.js index 7134f1881c..adca6b5b72 100644 --- a/src/core_modules/capture-core/converters/formToClient.js +++ b/src/core_modules/capture-core/converters/formToClient.js @@ -14,28 +14,35 @@ type RangeValue = { to: string, } -function convertDateTime(formValue: DateTimeValue): string { +function convertDateTime(formValue: DateTimeValue): ?string { const editedDate = formValue.date; const editedTime = formValue.time; - const momentTime = parseTime(editedTime).momentTime; + const parsedTime = parseTime(editedTime); + if (!parsedTime.isValid) return null; + const momentTime = parsedTime.momentTime; const hours = momentTime.hour(); const minutes = momentTime.minute(); + const parsedDate = parseDate(editedDate); + if (!parsedDate.isValid) return null; // $FlowFixMe[incompatible-type] automated comment - const momentDateTime: moment$Moment = parseDate(editedDate).momentDate; + const momentDateTime: moment$Moment = parsedDate.momentDate; momentDateTime.hour(hours); momentDateTime.minute(minutes); return momentDateTime.toISOString(); } function convertDate(dateValue: string) { + const parsedDate = parseDate(dateValue); // $FlowFixMe[incompatible-use] automated comment - return parseDate(dateValue).momentDate.toISOString(); + return parsedDate.isValid ? parsedDate.momentDate.toISOString() : null; } function convertTime(timeValue: string) { - const momentTime = parseTime(timeValue).momentTime; + const parsedTime = parseTime(timeValue); + if (!parsedTime.isValid) return null; + const momentTime = parsedTime.momentTime; momentTime.locale('en'); return momentTime.format('HH:mm'); } From e081debb8aab004f67ed25392365fbeb2b79a5f2 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Fri, 4 Oct 2024 13:59:54 +0000 Subject: [PATCH 22/91] chore(release): cut 101.7.1 [skip release] ## [101.7.1](https://github.com/dhis2/capture-app/compare/v101.7.0...v101.7.1) (2024-10-04) ### Bug Fixes * [DHIS2-18116] check return value of `parseDate` ([#3823](https://github.com/dhis2/capture-app/issues/3823)) ([a1626e0](https://github.com/dhis2/capture-app/commit/a1626e02991501c09df6d52d177374dff5fe75fe)) --- 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 2a5b490a37..fbafed76ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.7.1](https://github.com/dhis2/capture-app/compare/v101.7.0...v101.7.1) (2024-10-04) + + +### Bug Fixes + +* [DHIS2-18116] check return value of `parseDate` ([#3823](https://github.com/dhis2/capture-app/issues/3823)) ([a1626e0](https://github.com/dhis2/capture-app/commit/a1626e02991501c09df6d52d177374dff5fe75fe)) + # [101.7.0](https://github.com/dhis2/capture-app/compare/v101.6.2...v101.7.0) (2024-10-03) diff --git a/package.json b/package.json index 83604774ef..fe877bae66 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.7.0", + "version": "101.7.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.7.0", + "@dhis2/rules-engine-javascript": "101.7.1", "@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 b1d2a148b5..0a3487a1f6 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.7.0", + "version": "101.7.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From a0e306c6d15d1c180e81ddbc162091ba554cd40f Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 6 Oct 2024 03:44:47 +0200 Subject: [PATCH 23/91] fix(translations): sync translations from transifex (master) Automatically merged. --- i18n/ar.po | 17 +-- i18n/cs.po | 9 -- i18n/da.po | 400 +++++++++++++++++++++++++++++++++++++++-------------- i18n/es.po | 9 -- i18n/fr.po | 9 -- i18n/id.po | 9 -- i18n/lo.po | 9 -- i18n/my.po | 34 ++--- i18n/nb.po | 9 -- i18n/nl.po | 9 -- i18n/vi.po | 13 +- i18n/zh.po | 23 +-- 12 files changed, 322 insertions(+), 228 deletions(-) diff --git a/i18n/ar.po b/i18n/ar.po index b619c664e0..2e69358014 100644 --- a/i18n/ar.po +++ b/i18n/ar.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Arabic (https://app.transifex.com/hisp-uio/teams/100509/ar/)\n" @@ -605,15 +605,6 @@ msgstr "البرنامج غير موجود" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "متصل" - -msgid "Offline" -msgstr "غير متصل" - -msgid "Syncing" -msgstr "تزامن" - msgid "Add note" msgstr "أضف ملاحظة" @@ -1256,12 +1247,6 @@ msgstr "" msgid "Follow-up" msgstr "متابعة" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "الملغية" diff --git a/i18n/cs.po b/i18n/cs.po index 61c3bef8ce..040d421b6b 100644 --- a/i18n/cs.po +++ b/i18n/cs.po @@ -607,15 +607,6 @@ msgstr "Program neexistuje" msgid "Selected program is invalid for selected organisation unit" msgstr "Vybraný program je pro vybranou organizační jednotku neplatný" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "Probíhá synchronizace" - msgid "Add note" msgstr "Přidat poznámku" diff --git a/i18n/da.po b/i18n/da.po index 39145ad696..254ea3696e 100644 --- a/i18n/da.po +++ b/i18n/da.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-02-14T10:01:26.732Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Danish (https://app.transifex.com/hisp-uio/teams/100509/da/)\n" @@ -36,6 +36,9 @@ msgid "" "again, but be aware that this will close other versions." msgstr "" +msgid "More" +msgstr "" + msgid "View {{programName}} dashboard" msgstr "" @@ -189,15 +192,15 @@ msgstr "" msgid "Search for user" msgstr "" +msgid "Notes" +msgstr "" + msgid "Basic info" msgstr "" msgid "Status" msgstr "Status" -msgid "Comments" -msgstr "" - msgid "Relationships" msgstr "" @@ -226,7 +229,7 @@ msgstr "Active" msgid "Completed" msgstr "" -msgid "Please add or cancel comment before saving the event" +msgid "Please add or cancel note before saving the event" msgstr "" msgid "Save and add another" @@ -309,6 +312,30 @@ msgstr "" msgid "An error has occurred. See log for details" msgstr "" +msgid "{{programStageName}} completed" +msgstr "" + +msgid "" +"Would you like to complete the enrollment and all active events as well?" +msgstr "" + +msgid "{{count}} event in {{programStageName}}" +msgid_plural "{{count}} event in {{programStageName}}" +msgstr[0] "" +msgstr[1] "" + +msgid "Yes, complete enrollment and events" +msgstr "" + +msgid "Complete enrollment only" +msgstr "" + +msgid "Would you like to complete the enrollment?" +msgstr "" + +msgid "Complete enrollment" +msgstr "" + msgid "A duplicate exists (but there were some errors, see log for details" msgstr "" @@ -334,16 +361,10 @@ msgstr "" msgid "validation failed" msgstr "" -msgid "Errors" +msgid "No feedback for this event yet" msgstr "" -msgid "Feedback" -msgstr "Feedback" - -msgid "Indicators" -msgstr "Indicators" - -msgid "Warnings" +msgid "No indicator output for this event yet" msgstr "" msgid "Generate new event" @@ -456,18 +477,6 @@ msgstr "" msgid "Yes" msgstr "Yes" -msgid "mm/dd/yyyy" -msgstr "" - -msgid "Years" -msgstr "" - -msgid "Months" -msgstr "" - -msgid "Days" -msgstr "" - msgid "Uploading file" msgstr "" @@ -534,6 +543,9 @@ msgstr "" msgid "Column" msgstr "" +msgid "Visible" +msgstr "" + msgid "Update" msgstr "Update" @@ -573,25 +585,16 @@ msgstr "" msgid "Program doesn't exist" msgstr "" -msgid "Selected program is invalid for selected registering unit" -msgstr "" - -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" +msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Add comment" +msgid "Add note" msgstr "" -msgid "You don't have access to write comments" +msgid "You don't have access to write notes" msgstr "" -msgid "Write comment" +msgid "Write note" msgstr "" msgid "was blanked out and hidden by your last action" @@ -652,6 +655,12 @@ msgid "" "An error occurred while fetching enrollments. Please enter a valid url." msgstr "" +msgid "No feedback for this enrollment yet" +msgstr "" + +msgid "No indicator output for this enrollment yet" +msgstr "" + msgid "Quick actions" msgstr "" @@ -732,7 +741,7 @@ msgstr "" msgid "There was an error loading the page" msgstr "" -msgid "Choose a registering unit to start reporting" +msgid "Choose an organisation unit to start reporting" msgstr "" msgid "Program stage is invalid" @@ -765,6 +774,11 @@ msgstr "" msgid "Registered events" msgstr "" +msgid "" +"The category option is not valid for the selected organisation unit. Please " +"select a valid combination." +msgstr "" + msgid "Please select {{category}}." msgstr "" @@ -777,8 +791,10 @@ msgstr "" msgid "Please select an organisation unit." msgstr "" -msgid "New" -msgstr "New" +msgid "" +"You don't have access to create a {{trackedEntityName}} in the current " +"selections" +msgstr "" msgid "Choose the {{missingCategories}} to start reporting" msgstr "" @@ -786,8 +802,8 @@ msgstr "" msgid "Save as new" msgstr "" -msgid "View enrollment" -msgstr "" +msgid "New" +msgstr "New" msgid "Create for" msgstr "" @@ -865,6 +881,9 @@ msgstr "" msgid "Edit event" msgstr "" +msgid "View changelog" +msgstr "" + msgid "Event details" msgstr "" @@ -873,6 +892,18 @@ msgid "" "relationship" msgstr "" +msgid "Errors" +msgstr "" + +msgid "Feedback" +msgstr "Feedback" + +msgid "Indicators" +msgstr "Indicators" + +msgid "Warnings" +msgstr "" + msgid "Show all events" msgstr "" @@ -894,12 +925,6 @@ msgstr "" msgid "View Event" msgstr "" -msgid "No feedback for this enrollment yet" -msgstr "" - -msgid "No indicator output for this enrollment yet" -msgstr "" - msgid "Selected program" msgstr "" @@ -909,12 +934,23 @@ msgstr "" msgid "Search by attributes" msgstr "" +msgid "Fill in at least {{count}} attribute to search" +msgid_plural "Fill in at least {{count}} attribute to search" +msgstr[0] "" +msgstr[1] "" + msgid "Could not retrieve metadata. Please try again later." msgstr "" msgid "The enrollment event data could not be found" msgstr "" +msgid "Loading" +msgstr "" + +msgid "An error occurred while loading the form" +msgstr "" + msgid "Possible duplicates found" msgstr "" @@ -933,10 +969,7 @@ msgstr "" msgid "No results found for " msgstr "" -msgid "Registering unit" -msgstr "" - -msgid "Choose a registering unit" +msgid "Choose an organisation unit" msgstr "" msgid "Clear selection" @@ -948,7 +981,7 @@ msgstr "" msgid "Search for a program" msgstr "" -msgid "Some programs are being filtered by the chosen registering unit" +msgid "Some programs are being filtered by the chosen organisation unit" msgstr "" msgid "Show all programs" @@ -1041,12 +1074,18 @@ msgstr "" msgid "Create saved list" msgstr "" -msgid "New {{trackedEntityName}} in {{programName}}" +msgid "Create new in another program" +msgstr "" + +msgid "Create new event" msgstr "" msgid "Search for a {{trackedEntityName}} in {{programName}}" msgstr "" +msgid "No tracked entity types available" +msgstr "" + msgid "Assigned to" msgstr "" @@ -1084,9 +1123,6 @@ msgid "" "program. All activity will be logged." msgstr "" -msgid "Save comment" -msgstr "" - msgid "Enrollment actions" msgstr "" @@ -1125,6 +1161,12 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Transfer" +msgstr "" + +msgid "An error occurred while transferring ownership" +msgstr "" + msgid "Existing dates for auto-generated events will not be updated." msgstr "" @@ -1152,6 +1194,24 @@ msgstr "" msgid "Set area" msgstr "" +msgid "" +"Transferring enrollment ownership from {{ownerOrgUnit}} to " +"{{newOrgUnit}}{{escape}}" +msgstr "" + +msgid "" +"You will lose access to the enrollment when transferring ownership to " +"{{organisationUnit}}." +msgstr "" + +msgid "Transfer Ownership" +msgstr "" + +msgid "" +"Choose the organisation unit to which enrollment ownership should be " +"transferred." +msgstr "" + msgid "Enrollment date" msgstr "Enrollment date" @@ -1164,15 +1224,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - -msgid "Last updated {{date}}" -msgstr "" - msgid "Cancelled" msgstr "" @@ -1182,22 +1233,25 @@ msgstr "" msgid "Add area" msgstr "" -msgid "Comments about this enrollment" +msgid "Please add or cancel the note before saving the event" msgstr "" -msgid "Write a comment about this enrollment" +msgid "organisation unit could not be retrieved. Please try again later." msgstr "" -msgid "This enrollment doesn't have any comments" +msgid "Saving to {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" -msgid "organisation unit could not be retrieved. Please try again later." +msgid "program or stage is invalid" msgstr "" -msgid "Saving to {{stageName}} for {{programName}} in {{orgUnitName}}" +msgid "Notes about this enrollment" msgstr "" -msgid "program or stage is invalid" +msgid "Write a note about this enrollment" +msgstr "" + +msgid "This enrollment doesn't have any notes" msgstr "" msgid "Error" @@ -1206,15 +1260,6 @@ msgstr "Error" msgid "Warning" msgstr "Warning" -msgid "Comments about this event" -msgstr "" - -msgid "Write a comment about this event" -msgstr "" - -msgid "This event doesn't have any comments" -msgstr "" - msgid "stage not found in rules execution" msgstr "" @@ -1233,9 +1278,21 @@ msgstr "" msgid "Event completed" msgstr "" +msgid "The event cannot be edited after it has been completed" +msgstr "" + msgid "Back to all stages and events" msgstr "" +msgid "Notes about this event" +msgstr "" + +msgid "Write a note about this event" +msgstr "" + +msgid "This event doesn't have any notes" +msgstr "" + msgid "Schedule date info" msgstr "" @@ -1246,12 +1303,24 @@ msgid "" "The scheduled date matches the suggested date, but can be changed if needed." msgstr "" +msgid "The scheduled date is {{count}} days {{position}} the suggested date." +msgid_plural "" +"The scheduled date is {{count}} days {{position}} the suggested date." +msgstr[0] "" +msgstr[1] "" + msgid "after" msgstr "" msgid "before" msgstr "" +msgid "There are {{count}} scheduled event in {{orgUnitName}} on this day." +msgid_plural "" +"There are {{count}} scheduled event in {{orgUnitName}} on this day." +msgstr[0] "" +msgstr[1] "" + msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1262,10 +1331,13 @@ msgstr "" msgid "Schedule date / Due date" msgstr "" -msgid "Event comments" +msgid "Event notes" +msgstr "" + +msgid "Write a note about this scheduled event" msgstr "" -msgid "Write a comment about this scheduled event" +msgid "Save note" msgstr "" msgid "" @@ -1298,39 +1370,111 @@ msgstr "" msgid "Fix errors in the form to continue." msgstr "" +msgid "You do not have access to delete this {{trackedEntityTypeName}}" +msgstr "" + +msgid "Delete {{trackedEntityTypeName}}" +msgstr "" + +msgid "" +"Are you sure you want to delete this {{trackedEntityTypeName}}? This will " +"permanently remove the {{trackedEntityTypeName}} and all its associated " +"enrollments and events in all programs." +msgstr "" + +msgid "There was a problem deleting the {{trackedEntityTypeName}}" +msgstr "" + +msgid "Yes, delete {{trackedEntityTypeName}}" +msgstr "" + msgid "Profile widget could not be loaded. Please try again later" msgstr "" -msgid "{{TETName}} profile" +msgid "{{trackedEntityTypeName}} profile" msgstr "" msgid "tracked entity instance" msgstr "" -msgid "New {{ eventName }} event" +msgid "Link to an existing {{linkableStageLabel}}" msgstr "" -msgid "To open this event, please wait until saving is complete" +msgid "Choose a {{linkableStageLabel}}" msgstr "" -msgid "Show {{ rest }} more" +msgid "{{ linkableStageLabel }} is not repeatable" msgstr "" -msgid "Reset list" +msgid "{{ linkableStageLabel }} has no linkable events" msgstr "" -msgid "Go to full {{ eventName }}" +msgid "Ambiguous relationships, contact system administrator" +msgstr "" + +msgid "" +"Enter {{linkableStageLabel}} details in the next step after completing this " +"{{currentStageLabel}}." +msgstr "" + +msgid "Enter details now" +msgstr "" + +msgid "Link to an existing" +msgstr "" + +msgid "Scheduled date" +msgstr "" + +msgid "Report date" +msgstr "" + +msgid "Please select a valid event" +msgstr "" + +msgid "You do not have access to create events in this stage" msgstr "" msgid "This stage can only have one event" msgstr "" -msgid "Events could not be retrieved. Please try again later." +msgid "New {{ eventName }} event" +msgstr "" + +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + +msgid "To open this event, please wait until saving is complete" +msgstr "" + +msgid "Show {{ rest }} more" msgstr "" -msgid "{{ totalEvents }} events" +msgid "Go to full {{ eventName }}" +msgstr "" + +msgid "Events could not be retrieved. Please try again later." msgstr "" +msgid "{{ count }} event" +msgid_plural "{{ count }} event" +msgstr[0] "" +msgstr[1] "" + msgid "{{ overdueEvents }} overdue" msgstr "" @@ -1340,6 +1484,39 @@ msgstr "" msgid "Stages and Events" msgstr "" +msgid "An error occurred while loading the widget." +msgstr "" + +msgid "View linked event" +msgstr "" + +msgid "Scheduled" +msgstr "" + +msgid "Changelog" +msgstr "" + +msgid "No changes to display" +msgstr "" + +msgid "Created" +msgstr "" + +msgid "Deleted" +msgstr "" + +msgid "Date" +msgstr "Date" + +msgid "User" +msgstr "" + +msgid "Data item" +msgstr "" + +msgid "Change" +msgstr "" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" @@ -1365,28 +1542,33 @@ msgstr "" msgid "{{trackedEntityTypeName}} relationships" msgstr "" -msgid "To open this relationship, please wait until saving is complete" +msgid "Delete relationship" msgstr "" -msgid "Type" +msgid "" +"Deleting the relationship is permanent and cannot be undone. Are you sure " +"you want to delete this relationship?" msgstr "" -msgid "Created date" +msgid "Yes, delete relationship" msgstr "" -msgid "Program stage name" +msgid "An error occurred while deleting the relationship." msgstr "" -msgid "Working list could not be loaded" +msgid "To open this relationship, please wait until saving is complete" msgstr "" -msgid "Download as JSON" +msgid "Type" msgstr "" -msgid "Download as CSV" +msgid "Created date" msgstr "" -msgid "Download with current filters" +msgid "Program stage name" +msgstr "" + +msgid "Working list could not be loaded" msgstr "" msgid "Download data..." @@ -1404,6 +1586,9 @@ msgstr "" msgid "Enrollment status" msgstr "" +msgid "Follow up" +msgstr "" + msgid "Choose a program stage to filter by {{label}}" msgstr "" @@ -1458,13 +1643,19 @@ msgstr "" msgid "Show All" msgstr "" -msgid "An error has occured. See log for details" +msgid "Download as JSON" msgstr "" -msgid "Scheduled{{ escape }} due {{ time }}" +msgid "Download as CSV" msgstr "" -msgid "Scheduled" +msgid "Download with current filters" +msgstr "" + +msgid "An error has occured. See log for details" +msgstr "" + +msgid "Scheduled{{ escape }} due {{ time }}" msgstr "" msgid "Overdue{{ escape }} due {{ time }}" @@ -1530,9 +1721,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Date" -msgstr "Date" - msgid "Time" msgstr "" diff --git a/i18n/es.po b/i18n/es.po index 534e4de691..f102174f36 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -628,15 +628,6 @@ msgstr "" "El programa seleccionado no es válido para la unidad organizativa " "seleccionada" -msgid "Online" -msgstr "Conectado" - -msgid "Offline" -msgstr "Desconectado" - -msgid "Syncing" -msgstr "Sincronizando" - msgid "Add note" msgstr "Añadir nota" diff --git a/i18n/fr.po b/i18n/fr.po index c9418fa104..f74f7e4d77 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -626,15 +626,6 @@ msgstr "" "Le programme sélectionné n'est pas valide pour l'unité d'organisation " "sélectionnée" -msgid "Online" -msgstr "En ligne" - -msgid "Offline" -msgstr "Hors ligne" - -msgid "Syncing" -msgstr "Synchronisation" - msgid "Add note" msgstr "Ajouter une note" diff --git a/i18n/id.po b/i18n/id.po index a4124e8e01..7c64de57cb 100644 --- a/i18n/id.po +++ b/i18n/id.po @@ -612,15 +612,6 @@ msgstr "Program tidak ada" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "Menyinkronkan" - msgid "Add note" msgstr "Tambah catatan" diff --git a/i18n/lo.po b/i18n/lo.po index b12cc74fe7..24d7ea4464 100644 --- a/i18n/lo.po +++ b/i18n/lo.po @@ -605,15 +605,6 @@ msgstr "ບໍ່ມີໂປແກຼມ" msgid "Selected program is invalid for selected organisation unit" msgstr "ໂປແກຣມທີ່ເລືອກໄວ້ບໍ່ຖືກຕ້ອງກັບຫົວໜ່ວຍອົງການຈັດຕັ້ງ" -msgid "Online" -msgstr "ມີການເຊື່ອມຕໍ່" - -msgid "Offline" -msgstr "ບໍ່ມີການເຊື່ອມຕໍ່" - -msgid "Syncing" -msgstr "ກຳລັງອັບເດດຂໍ້ມູນໃຫ້ຄືກັນ" - msgid "Add note" msgstr "ຂຽນບັນທຶກລົງ" diff --git a/i18n/my.po b/i18n/my.po index 5bc6407800..1416f92911 100644 --- a/i18n/my.po +++ b/i18n/my.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Burmese (https://app.transifex.com/hisp-uio/teams/100509/my/)\n" @@ -590,15 +590,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "အင်တာနက်နှင့်ချိတ်ဆက်ထားသည်" - -msgid "Offline" -msgstr "အင်တာနက်နှင့်မချိတ်ဆက်ထားပါ" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "" @@ -1234,12 +1225,6 @@ msgstr "" msgid "Follow-up" msgstr "စောင့်ကြပ်ကြည့်ရှုခြင်း" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "" @@ -1455,6 +1440,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/nb.po b/i18n/nb.po index e14d1e2e25..7f32ad1482 100644 --- a/i18n/nb.po +++ b/i18n/nb.po @@ -608,15 +608,6 @@ msgstr "Programmet finnes ikke" msgid "Selected program is invalid for selected organisation unit" msgstr "Valgt program er ugyldig for valgt organisajonsenhet" -msgid "Online" -msgstr "Påkoblet" - -msgid "Offline" -msgstr "Frakoblet" - -msgid "Syncing" -msgstr "Synkroniserer" - msgid "Add note" msgstr "Legg til notat" diff --git a/i18n/nl.po b/i18n/nl.po index 1ab637a352..98e3e09bf6 100644 --- a/i18n/nl.po +++ b/i18n/nl.po @@ -614,15 +614,6 @@ msgstr "Programma bestaat niet" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "offline" - -msgid "Syncing" -msgstr "synchroniseren" - msgid "Add note" msgstr "Notitie toevoegen" diff --git a/i18n/vi.po b/i18n/vi.po index 10dc9f241e..4599936038 100644 --- a/i18n/vi.po +++ b/i18n/vi.po @@ -604,15 +604,6 @@ msgstr "Chương trình không tồn tại" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Trực tuyến" - -msgid "Offline" -msgstr "Ngoại tuyến" - -msgid "Syncing" -msgstr "Đang đồng bộ" - msgid "Add note" msgstr "Thêm ghi chú" @@ -898,7 +889,7 @@ msgid "events" msgstr "sự kiện" msgid "event" -msgstr "" +msgstr "sự kiện" msgid "You don't have access to edit this event" msgstr "" @@ -1194,7 +1185,7 @@ msgid "Mark for follow-up" msgstr "Đánh dấu để theo-dõi" msgid "Transfer" -msgstr "" +msgstr "Chuyển" msgid "An error occurred while transferring ownership" msgstr "" diff --git a/i18n/zh.po b/i18n/zh.po index 559372ca30..dcd850bd86 100644 --- a/i18n/zh.po +++ b/i18n/zh.po @@ -592,15 +592,6 @@ msgstr "项目不存在" msgid "Selected program is invalid for selected organisation unit" msgstr "所选项目对所选机构无效" -msgid "Online" -msgstr "在线" - -msgid "Offline" -msgstr "离线" - -msgid "Syncing" -msgstr "同步" - msgid "Add note" msgstr "添加笔记" @@ -1296,7 +1287,7 @@ msgid "Event completed" msgstr "事件完成" msgid "The event cannot be edited after it has been completed" -msgstr "" +msgstr "事件完成后不可编辑" msgid "Back to all stages and events" msgstr "回到所有阶段和事件" @@ -1450,7 +1441,7 @@ msgid "Please select a valid event" msgstr "请选择一个有效的事件" msgid "You do not have access to create events in this stage" -msgstr "" +msgstr "在此阶段,您无权限创建事件" msgid "This stage can only have one event" msgstr "这个阶段只能有一个事件" @@ -1459,18 +1450,18 @@ msgid "New {{ eventName }} event" msgstr "新的 {{ eventName }} 事件" msgid "An error occurred while deleting the event" -msgstr "" +msgstr "删除事件时发生错误" msgid "" "Deleting an event is permanent and cannot be undone. Are you sure you want " "to delete this event?" -msgstr "" +msgstr "删除事件是永久性的,无法撤销。您确定要删除此事件吗?" msgid "An error occurred when updating event status" -msgstr "" +msgstr "更新事件状态时发生错误" msgid "Unskip" -msgstr "" +msgstr "不跳过" msgid "Skip" msgstr "跳过" @@ -1696,7 +1687,7 @@ msgid "Program is not a tracker program" msgstr "项目不是跟踪随访项目" msgid "Error saving event" -msgstr "保存时间错误" +msgstr "保存事件发生错误" msgid "Could not save event" msgstr "无法保存事件" From 374042c41c66077e3d64fbd1dabcd081a389bb41 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 6 Oct 2024 01:48:58 +0000 Subject: [PATCH 24/91] chore(release): cut 101.7.2 [skip release] ## [101.7.2](https://github.com/dhis2/capture-app/compare/v101.7.1...v101.7.2) (2024-10-06) ### Bug Fixes * **translations:** sync translations from transifex (master) ([a0e306c](https://github.com/dhis2/capture-app/commit/a0e306c6d15d1c180e81ddbc162091ba554cd40f)) --- 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 fbafed76ae..e42dae3432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.7.2](https://github.com/dhis2/capture-app/compare/v101.7.1...v101.7.2) (2024-10-06) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([a0e306c](https://github.com/dhis2/capture-app/commit/a0e306c6d15d1c180e81ddbc162091ba554cd40f)) + ## [101.7.1](https://github.com/dhis2/capture-app/compare/v101.7.0...v101.7.1) (2024-10-04) diff --git a/package.json b/package.json index fe877bae66..fb7a31f23d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.7.1", + "version": "101.7.2", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.7.1", + "@dhis2/rules-engine-javascript": "101.7.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 0a3487a1f6..f41e24519f 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.7.1", + "version": "101.7.2", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 205bb82bd2289313859c697aa6a6106b270dce0a Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 7 Oct 2024 14:11:39 +0200 Subject: [PATCH 25/91] fix: [DHIS2-17530] show missing FILE url (#3787) --- .../WidgetProfile/hooks/getSubValueForTei.js | 6 ++ .../getEventListData/convertToClientEvents.js | 33 +++-------- .../buildUrlByElementType.js | 57 +++++++++++++++++++ .../helpers/getListDataCommon/getSubvalues.js | 3 + .../helpers/getListDataCommon/index.js | 1 + .../getTeiListData/convertToClientTeis.js | 20 ++----- .../trackedEntityInstances/getSubValues.js | 25 +++++++- 7 files changed, 106 insertions(+), 39 deletions(-) create mode 100644 src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js diff --git a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js index 89a9e819cf..7fb41b3a45 100644 --- a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js +++ b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js @@ -17,6 +17,11 @@ type SubValueFunctionParams = { minorServerVersion: number, }; +const buildTEAFileUrl = (attribute) => { + const { absoluteApiPath, teiId, id } = attribute; + return `${absoluteApiPath}/trackedEntityInstances/${teiId}/${id}/file`; +}; + const getFileResourceSubvalue = async ({ attribute, querySingleResource }: SubValueFunctionParams) => { if (!attribute.value) return null; @@ -25,6 +30,7 @@ const getFileResourceSubvalue = async ({ attribute, querySingleResource }: SubVa id, name, value: id, + url: buildTEAFileUrl(attribute), }; }; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getEventListData/convertToClientEvents.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getEventListData/convertToClientEvents.js index 4e0e339c90..943033bd6f 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getEventListData/convertToClientEvents.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getEventListData/convertToClientEvents.js @@ -1,6 +1,5 @@ // @flow import { translatedStatusTypes } from 'capture-core/events/statusTypes'; -import { featureAvailable, FEATURES } from 'capture-core-utils'; import { convertServerToClient } from '../../../../../../../converters'; import type { ApiEvents, @@ -13,7 +12,7 @@ import type { } from './types'; import { getFilterClientName, ADDITIONAL_FILTERS } from '../../../../helpers'; import { isEventOverdue } from '../../../../../../../utils/isEventOverdue'; -import { dataElementTypes } from '../../../../../../../metaData'; +import { RECORD_TYPE, buildUrlByElementType } from '../getListDataCommon'; const convertServerStatusToClient = ( status: 'ACTIVE' | 'VISITED' | 'COMPLETED' | 'SCHEDULE' | 'OVERDUE' | 'SKIPPED', @@ -47,16 +46,9 @@ const buildTEIRecord = ({ }) => columnsMetaForDataFetching.map(({ id, mainProperty, type }) => { const value = mainProperty ? apiTEI[id] : attributeValuesById[id]; - const urls = (type === dataElementTypes.IMAGE) ? - (() => (featureAvailable(FEATURES.trackerImageEndpoint) ? - { - imageUrl: `/tracker/trackedEntities/${trackedEntity}/attributes/${id}/image?program=${programId}`, - previewUrl: `/tracker/trackedEntities/${trackedEntity}/attributes/${id}/image?program=${programId}&dimension=small`, - } : { - imageUrl: `/trackedEntityInstances/${trackedEntity}/${id}/image?program=${programId}`, - previewUrl: `/trackedEntityInstances/${trackedEntity}/${id}/image?program=${programId}&dimension=SMALL`, - } - ))() : {}; + const urls = buildUrlByElementType[RECORD_TYPE.trackedEntity][type] + ? buildUrlByElementType[RECORD_TYPE.trackedEntity][type]({ trackedEntity, id, programId }) + : {}; return { id, @@ -86,17 +78,9 @@ const buildEventRecord = ({ const clientValue = isStatus ? convertServerStatusToClient(value, apiEvent.scheduledAt) : convertServerToClient(value, type); - - const urls = (type === dataElementTypes.IMAGE) ? - (() => (featureAvailable(FEATURES.trackerImageEndpoint) ? - { - imageUrl: `/tracker/events/${apiEvent.event}/dataValues/${id}/image`, - previewUrl: `/tracker/events/${apiEvent.event}/dataValues/${id}/image?dimension=small`, - } : { - imageUrl: `/events/files?dataElementUid=${id}&eventUid=${apiEvent.event}`, - previewUrl: `/events/files?dataElementUid=${id}&eventUid=${apiEvent.event}&dimension=SMALL`, - } - ))() : {}; + const urls = buildUrlByElementType[RECORD_TYPE.event][type] + ? buildUrlByElementType[RECORD_TYPE.event][type]({ event: apiEvent.event, id }) + : {}; return { id: getFilterClientName(id), @@ -133,9 +117,10 @@ export const convertToClientEvents = ( ...TEIRecord, ] .filter(({ value }) => value != null) - .reduce((acc, { id, value, imageUrl, previewUrl }: any) => { + .reduce((acc, { id, value, imageUrl, previewUrl, fileUrl }: any) => { acc[id] = { convertedValue: value, + fileUrl, ...(imageUrl ? { imageUrl, previewUrl } : {}), }; return acc; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js new file mode 100644 index 0000000000..696f12c20b --- /dev/null +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js @@ -0,0 +1,57 @@ +// @flow +import { featureAvailable, FEATURES } from 'capture-core-utils'; +import { dataElementTypes } from '../../../../../../../metaData'; + +const buildTEAUrlByElementType: {| + [string]: Function, +|} = { + [dataElementTypes.FILE_RESOURCE]: ({ trackedEntity, id }: { trackedEntity: string, id: string }) => ({ + fileUrl: `/trackedEntityInstances/${trackedEntity}/${id}/file`, + }), + [dataElementTypes.IMAGE]: ({ + trackedEntity, + id, + programId, + }: { + trackedEntity: string, + id: string, + programId: string, + }) => + (featureAvailable(FEATURES.trackerImageEndpoint) + ? { + imageUrl: `/tracker/trackedEntities/${trackedEntity}/attributes/${id}/image?program=${programId}`, + previewUrl: `/tracker/trackedEntities/${trackedEntity}/attributes/${id}/image?program=${programId}&dimension=small`, + } + : { + imageUrl: `/trackedEntityInstances/${trackedEntity}/${id}/image?program=${programId}`, + previewUrl: `/trackedEntityInstances/${trackedEntity}/${id}/image?program=${programId}&dimension=SMALL`, + }), +}; + +const buildDataElementUrlByElementType: {| + [string]: Function, +|} = { + [dataElementTypes.FILE_RESOURCE]: ({ event, id }: { event: string, id: string }) => ({ + fileUrl: `/events/files?dataElementUid=${id}&eventUid=${event}`, + }), + [dataElementTypes.IMAGE]: ({ event, id }: { event: string, id: string }) => + (featureAvailable(FEATURES.trackerImageEndpoint) + ? { + imageUrl: `/tracker/events/${event}/dataValues/${id}/image`, + previewUrl: `/tracker/events/${event}/dataValues/${id}/image?dimension=small`, + } + : { + imageUrl: `/events/files?dataElementUid=${id}&eventUid=${event}`, + previewUrl: `/events/files?dataElementUid=${id}&eventUid=${event}&dimension=SMALL`, + }), +}; + +export const RECORD_TYPE = Object.freeze({ + event: 'event', + trackedEntity: 'trackedEntity', +}); + +export const buildUrlByElementType = Object.freeze({ + [RECORD_TYPE.trackedEntity]: buildTEAUrlByElementType, + [RECORD_TYPE.event]: buildDataElementUrlByElementType, +}); diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js index 06fee42794..318b0f50ae 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js @@ -63,9 +63,11 @@ const getSubvaluesPlain = (querySingleResource: QuerySingleResource, absoluteApi [dataElementTypes.FILE_RESOURCE]: ({ subvalueKey: value, subvalue: name, + fileUrl, }) => ({ name, value, + url: `${absoluteApiPath}${fileUrl}`, }), }; @@ -142,6 +144,7 @@ const getSubvaluesPlain = (querySingleResource: QuerySingleResource, absoluteApi id, imageUrl: record[columnId].imageUrl, previewUrl: record[columnId].previewUrl, + fileUrl: record[columnId].fileUrl, }) : subvalue; } diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/index.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/index.js index 39fc13e849..bb9a44dfd0 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/index.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/index.js @@ -2,3 +2,4 @@ export * from './getFilterQueryArgs'; export * from './getSubvalues'; export { getOrderQueryArgs, DEFAULT_SORT } from './getOrderQueryArgs'; +export { buildUrlByElementType, RECORD_TYPE } from './buildUrlByElementType'; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getTeiListData/convertToClientTeis.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getTeiListData/convertToClientTeis.js index f726604bba..bf0d393186 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getTeiListData/convertToClientTeis.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getTeiListData/convertToClientTeis.js @@ -1,8 +1,7 @@ // @flow -import { featureAvailable, FEATURES } from 'capture-core-utils'; import { convertServerToClient } from '../../../../../../../converters'; import type { ApiTeis, ApiTeiAttributes, TeiColumnsMetaForDataFetchingArray, ClientTeis } from './types'; -import { dataElementTypes } from '../../../../../../../metaData'; +import { RECORD_TYPE, buildUrlByElementType } from '../getListDataCommon'; const getValuesById = (attributeValues?: ApiTeiAttributes = []) => attributeValues @@ -27,17 +26,9 @@ export const convertToClientTeis = ( } else { value = attributeValuesById[id]; } - - const urls = (type === dataElementTypes.IMAGE) ? - (() => (featureAvailable(FEATURES.trackerImageEndpoint) ? - { - imageUrl: `/tracker/trackedEntities/${tei.trackedEntity}/attributes/${id}/image?program=${programId}`, - previewUrl: `/tracker/trackedEntities/${tei.trackedEntity}/attributes/${id}/image?program=${programId}&dimension=small`, - } : { - imageUrl: `/trackedEntityInstances/${tei.trackedEntity}/${id}/image?program=${programId}`, - previewUrl: `/trackedEntityInstances/${tei.trackedEntity}/${id}/image?program=${programId}&dimension=SMALL`, - } - ))() : {}; + const urls = buildUrlByElementType[RECORD_TYPE.trackedEntity][type] + ? buildUrlByElementType[RECORD_TYPE.trackedEntity][type]({ trackedEntity: tei.trackedEntity, id, programId }) + : {}; return { id, @@ -46,9 +37,10 @@ export const convertToClientTeis = ( }; }) .filter(({ value }) => value != null) - .reduce((acc, { id, value, imageUrl, previewUrl }: any) => { + .reduce((acc, { id, value, imageUrl, previewUrl, fileUrl }: any) => { acc[id] = { convertedValue: value, + fileUrl, ...(imageUrl ? { imageUrl, previewUrl } : {}), }; return acc; diff --git a/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js b/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js index abd6eda46a..53da2bfa6b 100644 --- a/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js +++ b/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js @@ -1,6 +1,7 @@ // @flow import isDefined from 'd2-utilizr/lib/isDefined'; -import { featureAvailable, FEATURES } from 'capture-core-utils'; +import log from 'loglevel'; +import { featureAvailable, FEATURES, errorCreator } from 'capture-core-utils'; import { type DataElement, dataElementTypes } from '../metaData'; import type { QuerySingleResource } from '../utils/api/api.types'; @@ -26,6 +27,28 @@ const subValueGetterByElementType = { url: previewUrl, }; }, + [dataElementTypes.FILE_RESOURCE]: ({ + value, + teiId, + attributeId, + absoluteApiPath, + querySingleResource, + }: { + value: string, + teiId: string, + attributeId: string, + absoluteApiPath: string, + querySingleResource: QuerySingleResource, + }) => + querySingleResource({ resource: `fileResources/${value}` }) + .then(res => ({ + name: res.name, + url: `${absoluteApiPath}/trackedEntityInstances/${teiId}/${attributeId}/file`, + })) + .catch((error) => { + log.warn(errorCreator('Could not get subvalue')({ value, teiId, attributeId, error })); + return null; + }), }; export async function getSubValues({ From d687c282e5913e469f0f1ce2a704cfd3874c665c Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 7 Oct 2024 12:15:49 +0000 Subject: [PATCH 26/91] chore(release): cut 101.7.3 [skip release] ## [101.7.3](https://github.com/dhis2/capture-app/compare/v101.7.2...v101.7.3) (2024-10-07) ### Bug Fixes * [DHIS2-17530] show missing FILE url ([#3787](https://github.com/dhis2/capture-app/issues/3787)) ([205bb82](https://github.com/dhis2/capture-app/commit/205bb82bd2289313859c697aa6a6106b270dce0a)) --- 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 e42dae3432..effa3fe29c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.7.3](https://github.com/dhis2/capture-app/compare/v101.7.2...v101.7.3) (2024-10-07) + + +### Bug Fixes + +* [DHIS2-17530] show missing FILE url ([#3787](https://github.com/dhis2/capture-app/issues/3787)) ([205bb82](https://github.com/dhis2/capture-app/commit/205bb82bd2289313859c697aa6a6106b270dce0a)) + ## [101.7.2](https://github.com/dhis2/capture-app/compare/v101.7.1...v101.7.2) (2024-10-06) diff --git a/package.json b/package.json index fb7a31f23d..4563224912 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.7.2", + "version": "101.7.3", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.7.2", + "@dhis2/rules-engine-javascript": "101.7.3", "@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 f41e24519f..f7dbe02e86 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.7.2", + "version": "101.7.3", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 99066925df7011f64c5c2b290182df2b3e540ffe Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 7 Oct 2024 18:09:40 +0200 Subject: [PATCH 27/91] fix: [DHIS2-17537] use new endpoints for FILE (#3799) --- .../featuresSupport/support.js | 2 ++ .../WidgetProfile/hooks/getSubValueForTei.js | 17 +++++++++---- .../Stages/Stage/getEventDataWithSubValue.js | 4 +++- .../utils/getSubValueForDataValue.js | 4 +++- .../buildUrlByElementType.js | 24 ++++++++++++++----- .../helpers/getListDataCommon/getSubvalues.js | 24 +++++++++++++------ .../capture-core/events/getSubValues.js | 4 +++- .../trackedEntityInstances/getSubValues.js | 17 +++++++++---- 8 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/core_modules/capture-core-utils/featuresSupport/support.js b/src/core_modules/capture-core-utils/featuresSupport/support.js index 637439c74b..103df995a5 100644 --- a/src/core_modules/capture-core-utils/featuresSupport/support.js +++ b/src/core_modules/capture-core-utils/featuresSupport/support.js @@ -7,6 +7,7 @@ export const FEATURES = Object.freeze({ exportablePayload: 'exportablePayload', changelogs: 'changelogs', trackerImageEndpoint: 'trackerImageEndpoint', + trackerFileEndpoint: 'trackerFileEndpoint', trackedEntitiesCSV: 'trackedEntitiesCSV', newAocApiSeparator: 'newAocApiSeparator', }); @@ -18,6 +19,7 @@ const MINOR_VERSION_SUPPORT = Object.freeze({ [FEATURES.customIcons]: 41, [FEATURES.exportablePayload]: 41, [FEATURES.trackerImageEndpoint]: 41, + [FEATURES.trackerFileEndpoint]: 41, [FEATURES.newTransferQueryParam]: 41, [FEATURES.changelogs]: 41, [FEATURES.trackedEntitiesCSV]: 40, diff --git a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js index 7fb41b3a45..af3c5de5ec 100644 --- a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js +++ b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js @@ -17,12 +17,19 @@ type SubValueFunctionParams = { minorServerVersion: number, }; -const buildTEAFileUrl = (attribute) => { - const { absoluteApiPath, teiId, id } = attribute; - return `${absoluteApiPath}/trackedEntityInstances/${teiId}/${id}/file`; +const buildTEAFileUrl = (attribute, minorServerVersion) => { + const { absoluteApiPath, teiId, programId, id } = attribute; + + return hasAPISupportForFeature(minorServerVersion, FEATURES.trackerFileEndpoint) + ? `${absoluteApiPath}/tracker/trackedEntities/${teiId}/attributes/${id}/file?program=${programId}` + : `${absoluteApiPath}/trackedEntityInstances/${teiId}/${id}/file`; }; -const getFileResourceSubvalue = async ({ attribute, querySingleResource }: SubValueFunctionParams) => { +const getFileResourceSubvalue = async ({ + attribute, + querySingleResource, + minorServerVersion, +}: SubValueFunctionParams) => { if (!attribute.value) return null; const { id, displayName: name } = await querySingleResource({ resource: 'fileResources', id: attribute.value }); @@ -30,7 +37,7 @@ const getFileResourceSubvalue = async ({ attribute, querySingleResource }: SubVa id, name, value: id, - url: buildTEAFileUrl(attribute), + url: buildTEAFileUrl(attribute, minorServerVersion), }; }; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js index 29919f0fe8..a5493d19fd 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js @@ -12,7 +12,9 @@ const getFileResourceSubvalue = async (keys: Object, querySingleResource: QueryS return { id, name, - url: `${absoluteApiPath}/events/files?dataElementUid=${key}&eventUid=${eventId}`, + url: featureAvailable(FEATURES.trackerFileEndpoint) + ? `${absoluteApiPath}/tracker/events/${eventId}/dataValues/${key}/file` + : `${absoluteApiPath}/events/files?dataElementUid=${key}&eventUid=${eventId}`, }; } return {}; diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js index 8936d423b5..5de5037e21 100644 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js +++ b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js @@ -18,7 +18,9 @@ const getFileResourceSubvalue = async ({ dataElement, querySingleResource, event return { id, name, - url: `${absoluteApiPath}/events/files?dataElementUid=${dataElement.id}&eventUid=${eventId}`, + url: featureAvailable(FEATURES.trackerFileEndpoint) + ? `${absoluteApiPath}/tracker/events/${eventId}/dataValues/${dataElement.id}/file` + : `${absoluteApiPath}/events/files?dataElementUid=${dataElement.id}&eventUid=${eventId}`, }; }; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js index 696f12c20b..a901059530 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/buildUrlByElementType.js @@ -5,9 +5,19 @@ import { dataElementTypes } from '../../../../../../../metaData'; const buildTEAUrlByElementType: {| [string]: Function, |} = { - [dataElementTypes.FILE_RESOURCE]: ({ trackedEntity, id }: { trackedEntity: string, id: string }) => ({ - fileUrl: `/trackedEntityInstances/${trackedEntity}/${id}/file`, - }), + [dataElementTypes.FILE_RESOURCE]: ({ + trackedEntity, + id, + programId, + }: { + trackedEntity: string, + id: string, + programId: string, + }) => + (featureAvailable(FEATURES.trackerFileEndpoint) + ? { fileUrl: `/tracker/trackedEntities/${trackedEntity}/attributes/${id}/file?program=${programId}` } + : { fileUrl: `/trackedEntityInstances/${trackedEntity}/${id}/file` } + ), [dataElementTypes.IMAGE]: ({ trackedEntity, id, @@ -31,9 +41,11 @@ const buildTEAUrlByElementType: {| const buildDataElementUrlByElementType: {| [string]: Function, |} = { - [dataElementTypes.FILE_RESOURCE]: ({ event, id }: { event: string, id: string }) => ({ - fileUrl: `/events/files?dataElementUid=${id}&eventUid=${event}`, - }), + [dataElementTypes.FILE_RESOURCE]: ({ event, id }: { event: string, id: string }) => + (featureAvailable(FEATURES.trackerFileEndpoint) + ? { fileUrl: `/tracker/events/${event}/dataValues/${id}/file` } + : { fileUrl: `/events/files?dataElementUid=${id}&eventUid=${event}` } + ), [dataElementTypes.IMAGE]: ({ event, id }: { event: string, id: string }) => (featureAvailable(FEATURES.trackerImageEndpoint) ? { diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js index 318b0f50ae..0d0c3189a7 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/epics/teiViewEpics/helpers/getListDataCommon/getSubvalues.js @@ -17,16 +17,26 @@ const getSubvaluesPlain = (querySingleResource: QuerySingleResource, absoluteApi const getFileResourceSubvalue = async (keys: Array) => { const promises = keys .map(async (key) => { - const { id, displayName: name } = await querySingleResource({ resource: 'fileResources', id: key }); - return { - id, - name, - }; + try { + const { id, displayName: name } = await querySingleResource({ resource: 'fileResources', id: key }); + return { + id, + name, + }; + } catch (error) { + log.error( + errorCreator('subValue not found')({ key }), + ); + return null; + } }); return (await Promise.all(promises)) - .reduce((acc, { id, name }) => { - acc[id] = name; + .reduce((acc, file) => { + if (file) { + const { id, name } = file; + acc[id] = name; + } return acc; }, {}); }; diff --git a/src/core_modules/capture-core/events/getSubValues.js b/src/core_modules/capture-core/events/getSubValues.js index 005dbc4d9d..19b36daf2a 100644 --- a/src/core_modules/capture-core/events/getSubValues.js +++ b/src/core_modules/capture-core/events/getSubValues.js @@ -28,7 +28,9 @@ const subValueGetterByElementType = { ({ name: res.name, value: res.id, - url: `${absoluteApiPath}/events/files?dataElementUid=${metaElementId}&eventUid=${eventId}`, + url: featureAvailable(FEATURES.trackerFileEndpoint) + ? `${absoluteApiPath}/tracker/events/${eventId}/dataValues/${metaElementId}/file` + : `${absoluteApiPath}/events/files?dataElementUid=${metaElementId}&eventUid=${eventId}`, })) .catch((error) => { log.warn(errorCreator(GET_SUBVALUE_ERROR)({ value, eventId, metaElementId, error })); diff --git a/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js b/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js index 53da2bfa6b..5485e957e3 100644 --- a/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js +++ b/src/core_modules/capture-core/trackedEntityInstances/getSubValues.js @@ -33,18 +33,27 @@ const subValueGetterByElementType = { attributeId, absoluteApiPath, querySingleResource, + programId, }: { value: string, teiId: string, attributeId: string, absoluteApiPath: string, querySingleResource: QuerySingleResource, + programId: ?string, }) => querySingleResource({ resource: `fileResources/${value}` }) - .then(res => ({ - name: res.name, - url: `${absoluteApiPath}/trackedEntityInstances/${teiId}/${attributeId}/file`, - })) + .then((res) => { + const fileUrl = featureAvailable(FEATURES.trackerFileEndpoint) + ? `${absoluteApiPath}/tracker/trackedEntities/${teiId}/attributes/${attributeId}/file` + : `${absoluteApiPath}/trackedEntityInstances/${teiId}/${attributeId}/file`; + const url = programId ? `${fileUrl}?program=${programId}` : fileUrl; + + return { + name: res.name, + url, + }; + }) .catch((error) => { log.warn(errorCreator('Could not get subvalue')({ value, teiId, attributeId, error })); return null; From 39985b46e1fb18e7bab04e9b291c98d8d1a36134 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 7 Oct 2024 16:13:49 +0000 Subject: [PATCH 28/91] chore(release): cut 101.7.4 [skip release] ## [101.7.4](https://github.com/dhis2/capture-app/compare/v101.7.3...v101.7.4) (2024-10-07) ### Bug Fixes * [DHIS2-17537] use new endpoints for FILE ([#3799](https://github.com/dhis2/capture-app/issues/3799)) ([9906692](https://github.com/dhis2/capture-app/commit/99066925df7011f64c5c2b290182df2b3e540ffe)) --- 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 effa3fe29c..d2ae3db961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.7.4](https://github.com/dhis2/capture-app/compare/v101.7.3...v101.7.4) (2024-10-07) + + +### Bug Fixes + +* [DHIS2-17537] use new endpoints for FILE ([#3799](https://github.com/dhis2/capture-app/issues/3799)) ([9906692](https://github.com/dhis2/capture-app/commit/99066925df7011f64c5c2b290182df2b3e540ffe)) + ## [101.7.3](https://github.com/dhis2/capture-app/compare/v101.7.2...v101.7.3) (2024-10-07) diff --git a/package.json b/package.json index 4563224912..f5bdb7bebd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.7.3", + "version": "101.7.4", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.7.3", + "@dhis2/rules-engine-javascript": "101.7.4", "@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 f7dbe02e86..9bda957cff 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.7.3", + "version": "101.7.4", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From e12e561008ff181ad28b7d2fea215017467df22c Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:16:51 +0200 Subject: [PATCH 29/91] feat: [DHIS2-18081] Problem with date format when scheduling an event (#3816) --- .../ScheduleDate/ScheduleDate.component.js | 11 ++++++----- .../ScheduleDate/scheduleDate.types.js | 3 ++- .../WidgetEventSchedule.component.js | 3 ++- .../WidgetEventSchedule.container.js | 18 ++++++++++++------ .../widgetEventSchedule.types.js | 2 ++ 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/ScheduleDate/ScheduleDate.component.js b/src/core_modules/capture-core/components/WidgetEventSchedule/ScheduleDate/ScheduleDate.component.js index 63e00adb9f..8b62978b24 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/ScheduleDate/ScheduleDate.component.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/ScheduleDate/ScheduleDate.component.js @@ -5,7 +5,7 @@ import withStyles from '@material-ui/core/styles/withStyles'; import { DateField } from 'capture-core/components/FormFields/New'; import { InfoBox } from '../InfoBox'; import type { Props } from './scheduleDate.types'; -import { convertDateObjectToDateFormatString, convertStringToDateFormat } from '../../../utils/converters/date'; +import { convertStringToDateFormat } from '../../../utils/converters/date'; const styles = { @@ -20,16 +20,17 @@ const styles = { const ScheduleDatePlain = ({ scheduleDate, + serverScheduleDate, setScheduleDate, orgUnit, - suggestedScheduleDate, + serverSuggestedScheduleDate, eventCountInOrgUnit, classes, hideDueDate, }: Props) => (<> {!hideDueDate &&
{}} @@ -39,8 +40,8 @@ const ScheduleDatePlain = ({ />
} void, occurredAt: string, eventData: Array, eventCountInOrgUnit: number, - suggestedScheduleDate?: ?string, + serverSuggestedScheduleDate?: ?string, hideDueDate?: boolean, orgUnit: { id: string, name: string }, ...CssClasses, diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js index 5a9a05bf2e..d29cbd8a3a 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js @@ -64,6 +64,7 @@ const WidgetEventSchedulePlain = ({ classes, scheduleDate, suggestedScheduleDate, + serverSuggestedScheduleDate, notes, programCategory, enableUserAssignment, @@ -92,7 +93,7 @@ const WidgetEventSchedulePlain = ({ stageId={stageId} orgUnit={orgUnit} scheduleDate={scheduleDate} - suggestedScheduleDate={suggestedScheduleDate} + serverSuggestedScheduleDate={serverSuggestedScheduleDate} {...passOnProps} /> diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js index 843e40d96a..4132d024e9 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.container.js @@ -18,7 +18,9 @@ import { import { requestScheduleEvent } from './WidgetEventSchedule.actions'; import { NoAccess } from './AccessVerification'; import { useCategoryCombinations } from '../DataEntryDhis2Helpers/AOC/useCategoryCombinations'; -import { convertClientToServer } from '../../converters'; +import { convertFormToClient, convertClientToServer } from '../../converters'; +import { pipe } from '../../../capture-core-utils'; + export const WidgetEventSchedule = ({ enrollmentId, @@ -45,13 +47,15 @@ export const WidgetEventSchedule = ({ }); const { currentUser, noteId } = useNoteDetails(); const [scheduleDate, setScheduleDate] = useState(''); + const convertFn = pipe(convertFormToClient, convertClientToServer); + const serverScheduleDate = convertFn(scheduleDate, dataElementTypes.DATE); + const serverSuggestedScheduleDate = convertFn(suggestedScheduleDate, dataElementTypes.DATE); const [notes, setNotes] = useState([]); const [assignee, setAssignee] = useState(storedAssignee); - const { events } = useEventsInOrgUnit(orgUnitId, scheduleDate); + const { events } = useEventsInOrgUnit(orgUnitId, serverScheduleDate); const { eventId } = useLocationQuery(); const eventCountInOrgUnit = events - .filter(event => moment(event.scheduledAt).format('YYYY-MM-DD') === scheduleDate).length; - + .filter(event => moment(event.scheduledAt).format('YYYY-MM-DD') === serverScheduleDate).length; const [selectedCategories, setSelectedCategories] = useState({}); const [categoryOptionsError, setCategoryOptionsError] = useState(); const { programCategory } = useCategoryCombinations(programId); @@ -76,7 +80,7 @@ export const WidgetEventSchedule = ({ return; } dispatch(requestScheduleEvent({ - scheduleDate, + scheduleDate: serverScheduleDate, notes, programId, orgUnitId, @@ -93,7 +97,7 @@ export const WidgetEventSchedule = ({ })); }, [ dispatch, - scheduleDate, + serverScheduleDate, notes, programId, orgUnitId, @@ -179,8 +183,10 @@ export const WidgetEventSchedule = ({ programName={program.name} enableUserAssignment={enableUserAssignment && stage?.enableUserAssignment} scheduleDate={scheduleDate} + serverScheduleDate={serverScheduleDate} displayDueDateLabel={programStageScheduleConfig.displayDueDateLabel} suggestedScheduleDate={suggestedScheduleDate} + serverSuggestedScheduleDate={serverSuggestedScheduleDate} onCancel={onCancel} setScheduleDate={setScheduleDate} onSchedule={onHandleSchedule} diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js b/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js index b1fb963a88..7b89143d02 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js @@ -34,7 +34,9 @@ export type Props = {| stageName: string, programName: string, scheduleDate?: ?string, + serverScheduleDate?: ?string, suggestedScheduleDate?: ?string, + serverSuggestedScheduleDate?: ?string, eventCountInOrgUnit: number, notes: Array<{value: string}>, hideDueDate?: boolean, From 640067d3b550ba3cde6afe8321fa8605e74d7ed7 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 8 Oct 2024 15:21:11 +0000 Subject: [PATCH 30/91] chore(release): cut 101.8.0 [skip release] # [101.8.0](https://github.com/dhis2/capture-app/compare/v101.7.4...v101.8.0) (2024-10-08) ### Features * [DHIS2-18081] Problem with date format when scheduling an event ([#3816](https://github.com/dhis2/capture-app/issues/3816)) ([e12e561](https://github.com/dhis2/capture-app/commit/e12e561008ff181ad28b7d2fea215017467df22c)) --- 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 d2ae3db961..89d693d458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.8.0](https://github.com/dhis2/capture-app/compare/v101.7.4...v101.8.0) (2024-10-08) + + +### Features + +* [DHIS2-18081] Problem with date format when scheduling an event ([#3816](https://github.com/dhis2/capture-app/issues/3816)) ([e12e561](https://github.com/dhis2/capture-app/commit/e12e561008ff181ad28b7d2fea215017467df22c)) + ## [101.7.4](https://github.com/dhis2/capture-app/compare/v101.7.3...v101.7.4) (2024-10-07) diff --git a/package.json b/package.json index f5bdb7bebd..a96b8b1864 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.7.4", + "version": "101.8.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.7.4", + "@dhis2/rules-engine-javascript": "101.8.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 9bda957cff..a3ef56b41b 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.7.4", + "version": "101.8.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From e032d5004de91ee30fff89a53e273faf52bea234 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Wed, 9 Oct 2024 14:24:40 +0200 Subject: [PATCH 31/91] feat: [DHIS2-15238] show and filter on assigned user in program stage WL (#3821) --- .../EventWorkingListsDev.js | 2 +- .../EventWorkingListsUser.js | 2 +- .../EventWorkingLists/sharedSteps.js | 18 +++++ .../TeiWorkingListsDev.feature | 4 +- .../TeiWorkingListsDev/TeiWorkingListsDev.js | 2 +- .../TeiWorkingListsUser.feature | 38 +++++++++- .../TeiWorkingListsUser.js | 63 ++++++++++++----- .../TeiWorkingLists/sharedSteps.js | 18 +++++ cypress/e2e/WorkingLists/sharedSteps.js | 32 --------- docs/user/using-the-capture-app.md | 4 +- .../Setup/TeiWorkingListsSetup.component.js | 2 +- .../Setup/hooks/useDefaultColumnConfig.js | 16 ++++- .../Setup/hooks/useFiltersOnly.js | 21 ++++-- .../Setup/hooks/useProgramStageFilters.js | 27 ++++++- .../additionalFiltersConvertor.js | 3 + .../templates/buildArgumentsForTemplate.js | 70 +++++++++++++++---- 16 files changed, 234 insertions(+), 88 deletions(-) create mode 100644 cypress/e2e/WorkingLists/EventWorkingLists/sharedSteps.js create mode 100644 cypress/e2e/WorkingLists/TeiWorkingLists/sharedSteps.js diff --git a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsDev/EventWorkingListsDev.js b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsDev/EventWorkingListsDev.js index 0b507921ea..c633a34430 100644 --- a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsDev/EventWorkingListsDev.js +++ b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsDev/EventWorkingListsDev.js @@ -1,5 +1,5 @@ import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'; -import '../../sharedSteps'; +import '../sharedSteps'; beforeEach(() => { // Disable cache for chromium browsers to force the api to be called diff --git a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js index c5cb9fc63b..b1a6158642 100644 --- a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js +++ b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js @@ -1,6 +1,6 @@ import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'; import { v4 as uuid } from 'uuid'; -import '../../sharedSteps'; +import '../sharedSteps'; import { getCurrentYear, combineDataAndYear } from '../../../../support/date'; Given('you open the main page with Ngelehun and malaria case context', () => { diff --git a/cypress/e2e/WorkingLists/EventWorkingLists/sharedSteps.js b/cypress/e2e/WorkingLists/EventWorkingLists/sharedSteps.js new file mode 100644 index 0000000000..f2fdb84848 --- /dev/null +++ b/cypress/e2e/WorkingLists/EventWorkingLists/sharedSteps.js @@ -0,0 +1,18 @@ +import { When, Then } from '@badeball/cypress-cucumber-preprocessor'; +import '../sharedSteps'; + +When('you set the assignee filter to anyone', () => { + cy.get('[data-test="event-working-lists"]') + .contains('Assigned to') + .click(); + + cy.get('[data-test="list-view-filter-contents"]') + .contains('Anyone') + .click(); +}); + +Then('the assigned to filter button should show that the anyone filter is in effect', () => { + cy.get('[data-test="event-working-lists"]') + .contains('Assigned to: Anyone') + .should('exist'); +}); diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.feature b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.feature index 1e0857292e..981ef03ca1 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.feature +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.feature @@ -27,10 +27,10 @@ Scenario: Show only teis with active enrollments and unassinged events using the 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 enrollment status filter -And you set the assginee filter to none +And you set the assginee filter to None And you apply the assignee filter Then the enrollment status filter button should show that the active filter is in effect -And the assignee filter button should show that unassigned filter is in effect +And the assignee filter button should show that None filter is in effect And teis with active enrollments and unassigned events should be retrieved from the api And the list should display the teis retrieved from the api And for a tracker program the page navigation should show that you are on the first page diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.js b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.js index 5a0dd69651..050be8508b 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.js +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsDev/TeiWorkingListsDev.js @@ -1,5 +1,5 @@ import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'; -import '../../sharedSteps'; +import '../sharedSteps'; beforeEach(() => { // Disable cache for chromium browsers to force the api to be called diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature index a80e857fcd..3bf9fbfaf8 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.feature @@ -37,10 +37,10 @@ Scenario: Show only teis with active enrollments and unassinged events using the 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 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 unassigned 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 @@ -201,6 +201,40 @@ 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 diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js index 9026a15f3d..260e312422 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js @@ -1,6 +1,6 @@ import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor'; import { v4 as uuid } from 'uuid'; -import '../../sharedSteps'; +import '../sharedSteps'; const cleanUpIfApplicable = (programId) => { cy.buildApiUrl(`programStageWorkingLists?filter=program.id:eq:${programId}&fields=id,displayName`) @@ -198,22 +198,6 @@ When('you set the WHOMCH Smoking filter to No', () => { .click(); }); -When('you set the assginee filter to none', () => { - cy.get('[data-test="tei-working-lists"]') - .contains('Assigned to') - .click(); - - cy.get('[data-test="list-view-filter-contents"]') - .contains('None') - .click(); -}); - -Then('the assignee filter button should show that unassigned filter is in effect', () => { - cy.get('[data-test="tei-working-lists"]') - .contains('Assigned to: None') - .should('exist'); -}); - Then('the list should display teis with an active enrollment and unassinged events', () => { const ids = [ 'ZDA984904', @@ -627,7 +611,7 @@ When('you select a data element columns and save from the column selector', () = }); Then('you see data elements specific filters and columns', () => { - cy.get('[data-test="filter-button-container-DX4LVYeP7bw"]') + cy.get('[data-test="filter-button-container-assignee"]') .should('exist'); cy.get('[data-test="tei-working-lists"]') .should('exist'); @@ -866,3 +850,46 @@ Then('the working list is empty', () => { .contains('No items to display') .click(); }); + +Then('the assignee column is displayed', () => { + cy.get('[data-test="dhis2-uicore-tablehead"]') + .contains('Assigned to') + .should('exist'); + + cy.get('[data-test="dhis2-uicore-tablebody"]') + .contains('Tracker demo User (tracker)') + .should('exist'); + + cy.get('[data-test="tei-working-lists"]') + .find('tr') + .should('have.length', 2); +}); + +And('you filter by assigned Foci investigation & classification events', () => { + cy.get('[data-test="tei-working-lists"]') + .within(() => { + cy.contains('More filters') + .click(); + }); + + cy.get('[data-test="more-filters-menu"]') + .within(() => cy.contains('Program stage').click()); + + cy.get('[data-test="list-view-filter-contents"]') + .contains('Foci investigation & classification') + .click(); + + cy.get('[data-test="list-view-filter-apply-button"]') + .click(); + + cy.get('[data-test="tei-working-lists"]') + .contains('Assigned to') + .click(); + + cy.get('[data-test="list-view-filter-contents"]') + .contains('Anyone') + .click(); + + cy.get('[data-test="list-view-filter-apply-button"]') + .click(); +}); diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/sharedSteps.js b/cypress/e2e/WorkingLists/TeiWorkingLists/sharedSteps.js new file mode 100644 index 0000000000..190c14624b --- /dev/null +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/sharedSteps.js @@ -0,0 +1,18 @@ +import { When, Then } from '@badeball/cypress-cucumber-preprocessor'; +import '../sharedSteps'; + +When(/^you set the assginee filter to (.*)$/, (assignedUser) => { + cy.get('[data-test="tei-working-lists"]') + .contains('Assigned to') + .click(); + + cy.get('[data-test="list-view-filter-contents"]') + .contains(assignedUser) + .click(); +}); + +Then(/^the assignee filter button should show that (.*) filter is in effect/, (assignedUser) => { + cy.get('[data-test="tei-working-lists"]') + .contains(`Assigned to: ${assignedUser}`) + .should('exist'); +}); diff --git a/cypress/e2e/WorkingLists/sharedSteps.js b/cypress/e2e/WorkingLists/sharedSteps.js index c28bdb5ccb..dbe0bb9928 100644 --- a/cypress/e2e/WorkingLists/sharedSteps.js +++ b/cypress/e2e/WorkingLists/sharedSteps.js @@ -12,22 +12,6 @@ Then('for a tracker program the page navigation should show that you are on the .should('exist'); }); -Then('the assigned to filter button should show that the anyone filter is in effect', () => { - cy.get('[data-test="event-working-lists"]') - .contains('Assigned to: Anyone') - .should('exist'); -}); - -When('you set the assignee filter to anyone', () => { - cy.get('[data-test="event-working-lists"]') - .contains('Assigned to') - .click(); - - cy.get('[data-test="list-view-filter-contents"]') - .contains('Anyone') - .click(); -}); - When('you set the status filter to active', () => { cy.get('[data-test="event-working-lists"]') .contains('Status') @@ -98,16 +82,6 @@ When('you set the enrollment status filter to active', () => { .click(); }); -When('you set the assginee filter to none', () => { - cy.get('[data-test="tei-working-lists"]') - .contains('Assigned to') - .click(); - - cy.get('[data-test="list-view-filter-contents"]') - .contains('None') - .click(); -}); - When(/^you set the first name filter to (.*)$/, (name) => { cy.get('[data-test="tei-working-lists"]') .contains('First name') @@ -147,12 +121,6 @@ Then('rows per page should be set to 15', () => { .should('exist'); }); -Then('the assignee filter button should show that unassigned filter is in effect', () => { - cy.get('[data-test="tei-working-lists"]') - .contains('Assigned to: None') - .should('exist'); -}); - When('you change rows per page to 10', () => { cy.get('div[data-test="rows-per-page-selector"]') .click() diff --git a/docs/user/using-the-capture-app.md b/docs/user/using-the-capture-app.md index 1d64b1a4e2..651e9f7eb0 100644 --- a/docs/user/using-the-capture-app.md +++ b/docs/user/using-the-capture-app.md @@ -594,7 +594,7 @@ Events can be assigned to users. This feature must be enabled per program. 5. Search for and select the user you would like to reassign the event to. Click the **Save** button. -### Assignee in the event list { #capture_user_assignment_event_list } +### Assignee in the event list In the event list you will be able to view the assignee per event. Moreover, you can sort and filter the list by the assignee. @@ -804,7 +804,7 @@ You can show data elements from a single stage in a working list. Select the "Pr ![](resources/images/program_stage_working_list.png) -The tracker program stage list can be [filtered](#filter-the-list), [sorted](#sort-the-list), [modified](#modify-the-list-layout), [saved](#capture_view_save), [updated](#capture_view_update), [deleted](#capture_view_delete) and [shared](#capture_view_share) in the same way as other working lists. +The tracker program stage list can be [filtered](#filter-the-list), [sorted](#sort-the-list), [modified](#modify-the-list-layout), [saved](#capture_view_save), [updated](#capture_view_update), [deleted](#capture_view_delete) and [shared](#capture_view_share) in the same way as other working lists. Additionally, the program stage list can be [filtered by assignee](#assignee-in-the-event-list), just like an event program list. ## Implementer / administrator info { #implementer_info } diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/TeiWorkingListsSetup.component.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/TeiWorkingListsSetup.component.js index f2dfe2809b..b59d0233cd 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/TeiWorkingListsSetup.component.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/TeiWorkingListsSetup.component.js @@ -61,7 +61,7 @@ export const TeiWorkingListsSetup = ({ const prevTemplateId = useRef(currentTemplateId); const defaultColumns = useDefaultColumnConfig(program, orgUnitId, programStageId); const columns = useColumns(customColumnOrder, defaultColumns); - const filtersOnly = useFiltersOnly(program); + const filtersOnly = useFiltersOnly(program, programStageId); const programStageFiltersOnly = useProgramStageFilters(program, programStageId); const staticTemplates = useStaticTemplates( storedTemplates?.find(storedTemplate => storedTemplate.isDefault && storedTemplate.isAltered), diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useDefaultColumnConfig.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useDefaultColumnConfig.js index 3f6b926761..f15ade1d0e 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useDefaultColumnConfig.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useDefaultColumnConfig.js @@ -36,13 +36,13 @@ const getProgramStageMainConfig = (programStage): Array => [ { id: ADDITIONAL_FILTERS.status, - visible: false, + visible: true, type: dataElementTypes.TEXT, header: i18n.t(ADDITIONAL_FILTERS_LABELS.status), }, { id: ADDITIONAL_FILTERS.occurredAt, - visible: false, + visible: true, type: dataElementTypes.DATE, header: programStage.stageForm.getLabel('occurredAt') || i18n.t(ADDITIONAL_FILTERS_LABELS.occurredAt), }, @@ -50,7 +50,7 @@ const getProgramStageMainConfig = (programStage): Array => ? [ { id: ADDITIONAL_FILTERS.scheduledAt, - visible: false, + visible: true, type: dataElementTypes.DATE, header: programStage.stageForm.getLabel('scheduledAt') || @@ -58,6 +58,16 @@ const getProgramStageMainConfig = (programStage): Array => }, ] : []), + ...(programStage.enableUserAssignment + ? [ + { + id: ADDITIONAL_FILTERS.assignedUser, + visible: true, + type: dataElementTypes.ASSIGNEE, + header: i18n.t(ADDITIONAL_FILTERS_LABELS.assignee), + }, + ] + : []), ].map(field => ({ ...field, mainProperty: true, diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useFiltersOnly.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useFiltersOnly.js index 155d6b9775..76c4ef14db 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useFiltersOnly.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useFiltersOnly.js @@ -4,12 +4,13 @@ import i18n from '@dhis2/d2-i18n'; import { dataElementTypes, type TrackerProgram } from '../../../../../metaData'; import { MAIN_FILTERS } from '../../constants'; -export const useFiltersOnly = ({ - enrollment: { enrollmentDateLabel, incidentDateLabel, showIncidentDate }, - stages, -}: TrackerProgram) => +export const useFiltersOnly = ( + { enrollment: { enrollmentDateLabel, incidentDateLabel, showIncidentDate }, stages }: TrackerProgram, + programStageId?: string, +) => useMemo(() => { - const enableUserAssignment = Array.from(stages.values()).find(stage => stage.enableUserAssignment); + const enableUserAssignment = + !programStageId && Array.from(stages.values()).find(stage => stage.enableUserAssignment); return [ { id: MAIN_FILTERS.PROGRAM_STATUS, @@ -80,9 +81,15 @@ export const useFiltersOnly = ({ id: MAIN_FILTERS.ASSIGNEE, type: dataElementTypes.ASSIGNEE, header: i18n.t('Assigned to'), - transformRecordsFilter: (rawFilter: Object) => rawFilter, + transformRecordsFilter: (rawFilter: Object) => { + const { assignedUser, assignedUserMode } = rawFilter; + return { + assignedUserMode, + ...(assignedUser && { assignedUser }), + }; + }, }, ] : []), ]; - }, [enrollmentDateLabel, incidentDateLabel, showIncidentDate, stages]); + }, [enrollmentDateLabel, incidentDateLabel, showIncidentDate, stages, programStageId]); diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useProgramStageFilters.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useProgramStageFilters.js index d17f1be4b1..108f76bc0e 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useProgramStageFilters.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/Setup/hooks/useProgramStageFilters.js @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import i18n from '@dhis2/d2-i18n'; import { statusTypes, translatedStatusTypes } from 'capture-core/events/statusTypes'; -import { type TrackerProgram, type ProgramStage } from '../../../../../metaData'; +import { type TrackerProgram, type ProgramStage, dataElementTypes } from '../../../../../metaData'; import { ADDITIONAL_FILTERS, ADDITIONAL_FILTERS_LABELS } from '../../helpers'; const useProgramStageData = (programStageId, stages) => @@ -13,12 +13,14 @@ const useProgramStageData = (programStageId, stages) => hideDueDate: programStage.hideDueDate, occurredAtLabel: programStage.stageForm.getLabel('occurredAt'), scheduledAtLabel: programStage.stageForm.getLabel('scheduledAt'), + enableUserAssignment: programStage.enableUserAssignment, }; } return { occurredAtLabel: i18n.t(ADDITIONAL_FILTERS_LABELS.occurredAt), scheduledAtLabel: i18n.t(ADDITIONAL_FILTERS_LABELS.scheduledAt), hideDueDate: undefined, + enableUserAssignment: false, }; }, [programStageId, stages]); @@ -33,7 +35,10 @@ const useProgramStageDropdowOptions = stages => ); export const useProgramStageFilters = ({ stages }: TrackerProgram, programStageId?: string) => { - const { hideDueDate, occurredAtLabel, scheduledAtLabel } = useProgramStageData(programStageId, stages); + const { hideDueDate, occurredAtLabel, scheduledAtLabel, enableUserAssignment } = useProgramStageData( + programStageId, + stages, + ); const options: Array<{ text: string, value: string }> = useProgramStageDropdowOptions(stages); return useMemo(() => { @@ -117,6 +122,22 @@ export const useProgramStageFilters = ({ stages }: TrackerProgram, programStageI }, ] : []), + ...(enableUserAssignment + ? [ + { + id: ADDITIONAL_FILTERS.assignedUser, + type: dataElementTypes.ASSIGNEE, + header: ADDITIONAL_FILTERS_LABELS.assignee, + transformRecordsFilter: (rawFilter: Object) => { + const { assignedUser, assignedUserMode } = rawFilter; + return { + assignedUserMode, + ...(assignedUser && { assignedUser }), + }; + }, + }, + ] + : []), ]; - }, [programStageId, occurredAtLabel, scheduledAtLabel, hideDueDate, options]); + }, [programStageId, occurredAtLabel, scheduledAtLabel, hideDueDate, options, enableUserAssignment]); }; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/eventFilters/additionalFiltersConvertor.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/eventFilters/additionalFiltersConvertor.js index 72350fbdf3..ac209da460 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/eventFilters/additionalFiltersConvertor.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/eventFilters/additionalFiltersConvertor.js @@ -4,6 +4,7 @@ export const ADDITIONAL_FILTERS = { occurredAt: 'eventOccurredAt', scheduledAt: 'scheduledAt', status: 'status', + assignedUser: 'assignee', }; export const ADDITIONAL_FILTERS_LABELS = { @@ -11,10 +12,12 @@ export const ADDITIONAL_FILTERS_LABELS = { occurredAt: 'Report date', scheduledAt: 'Scheduled date', status: 'Event status', + assignee: 'Assigned to', }; export const ADDITIONAL_FILTERS_API_NAME = { [ADDITIONAL_FILTERS.occurredAt]: 'occurredAt', + [ADDITIONAL_FILTERS.assignedUser]: 'assignedUser', }; export const getFilterApiName = (clientFilter: string) => ADDITIONAL_FILTERS_API_NAME[clientFilter] || clientFilter; diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/templates/buildArgumentsForTemplate.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/templates/buildArgumentsForTemplate.js index 9d16721c2e..8f8014a1a1 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/templates/buildArgumentsForTemplate.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/helpers/templates/buildArgumentsForTemplate.js @@ -9,6 +9,51 @@ import type { TeiWorkingListsColumnConfigs, ApiTrackerQueryCriteria } from '../. import type { FiltersData } from '../../../WorkingListsBase'; import { getOrderQueryArgs } from '../../epics'; +const buildArguments = ({ + filters, + programStageFiltersOnly, + columns, + programStageId, + mainFiltersConverted, +}: { + filters?: FiltersData, + programStageFiltersOnly: Array<{ id: string, type: string }>, + columns: TeiWorkingListsColumnConfigs, + programStageId?: string, + mainFiltersConverted: Object, +}) => { + if (!programStageId) { + return { + assignedUserMode: mainFiltersConverted.assignedUserMode, + assignedUsers: mainFiltersConverted.assignedUsers, + attributesColumns: columns, + dataFilters: [], + status: undefined, + eventOccurredAt: undefined, + scheduledAt: undefined, + }; + } + + const additionalFiltersConverted = convertMainFilters({ + filters, + mainFilters: programStageFiltersOnly, + }); + const { status, eventOccurredAt, scheduledAt } = additionalFiltersConverted; + return { + status, + eventOccurredAt, + scheduledAt, + assignedUserMode: additionalFiltersConverted.assignedUserMode, + assignedUsers: additionalFiltersConverted.assignedUsers, + attributesColumns: columns.filter(column => !column.additionalColumn), + dataFilters: convertToEventFilterQuery({ + filters, + mainFilters: programStageFiltersOnly, + dataElementsValueFilters: columns.filter(column => column.additionalColumn), + }), + }; +}; + export const buildArgumentsForTemplate = ({ filters, filtersOnly, @@ -28,25 +73,20 @@ export const buildArgumentsForTemplate = ({ programId: string, programStageId?: string, }) => { - const { programStatus, occurredAt, enrolledAt, assignedUserMode, assignedUsers, followUp } = convertMainFilters({ + const mainFiltersConverted = convertMainFilters({ filters, mainFilters: filtersOnly, }); - const { status, eventOccurredAt, scheduledAt } = convertMainFilters({ - filters, - mainFilters: programStageFiltersOnly, - }); - const attributeValueFilters = convertToTEIFilterAttributes({ - filters, - attributeValueFilters: programStageId ? columns.filter(column => !column.additionalColumn) : columns, - }); - const dataFilters = programStageId - ? convertToEventFilterQuery({ + const { programStatus, occurredAt, enrolledAt, followUp } = mainFiltersConverted; + const { assignedUserMode, assignedUsers, attributesColumns, dataFilters, status, eventOccurredAt, scheduledAt } = + buildArguments({ filters, - mainFilters: programStageFiltersOnly, - dataElementsValueFilters: columns.filter(column => column.additionalColumn), - }) - : []; + programStageFiltersOnly, + columns, + programStageId, + mainFiltersConverted, + }); + const attributeValueFilters = convertToTEIFilterAttributes({ filters, attributeValueFilters: attributesColumns }); const visibleColumnIds: Array = columns.filter(({ visible }) => visible).map(({ id }) => id); const criteria: ApiTrackerQueryCriteria = { programStatus, From 06d5603dcb621521d7e70eb02dea92fea1eec2da Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Wed, 9 Oct 2024 12:29:05 +0000 Subject: [PATCH 32/91] chore(release): cut 101.9.0 [skip release] # [101.9.0](https://github.com/dhis2/capture-app/compare/v101.8.0...v101.9.0) (2024-10-09) ### Features * [DHIS2-15238] show and filter on assigned user in program stage WL ([#3821](https://github.com/dhis2/capture-app/issues/3821)) ([e032d50](https://github.com/dhis2/capture-app/commit/e032d5004de91ee30fff89a53e273faf52bea234)) --- 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 89d693d458..07ffe6de6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.9.0](https://github.com/dhis2/capture-app/compare/v101.8.0...v101.9.0) (2024-10-09) + + +### Features + +* [DHIS2-15238] show and filter on assigned user in program stage WL ([#3821](https://github.com/dhis2/capture-app/issues/3821)) ([e032d50](https://github.com/dhis2/capture-app/commit/e032d5004de91ee30fff89a53e273faf52bea234)) + # [101.8.0](https://github.com/dhis2/capture-app/compare/v101.7.4...v101.8.0) (2024-10-08) diff --git a/package.json b/package.json index a96b8b1864..adcf77dda8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.8.0", + "version": "101.9.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.8.0", + "@dhis2/rules-engine-javascript": "101.9.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 a3ef56b41b..736c8ceabc 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.8.0", + "version": "101.9.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 2603f342d3e34e1f4ac631797c60b93e2aa3606a Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 13 Oct 2024 03:44:44 +0200 Subject: [PATCH 33/91] fix(translations): sync translations from transifex (master) Automatically merged. --- i18n/ar_IQ.po | 34 ++++++++++++++++++---------------- i18n/ckb.po | 34 ++++++++++++++++++---------------- i18n/es_419.po | 17 +---------------- i18n/km.po | 34 ++++++++++++++++++---------------- i18n/prs.po | 17 +---------------- i18n/ps.po | 17 +---------------- i18n/pt.po | 14 +++----------- i18n/pt_BR.po | 17 +---------------- i18n/ro.po | 9 --------- i18n/ru.po | 9 --------- i18n/sv.po | 34 ++++++++++++++++++---------------- i18n/tet.po | 34 ++++++++++++++++++---------------- i18n/tg.po | 34 ++++++++++++++++++---------------- i18n/uk.po | 17 +---------------- i18n/ur.po | 17 +---------------- i18n/uz_UZ_Cyrl.po | 9 --------- i18n/uz_UZ_Latn.po | 17 +---------------- i18n/zh_CN.po | 9 --------- 18 files changed, 118 insertions(+), 255 deletions(-) diff --git a/i18n/ar_IQ.po b/i18n/ar_IQ.po index cbeeaaf0e3..13422d6d58 100644 --- a/i18n/ar_IQ.po +++ b/i18n/ar_IQ.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: KRG HIS , 2024\n" "Language-Team: Arabic (Iraq) (https://app.transifex.com/hisp-uio/teams/100509/ar_IQ/)\n" @@ -602,15 +602,6 @@ msgstr "البرنامج غير موجود" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "متصل" - -msgid "Offline" -msgstr "غير متصل" - -msgid "Syncing" -msgstr "تزامن" - msgid "Add note" msgstr "" @@ -1251,12 +1242,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "تم الإلغاء" @@ -1482,6 +1467,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/ckb.po b/i18n/ckb.po index 1a33d92772..851ae43bd0 100644 --- a/i18n/ckb.po +++ b/i18n/ckb.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Central Kurdish (https://app.transifex.com/hisp-uio/teams/100509/ckb/)\n" @@ -607,15 +607,6 @@ msgstr "پرۆگرامەکە بوونی نیە" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "ئۆنڵاین" - -msgid "Offline" -msgstr "ئۆفڵاین" - -msgid "Syncing" -msgstr "هاوتاکردن" - msgid "Add note" msgstr "" @@ -1254,12 +1245,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "" @@ -1477,6 +1462,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/es_419.po b/i18n/es_419.po index 1007032b9c..f5afa49b7d 100644 --- a/i18n/es_419.po +++ b/i18n/es_419.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Jaime Bosque , 2024\n" "Language-Team: Spanish (Latin America) (https://app.transifex.com/hisp-uio/teams/100509/es_419/)\n" @@ -617,15 +617,6 @@ msgstr "El programa no existe" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "En línea" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "Sincronizando" - msgid "Add note" msgstr "Añadir nota" @@ -1293,12 +1284,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Cancelar" diff --git a/i18n/km.po b/i18n/km.po index 04fa91cdc5..ec9c3dac3e 100644 --- a/i18n/km.po +++ b/i18n/km.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Khmer (https://app.transifex.com/hisp-uio/teams/100509/km/)\n" @@ -589,15 +589,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "លើបណ្ដាញអិនធឺរណែត" - -msgid "Offline" -msgstr "ក្រៅ​បណ្ដាញអិនធឺរណែត" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "បន្ថែមការកត់ចំណាំ" @@ -1233,12 +1224,6 @@ msgstr "" msgid "Follow-up" msgstr "តាមដាន" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "បានលុបចោល" @@ -1454,6 +1439,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/prs.po b/i18n/prs.po index 89f3234f12..9b6cbf8306 100644 --- a/i18n/prs.po +++ b/i18n/prs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Persian (Afghanistan) (https://app.transifex.com/hisp-uio/teams/100509/fa_AF/)\n" @@ -588,15 +588,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "آنلاین" - -msgid "Offline" -msgstr "آفلاین" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "افزودن یاداشت" @@ -1233,12 +1224,6 @@ msgstr "" msgid "Follow-up" msgstr "تعقیب کردن" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "" diff --git a/i18n/ps.po b/i18n/ps.po index 31f1707af2..38518df9a7 100644 --- a/i18n/ps.po +++ b/i18n/ps.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Pashto (https://app.transifex.com/hisp-uio/teams/100509/ps/)\n" @@ -589,15 +589,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "په لیکه کې دی" - -msgid "Offline" -msgstr "په لیکه کې نشته" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "نوټ ور اضافه کړئ" @@ -1234,12 +1225,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "لغوه شوی" diff --git a/i18n/pt.po b/i18n/pt.po index 7531dccfa4..45ada7e10f 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -7,13 +7,14 @@ # Sheila André , 2024 # Ge Joao , 2024 # Viktor Varland , 2024 +# Juan M Alcantara Acosta , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Juan M Alcantara Acosta , 2024\n" "Language-Team: Portuguese (https://app.transifex.com/hisp-uio/teams/100509/pt/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -616,15 +617,6 @@ msgstr "Programa não existe" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Ligado" - -msgid "Offline" -msgstr "Desligado" - -msgid "Syncing" -msgstr "Sincronizando" - msgid "Add note" msgstr "Adicionar uma nota" @@ -1594,7 +1586,7 @@ msgid "Scheduled" msgstr "Agendado" msgid "Changelog" -msgstr "" +msgstr "Registo de mudanças" msgid "No changes to display" msgstr "" diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po index 00cd51c882..f33904fb18 100644 --- a/i18n/pt_BR.po +++ b/i18n/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Thiago Rocha, 2024\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/hisp-uio/teams/100509/pt_BR/)\n" @@ -592,15 +592,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Ligado" - -msgid "Offline" -msgstr "Desligado" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "Adicionar uma nota" @@ -1238,12 +1229,6 @@ msgstr "" msgid "Follow-up" msgstr "Seguimento" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Cancelado" diff --git a/i18n/ro.po b/i18n/ro.po index 5c64022113..1308197957 100644 --- a/i18n/ro.po +++ b/i18n/ro.po @@ -603,15 +603,6 @@ msgstr "Programul nu există" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "Sincronizare" - msgid "Add note" msgstr "" diff --git a/i18n/ru.po b/i18n/ru.po index 01896cce66..3182a61401 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -615,15 +615,6 @@ msgid "Selected program is invalid for selected organisation unit" msgstr "" "Выбранная программа недействительна для выбранной организационной единицы" -msgid "Online" -msgstr "Онлайн" - -msgid "Offline" -msgstr "Оффлайн" - -msgid "Syncing" -msgstr "Синхронизация" - msgid "Add note" msgstr "Добавить заметку" diff --git a/i18n/sv.po b/i18n/sv.po index 62edd96eb5..e771dc9cec 100644 --- a/i18n/sv.po +++ b/i18n/sv.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Swedish (https://app.transifex.com/hisp-uio/teams/100509/sv/)\n" @@ -591,15 +591,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Uppkopplad" - -msgid "Offline" -msgstr "Off-line" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "Lägg till anteckning" @@ -1236,12 +1227,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Avbruten" @@ -1459,6 +1444,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/tet.po b/i18n/tet.po index 719938fd39..d268e14ea8 100644 --- a/i18n/tet.po +++ b/i18n/tet.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Tetum (Tetun) (https://app.transifex.com/hisp-uio/teams/100509/tet/)\n" @@ -588,15 +588,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "" @@ -1232,12 +1223,6 @@ msgstr "" msgid "Follow-up" msgstr "Segimentu" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "" @@ -1453,6 +1438,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/tg.po b/i18n/tg.po index 1346766a62..02c2ea6da5 100644 --- a/i18n/tg.po +++ b/i18n/tg.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Tajik (https://app.transifex.com/hisp-uio/teams/100509/tg/)\n" @@ -589,15 +589,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Онлайн" - -msgid "Offline" -msgstr "Офлайн" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "" @@ -1234,12 +1225,6 @@ msgstr "" msgid "Follow-up" msgstr "Пайгирӣ кардан" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "" @@ -1457,6 +1442,23 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" +msgid "An error occurred while deleting the event" +msgstr "" + +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" +msgstr "" + +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + msgid "To open this event, please wait until saving is complete" msgstr "" diff --git a/i18n/uk.po b/i18n/uk.po index c51bff2210..b294680692 100644 --- a/i18n/uk.po +++ b/i18n/uk.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Ukrainian (https://app.transifex.com/hisp-uio/teams/100509/uk/)\n" @@ -594,15 +594,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Онлайн" - -msgid "Offline" -msgstr "Офлайн" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "Додати нотатку" @@ -1241,12 +1232,6 @@ msgstr "" msgid "Follow-up" msgstr "Подальші дії" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Скасовано" diff --git a/i18n/ur.po b/i18n/ur.po index ce4b3021c3..9a1900631a 100644 --- a/i18n/ur.po +++ b/i18n/ur.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Urdu (https://app.transifex.com/hisp-uio/teams/100509/ur/)\n" @@ -589,15 +589,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "آن لائن" - -msgid "Offline" -msgstr "آف لائن" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "نوٹ شامل" @@ -1234,12 +1225,6 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "منسوخ" diff --git a/i18n/uz_UZ_Cyrl.po b/i18n/uz_UZ_Cyrl.po index 32a8d2e932..6ad437c602 100644 --- a/i18n/uz_UZ_Cyrl.po +++ b/i18n/uz_UZ_Cyrl.po @@ -606,15 +606,6 @@ msgstr "Дастур мавжуд эмас" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Онлайн" - -msgid "Offline" -msgstr "Оффлайн" - -msgid "Syncing" -msgstr "Синхронлашмоқда" - msgid "Add note" msgstr "Изоҳ қолдириш" diff --git a/i18n/uz_UZ_Latn.po b/i18n/uz_UZ_Latn.po index 0379eb17c6..720b8be8e6 100644 --- a/i18n/uz_UZ_Latn.po +++ b/i18n/uz_UZ_Latn.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Yury Rogachev , 2024\n" "Language-Team: Uzbek (Latin) (https://app.transifex.com/hisp-uio/teams/100509/uz@Latn/)\n" @@ -607,15 +607,6 @@ msgstr "Dastur mavjud emas" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "Onlayn" - -msgid "Offline" -msgstr "Offlayn" - -msgid "Syncing" -msgstr "Sinxronlashmoqda" - msgid "Add note" msgstr "Izoh qoldirish" @@ -1258,12 +1249,6 @@ msgstr "" msgid "Follow-up" msgstr "Kuzatish" -msgid "Started at {{orgUnitName}}" -msgstr "" - -msgid "Owned by {{ownerOrgUnit}}" -msgstr "" - msgid "Cancelled" msgstr "Bekor qilindi" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po index d370cc02a6..68ce40fc28 100644 --- a/i18n/zh_CN.po +++ b/i18n/zh_CN.po @@ -591,15 +591,6 @@ msgstr "项目不存在" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "在线" - -msgid "Offline" -msgstr "离线" - -msgid "Syncing" -msgstr "同步" - msgid "Add note" msgstr "添加笔记" From 5e377e6b910d729e4d6296c0259f78ff13134773 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 13 Oct 2024 01:48:51 +0000 Subject: [PATCH 34/91] chore(release): cut 101.9.1 [skip release] ## [101.9.1](https://github.com/dhis2/capture-app/compare/v101.9.0...v101.9.1) (2024-10-13) ### Bug Fixes * **translations:** sync translations from transifex (master) ([2603f34](https://github.com/dhis2/capture-app/commit/2603f342d3e34e1f4ac631797c60b93e2aa3606a)) --- 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 07ffe6de6b..be5bbe281c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.9.1](https://github.com/dhis2/capture-app/compare/v101.9.0...v101.9.1) (2024-10-13) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([2603f34](https://github.com/dhis2/capture-app/commit/2603f342d3e34e1f4ac631797c60b93e2aa3606a)) + # [101.9.0](https://github.com/dhis2/capture-app/compare/v101.8.0...v101.9.0) (2024-10-09) diff --git a/package.json b/package.json index adcf77dda8..22ae5cce65 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.9.0", + "version": "101.9.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.9.0", + "@dhis2/rules-engine-javascript": "101.9.1", "@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 736c8ceabc..968878a1d4 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.9.0", + "version": "101.9.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From b1a720afc58b281ec7fc50e5af39ac19f4ec0cf4 Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:55:13 +0200 Subject: [PATCH 35/91] feat: [DHIS2-17771] Org unit context in tables and lists (#3813) * feat: update client to list converter * feat: changes in tooltip component * feat: add orgunit context stages and events widget * feat: use cache for subvalues * feat: orgunit context event workspace * fix: renaming of return statement --- .../hooks/getSubValueForTei.js | 12 ++++------- .../TooltipOrgUnit.component.js | 13 ++++++------ .../WidgetEnrollment.component.js | 4 ++-- .../WidgetProfile/hooks/getSubValueForTei.js | 20 ++++--------------- .../Stages/Stage/StageDetail/hooks/helpers.js | 4 ++-- .../Stage/StageDetail/hooks/useEventList.js | 2 +- .../Stages/Stage/getEventDataWithSubValue.js | 17 ++++------------ .../FlatListOrgUnitField.js | 19 ------------------ .../FlatListOrgUnitField/index.js | 3 --- .../utils/getDataEntryDetails.js | 4 ++-- .../utils/getSubValueForDataValue.js | 13 ++++-------- .../capture-core/converters/clientToList.js | 9 +++++++-- .../capture-core/converters/clientToView.js | 14 +++---------- .../metadataRetrieval/orgUnitName/index.js | 1 - .../orgUnitName/orgUnitName.js | 2 -- 15 files changed, 40 insertions(+), 97 deletions(-) delete mode 100644 src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js delete mode 100644 src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/index.js diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/getSubValueForTei.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/getSubValueForTei.js index b8df8130ed..eab8d88a89 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/getSubValueForTei.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/getSubValueForTei.js @@ -1,6 +1,8 @@ // @flow import type { QuerySingleResource } from 'capture-core/utils/api'; import { dataElementTypes } from '../../../../metaData'; +import { getOrgUnitNames } from '../../../../metadataRetrieval/orgUnitName'; + const getImageOrFileResourceSubvalue = async (key: string, querySingleResource: QuerySingleResource) => { const { id, displayName: name } = await querySingleResource({ resource: 'fileResources', id: key }); @@ -11,14 +13,8 @@ const getImageOrFileResourceSubvalue = async (key: string, querySingleResource: }; const getOrganisationUnitSubvalue = async (key: string, querySingleResource: QuerySingleResource) => { - const organisationUnit = await querySingleResource({ - resource: 'organisationUnits', - id: key, - params: { - fields: 'id,name', - }, - }); - return { ...organisationUnit }; + const organisationUnit = await getOrgUnitNames([key], querySingleResource); + return organisationUnit[key]; }; export const subValueGetterByElementType = { diff --git a/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js index 8b756f7e9c..7173df8144 100644 --- a/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js +++ b/src/core_modules/capture-core/components/Tooltips/TooltipOrgUnit/TooltipOrgUnit.component.js @@ -1,18 +1,19 @@ // @flow import React from 'react'; import { Tooltip } from '@dhis2/ui'; +import { useOrgUnitNameWithAncestors } from '../../../metadataRetrieval/orgUnitName'; type Props = { - orgUnitName: string, - ancestors?: Array, + orgUnitId: string, }; -export const TooltipOrgUnit = ({ orgUnitName, ancestors = [] }: Props) => { - const fullPath = [...ancestors, orgUnitName].join(' / '); +export const TooltipOrgUnit = ({ orgUnitId }: Props) => { + const { displayName, ancestors = [] } = useOrgUnitNameWithAncestors(orgUnitId); + const fullPath = [...ancestors, displayName].join(' / '); return ( - - {orgUnitName} + + {displayName} ); }; diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js index 3bec583e85..00c44c0a6e 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js +++ b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js @@ -78,8 +78,8 @@ export const WidgetEnrollmentPlain = ({ const { displayName: orgUnitName, ancestors } = useOrgUnitNameWithAncestors(enrollment?.orgUnit); const { displayName: ownerOrgUnitName, ancestors: ownerAncestors } = useOrgUnitNameWithAncestors(ownerOrgUnit?.id); - const orgUnitClientValue = { name: orgUnitName, ancestors }; - const ownerOrgUnitClientValue = { name: ownerOrgUnitName, ancestors: ownerAncestors }; + const orgUnitClientValue = { id: enrollment?.orgUnit, name: orgUnitName, ancestors }; + const ownerOrgUnitClientValue = { id: ownerOrgUnit?.id, name: ownerOrgUnitName, ancestors: ownerAncestors }; return (
diff --git a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js index af3c5de5ec..18891f0578 100644 --- a/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js +++ b/src/core_modules/capture-core/components/WidgetProfile/hooks/getSubValueForTei.js @@ -2,6 +2,7 @@ import type { QuerySingleResource } from 'capture-core/utils/api'; import { dataElementTypes } from '../../../metaData'; import { FEATURES, hasAPISupportForFeature } from '../../../../capture-core-utils'; +import { getOrgUnitNames } from '../../../metadataRetrieval/orgUnitName'; type Attribute = { id: string, @@ -59,22 +60,9 @@ const getImageResourceSubvalue = async ({ attribute, minorServerVersion }: SubVa }; }; -const getOrganisationUnitSubvalue = async ({ attribute, querySingleResource }: SubValueFunctionParams) => { - const organisationUnit = await querySingleResource({ - resource: 'organisationUnits', - id: attribute.value, - params: { - fields: 'id,name,ancestors[displayName]', - }, - }); - - const orgUnitClientValue = { - id: organisationUnit.id, - name: organisationUnit.name, - ancestors: organisationUnit.ancestors.map(ancestor => ancestor.displayName), - }; - - return orgUnitClientValue; +const getOrganisationUnitSubvalue = async ({ attribute: { value }, querySingleResource }: SubValueFunctionParams) => { + const organisationUnits = await getOrgUnitNames([value], querySingleResource); + return organisationUnits[value]; }; export const subValueGetterByElementType = { diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js index d4f2d6b2a6..74ae039f19 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js @@ -8,7 +8,7 @@ import type { StageDataElement } from '../../../../types/common.types'; import { Notes } from '../Notes.component'; import type { QuerySingleResource } from '../../../../../../utils/api/api.types'; import { isEventOverdue } from '../../../../../../utils/isEventOverdue'; -import { getCachedOrgUnitName } from '../../../../../../metadataRetrieval/orgUnitName'; +import { TooltipOrgUnit } from '../../../../../Tooltips/TooltipOrgUnit/TooltipOrgUnit.component'; const getEventStatus = (event: ApiEnrollmentEvent) => { const today = moment().startOf('day'); @@ -58,7 +58,7 @@ const convertStatusForView = (event: ApiEnrollmentEvent) => { }; }; -const convertOrgUnitForView = (event: ApiEnrollmentEvent) => getCachedOrgUnitName(event.orgUnit); +const convertOrgUnitForView = (event: ApiEnrollmentEvent) => ; const convertNoteForView = (event: ApiEnrollmentEvent) => ; diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js index 2199216154..f160eb00e3 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js @@ -22,7 +22,7 @@ import { } from '../../../../../../metaDataMemoryStoreBuilders/common/helpers/dataElement/unsupportedMultiText'; import { useOrgUnitNames } from '../../../../../../metadataRetrieval/orgUnitName'; -const baseKeys = [{ id: 'status' }, { id: 'occurredAt' }, { id: 'assignedUser' }, { id: 'orgUnitName' }, { id: 'scheduledAt' }, { id: 'notes' }]; +const baseKeys = [{ id: 'status' }, { id: 'occurredAt' }, { id: 'assignedUser' }, { id: 'orgUnit' }, { id: 'scheduledAt' }, { id: 'notes' }]; const basedFieldTypes = [ { type: dataElementTypes.STATUS, resolveValue: convertStatusForView }, { type: dataElementTypes.DATE }, diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js index a5493d19fd..d0aa4cc038 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/getEventDataWithSubValue.js @@ -2,6 +2,7 @@ import { featureAvailable, FEATURES } from 'capture-core-utils'; import { dataElementTypes } from '../../../../metaData'; import type { QuerySingleResource } from '../../../../utils/api/api.types'; +import { getOrgUnitNames } from '../../../../metadataRetrieval/orgUnitName'; const getFileResourceSubvalue = async (keys: Object, querySingleResource: QuerySingleResource, eventId: string, absoluteApiPath: string) => { const promises = Object.keys(keys) @@ -57,19 +58,9 @@ const getImageSubvalue = (keys: Object, querySingleResource: QuerySingleResource ); const getOrganisationUnitSubvalue = async (keys: Object, querySingleResource: QuerySingleResource) => { - const ids = Object.values(keys) - .join(','); - - const { organisationUnits = [] } = await querySingleResource({ - resource: 'organisationUnits', - params: { filter: `id:in:[${ids}]` }, - }); - - return organisationUnits - .reduce((acc, { id, displayName: name }) => { - acc[id] = { id, name }; - return acc; - }, {}); + const ids = Object.values(keys).map(value => String(value)); + const orgUnitNames = await getOrgUnitNames(ids, querySingleResource); + return orgUnitNames; }; const subValueGetterByElementType = { diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js deleted file mode 100644 index aaf3ffdf3c..0000000000 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/FlatListOrgUnitField.js +++ /dev/null @@ -1,19 +0,0 @@ -// @flow -import React from 'react'; -import { useOrgUnitNameWithAncestors } from '../../../metadataRetrieval/orgUnitName'; - -type Props = { - orgUnitId: string, -} - -export const FlatListOrgUnitField = ({ - orgUnitId, -}: Props) => { - const { displayName } = useOrgUnitNameWithAncestors(orgUnitId); - - return ( - - {displayName} - - ); -}; diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/index.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/index.js deleted file mode 100644 index cf8e8c20b7..0000000000 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/FlatListOrgUnitField/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// @flow - -export { FlatListOrgUnitField } from './FlatListOrgUnitField'; diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getDataEntryDetails.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getDataEntryDetails.js index 3e42d171de..a76d895a77 100644 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getDataEntryDetails.js +++ b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getDataEntryDetails.js @@ -5,7 +5,7 @@ import i18n from '@dhis2/d2-i18n'; import { dataElementTypes, type RenderFoundation } from '../../../metaData'; import { convertClientToView, convertServerToClient } from '../../../converters'; import type { LinkedEvent } from '../WidgetTwoEventWorkspace.types'; -import { FlatListOrgUnitField } from '../FlatListOrgUnitField'; +import { TooltipOrgUnit } from '../../Tooltips/TooltipOrgUnit'; const convertFn = pipe(convertServerToClient, convertClientToView); @@ -37,7 +37,7 @@ const DataEntryFieldsToInclude = { type: dataElementTypes.ORGANISATION_UNIT, placement: Placements.TOP, label: i18n.t('Organisation unit'), - convertFn: orgUnitId => , + convertFn: orgUnitId => , }, status: { apiKey: 'status', diff --git a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js index 5de5037e21..2a54bc5f8c 100644 --- a/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js +++ b/src/core_modules/capture-core/components/WidgetTwoEventWorkspace/utils/getSubValueForDataValue.js @@ -2,6 +2,7 @@ import { dataElementTypes } from '../../../metaData'; import type { QuerySingleResource } from '../../../utils/api'; import { featureAvailable, FEATURES } from '../../../../capture-core-utils'; +import { getOrgUnitNames } from '../../../metadataRetrieval/orgUnitName'; type SubValueFunctionProps = { dataElement: Object, @@ -44,15 +45,9 @@ const getImageSubvalue = async ({ dataElement, querySingleResource, eventId, abs }; }; -const getOrganisationUnitSubvalue = async ({ dataElement, querySingleResource }: SubValueFunctionProps) => { - const organisationUnit = await querySingleResource({ - resource: 'organisationUnits', - id: dataElement.value, - params: { - fields: 'id,name', - }, - }); - return { ...organisationUnit }; +const getOrganisationUnitSubvalue = async ({ dataElement: { value }, querySingleResource }: SubValueFunctionProps) => { + const organisationUnits = await getOrgUnitNames([value], querySingleResource); + return organisationUnits[value]; }; export const subValueGetterByElementType = { diff --git a/src/core_modules/capture-core/converters/clientToList.js b/src/core_modules/capture-core/converters/clientToList.js index a5f39b4105..870d0d7981 100644 --- a/src/core_modules/capture-core/converters/clientToList.js +++ b/src/core_modules/capture-core/converters/clientToList.js @@ -8,6 +8,7 @@ import { dataElementTypes, type DataElement } from '../metaData'; import { convertMomentToDateFormatString } from '../utils/converters/date'; import { stringifyNumber } from './common/stringifyNumber'; import { MinimalCoordinates } from '../components/MinimalCoordinates'; +import { TooltipOrgUnit } from '../components/Tooltips/TooltipOrgUnit'; function convertDateForListDisplay(rawValue: string): string { const momentDate = moment(rawValue); @@ -37,6 +38,7 @@ type ImageClientValue = { previewUrl: string, }; + function convertFileForDisplay(clientValue: FileClientValue) { // Fallback until https://dhis2.atlassian.net/browse/DHIS2-16994 is implemented if (typeof clientValue === 'string' || clientValue instanceof String) { @@ -86,10 +88,13 @@ function convertStatusForDisplay(clientValue: Object) { ); } -function convertOrgUnitForDisplay(rawValue: string | Object) { - return (typeof rawValue === 'string' ? rawValue : rawValue.name); +function convertOrgUnitForDisplay(clientValue: { id: string }) { + return ( + + ); } + const valueConvertersForType = { [dataElementTypes.NUMBER]: stringifyNumber, [dataElementTypes.INTEGER]: stringifyNumber, diff --git a/src/core_modules/capture-core/converters/clientToView.js b/src/core_modules/capture-core/converters/clientToView.js index 115bcbeb69..2849a02b01 100644 --- a/src/core_modules/capture-core/converters/clientToView.js +++ b/src/core_modules/capture-core/converters/clientToView.js @@ -34,11 +34,6 @@ type ImageClientValue = { previewUrl: string, }; -type OrgUnitClientValue = { - name: string, - ancestors?: Array, - tooltip?: string, -}; function convertFileForDisplay(clientValue: FileClientValue) { return ( @@ -57,16 +52,13 @@ function convertImageForDisplay(clientValue: ImageClientValue) { return ; } -function convertOrgUnitForDisplay(clientValue: OrgUnitClientValue) { +function convertOrgUnitForDisplay(clientValue: { id: string }) { return ( - + ); } + const valueConvertersForType = { [dataElementTypes.NUMBER]: stringifyNumber, [dataElementTypes.INTEGER]: stringifyNumber, diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js index 21e8b84212..204c983009 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js @@ -3,5 +3,4 @@ export { useOrgUnitNameWithAncestors, useOrgUnitNames, getOrgUnitNames, - getCachedOrgUnitName, } from './orgUnitName'; diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js index 56d222c119..c86c4d7c14 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js @@ -209,5 +209,3 @@ export const useOrgUnitNameWithAncestors = (orgUnitId: ?string): { return { error }; }; - -export const getCachedOrgUnitName = (orgUnitId: string): ?string => displayNameCache[orgUnitId]?.displayName; From dbbf8347a44b338e229cbb55ebd2c0e8dedc3614 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 14 Oct 2024 08:59:21 +0000 Subject: [PATCH 36/91] chore(release): cut 101.10.0 [skip release] # [101.10.0](https://github.com/dhis2/capture-app/compare/v101.9.1...v101.10.0) (2024-10-14) ### Features * [DHIS2-17771] Org unit context in tables and lists ([#3813](https://github.com/dhis2/capture-app/issues/3813)) ([b1a720a](https://github.com/dhis2/capture-app/commit/b1a720afc58b281ec7fc50e5af39ac19f4ec0cf4)) --- 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 be5bbe281c..83f9e12192 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [101.10.0](https://github.com/dhis2/capture-app/compare/v101.9.1...v101.10.0) (2024-10-14) + + +### Features + +* [DHIS2-17771] Org unit context in tables and lists ([#3813](https://github.com/dhis2/capture-app/issues/3813)) ([b1a720a](https://github.com/dhis2/capture-app/commit/b1a720afc58b281ec7fc50e5af39ac19f4ec0cf4)) + ## [101.9.1](https://github.com/dhis2/capture-app/compare/v101.9.0...v101.9.1) (2024-10-13) diff --git a/package.json b/package.json index 22ae5cce65..f93636a12f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.9.1", + "version": "101.10.0", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.9.1", + "@dhis2/rules-engine-javascript": "101.10.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 968878a1d4..56a1e753fb 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.9.1", + "version": "101.10.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 301585ed17379900db642a05e0157d52107f96a2 Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Mon, 14 Oct 2024 13:32:53 +0200 Subject: [PATCH 37/91] fix: [DHIS2-18028] User is able to add invalid related stages event (#3795) * fix: change logic for linkable events * fix: split up all and linkable events * chore: remove redundant filter --- .../getConvertedRelatedStageEvent.js | 2 +- .../LinkToExisting.component.js | 22 +++++++++---------- .../LinkToExisting/LinkToExisting.types.js | 7 ++++-- .../RelatedStagesActions.component.js | 5 +++-- .../RelatedStagesActions.types.js | 7 ++++-- .../WidgetRelatedStages.component.js | 7 +++--- .../hooks/useCanAddNewEventToStage.js | 4 ++-- ...tageEvents.js => useRelatedStageEvents.js} | 19 +++++++++------- 8 files changed, 41 insertions(+), 32 deletions(-) rename src/core_modules/capture-core/components/WidgetRelatedStages/hooks/{useAvailableRelatedStageEvents.js => useRelatedStageEvents.js} (74%) diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/getConvertedRelatedStageEvent/getConvertedRelatedStageEvent.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/getConvertedRelatedStageEvent/getConvertedRelatedStageEvent.js index 061f7a5fe4..2da2338fe6 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/getConvertedRelatedStageEvent/getConvertedRelatedStageEvent.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/getConvertedRelatedStageEvent/getConvertedRelatedStageEvent.js @@ -61,7 +61,7 @@ const getEventDetailsByLinkMode = ({ linkedEvent: { ...baseEventDetails, scheduledAt: convertFn(clientRequestEvent.scheduledAt, dataElementTypes.DATE), - orgUnit: convertFn(clientRequestEvent.orgUnit, dataElementTypes.ORGANISATION_UNIT), + orgUnit: clientRequestEvent.orgUnit, }, linkedEventId: baseEventDetails.event, }); diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.component.js b/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.component.js index 85bf2dae37..47f623af6e 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.component.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.component.js @@ -1,11 +1,7 @@ // @flow import React from 'react'; import i18n from '@dhis2/d2-i18n'; -import { - SingleSelectField, - SingleSelectOption, - spacers, -} from '@dhis2/ui'; +import { SingleSelectField, SingleSelectOption, spacers } from '@dhis2/ui'; import { withStyles } from '@material-ui/core'; import type { LinkToExistingProps } from './LinkToExisting.types'; @@ -58,13 +54,15 @@ export const LinkToExistingPlain = ({ error={saveAttempted && !!errorMessages.linkedEventId} validationText={saveAttempted && errorMessages.linkedEventId} > - {linkableEvents.map(event => ( - - ))} + {linkableEvents + .map(event => ( + + )) + }
); diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.types.js b/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.types.js index 386160b8e2..afa25ce233 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.types.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/LinkToExisting/LinkToExisting.types.js @@ -1,12 +1,15 @@ // @flow -import type { ErrorMessagesForRelatedStages, LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types'; +import type { + ErrorMessagesForRelatedStages, + RelatedStagesEvents, +} from '../RelatedStagesActions/RelatedStagesActions.types'; import type { RelatedStageDataValueStates } from '../WidgetRelatedStages.types'; export type LinkToExistingProps = {| relatedStagesDataValues: RelatedStageDataValueStates, setRelatedStagesDataValues: (RelatedStageDataValueStates) => void, - linkableEvents: Array, + linkableEvents: Array, errorMessages: ErrorMessagesForRelatedStages, saveAttempted: boolean, linkableStageLabel: string, diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.component.js b/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.component.js index 5bd127a887..4266eaf52a 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.component.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.component.js @@ -1,7 +1,7 @@ // @flow import React, { type ComponentType, useMemo } from 'react'; import i18n from '@dhis2/d2-i18n'; -import { Radio, colors, spacers, spacersNum, IconInfo16, Button } from '@dhis2/ui'; +import { Button, colors, IconInfo16, Radio, spacers, spacersNum } from '@dhis2/ui'; import { withStyles } from '@material-ui/core'; import { ConditionalTooltip } from 'capture-core/components/Tooltips/ConditionalTooltip'; import { actions as RelatedStagesActionTypes, mainOptionTranslatedTexts, relatedStageStatus } from '../constants'; @@ -53,6 +53,7 @@ export const RelatedStagesActionsPlain = ({ type, relationshipName, scheduledLabel, + events, linkableEvents, relatedStagesDataValues, setRelatedStagesDataValues, @@ -71,7 +72,7 @@ export const RelatedStagesActionsPlain = ({ linkMode: action, })); }; - const canAddNewEventToStage = useCanAddNewEventToStage(programStage, linkableEvents); + const canAddNewEventToStage = useCanAddNewEventToStage(programStage, events); if (!programStage) { return null; diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.types.js b/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.types.js index ea381b6374..a99f2d0758 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.types.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/RelatedStagesActions/RelatedStagesActions.types.js @@ -17,16 +17,19 @@ export type ErrorMessagesForRelatedStages = {| linkedEventId?: ?string, |} -export type LinkableEvent = { +export type RelatedStagesEvents = { id: string, label: string, + isLinkable: boolean, + status: string, } export type Props = {| type: string, relationshipName: string, relatedStagesDataValues: RelatedStageDataValueStates, - linkableEvents: Array, + events: Array, + linkableEvents: Array, scheduledLabel: string, saveAttempted: boolean, errorMessages: ErrorMessagesForRelatedStages, 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 3050b4d3e9..7ac5068e44 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/WidgetRelatedStages.component.js @@ -2,12 +2,12 @@ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react'; import { useRelatedStages } from './useRelatedStages'; import type { Props, RelatedStageDataValueStates } from './WidgetRelatedStages.types'; +import type { ErrorMessagesForRelatedStages } from './RelatedStagesActions'; import { RelatedStagesActions } from './RelatedStagesActions'; import { relatedStageStatus } from './constants'; import { useStageLabels } from './hooks/useStageLabels'; -import type { ErrorMessagesForRelatedStages } from './RelatedStagesActions'; import { relatedStageWidgetIsValid } from './relatedStageEventIsValid/relatedStageEventIsValid'; -import { useAvailableRelatedStageEvents } from './hooks/useAvailableRelatedStageEvents'; +import { useRelatedStageEvents } from './hooks/useRelatedStageEvents'; const WidgetRelatedStagesPlain = ({ programId, @@ -21,7 +21,7 @@ const WidgetRelatedStagesPlain = ({ programId, }); const { scheduledLabel, occurredLabel } = useStageLabels(programId, constraint?.programStage?.id); - const { linkableEvents, isLoading: isLoadingEvents } = useAvailableRelatedStageEvents({ + const { events, linkableEvents, isLoading: isLoadingEvents } = useRelatedStageEvents({ stageId: constraint?.programStage?.id, relationshipTypeId: selectedRelationshipType?.id, scheduledLabel, @@ -90,6 +90,7 @@ const WidgetRelatedStagesPlain = ({ relationshipName={selectedRelationshipType.displayName} scheduledLabel={scheduledLabel} type={currentRelatedStagesStatus} + events={events} linkableEvents={linkableEvents} relatedStagesDataValues={relatedStageDataValues} setRelatedStagesDataValues={setRelatedStageDataValues} diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useCanAddNewEventToStage.js b/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useCanAddNewEventToStage.js index e78e53a554..a95321b927 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useCanAddNewEventToStage.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useCanAddNewEventToStage.js @@ -2,9 +2,9 @@ import { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { ProgramStage } from '../../../metaData'; -import type { LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types'; +import type { RelatedStagesEvents } from '../RelatedStagesActions/RelatedStagesActions.types'; -export const useCanAddNewEventToStage = (programStage: ?ProgramStage, existingRelatedEvents: LinkableEvent[]) => { +export const useCanAddNewEventToStage = (programStage: ?ProgramStage, existingRelatedEvents: RelatedStagesEvents[]) => { const hiddenProgramStages = useSelector(({ rulesEffectsHiddenProgramStageDesc }) => rulesEffectsHiddenProgramStageDesc?.['enrollmentEvent-newEvent'], ); diff --git a/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useAvailableRelatedStageEvents.js b/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useRelatedStageEvents.js similarity index 74% rename from src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useAvailableRelatedStageEvents.js rename to src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useRelatedStageEvents.js index b273b3f66f..8a5e8a7c17 100644 --- a/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useAvailableRelatedStageEvents.js +++ b/src/core_modules/capture-core/components/WidgetRelatedStages/hooks/useRelatedStageEvents.js @@ -1,7 +1,7 @@ // @flow import { useMemo } from 'react'; import { convertDateObjectToDateFormatString } from '../../../utils/converters/date'; -import type { LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types'; +import type { RelatedStagesEvents } from '../RelatedStagesActions/RelatedStagesActions.types'; import { useApiDataQuery } from '../../../utils/reactQueryHelpers'; import { handleAPIResponse, REQUESTED_ENTITIES } from '../../../utils/api'; @@ -15,12 +15,13 @@ type Props = { } type ReturnType = { - linkableEvents: Array, + events: Array, + linkableEvents: Array, isLoading: boolean, isError: boolean, } -export const useAvailableRelatedStageEvents = ({ +export const useRelatedStageEvents = ({ stageId, enrollmentId, relationshipTypeId, @@ -36,7 +37,7 @@ export const useAvailableRelatedStageEvents = ({ fields: 'event,occurredAt,scheduledAt,status,relationships', }, }), [stageId, enrollmentId]); - const { data, isLoading, isError } = useApiDataQuery>( + const { data, isLoading, isError } = useApiDataQuery>( ['availableRelatedStageEvents', stageId, enrollmentId, relationshipTypeId], query, { @@ -45,19 +46,20 @@ export const useAvailableRelatedStageEvents = ({ staleTime: 0, select: (response: any) => { const events = handleAPIResponse(REQUESTED_ENTITIES.events, response); - if (events.length === 0) return []; return events - .filter(event => !event.relationships || - !event.relationships.some(relationship => relationship.relationshipType === relationshipTypeId)) .map((event) => { + const isLinkable = !event.relationships + ?.some(relationship => relationship.relationshipType === relationshipTypeId); const label = event.occurredAt ? `${occurredLabel}: ${convertDateObjectToDateFormatString(new Date(event.occurredAt))}` : `${scheduledLabel}: ${convertDateObjectToDateFormatString(new Date(event.scheduledAt))}`; return ({ id: event.event, + status: event.status, + isLinkable, label, }); }); @@ -66,7 +68,8 @@ export const useAvailableRelatedStageEvents = ({ ); return { - linkableEvents: data ?? [], + events: data ?? [], + linkableEvents: data?.filter(event => event.isLinkable) ?? [], isLoading, isError, }; From 394efe983be1c71bf997ea5e6f73978cae2c8ed0 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 14 Oct 2024 11:42:37 +0000 Subject: [PATCH 38/91] chore(release): cut 101.10.1 [skip release] ## [101.10.1](https://github.com/dhis2/capture-app/compare/v101.10.0...v101.10.1) (2024-10-14) ### Bug Fixes * [DHIS2-18028] User is able to add invalid related stages event ([#3795](https://github.com/dhis2/capture-app/issues/3795)) ([301585e](https://github.com/dhis2/capture-app/commit/301585ed17379900db642a05e0157d52107f96a2)) --- 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 83f9e12192..1897fba86d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.10.1](https://github.com/dhis2/capture-app/compare/v101.10.0...v101.10.1) (2024-10-14) + + +### Bug Fixes + +* [DHIS2-18028] User is able to add invalid related stages event ([#3795](https://github.com/dhis2/capture-app/issues/3795)) ([301585e](https://github.com/dhis2/capture-app/commit/301585ed17379900db642a05e0157d52107f96a2)) + # [101.10.0](https://github.com/dhis2/capture-app/compare/v101.9.1...v101.10.0) (2024-10-14) diff --git a/package.json b/package.json index f93636a12f..437c545d18 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.10.0", + "version": "101.10.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.10.0", + "@dhis2/rules-engine-javascript": "101.10.1", "@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 56a1e753fb..a922df4111 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.0", + "version": "101.10.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From ff859dc40a6ee43041dd0870e6730b89fc51b1e7 Mon Sep 17 00:00:00 2001 From: Eirik Haugstulen Date: Mon, 14 Oct 2024 15:21:34 +0200 Subject: [PATCH 39/91] test: cleanup after running NewPage tests (#3843) fix: cleanup after tests are run --- cypress/e2e/NewPage/NewPage.feature | 3 +++ cypress/e2e/NewPage/NewPage.js | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/NewPage/NewPage.feature b/cypress/e2e/NewPage/NewPage.feature index 49e3d27f99..b6a7907dee 100644 --- a/cypress/e2e/NewPage/NewPage.feature +++ b/cypress/e2e/NewPage/NewPage.feature @@ -196,6 +196,9 @@ Feature: User creates a new entries from the registration page And you fill the Malaria case diagnosis registration form with values And you click the save malaria entity submit button Then you see the enrollment event Edit page + # Cleanup + And you delete the recently added malaria entity + ## New enrollment of existing TEI diff --git a/cypress/e2e/NewPage/NewPage.js b/cypress/e2e/NewPage/NewPage.js index de6efe53e2..9ef6ab3440 100644 --- a/cypress/e2e/NewPage/NewPage.js +++ b/cypress/e2e/NewPage/NewPage.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 moment from 'moment'; import { getCurrentYear } from '../../support/date'; @@ -17,7 +17,7 @@ And('there should be informative message explaining you need to select an organi }); And('you select tracked entity type person', () => { - cy.get('[data-test="dhis2-uicore-select"') + cy.get('[data-test="dhis2-uicore-select"]') .click(); cy.get('[data-test="dhis2-uicore-singleselectoption"]') .contains('Person') @@ -645,6 +645,17 @@ And('you delete the recently added tracked entity', () => { cy.url().should('include', 'selectedTemplateId=IpHINAT79UW'); }); +And('you delete the recently added malaria entity', () => { + cy.get('[data-test="widget-profile-overflow-menu"]') + .click(); + cy.contains('Delete Malaria Entity') + .click(); + cy.get('[data-test="widget-profile-delete-modal"]').within(() => { + cy.contains('Yes, delete Malaria Entity') + .click(); + }); +}); + And(/^you select (.*) from the available tracked entity types/, (selection) => { cy.get('[data-test="dhis2-uicore-select-input"]') .click(); From ab3c5326b66c680c43a12183e02a2a5b1462f646 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 14 Oct 2024 15:50:08 +0200 Subject: [PATCH 40/91] 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 41/91] 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 42/91] 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 43/91] 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 44/91] 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": { From 5e6dfa6bb4b82a68305741bd4bb672a5a1af8f5f Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:36:31 +0200 Subject: [PATCH 45/91] fix: [DHIS2-16993] Text and long text DEs are missing arrows in changelog when deleted (#3827) * fix: make arrow size static * fix: revert changes to text --- .../common/ChangelogTable/ChangelogChangeCell.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogChangeCell.js b/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogChangeCell.js index e5dbef266a..1ec493edff 100644 --- a/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogChangeCell.js +++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogChangeCell.js @@ -35,7 +35,7 @@ const styles = { const Updated = ({ previousValue, currentValue, classes }) => (
{previousValue} - + {currentValue}
); @@ -50,7 +50,7 @@ const Created = ({ currentValue, classes }) => ( const Deleted = ({ previousValue, classes }) => (
{previousValue} - + {i18n.t('Deleted')}
); From b6bb0ff43dfa6c9e37718fda0f456512aabf77b9 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 15 Oct 2024 07:40:44 +0000 Subject: [PATCH 46/91] chore(release): cut 101.11.1 [skip release] ## [101.11.1](https://github.com/dhis2/capture-app/compare/v101.11.0...v101.11.1) (2024-10-15) ### Bug Fixes * [DHIS2-16993] Text and long text DEs are missing arrows in changelog when deleted ([#3827](https://github.com/dhis2/capture-app/issues/3827)) ([5e6dfa6](https://github.com/dhis2/capture-app/commit/5e6dfa6bb4b82a68305741bd4bb672a5a1af8f5f)) --- 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 08e6811337..c8583ebad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.11.1](https://github.com/dhis2/capture-app/compare/v101.11.0...v101.11.1) (2024-10-15) + + +### Bug Fixes + +* [DHIS2-16993] Text and long text DEs are missing arrows in changelog when deleted ([#3827](https://github.com/dhis2/capture-app/issues/3827)) ([5e6dfa6](https://github.com/dhis2/capture-app/commit/5e6dfa6bb4b82a68305741bd4bb672a5a1af8f5f)) + # [101.11.0](https://github.com/dhis2/capture-app/compare/v101.10.2...v101.11.0) (2024-10-14) diff --git a/package.json b/package.json index 2ca3ec5672..dbc834dc74 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.11.0", + "version": "101.11.1", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.11.0", + "@dhis2/rules-engine-javascript": "101.11.1", "@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 ac2c2f545a..6d49dda633 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.11.0", + "version": "101.11.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From cbfe70b850554678c7a8bad40e0874ea227fe65c Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Tue, 15 Oct 2024 12:13:15 +0200 Subject: [PATCH 47/91] fix: [DHIS2-18056] use linkedEntityFormFoundation instead of the searchFormFoundation (#3835) --- .../TeiRelationshipSearchResults.component.js | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/core_modules/capture-core/components/Pages/NewRelationship/TeiRelationship/SearchResults/TeiRelationshipSearchResults.component.js b/src/core_modules/capture-core/components/Pages/NewRelationship/TeiRelationship/SearchResults/TeiRelationshipSearchResults.component.js index 3cced06ccf..461424f302 100644 --- a/src/core_modules/capture-core/components/Pages/NewRelationship/TeiRelationship/SearchResults/TeiRelationshipSearchResults.component.js +++ b/src/core_modules/capture-core/components/Pages/NewRelationship/TeiRelationship/SearchResults/TeiRelationshipSearchResults.component.js @@ -10,7 +10,11 @@ import { makeAttributesSelector } from './teiRelationshipSearchResults.selectors import { CardList } from '../../../../CardList'; import type { CurrentSearchTerms } from '../../../../SearchBox'; import { SearchResultsHeader } from '../../../../SearchResultsHeader'; -import { type SearchGroup } from '../../../../../metaData'; +import { + type SearchGroup, + getTrackerProgramThrowIfNotFound, + getTrackedEntityTypeThrowIfNotFound, +} from '../../../../../metaData'; import { ResultsPageSizeContext } from '../../../shared-contexts'; import type { ListItem } from '../../../../CardList/CardList.types'; import { convertClientValuesToServer } from '../../../../../converters/helpers/clientToServer'; @@ -25,7 +29,8 @@ type Props = {| currentPage: number, searchGroup: SearchGroup, searchValues: any, - selectedProgramId: string, + selectedProgramId?: string, + selectedTrackedEntityTypeId: string, teis: Array, trackedEntityTypeName: string, ...CssClasses @@ -60,6 +65,15 @@ const getStyles = (theme: Theme) => ({ }, }); +const getLinkedEntityFormFoundation = (selectedProgramId, selectedTrackedEntityTypeId) => { + if (selectedProgramId) { + const program = getTrackerProgramThrowIfNotFound(selectedProgramId); + return program.enrollment.enrollmentForm; + } + const trackedEntityType = getTrackedEntityTypeThrowIfNotFound(selectedTrackedEntityTypeId); + return trackedEntityType.teiRegistration.form; +}; + const CardListButton = ({ handleOnClick, teiId }) => ( - + + + + + ); }; -export const DeleteConfirmationDialog = withStyles(getStyles)(DeleteConfirmationDialogPlain); diff --git a/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/ExistingTemplateContents.component.js b/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/ExistingTemplateContents.component.js index 0efef529f0..993b30eb2d 100644 --- a/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/ExistingTemplateContents.component.js +++ b/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/ExistingTemplateContents.component.js @@ -1,40 +1,30 @@ // @flow import * as React from 'react'; -import { withStyles } from '@material-ui/core/styles'; import i18n from '@dhis2/d2-i18n'; -import { Button, ModalTitle, ModalContent, ModalActions } from '@dhis2/ui'; - -const getStyles = () => ({ - buttonContainer: { - display: 'flex', - justifyContent: 'space-between', - }, -}); +import { Button, ButtonStrip, ModalActions, ModalContent, ModalTitle } from '@dhis2/ui'; type Props = { onSaveTemplate: () => void, onClose: () => void, - classes: Object, }; -const ExistingTemplateContentsPlain = (props: Props) => { - const { onSaveTemplate, onClose, classes } = props; +export const ExistingTemplateContents = (props: Props) => { + const { onSaveTemplate, onClose } = props; return ( {i18n.t('Save')} - - - + + + + + ); }; -export const ExistingTemplateContents = withStyles(getStyles)(ExistingTemplateContentsPlain); diff --git a/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/NewTemplateContents.component.js b/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/NewTemplateContents.component.js index c064f74893..ca1a446e8f 100644 --- a/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/NewTemplateContents.component.js +++ b/src/core_modules/capture-core/components/WorkingLists/WorkingListsBase/TemplateMaintenance/NewTemplateContents.component.js @@ -1,6 +1,6 @@ // @flow import * as React from 'react'; -import { colors, Button, ModalTitle, ModalContent, ModalActions } from '@dhis2/ui'; +import { Button, ButtonStrip, colors, ModalActions, ModalContent, ModalTitle } from '@dhis2/ui'; import { withStyles } from '@material-ui/core/styles'; import i18n from '@dhis2/d2-i18n'; import { NewTemplateTextField } from './NewTemplateTextField.component'; @@ -64,15 +64,15 @@ const NewTemplateContentsPlain = (props: Props) => { {error} - - - + + + + + ); From 28e1f15d82b0da1aa93dba6bc3d1e6d2fba3b7a6 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Fri, 1 Nov 2024 14:58:30 +0000 Subject: [PATCH 71/91] chore(release): cut 101.14.5 [skip release] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [101.14.5](https://github.com/dhis2/capture-app/compare/v101.14.4...v101.14.5) (2024-11-01) ### Bug Fixes * [DHIS2-18238] incorrect criteria when saving list with follow up false ([#3868](https://github.com/dhis2/capture-app/issues/3868)) ([53c21f0](https://github.com/dhis2/capture-app/commit/53c21f0a4942d09ae4bf88253b576de8ca94b9b6)) * [DHIS2-18248] pass on createdAt to rules engine when editing ([#3848](https://github.com/dhis2/capture-app/issues/3848)) ([31cb56c](https://github.com/dhis2/capture-app/commit/31cb56c4f05727eb84fcc36e39f897cccc5627b3)) --- CHANGELOG.md | 8 ++++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec9917046..8136f020c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [101.14.5](https://github.com/dhis2/capture-app/compare/v101.14.4...v101.14.5) (2024-11-01) + + +### Bug Fixes + +* [DHIS2-18238] incorrect criteria when saving list with follow up false ([#3868](https://github.com/dhis2/capture-app/issues/3868)) ([53c21f0](https://github.com/dhis2/capture-app/commit/53c21f0a4942d09ae4bf88253b576de8ca94b9b6)) +* [DHIS2-18248] pass on createdAt to rules engine when editing ([#3848](https://github.com/dhis2/capture-app/issues/3848)) ([31cb56c](https://github.com/dhis2/capture-app/commit/31cb56c4f05727eb84fcc36e39f897cccc5627b3)) + ## [101.14.4](https://github.com/dhis2/capture-app/compare/v101.14.3...v101.14.4) (2024-10-29) diff --git a/package.json b/package.json index cb10cd10a4..c0edde4cd1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.14.4", + "version": "101.14.5", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.14.4", + "@dhis2/rules-engine-javascript": "101.14.5", "@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 33aba0adb7..459d5ca235 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.14.4", + "version": "101.14.5", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From facbee13d009d11e955a1a9b277e27ba41b63867 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 3 Nov 2024 02:44:44 +0100 Subject: [PATCH 72/91] fix(translations): sync translations from transifex (master) Automatically merged. --- i18n/ar.po | 65 +++++++++------------------------ i18n/ar_IQ.po | 61 ++++++++----------------------- i18n/ckb.po | 65 +++++++++------------------------ i18n/km.po | 65 +++++++++------------------------ i18n/my.po | 65 +++++++++------------------------ i18n/prs.po | 61 ++++++++----------------------- i18n/ps.po | 65 +++++++++------------------------ i18n/pt.po | 36 +++++++++++------- i18n/pt_BR.po | 65 +++++++++------------------------ i18n/ro.po | 25 ++++++++----- i18n/ru.po | 27 ++++++++------ i18n/si.po | 91 ++++++++++++++++------------------------------ i18n/sv.po | 61 ++++++++----------------------- i18n/tet.po | 61 ++++++++----------------------- i18n/tg.po | 65 +++++++++------------------------ i18n/uk.po | 65 +++++++++------------------------ i18n/ur.po | 61 ++++++++----------------------- i18n/uz_UZ_Cyrl.po | 61 ++++++++----------------------- i18n/uz_UZ_Latn.po | 61 ++++++++----------------------- i18n/vi.po | 65 +++++++++------------------------ i18n/zh_CN.po | 25 ++++++++----- 21 files changed, 377 insertions(+), 839 deletions(-) diff --git a/i18n/ar.po b/i18n/ar.po index 2e69358014..bd06150d1f 100644 --- a/i18n/ar.po +++ b/i18n/ar.po @@ -2,15 +2,15 @@ # Translators: # KRG HIS , 2020 # Philip Larsen Donnelly, 2023 -# Hamza Assada <7amza.it@gmail.com>, 2024 # Viktor Varland , 2024 +# Hamza Assada <7amza.it@gmail.com>, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Hamza Assada <7amza.it@gmail.com>, 2024\n" "Language-Team: Arabic (https://app.transifex.com/hisp-uio/teams/100509/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -623,42 +623,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -746,9 +710,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1167,6 +1128,9 @@ msgstr "" msgid "Mark incomplete" msgstr "تعيين كـ غير مكتمل" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "الغِ التسجيل" @@ -1247,6 +1211,12 @@ msgstr "" msgid "Follow-up" msgstr "متابعة" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "الملغية" @@ -1443,11 +1413,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1534,6 +1499,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "تم تحديثه" + msgid "Created" msgstr "تم الإنشاء" @@ -1552,6 +1520,9 @@ msgstr "عنصر بيانات" msgid "Change" msgstr "" +msgid "Value" +msgstr "القيمة" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ar_IQ.po b/i18n/ar_IQ.po index 13422d6d58..f818d29a25 100644 --- a/i18n/ar_IQ.po +++ b/i18n/ar_IQ.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: KRG HIS , 2024\n" "Language-Team: Arabic (Iraq) (https://app.transifex.com/hisp-uio/teams/100509/ar_IQ/)\n" @@ -620,42 +620,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -743,9 +707,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1162,6 +1123,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1242,6 +1206,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "تم الإلغاء" @@ -1438,11 +1408,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1529,6 +1494,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "تم الإنشاء" @@ -1547,6 +1515,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "القيمة" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ckb.po b/i18n/ckb.po index 851ae43bd0..54b435b433 100644 --- a/i18n/ckb.po +++ b/i18n/ckb.po @@ -2,15 +2,15 @@ # Translators: # Antonia Bezenchek , 2021 # KRG HIS , 2021 -# Viktor Varland , 2022 # Philip Larsen Donnelly, 2024 +# Viktor Varland , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Philip Larsen Donnelly, 2024\n" +"Last-Translator: Viktor Varland , 2024\n" "Language-Team: Central Kurdish (https://app.transifex.com/hisp-uio/teams/100509/ckb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -625,42 +625,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -748,9 +712,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1165,6 +1126,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1245,6 +1209,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "" @@ -1433,11 +1403,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1520,6 +1485,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1538,6 +1506,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "بةها" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/km.po b/i18n/km.po index ec9c3dac3e..f203f663af 100644 --- a/i18n/km.po +++ b/i18n/km.po @@ -1,15 +1,15 @@ # # Translators: # channara rin, 2023 -# Philip Larsen Donnelly, 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Khmer (https://app.transifex.com/hisp-uio/teams/100509/km/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -607,42 +607,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -730,9 +694,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1144,6 +1105,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1224,6 +1188,12 @@ msgstr "" msgid "Follow-up" msgstr "តាមដាន" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "បានលុបចោល" @@ -1410,11 +1380,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1496,6 +1461,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1514,6 +1482,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "តម្លៃ" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/my.po b/i18n/my.po index 1416f92911..e86c5d5eca 100644 --- a/i18n/my.po +++ b/i18n/my.po @@ -1,16 +1,16 @@ # # Translators: # Wanda , 2021 -# Philip Larsen Donnelly, 2024 # Aung Kyi Min , 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Burmese (https://app.transifex.com/hisp-uio/teams/100509/my/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -608,42 +608,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -731,9 +695,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1145,6 +1106,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1225,6 +1189,12 @@ msgstr "" msgid "Follow-up" msgstr "စောင့်ကြပ်ကြည့်ရှုခြင်း" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "" @@ -1411,11 +1381,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1497,6 +1462,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1515,6 +1483,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "တန်ဖိုး" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/prs.po b/i18n/prs.po index 9b6cbf8306..76198d8d85 100644 --- a/i18n/prs.po +++ b/i18n/prs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Persian (Afghanistan) (https://app.transifex.com/hisp-uio/teams/100509/fa_AF/)\n" @@ -606,42 +606,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -729,9 +693,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1144,6 +1105,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "حذف شمولیت" @@ -1224,6 +1188,12 @@ msgstr "" msgid "Follow-up" msgstr "تعقیب کردن" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "" @@ -1412,11 +1382,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1499,6 +1464,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "ایجاد شده" @@ -1517,6 +1485,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "مقدار" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ps.po b/i18n/ps.po index 38518df9a7..f8acba0571 100644 --- a/i18n/ps.po +++ b/i18n/ps.po @@ -1,14 +1,14 @@ # # Translators: -# Philip Larsen Donnelly, 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Pashto (https://app.transifex.com/hisp-uio/teams/100509/ps/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -607,42 +607,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -730,9 +694,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1145,6 +1106,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "د شمولیت حذفول" @@ -1225,6 +1189,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "لغوه شوی" @@ -1413,11 +1383,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1500,6 +1465,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "ایجاد شوی دی" @@ -1518,6 +1486,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "ارزښت یا رقم" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/pt.po b/i18n/pt.po index 0f02ab2cdc..1a05f44f6b 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -4,17 +4,20 @@ # Fernando Jorge Bade, 2023 # Philip Larsen Donnelly, 2024 # Gabriela Rodriguez , 2024 -# Sheila André , 2024 # Ge Joao , 2024 # Viktor Varland , 2024 # Juan M Alcantara Acosta , 2024 +# Sheila André , 2024 +# Jason Pickering , 2024 +# Helton Dias, 2024 +# Shelsea Chumaio, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-10-14T14:53:34.553Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Juan M Alcantara Acosta , 2024\n" +"Last-Translator: Shelsea Chumaio, 2024\n" "Language-Team: Portuguese (https://app.transifex.com/hisp-uio/teams/100509/pt/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -531,7 +534,7 @@ msgid "Type to filter options" msgstr "" msgid "No match found" -msgstr "" +msgstr "Nenhuma correspondência encontrada" msgid "Search" msgstr "Pesquisar" @@ -730,9 +733,6 @@ msgstr "Veja a lista de trabalho neste programa." msgid "Page is missing required values from URL" msgstr "A página tem em falta os valores obrigatórios do URL" -msgid "Program is not valid" -msgstr "O programa não é válido" - msgid "Org unit is not valid with current program" msgstr "A unidade organizacional não é válida com o programa atual" @@ -1166,6 +1166,9 @@ msgstr "Marcar como cancelado" msgid "Mark incomplete" msgstr "Marca incompleta" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Excluir inscrição" @@ -1186,7 +1189,7 @@ msgid "Mark for follow-up" msgstr "Marcar para acompanhamento" msgid "Transfer" -msgstr "" +msgstr "Transferir" msgid "An error occurred while transferring ownership" msgstr "" @@ -1250,6 +1253,12 @@ msgstr "" msgid "Follow-up" msgstr "Acompanhamento" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Cancelado" @@ -1452,11 +1461,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1543,6 +1547,9 @@ msgstr "Registo de mudanças" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "Actualizado" + msgid "Created" msgstr "Criado" @@ -1561,6 +1568,9 @@ msgstr "Item de dados" msgid "Change" msgstr "" +msgid "Value" +msgstr "Valor" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po index f33904fb18..dde9b5e1e0 100644 --- a/i18n/pt_BR.po +++ b/i18n/pt_BR.po @@ -1,16 +1,16 @@ # # Translators: # Oscar Mesones Lapouble , 2021 -# Philip Larsen Donnelly, 2024 # Viktor Varland , 2024 # Thiago Rocha, 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Thiago Rocha, 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/hisp-uio/teams/100509/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -610,42 +610,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -733,9 +697,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1149,6 +1110,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Excluir inscrição" @@ -1229,6 +1193,12 @@ msgstr "" msgid "Follow-up" msgstr "Seguimento" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Cancelado" @@ -1419,11 +1389,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1507,6 +1472,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "Criado" @@ -1525,6 +1493,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "Valor" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ro.po b/i18n/ro.po index ee6543821a..ee369e5446 100644 --- a/i18n/ro.po +++ b/i18n/ro.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-10-14T14:53:34.553Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Valeriu Plesca , 2024\n" "Language-Team: Romanian (https://app.transifex.com/hisp-uio/teams/100509/ro/)\n" @@ -708,9 +708,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "În pagină lipsesc valorile obligatorii din URL" -msgid "Program is not valid" -msgstr "Programul nu este valid" - msgid "Org unit is not valid with current program" msgstr "Unitatea organizațională nu este validă cu programul curent" @@ -1130,6 +1127,9 @@ msgstr "Marcare ca anulat" msgid "Mark incomplete" msgstr "Marcare ca incomplet" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Lichidare înrolare" @@ -1210,6 +1210,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Anulat" @@ -1401,11 +1407,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1489,6 +1490,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1507,6 +1511,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ru.po b/i18n/ru.po index 68ea9d95c7..23d7e47cd1 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-10-14T14:53:34.553Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Russian (https://app.transifex.com/hisp-uio/teams/100509/ru/)\n" @@ -735,9 +735,6 @@ msgstr "Просмотреть рабочий список в данной пр msgid "Page is missing required values from URL" msgstr "Страница не содержит необходимых данных в URL адресе" -msgid "Program is not valid" -msgstr "Программа недействительна" - msgid "Org unit is not valid with current program" msgstr "Организационная единица не действительна для данной программы" @@ -1170,6 +1167,9 @@ msgstr "Присвоить метку \"Отменено\"" msgid "Mark incomplete" msgstr " Присвоить метку \"Незавершено\"" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Удалить регистрационную запись" @@ -1262,6 +1262,12 @@ msgstr "" msgid "Follow-up" msgstr "Наблюдать" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Отменен/а/о" @@ -1483,13 +1489,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "Неопределенные связи, обратитесь к системному администратору" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" -"Ввести данные этапа {{linkableStageLabel}} на следующем шаге после " -"заполнения данных данного этапа {{currentStageLabel}}." - msgid "Enter details now" msgstr "Ввести данные сейчас" @@ -1574,6 +1573,9 @@ msgstr "Лог изменений" msgid "No changes to display" msgstr "Нет изменений для отображения" +msgid "Updated" +msgstr "Обновлено" + msgid "Created" msgstr "Создан/а/о" @@ -1592,6 +1594,9 @@ msgstr "Переменная" msgid "Change" msgstr "Изменить" +msgid "Value" +msgstr "Значение" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "Новая связь для объекта {{trackedEntityTypeName}} " diff --git a/i18n/si.po b/i18n/si.po index 996801aea5..35f0e324d6 100644 --- a/i18n/si.po +++ b/i18n/si.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-08-10T10:42:21.141Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Malinda Wijeratne, 2024\n" "Language-Team: Sinhala (https://app.transifex.com/hisp-uio/teams/100509/si/)\n" @@ -588,15 +588,6 @@ msgstr "" msgid "Selected program is invalid for selected organisation unit" msgstr "" -msgid "Online" -msgstr "" - -msgid "Offline" -msgstr "" - -msgid "Syncing" -msgstr "" - msgid "Add note" msgstr "" @@ -615,42 +606,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -738,9 +693,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1153,6 +1105,9 @@ msgstr "" msgid "Mark incomplete" msgstr "අසම්පූර්ණ බව සලකුණු කරන්න" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1233,10 +1188,10 @@ msgstr "" msgid "Follow-up" msgstr "" -msgid "Started at {{orgUnitName}}" +msgid "Started at{{escape}}" msgstr "" -msgid "Owned by {{ownerOrgUnit}}" +msgid "Owned by{{escape}}" msgstr "" msgid "Cancelled" @@ -1293,6 +1248,9 @@ msgstr "" msgid "Event completed" msgstr "" +msgid "The event cannot be edited after it has been completed" +msgstr "" + msgid "Back to all stages and events" msgstr "" @@ -1424,11 +1382,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1453,13 +1406,27 @@ msgstr "" msgid "New {{ eventName }} event" msgstr "" -msgid "To open this event, please wait until saving is complete" +msgid "An error occurred while deleting the event" msgstr "" -msgid "Show {{ rest }} more" +msgid "" +"Deleting an event is permanent and cannot be undone. Are you sure you want " +"to delete this event?" msgstr "" -msgid "Reset list" +msgid "An error occurred when updating event status" +msgstr "" + +msgid "Unskip" +msgstr "" + +msgid "Skip" +msgstr "" + +msgid "To open this event, please wait until saving is complete" +msgstr "" + +msgid "Show {{ rest }} more" msgstr "" msgid "Go to full {{ eventName }}" @@ -1497,6 +1464,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1515,6 +1485,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "අගය" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/sv.po b/i18n/sv.po index e771dc9cec..6e16f66d26 100644 --- a/i18n/sv.po +++ b/i18n/sv.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Swedish (https://app.transifex.com/hisp-uio/teams/100509/sv/)\n" @@ -609,42 +609,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -732,9 +696,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1147,6 +1108,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1227,6 +1191,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Avbruten" @@ -1415,11 +1385,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1502,6 +1467,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "Uppdaterad" + msgid "Created" msgstr "Skapad" @@ -1520,6 +1488,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "Värde" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/tet.po b/i18n/tet.po index d268e14ea8..4757d41fce 100644 --- a/i18n/tet.po +++ b/i18n/tet.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Tetum (Tetun) (https://app.transifex.com/hisp-uio/teams/100509/tet/)\n" @@ -606,42 +606,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -729,9 +693,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1143,6 +1104,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1223,6 +1187,12 @@ msgstr "" msgid "Follow-up" msgstr "Segimentu" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "" @@ -1409,11 +1379,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1495,6 +1460,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1513,6 +1481,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "Valor" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/tg.po b/i18n/tg.po index 02c2ea6da5..545222c3dc 100644 --- a/i18n/tg.po +++ b/i18n/tg.po @@ -1,14 +1,14 @@ # # Translators: -# Philip Larsen Donnelly, 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Tajik (https://app.transifex.com/hisp-uio/teams/100509/tg/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -607,42 +607,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -730,9 +694,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1145,6 +1106,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "" @@ -1225,6 +1189,12 @@ msgstr "" msgid "Follow-up" msgstr "Пайгирӣ кардан" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "" @@ -1413,11 +1383,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1500,6 +1465,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "" @@ -1518,6 +1486,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "Қимат" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/uk.po b/i18n/uk.po index b294680692..0506bb74f1 100644 --- a/i18n/uk.po +++ b/i18n/uk.po @@ -1,17 +1,17 @@ # # Translators: -# Philip Larsen Donnelly, 2023 # Wanda , 2024 # Éva Tamási, 2024 # Nadiia , 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2024\n" +"Last-Translator: Philip Larsen Donnelly, 2024\n" "Language-Team: Ukrainian (https://app.transifex.com/hisp-uio/teams/100509/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -612,42 +612,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -735,9 +699,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1152,6 +1113,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Видалити реєстрацію" @@ -1232,6 +1196,12 @@ msgstr "" msgid "Follow-up" msgstr "Подальші дії" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Скасовано" @@ -1424,11 +1394,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1513,6 +1478,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "Створено" @@ -1531,6 +1499,9 @@ msgstr "Елемент даних" msgid "Change" msgstr "" +msgid "Value" +msgstr "Значення" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/ur.po b/i18n/ur.po index 9a1900631a..a955c4e3e1 100644 --- a/i18n/ur.po +++ b/i18n/ur.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2024\n" "Language-Team: Urdu (https://app.transifex.com/hisp-uio/teams/100509/ur/)\n" @@ -607,42 +607,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -730,9 +694,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1145,6 +1106,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "اندراج حذف کریں" @@ -1225,6 +1189,12 @@ msgstr "" msgid "Follow-up" msgstr "" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "منسوخ" @@ -1413,11 +1383,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1500,6 +1465,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "تخلیق" @@ -1518,6 +1486,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "قدر" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/uz_UZ_Cyrl.po b/i18n/uz_UZ_Cyrl.po index 6ad437c602..a397b0df49 100644 --- a/i18n/uz_UZ_Cyrl.po +++ b/i18n/uz_UZ_Cyrl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Khurshid Ibatov , 2024\n" "Language-Team: Uzbek (Cyrillic) (https://app.transifex.com/hisp-uio/teams/100509/uz@Cyrl/)\n" @@ -624,42 +624,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "\"{{enrollmentId}}\" идентификатори билан қайд қилиш имконсиз" @@ -754,9 +718,6 @@ msgstr "Ушбу дастурдаги ишчи рўйхатни кўриб чи msgid "Page is missing required values from URL" msgstr "URL саҳифасида керакли қийматлар йўқ" -msgid "Program is not valid" -msgstr "Дастур яроқли эмас" - msgid "Org unit is not valid with current program" msgstr "Жорий дастур учун ташкилий бирлик яроқли эмас" @@ -1178,6 +1139,9 @@ msgstr "" msgid "Mark incomplete" msgstr "Тугалланмаган деб белгилансин" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Рўйхатдан ўтказиш ўчирилсин " @@ -1259,6 +1223,12 @@ msgstr "" msgid "Follow-up" msgstr "Кузатиш" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Бекор қилинди" @@ -1446,11 +1416,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1532,6 +1497,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "Янгиланди" + msgid "Created" msgstr "Яратилган" @@ -1550,6 +1518,9 @@ msgstr "Маълумот элементи" msgid "Change" msgstr "" +msgid "Value" +msgstr "Қиймат" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/uz_UZ_Latn.po b/i18n/uz_UZ_Latn.po index 720b8be8e6..cbb6637b95 100644 --- a/i18n/uz_UZ_Latn.po +++ b/i18n/uz_UZ_Latn.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Yury Rogachev , 2024\n" "Language-Team: Uzbek (Latin) (https://app.transifex.com/hisp-uio/teams/100509/uz@Latn/)\n" @@ -625,42 +625,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -748,9 +712,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -1169,6 +1130,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Roʼyxatdan oʼtkazish oʼchirilsin" @@ -1249,6 +1213,12 @@ msgstr "" msgid "Follow-up" msgstr "Kuzatish" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Bekor qilindi" @@ -1435,11 +1405,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1521,6 +1486,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "Yangilandi" + msgid "Created" msgstr "Yaratilgan" @@ -1539,6 +1507,9 @@ msgstr "Maʼlumot elementi" msgid "Change" msgstr "" +msgid "Value" +msgstr "Қиймат" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/vi.po b/i18n/vi.po index 4599936038..5ca15df651 100644 --- a/i18n/vi.po +++ b/i18n/vi.po @@ -1,14 +1,14 @@ # # Translators: -# Philip Larsen Donnelly, 2024 # Mai Nguyen , 2024 # Viktor Varland , 2024 +# Philip Larsen Donnelly, 2024 # Thuy Nguyen , 2024 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-09-02T11:08:16.281Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Thuy Nguyen , 2024\n" "Language-Team: Vietnamese (https://app.transifex.com/hisp-uio/teams/100509/vi/)\n" @@ -622,42 +622,6 @@ msgstr "" msgid "Close the notice" msgstr "" -msgid "Use new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt in for {{programName}}" -msgstr "" - -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 "" - -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 "" - -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 "" - -msgid "Yes, opt in" -msgstr "" - -msgid "Stop using new Enrollment dashboard for {{programName}}" -msgstr "" - -msgid "Opt out for {{programName}}" -msgstr "" - msgid "Enrollment with id \"{{enrollmentId}}\" does not exist" msgstr "" @@ -745,9 +709,6 @@ msgstr "" msgid "Page is missing required values from URL" msgstr "" -msgid "Program is not valid" -msgstr "" - msgid "Org unit is not valid with current program" msgstr "" @@ -770,7 +731,7 @@ msgid "Schedule" msgstr "Lịch biểu" msgid "Refer" -msgstr "" +msgstr "Tham chiếu" msgid "You can't add any more {{ programStageName }} events" msgstr "" @@ -1167,6 +1128,9 @@ msgstr "" msgid "Mark incomplete" msgstr "" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "Xóa đăng ký" @@ -1247,6 +1211,12 @@ msgstr "" msgid "Follow-up" msgstr "Theo dõi sau" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "Đã hủy" @@ -1433,11 +1403,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1519,6 +1484,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "" + msgid "Created" msgstr "Đã tạo" @@ -1537,6 +1505,9 @@ msgstr "Mục dữ liệu" msgid "Change" msgstr "" +msgid "Value" +msgstr "Giá trị" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po index 3f3a8e6b43..8d01178792 100644 --- a/i18n/zh_CN.po +++ b/i18n/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-10-14T14:53:34.553Z\n" +"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: 晓东 林 <13981924470@126.com>, 2024\n" "Language-Team: Chinese (China) (https://app.transifex.com/hisp-uio/teams/100509/zh_CN/)\n" @@ -697,9 +697,6 @@ msgstr "查看此项目中的工作清单。" msgid "Page is missing required values from URL" msgstr "页面缺少 URL 中的必需值" -msgid "Program is not valid" -msgstr "项目无效" - msgid "Org unit is not valid with current program" msgstr "机构对当前项目无效" @@ -1113,6 +1110,9 @@ msgstr "标记为已取消" msgid "Mark incomplete" msgstr "标记不完整" +msgid "You do not have access to delete this enrollment" +msgstr "" + msgid "Delete enrollment" msgstr "删除报名" @@ -1193,6 +1193,12 @@ msgstr "无法加载报名的小部件。请稍后再试" msgid "Follow-up" msgstr "后续" +msgid "Started at{{escape}}" +msgstr "" + +msgid "Owned by{{escape}}" +msgstr "" + msgid "Cancelled" msgstr "已取消" @@ -1379,11 +1385,6 @@ msgstr "" msgid "Ambiguous relationships, contact system administrator" msgstr "" -msgid "" -"Enter {{linkableStageLabel}} details in the next step after completing this " -"{{currentStageLabel}}." -msgstr "" - msgid "Enter details now" msgstr "" @@ -1465,6 +1466,9 @@ msgstr "" msgid "No changes to display" msgstr "" +msgid "Updated" +msgstr "更新的" + msgid "Created" msgstr "已创建" @@ -1483,6 +1487,9 @@ msgstr "" msgid "Change" msgstr "" +msgid "Value" +msgstr "值" + msgid "New {{trackedEntityTypeName}} relationship" msgstr "" From 2bbea47eb519b6c91a7c76c10bf817e26f35ca41 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sun, 3 Nov 2024 01:49:02 +0000 Subject: [PATCH 73/91] chore(release): cut 101.14.6 [skip release] ## [101.14.6](https://github.com/dhis2/capture-app/compare/v101.14.5...v101.14.6) (2024-11-03) ### Bug Fixes * **translations:** sync translations from transifex (master) ([facbee1](https://github.com/dhis2/capture-app/commit/facbee13d009d11e955a1a9b277e27ba41b63867)) --- 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 8136f020c9..6c192352e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [101.14.6](https://github.com/dhis2/capture-app/compare/v101.14.5...v101.14.6) (2024-11-03) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([facbee1](https://github.com/dhis2/capture-app/commit/facbee13d009d11e955a1a9b277e27ba41b63867)) + ## [101.14.5](https://github.com/dhis2/capture-app/compare/v101.14.4...v101.14.5) (2024-11-01) diff --git a/package.json b/package.json index c0edde4cd1..59fa6c912d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.14.5", + "version": "101.14.6", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.14.5", + "@dhis2/rules-engine-javascript": "101.14.6", "@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 459d5ca235..dcd47d7c56 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.14.5", + "version": "101.14.6", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 1d9ae5731331d3f19a0980cf09ebdd9cc46e4583 Mon Sep 17 00:00:00 2001 From: henrikmv <110386561+henrikmv@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:22:37 +0100 Subject: [PATCH 74/91] fix: [DHIS2-17135][DHIS2-17018] Adjust strings for error messages (#3858) * fix: string adjustment * fix: disable button and add tooltip * Revert "fix: disable button and add tooltip" This reverts commit 8cfb4a655a45420f714d4c12d5d91ce4a90475c9. * fix: string improvement for record access error * fix: string improvement * fix: merge conflict * fix: merge conflict --- i18n/en.pot | 16 ++++++++++------ .../Pages/Enrollment/MissingMessage.component.js | 2 +- .../WidgetAssignee/DisplayMode.component.js | 4 ++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/i18n/en.pot b/i18n/en.pot index 5fb403e3d7..370523a4b2 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -674,8 +674,12 @@ msgstr "There are no active enrollments." msgid "Add new enrollment for {{teiDisplayName}} in this program." msgstr "Add new enrollment for {{teiDisplayName}} in this program." -msgid "No access to program owner." -msgstr "No access to program owner." +msgid "" +"You do not have permissions to access to this program, registering unit or " +"record, contact your administrator for more information." +msgstr "" +"You do not have permissions to access to this program, registering unit or " +"record, contact your administrator for more information." msgid "{{teiDisplayName}} is not enrolled in this program." msgstr "{{teiDisplayName}} is not enrolled in this program." @@ -1074,8 +1078,8 @@ msgstr "No tracked entity types available" msgid "Assigned to" msgstr "Assigned to" -msgid "You don't have access to edit this assignee" -msgstr "You don't have access to edit this assignee" +msgid "You don't have access to edit the assigned user" +msgstr "You don't have access to edit the assigned user" msgid "Edit" msgstr "Edit" @@ -1083,8 +1087,8 @@ msgstr "Edit" msgid "No one is assigned to this event" msgstr "No one is assigned to this event" -msgid "You don't have access to assign an assignee" -msgstr "You don't have access to assign an assignee" +msgid "You don't have access to assign a user to this event" +msgstr "You don't have access to assign a user to this event" msgid "Assign" msgstr "Assign" diff --git a/src/core_modules/capture-core/components/Pages/Enrollment/MissingMessage.component.js b/src/core_modules/capture-core/components/Pages/Enrollment/MissingMessage.component.js index 17d36faedd..e46f36adb9 100644 --- a/src/core_modules/capture-core/components/Pages/Enrollment/MissingMessage.component.js +++ b/src/core_modules/capture-core/components/Pages/Enrollment/MissingMessage.component.js @@ -194,7 +194,7 @@ export const MissingMessage = withStyles(getStyles)(({ { missingStatus === missingStatuses.RESTRICTED_PROGRAM_NO_ACCESS && - {i18n.t('No access to program owner.')} + {i18n.t('You do not have permissions to access to this program, registering unit or record, contact your administrator for more information.')} } diff --git a/src/core_modules/capture-core/components/WidgetAssignee/DisplayMode.component.js b/src/core_modules/capture-core/components/WidgetAssignee/DisplayMode.component.js index e0b2ebb2dd..8f49833590 100644 --- a/src/core_modules/capture-core/components/WidgetAssignee/DisplayMode.component.js +++ b/src/core_modules/capture-core/components/WidgetAssignee/DisplayMode.component.js @@ -44,7 +44,7 @@ const DisplayModePlain = ({ assignee, onEdit, writeAccess, avatarId, classes }: {assignee.name}