diff --git a/.tx/config b/.tx/config index b85af354a6..2b6c02f453 100644 --- a/.tx/config +++ b/.tx/config @@ -1,6 +1,6 @@ [main] host = https://www.transifex.com -lang_map = fa_AF: prs, uz@Cyrl: uz, uz@Latn: uz_Latn +lang_map = fa_AF: prs, uz@Cyrl: uz_UZ_Cyrl, uz@Latn: uz_UZ_Latn [o:hisp-uio:p:app-capture-app:r:en-pot] file_filter = i18n/.po diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bbd699a93..a9b8e29d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,52 @@ +# [100.41.0](https://github.com/dhis2/capture-app/compare/v100.40.1...v100.41.0) (2023-10-03) + + +### Features + +* [DHIS2-9661][DHIS2-14830] first stage on registration page ([#3267](https://github.com/dhis2/capture-app/issues/3267)) ([6e5f6fe](https://github.com/dhis2/capture-app/commit/6e5f6fea7b6ab043800e806c7459210f10ef608a)) + +## [100.40.1](https://github.com/dhis2/capture-app/compare/v100.40.0...v100.40.1) (2023-09-30) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([b58bc66](https://github.com/dhis2/capture-app/commit/b58bc66db4136ad558c02f38ac54a2319b3af3f1)) + +# [100.40.0](https://github.com/dhis2/capture-app/compare/v100.39.4...v100.40.0) (2023-09-20) + + +### Features + +* [DHIS2-15830] Add orgUnitId to plugin context ([b9ec237](https://github.com/dhis2/capture-app/commit/b9ec237af595a1112dc6db01206e8332c9bb6647)) + +## [100.39.4](https://github.com/dhis2/capture-app/compare/v100.39.3...v100.39.4) (2023-09-19) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([712b56e](https://github.com/dhis2/capture-app/commit/712b56e749d08432ac18d854cf06cc45dabeda55)) + +## [100.39.3](https://github.com/dhis2/capture-app/compare/v100.39.2...v100.39.3) (2023-09-14) + + +### Bug Fixes + +* [DHIS2-15356] change tei search parameter from `ou` to `orgUnit` ([#3362](https://github.com/dhis2/capture-app/issues/3362)) ([c7ab828](https://github.com/dhis2/capture-app/commit/c7ab82826254be24959ff25d643b68c1e525c893)) + +## [100.39.2](https://github.com/dhis2/capture-app/compare/v100.39.1...v100.39.2) (2023-09-14) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([c17c663](https://github.com/dhis2/capture-app/commit/c17c6637f0e6ce93bdd5f5ef3d534d3ac9206c86)) + +## [100.39.1](https://github.com/dhis2/capture-app/compare/v100.39.0...v100.39.1) (2023-09-13) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([0fab0eb](https://github.com/dhis2/capture-app/commit/0fab0eba7b63cbfd080990913313fc6b6ff2d38f)) + # [100.39.0](https://github.com/dhis2/capture-app/compare/v100.38.0...v100.39.0) (2023-09-07) diff --git a/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js b/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js index 45ad92f517..70a2fdad96 100644 --- a/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js +++ b/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js @@ -31,6 +31,10 @@ And('you create a new tei in Child programme from Ngelehun CHC', () => { .eq(1) .type('TheGlass') .blur(); + cy.get('[data-test="capture-ui-input"]') + .eq(7) + .type('2023-09-01') + .blur(); clickSave(); }); diff --git a/cypress/integration/NewPage.feature b/cypress/integration/NewPage.feature index 21b3d996d8..85aaa709d3 100644 --- a/cypress/integration/NewPage.feature +++ b/cypress/integration/NewPage.feature @@ -178,6 +178,7 @@ Feature: User creates a new entries from the registration page Scenario: New person in Tracker Program > Submitting the form shows a list with duplicates Given you are in Child programme registration page When you fill the Child programme registration form with a first name with value that has duplicates + And you fill in the birth report date And you click the save person submit button And you see the possible duplicates modal When you click the next page button @@ -197,7 +198,7 @@ Feature: User creates a new entries from the registration page When you are in the Malaria case diagnosis, treatment and investigation program registration page And you fill the Malaria case diagnosis registration form with values And you click the save malaria entity submit button - Then you see the enrollment event New page + Then you see the enrollment event Edit page When you open the main page with Ngelehun and Malaria case diagnosis, treatment and investigation context And you opt out to use the new enrollment Dashboard for Malaria case diagnosis, treatment and investigation Then you see the opt in component for Malaria case diagnosis, treatment and investigation @@ -208,3 +209,7 @@ Feature: User creates a new entries from the registration page Given you are in Child programme reenrollment page Then you see the form prefield with existing TEI attributes values And the scope selector has the TEI context + + Scenario: First stage appears on registration page + Given you are in Child programme registration page + Then the first stage appears on registration page diff --git a/cypress/integration/NewPage/index.js b/cypress/integration/NewPage/index.js index 09046c7c65..4cc6af0afb 100644 --- a/cypress/integration/NewPage/index.js +++ b/cypress/integration/NewPage/index.js @@ -502,6 +502,13 @@ And('you fill the Child programme registration form with a first name with value .blur(); }); +And('you fill in the birth report date', () => { + cy.get('[data-test="capture-ui-input"]') + .eq(7) + .type('2023-01-01') + .blur(); +}); + And('you are in the WNCH PNC program registration page', () => { cy.visit('/#/new?programId=uy2gU8kT1jF&orgUnitId=DiszpKrYNg8'); }); @@ -561,12 +568,10 @@ And('you fill the Malaria case diagnosis registration form with values', () => { .blur(); }); -Then('you see the enrollment event New page', () => { - cy.url().should('include', '/#/enrollmentEventNew?'); - cy.url().should('include', 'stageId=hYyB7FUS5eR'); +Then('you see the enrollment event Edit page', () => { + cy.url().should('include', '/#/enrollmentEventEdit?'); }); - And('you fill in multiple Allergies options', () => { cy.get('[data-test="registration-page-content"]').within(() => { cy.contains('Allergies').should('exist'); @@ -585,3 +590,13 @@ Then('you can see the multiple selections in the form', () => { cy.contains('Other').should('exist'); }); }); + +Then('the first stage appears on registration page', () => { + cy.get('[data-test="registration-page-content"]').within(() => { + cy.contains('Birth - Basic info').should('exist'); + cy.contains('Birth - Details').should('exist'); + cy.contains('Birth - Status').should('exist'); + cy.contains('Report date').should('exist'); + cy.contains('Apgar Score').should('exist'); + }); +}); diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature index 8059bed14d..d3f07adfe2 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature @@ -159,9 +159,9 @@ 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 Smoking column header +When you click the WHOMCH Hemoglobin value column header Then the sort arrow should indicate descending order -And the list should display data ordered ascendingly by WHOMCH Smoking +And the list should display data ordered descending by WHOMCH Hemoglobin @v>=39 Scenario: The user can remove the program stage filter @@ -233,7 +233,7 @@ 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 the main page with Ngelehun and Malaria focus investigation context +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 diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js index 6426baf38c..7e5825c8a1 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js @@ -2,6 +2,19 @@ import { v4 as uuid } from 'uuid'; import '../../sharedSteps'; import '../../../sharedSteps'; +const cleanUpIfApplicable = (programId) => { + cy.buildApiUrl(`programStageWorkingLists?filter=program.id:eq:${programId}&fields=id,displayName`) + .then(url => cy.request(url)) + .then(({ body }) => { + const workingList = body.programStageWorkingLists?.find(e => e.displayName === 'Custom Program stage list'); + if (!workingList) { + return null; + } + return cy + .buildApiUrl('programStageWorkingLists', workingList.id) + .then(workingListUrl => cy.request('DELETE', workingListUrl)); + }); +}; Given('you open the main page with Ngelehun and child programme context', () => { cy.visit('#/?programId=IpHINAT79UW&orgUnitId=DiszpKrYNg8'); }); @@ -42,6 +55,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis context', }); Given('you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context', () => { + cleanUpIfApplicable('qDkgAbB5Jlk'); cy.visit('#/?programId=qDkgAbB5Jlk&orgUnitId=DiszpKrYNg8'); cy.get('[data-test="tei-working-lists"]') @@ -60,6 +74,11 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis and House .click(); }); +Given('you open a clean main page with Ngelehun and Malaria focus investigation context', () => { + cleanUpIfApplicable('M3xtLkYBlKI'); + cy.visit('#/?programId=M3xtLkYBlKI&orgUnitId=DiszpKrYNg8'); +}); + Then('the default working list should be displayed', () => { const names = [ 'Filona', @@ -343,9 +362,9 @@ When('you click the last name column header', () => { .click(); }); -When('you click the WHOMCH Smoking column header', () => { +When('you click the WHOMCH Hemoglobin value column header', () => { cy.get('[data-test="dhis2-uicore-tableheadercellaction"]') - .eq(6) + .last() .click() .click(); }); @@ -400,10 +419,10 @@ Then('the list should display data ordered ascendingly by last name', () => { }); }); -Then('the list should display data ordered ascendingly by WHOMCH Smoking', () => { +Then('the list should display data ordered descending by WHOMCH Hemoglobin', () => { const names = [ - 'Siren', 'Hertz', + 'Siren', ]; cy.get('[data-test="tei-working-lists"]') @@ -740,3 +759,4 @@ Then('the program stage custom working list filters are loaded', () => { .find('[data-test="more-filters"]') .should('have.length', 2); }); + diff --git a/i18n/ar.po b/i18n/ar.po index f8e252c635..5960f8ec4d 100644 --- a/i18n/ar.po +++ b/i18n/ar.po @@ -1,14 +1,14 @@ # # Translators: # KRG HIS , 2020 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Viktor Varland , 2023 # Hamza Assada <7amza.it@gmail.com>, 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Hamza Assada <7amza.it@gmail.com>, 2023\n" "Language-Team: Arabic (https://app.transifex.com/hisp-uio/teams/100509/ar/)\n" @@ -75,6 +75,16 @@ msgstr "تاريخ التسجيل" msgid "Last updated" msgstr "آخر تحديث" +msgid "error encountered during field validation" +msgstr "حدث خطأ أثناء التحقق من صحة الحقل" + +msgid "error" +msgstr "خطأ" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "يتم التحقق من القيمة" @@ -368,9 +378,6 @@ msgstr "لا تزال بعض العمليات قيد التشغيل. يرجى ا msgid "Operations running" msgstr "العمليات الجارية" -msgid "Sort" -msgstr "فرز" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -755,7 +762,7 @@ msgstr "المجدولة زمنياً" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -819,6 +826,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -972,15 +982,6 @@ msgstr "يمكنك أيضًا اختيار برنامج من الشريط الع msgid "Choose a type to start searching" msgstr "اختر نوعًا لبدء البحث" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - msgid "Search {{name}}" msgstr "البحث عن {{name}}" @@ -1135,6 +1136,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "اشر من أجل الملحق" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "تاريخ التسجيل" @@ -1223,32 +1227,12 @@ 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] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - 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] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1496,9 +1480,6 @@ msgstr "" msgid "Set coordinate" msgstr "ضبط الإحداثية" -msgid "Page {{currentPage}}" -msgstr "صفحة {{currentPage}}" - msgid "Date" msgstr "التاريخ" @@ -1517,11 +1498,8 @@ msgstr "حتى تاريخ" msgid "To time" msgstr "إلى وقت" -msgid "error encountered during field validation" -msgstr "حدث خطأ أثناء التحقق من صحة الحقل" - -msgid "error" -msgstr "خطأ" +msgid "Page {{currentPage}}" +msgstr "صفحة {{currentPage}}" msgid "Delete polygon" msgstr "حذف المضلع" diff --git a/i18n/ar_IQ.po b/i18n/ar_IQ.po index 7e6d0fde57..24c60620d7 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: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: KRG HIS , 2022\n" "Language-Team: Arabic (Iraq) (https://app.transifex.com/hisp-uio/teams/100509/ar_IQ/)\n" @@ -72,6 +72,16 @@ msgstr "" msgid "Last updated" msgstr "آخر تحديث" +msgid "error encountered during field validation" +msgstr "حدث خطأ أثناء التحقق من صحة الحقل" + +msgid "error" +msgstr "خطأ" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "يتم التحقق من القيمة" @@ -365,9 +375,6 @@ msgstr "لا تزال بعض العمليات قيد التشغيل. أرجو ا msgid "Operations running" msgstr "العمليات الجارية" -msgid "Sort" -msgstr "فرز" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -481,6 +488,12 @@ msgstr "تحميل الصورة" msgid "Select image" msgstr "حدد الصورة" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "البحث" @@ -746,7 +759,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -810,6 +823,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -963,15 +979,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - msgid "Search {{name}}" msgstr "" @@ -1124,6 +1131,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "تاريخ التسجيل" @@ -1212,32 +1222,12 @@ 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] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - 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] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1281,9 +1271,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "نموذج الكيان المتتبع" - msgid "Fix errors in the form to continue." msgstr "" @@ -1296,6 +1283,9 @@ msgstr "" msgid "Edit" msgstr "تعديل" +msgid "tracked entity instance" +msgstr "نموذج الكيان المتتبع" + msgid "New {{ eventName }} event" msgstr "" @@ -1485,9 +1475,6 @@ msgstr "" msgid "Set coordinate" msgstr "ضبط الإحداثية" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "التاريخ" @@ -1506,11 +1493,8 @@ msgstr "حتى تاريخ" msgid "To time" msgstr "إلى وقت" -msgid "error encountered during field validation" -msgstr "حدث خطأ أثناء التحقق من صحة الحقل" - -msgid "error" -msgstr "خطأ" +msgid "Page {{currentPage}}" +msgstr "" msgid "Delete polygon" msgstr "حذف المضلع" diff --git a/i18n/ckb.po b/i18n/ckb.po index 776a5d6003..8ad5dab62a 100644 --- a/i18n/ckb.po +++ b/i18n/ckb.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2022\n" "Language-Team: Central Kurdish (https://app.transifex.com/hisp-uio/teams/100509/ckb/)\n" @@ -74,6 +74,16 @@ msgstr "" msgid "Last updated" msgstr "" +msgid "error encountered during field validation" +msgstr "هەڵەیەک ڕوویدا لە کاتی سەلماندی خانەکە" + +msgid "error" +msgstr "هەڵە" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "ئەم نرخە دەسەلمێندرێت" @@ -373,9 +383,6 @@ msgstr "" msgid "Operations running" msgstr "کردارەکان کاردەکەن" -msgid "Sort" -msgstr "پۆلینکردن" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -489,6 +496,12 @@ msgstr "سەرخستنی وێنە" msgid "Select image" msgstr "وێنە هەڵبژێرە" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "گەڕان" @@ -754,7 +767,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -818,6 +831,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -973,11 +989,6 @@ msgstr "" msgid "Choose a type to start searching" 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 "Search {{name}}" msgstr "" @@ -1130,6 +1141,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "" @@ -1218,24 +1232,12 @@ 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 "" @@ -1279,9 +1281,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "نمونەی یەکەی بەدواداچوون" - msgid "Fix errors in the form to continue." msgstr "" @@ -1294,6 +1293,9 @@ msgstr "" msgid "Edit" msgstr "دةستكاري" +msgid "tracked entity instance" +msgstr "نمونەی یەکەی بەدواداچوون" + msgid "New {{ eventName }} event" msgstr "" @@ -1483,9 +1485,6 @@ msgstr "" msgid "Set coordinate" msgstr "هێڵی درێژی و پانی دیاریبکە" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "بەروار" @@ -1504,11 +1503,8 @@ msgstr "بۆ بەرواری" msgid "To time" msgstr " کاتی" -msgid "error encountered during field validation" -msgstr "هەڵەیەک ڕوویدا لە کاتی سەلماندی خانەکە" - -msgid "error" -msgstr "هەڵە" +msgid "Page {{currentPage}}" +msgstr "" msgid "Delete polygon" msgstr "فرەلاکە بسڕەوە" diff --git a/i18n/cs.po b/i18n/cs.po index dfa8f49095..e85d26ac5f 100644 --- a/i18n/cs.po +++ b/i18n/cs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Jiří Podhorecký, 2023\n" "Language-Team: Czech (https://app.transifex.com/hisp-uio/teams/100509/cs/)\n" @@ -379,9 +379,6 @@ msgstr "Některé operace stále běží. Prosím, čekejte.." msgid "Operations running" msgstr "Provoz běží" -msgid "Sort" -msgstr "Třídit" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -773,7 +770,7 @@ msgstr "Plán" msgid "Refer" msgstr "Odkazovat" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -1159,6 +1156,9 @@ msgstr "Odstranit značku pro další sledování" msgid "Mark for follow-up" msgstr "Označit pro další sledování" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Datum zápisu" @@ -1506,9 +1506,6 @@ msgstr "Chyba při úpravě události, provedené změny nebyly uloženy" msgid "Set coordinate" msgstr "Nastavit souřadnice" -msgid "Page {{currentPage}}" -msgstr "Stránka {{currentPage}}" - msgid "Date" msgstr "datum" @@ -1527,6 +1524,9 @@ msgstr "K datu" msgid "To time" msgstr "Na čas" +msgid "Page {{currentPage}}" +msgstr "Stránka {{currentPage}}" + msgid "Delete polygon" msgstr "Smazat polygon" diff --git a/i18n/en.pot b/i18n/en.pot index 6c3ad737be..2396905e88 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -149,6 +149,15 @@ msgstr "Coordinate" msgid "Enrollment" msgstr "Enrollment" +msgid "Complete event" +msgstr "Complete event" + +msgid "{{ stageName }} - Basic info" +msgstr "{{ stageName }} - Basic info" + +msgid "{{ stageName }} - Status" +msgstr "{{ stageName }} - Status" + msgid "Please select {{categoryName}}" msgstr "Please select {{categoryName}}" @@ -167,15 +176,18 @@ msgstr "Cancel" msgid "Metadata error. see log for details" msgstr "Metadata error. see log for details" +msgid "{{ stageName }} - Details" +msgstr "{{ stageName }} - Details" + +msgid "{{ stageName }} - {{ sectionName }}" +msgstr "{{ stageName }} - {{ sectionName }}" + msgid "Assigned user" msgstr "Assigned user" msgid "Search for user" msgstr "Search for user" -msgid "Complete event" -msgstr "Complete event" - msgid "Basic info" msgstr "Basic info" diff --git a/i18n/es.po b/i18n/es.po index 836149c137..b74921f8ef 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -3,22 +3,23 @@ # Sergio Valenzuela , 2020 # ericbp , 2021 # Jaime Bosque , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Gabriela Rodriguez , 2022 # Marta Vila , 2022 # Pablo Pajuelo Cabezas , 2022 -# Enzo Nicolas Rossi , 2023 # Viktor Varland , 2023 # Alison Andrade , 2023 # Janeth Cruz, 2023 # Prabhjot Singh, 2023 +# Christian Atavillos, 2023 +# Enzo Nicolas Rossi , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Prabhjot Singh, 2023\n" +"Last-Translator: Enzo Nicolas Rossi , 2023\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" @@ -93,6 +94,8 @@ msgstr "error" msgid "" "Plugins are not yet available - Please contact your system administrator" msgstr "" +"Los complementos plugin aún no están disponibles. Comuníquese con el " +"administrador del sistema." msgid "This value is validating" msgstr "Este valor está siendo validado" @@ -396,13 +399,13 @@ msgstr "Algunas operaciones aún se están ejecutando. Espere por favor.." msgid "Operations running" msgstr "Operaciones en ejecución" -msgid "Sort" -msgstr "Organizar" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" msgstr "" +"Este evento tiene cambios no guardados. Si abandona esta página sin guardar," +" se perderán estos cambios. ¿Está seguro de que desea descartar los cambios " +"no guardados?" msgid "No events to display" msgstr "No hay eventos para mostrar" @@ -617,13 +620,13 @@ msgid "Write comment" msgstr "Escribir comentario" msgid "was blanked out and hidden by your last action" -msgstr "" +msgstr "fue borrado y oculto por tu última acción" msgid "Notice" -msgstr "" +msgstr "Aviso" msgid "Close the notice" -msgstr "" +msgstr "cerrar el aviso" msgid "Use new Enrollment dashboard for {{programName}}" msgstr "Usar el nuevo panel de inscripción para {{programName}}" @@ -639,18 +642,30 @@ msgid "" "functionality in Capture is ongoing and will be added in upcoming app " "releases." msgstr "" +"Al hacer clic en registrarse a continuación, comenzará a utilizar el nuevo " +"panel de inscripción en la aplicación Capture para este programa. Por el " +"momento, hay ciertas funciones de la Tracker Capture que aún no se han " +"agregado, incluida la función de relación y referencia. El trabajo para " +"incluir esta funcionalidad Tracker en Capture está en curso y se agregará en" +" próximos lanzamientos de la aplicación." 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 "" +"El equipo de desarrollo agradece cualquier comentario sobre esta nueva " +"funcionalidad que actualmente se está probando en versión beta. Informe " +"cualquier problema y comentario en el proyecto de JIRA de DHIS2" 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 "" +"Haga clic en el botón de abajo para optar por la nueva funcionalidad del " +"panel de inscripción en la aplicación Capture (beta) para este programa " +"Tracker para todos los usuarios." msgid "Yes, opt in" msgstr "Sí, aceptar" @@ -796,8 +811,8 @@ msgstr "Programado" msgid "Refer" msgstr "Referir" -msgid "You can’t add any more {{ programStageName }} events" -msgstr "Nos e pueden agregar más eventos de {{ programStageName }}" +msgid "You can't add any more {{ programStageName }} events" +msgstr "" msgid "Cancel without saving" msgstr "Cancelar sin guardar" @@ -809,7 +824,7 @@ msgid "Program Stages could not be loaded" msgstr "No se pudieron cargar las etapas del programa" msgid "Stage" -msgstr "Fase" +msgstr "Etapa" msgid "Enrollment{{escape}} View Event" msgstr "Inscripción {{escape}} Ver evento" @@ -863,7 +878,7 @@ msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "Nueva inscripción en el programa{{escape}} {{programName}}" msgid "Save {{trackedEntityTypeName}}" -msgstr "" +msgstr "Guardar {{trackedEntityTypeName}}" msgid "Save {{trackedEntityName}}" msgstr "Guardar {{trackedEntityName}}" @@ -1009,7 +1024,7 @@ msgid "Choose a program" msgstr "Elija un programa" msgid "Search for {{titleText}}" -msgstr "Buscar para {{titleText}}" +msgstr "Buscar por {{titleText}}" msgid "Search for" msgstr "Buscar por" @@ -1030,7 +1045,7 @@ msgid "Search by {{name}}" msgstr "Buscar por {{name}}" msgid "Search by attributes" -msgstr "Buscar por atributos" +msgstr "Buscar por atributos de {{trackedEntityName}}" msgid "all programs" msgstr "todos los programas" @@ -1119,7 +1134,7 @@ msgid "New {{trackedEntityName}} in {{programName}}" msgstr "Nuevo {{trackedEntityName}} en {{programName}}" msgid "Search for a {{trackedEntityName}} in {{programName}}" -msgstr "Buscar un {{trackedEntityName}} en {{programName}}" +msgstr "Buscar un(a) {{trackedEntityName}} en {{programName}}" msgid "To work with the selected program," msgstr "Para trabajar con el programa seleccionado," @@ -1193,6 +1208,9 @@ msgstr "Elimina la marca para el seguimiento" msgid "Mark for follow-up" msgstr "Marcar para seguimiento" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Fecha de inscripción" @@ -1365,7 +1383,7 @@ msgid "New {{ eventName }} event" msgstr "Nuevo evento {{ eventName }}" msgid "To open this event, please wait until saving is complete" -msgstr "" +msgstr "Para abrir este evento, espere hasta que se complete el guardado." msgid "Show {{ rest }} more" msgstr "Mostrar más {{ resto }} " @@ -1433,13 +1451,13 @@ msgid "Choose a program stage to filter by {{label}}" msgstr "Elija una etapa del programa para filtrar por {{label}}" msgid "Active enrollments" -msgstr "" +msgstr "Inscripciones activas" msgid "Completed enrollments" -msgstr "" +msgstr "Inscripciónes completadas" msgid "Cancelled enrollments" -msgstr "" +msgstr "Inscripciones canceladas " msgid "Working list could not be updated" msgstr "No se pudo actualizar la lista de trabajo" @@ -1554,9 +1572,6 @@ msgstr "Error al editar el evento, no se guardaron los cambios realizados" msgid "Set coordinate" msgstr "Establecer coordenadas" -msgid "Page {{currentPage}}" -msgstr "Página {{currentPage}}" - msgid "Date" msgstr "Fecha" @@ -1575,6 +1590,9 @@ msgstr "A la fecha" msgid "To time" msgstr "Hasta la hora" +msgid "Page {{currentPage}}" +msgstr "Página {{currentPage}}" + msgid "Delete polygon" msgstr "Eliminar polígono" @@ -1582,7 +1600,7 @@ msgid "Set area" msgstr "Establecer área" msgid "Area on map saved" -msgstr "" +msgstr "Área en el mapa guardada" msgid "Compatibility mode" msgstr "Modo de compatibilidad" diff --git a/i18n/es_419.po b/i18n/es_419.po index 737f30c127..42247a9fcb 100644 --- a/i18n/es_419.po +++ b/i18n/es_419.po @@ -1,14 +1,14 @@ # # Translators: -# Enzo Nicolas Rossi , 2023 # Jaime Bosque , 2023 +# Enzo Nicolas Rossi , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Jaime Bosque , 2023\n" +"Last-Translator: Enzo Nicolas Rossi , 2023\n" "Language-Team: Spanish (Latin America) (https://app.transifex.com/hisp-uio/teams/100509/es_419/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -75,6 +75,16 @@ msgstr "Fecha de inscripción" msgid "Last updated" msgstr "Última actualización" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "Este valor está siendo validado" @@ -267,7 +277,7 @@ msgid "Go back to event without saving relationship" msgstr "Volver al evento sin guardar la relación" msgid "Discard unsaved changes?" -msgstr "" +msgstr "¿Descartar los cambios no guardados?" msgid "" "Leaving this page will discard the selections you made for a new " @@ -379,9 +389,6 @@ msgstr "Algunas operaciones aún se están ejecutando. Espere por favor.." msgid "Operations running" msgstr "Operaciones en ejecución" -msgid "Sort" -msgstr "Clasificar" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -495,6 +502,12 @@ msgstr "Cargando imagen" msgid "Select image" msgstr "Seleccionar imagen" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Buscar" @@ -770,7 +783,7 @@ msgstr "Programado" msgid "Refer" msgstr "Referir" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -836,6 +849,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "Nueva inscripción en el programa{{escape}} {{programName}}" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "Guardar {{trackedEntityName}}" @@ -989,12 +1005,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - msgid "Search {{name}}" msgstr "" @@ -1147,6 +1157,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Fecha de inscripción" @@ -1235,26 +1248,12 @@ 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] "" -msgstr[2] "" - 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] "" -msgstr[2] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1298,9 +1297,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1313,6 +1309,9 @@ msgstr "Perfil de {{TETName}} " msgid "Edit" msgstr "" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "Nuevo evento {{ eventName }}" @@ -1502,9 +1501,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "Fecha" @@ -1523,10 +1519,7 @@ msgstr "" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/fr.po b/i18n/fr.po index 5ef57aa537..c0ce1365e1 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -1,7 +1,7 @@ # # Translators: # Edem Kossi , 2022 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Karoline Tufte Lien , 2022 # tx_e2f_fr r25 , 2022 # Bram Piot , 2022 @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Yayra Gomado , 2023\n" "Language-Team: French (https://app.transifex.com/hisp-uio/teams/100509/fr/)\n" @@ -402,9 +402,6 @@ msgstr "Certaines opérations sont encore en cours. Veuillez patienter..." msgid "Operations running" msgstr "Opérations en cours" -msgid "Sort" -msgstr "Trier" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -804,7 +801,7 @@ msgstr "Planning" msgid "Refer" msgstr "Référer" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -1198,6 +1195,9 @@ msgstr "Supprimer le marquage pour suivi" msgid "Mark for follow-up" msgstr "Marquer pour suivi" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Date d'enrôlement" @@ -1559,9 +1559,6 @@ msgstr "" msgid "Set coordinate" msgstr "Définir les coordonnées" -msgid "Page {{currentPage}}" -msgstr "Page {{page en cours}}" - msgid "Date" msgstr "Date" @@ -1580,6 +1577,9 @@ msgstr "Date de fin" msgid "To time" msgstr "À" +msgid "Page {{currentPage}}" +msgstr "Page {{page en cours}}" + msgid "Delete polygon" msgstr "Supprimer polygone" diff --git a/i18n/id.po b/i18n/id.po index d370e1398a..c8da75e732 100644 --- a/i18n/id.po +++ b/i18n/id.po @@ -5,7 +5,7 @@ # Guardian Sanjaya , 2022 # Viktor Varland , 2022 # Untoro Dwi Raharjo , 2023 -# phil_dhis2, 2023 +# Philip Larsen Donnelly, 2023 # Aprisa Chrysantina , 2023 # Raja Fathurrahim, 2023 # Farida Sibuea , 2023 @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Farida Sibuea , 2023\n" "Language-Team: Indonesian (https://app.transifex.com/hisp-uio/teams/100509/id/)\n" @@ -81,6 +81,16 @@ msgstr "Tanggal pendaftaran" msgid "Last updated" msgstr "Terakhir diperbarui" +msgid "error encountered during field validation" +msgstr "kesalahan yang ditemui selama validasi bidang" + +msgid "error" +msgstr "kesalahan" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "Nilai ini memvalidasi" @@ -379,9 +389,6 @@ msgstr "Beberapa operasi masih berjalan. Mohon tunggu.." msgid "Operations running" msgstr "Operasi berjalan" -msgid "Sort" -msgstr "Urutkan" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -773,7 +780,7 @@ msgstr "Jadwal" msgid "Refer" msgstr "Merujuk" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -838,6 +845,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -995,10 +1005,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "Pilih jenis untuk mulai mencari" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" - msgid "Search {{name}}" msgstr "Telusuri {{nama}}" @@ -1157,6 +1163,9 @@ msgstr "Hapus tanda untuk ditindaklanjuti" msgid "Mark for follow-up" msgstr "Tandai untuk follow up" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Tanggal pendaftaran" @@ -1245,22 +1254,12 @@ 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] "" - msgid "after" msgstr "Setelah" msgid "before" msgstr "Sebelum" -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] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1508,9 +1507,6 @@ msgstr "" msgid "Set coordinate" msgstr "Tentukan koordinat" -msgid "Page {{currentPage}}" -msgstr "Halaman {{Halaman saat ini}}" - msgid "Date" msgstr "Tanggal" @@ -1529,11 +1525,8 @@ msgstr "Ke tanggal" msgid "To time" msgstr "Ke waktu" -msgid "error encountered during field validation" -msgstr "kesalahan yang ditemui selama validasi bidang" - -msgid "error" -msgstr "kesalahan" +msgid "Page {{currentPage}}" +msgstr "Halaman {{Halaman saat ini}}" msgid "Delete polygon" msgstr "Hapus poligon" diff --git a/i18n/km.po b/i18n/km.po index 410c983e2d..a36bcf4e1a 100644 --- a/i18n/km.po +++ b/i18n/km.po @@ -1,13 +1,13 @@ # # Translators: -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Viktor Varland , 2022 # channara rin, 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: channara rin, 2023\n" "Language-Team: Khmer (https://app.transifex.com/hisp-uio/teams/100509/km/)\n" @@ -68,6 +68,16 @@ msgstr "" msgid "Last updated" msgstr "បាន​ធ្វើ​បច្ចុប្បន្នភាព​ចុងក្រោយ" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -357,9 +367,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "តម្រៀប" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -744,7 +751,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -808,6 +815,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -961,10 +971,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" - msgid "Search {{name}}" msgstr "" @@ -1117,6 +1123,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "ថ្ងៃខែឆ្នាំចុះឈ្មោះ" @@ -1205,22 +1214,12 @@ 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] "" - 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] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1468,9 +1467,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "កាលបរិច្ឆេទ" @@ -1489,10 +1485,7 @@ msgstr "" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/lo.po b/i18n/lo.po index 768265b14c..96a462426d 100644 --- a/i18n/lo.po +++ b/i18n/lo.po @@ -1,6 +1,6 @@ # # Translators: -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Thuy Nguyen , 2022 # Viktor Varland , 2023 # Saysamone Sibounma, 2023 @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Saysamone Sibounma, 2023\n" "Language-Team: Lao (https://app.transifex.com/hisp-uio/teams/100509/lo/)\n" @@ -368,9 +368,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "Sort" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -755,7 +752,7 @@ msgstr "ກຳນົດເວລາ" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -1127,6 +1124,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "ໝາຍໄວ້ເພື່ອຕິດຕາມ" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "ວັນທີ່ລົງທະບຽນ" @@ -1468,9 +1468,6 @@ msgstr "" msgid "Set coordinate" msgstr "ຕັ້ງຄ່າເສັ້ນສະແດງ" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "ວັນທີ່" @@ -1489,6 +1486,9 @@ msgstr "ເຖີງວັນທີ່" msgid "To time" msgstr "" +msgid "Page {{currentPage}}" +msgstr "" + msgid "Delete polygon" msgstr "" diff --git a/i18n/my.po b/i18n/my.po index e9c710e301..370b8a7761 100644 --- a/i18n/my.po +++ b/i18n/my.po @@ -3,14 +3,14 @@ # Aung Kyi Min , 2019 # Viktor Varland , 2021 # Wanda , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-05-15T10:06:53.276Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: phil_dhis2, 2022\n" +"Last-Translator: Philip Larsen Donnelly, 2022\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" @@ -69,6 +69,16 @@ msgstr "" msgid "Last updated" msgstr "နောက်ဆုံး အသစ်ဆက်ဆက်" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -253,7 +263,7 @@ msgstr "" msgid "Go back to event without saving relationship" msgstr "" -msgid "Unsaved changes" +msgid "Discard unsaved changes?" msgstr "" msgid "" @@ -261,10 +271,10 @@ msgid "" "relationship" msgstr "" -msgid "Yes, discard" +msgid "Yes, discard changes" msgstr "" -msgid "No, stay here" +msgid "No, cancel" msgstr "" msgid "New event" @@ -334,21 +344,9 @@ msgstr "" msgid "Do you want to create another event?" msgstr "" -msgid "No, cancel" -msgstr "" - msgid "Yes, create new event" msgstr "" -msgid "Leaving this page will discard the changes you made to this event." -msgstr "" - -msgid "Warnings found" -msgstr "" - -msgid "Abort" -msgstr "" - msgid "Back to form" msgstr "" @@ -370,8 +368,10 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "မျိုးတူခြင်း စုပေါင်းသည်။" +msgid "" +"This event has unsaved changes. Leaving this page without saving will lose " +"these changes. Are you sure you want to discard unsaved changes?" +msgstr "" msgid "No events to display" msgstr "" @@ -481,6 +481,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "" @@ -577,12 +583,42 @@ msgstr "" msgid "Write comment" msgstr "" +msgid "was blanked out and hidden by your last action" +msgstr "" + +msgid "Notice" +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 "" @@ -716,7 +752,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -780,6 +816,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -828,196 +867,189 @@ msgstr "" msgid "Register" msgstr "" -msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} attributes to search" +msgid "Back" +msgstr "‌နောက်သို့ပြန်သွားသည်" + +msgid "events" msgstr "" -msgid "Search {{name}}" +msgid "event" msgstr "" -msgid "Search by {{name}}" +msgid "You don't have access to edit this event" msgstr "" -msgid "Search by attributes" +msgid "Edit event" msgstr "" -msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" +msgid "Event details" msgstr "" msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " -"search{{escape}} {{searchableAttributes}}" +"Leaving this page will discard any selections you made for a new " +"relationship" msgstr "" -msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" +msgid "No one is assigned to this event" msgstr "" -msgid "No results found" -msgstr "No results found" - -msgid "" -"You can change your search terms and search again to find what you are " -"looking for." +msgid "Assign" msgstr "" -msgid "Register a user" +msgid "Event assigned to {{name}}" msgstr "" -msgid "Back to search" +msgid "Feedbacks" msgstr "" -msgid "An error has occurred" +msgid "Show all events" msgstr "" -msgid "Too many results" +msgid "Event could not be loaded. Are you sure it exists?" msgstr "" -msgid "Cannot search in all programs" +msgid "Event could not be loaded" msgstr "" -msgid "Back" -msgstr "‌နောက်သို့ပြန်သွားသည်" - -msgid "Search for {{titleText}}" +msgid "Organisation unit could not be loaded" msgstr "" -msgid "Search for" +msgid "Possible duplicates found" msgstr "" -msgid "" -"You can also choose a program from the top bar and search in that program" -msgstr "" +msgid "No results found" +msgstr "No results found" -msgid "Choose a type to start searching" +msgid "An error occurred loading possible duplicates" msgstr "" -msgid "all programs" +msgid "You don't have access to delete this relationship" msgstr "" -msgid "" -"Not finding the results you were looking for? Try to search all programs " -"that use type " +msgid "You don't have access to create any relationships" msgstr "" -msgid "Search in all programs" +msgid "Add relationship" msgstr "" -msgid "If none of search results match, you can create a new " +msgid "No results found for " msgstr "" -msgid "Create new" +msgid "Registering unit" msgstr "" -msgid "Saved lists in this program" +msgid "Choose a registering unit" msgstr "" -msgid "Saved lists offer quick access to your most used views in a program." +msgid "Clear selection" msgstr "" -msgid "" -"There are no saved lists in this program yet, create one using the button " -"below." +msgid "No programs available." msgstr "" -msgid "Create saved list" +msgid "Search for a program" msgstr "" -msgid "events" +msgid "Some programs are being filtered by the chosen registering unit" msgstr "" -msgid "event" +msgid "Show all programs" msgstr "" -msgid "You don't have access to edit this event" +msgid "Choose a program" msgstr "" -msgid "Edit event" +msgid "Search for {{titleText}}" msgstr "" -msgid "Event details" +msgid "Search for" msgstr "" msgid "" -"Leaving this page will discard any selections you made for a new " -"relationship" -msgstr "" - -msgid "No one is assigned to this event" +"You can also choose a program from the top bar and search in that program" msgstr "" -msgid "Assign" +msgid "Choose a type to start searching" msgstr "" -msgid "Event assigned to {{name}}" +msgid "Search {{name}}" msgstr "" -msgid "Feedbacks" +msgid "Search by {{name}}" msgstr "" -msgid "Show all events" +msgid "Search by attributes" msgstr "" -msgid "Event could not be loaded. Are you sure it exists?" +msgid "all programs" msgstr "" -msgid "Event could not be loaded" +msgid "" +"Not finding the results you were looking for? Try to search all programs " +"that use type " msgstr "" -msgid "Organisation unit could not be loaded" +msgid "Search in all programs" msgstr "" -msgid "Possible duplicates found" +msgid "If none of search results match, you can create a new " msgstr "" -msgid "An error occurred loading possible duplicates" +msgid "Create new" msgstr "" -msgid "You don't have access to delete this relationship" +msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" msgstr "" -msgid "You don't have access to create any relationships" +msgid "" +"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " +"search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "Add relationship" +msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "No results found for " +msgid "" +"You can change your search terms and search again to find what you are " +"looking for." msgstr "" -msgid "Registering unit" +msgid "Back to search" msgstr "" -msgid "Choose a registering unit" +msgid "An error has occurred" msgstr "" -msgid "Clear selection" +msgid "Too many results" msgstr "" -msgid "No programs available." +msgid "Cannot search in all programs" msgstr "" -msgid "Search for a program" +msgid "Missing search criteria" msgstr "" -msgid "Some programs are being filtered by the chosen registering unit" +msgid "Results found" msgstr "" -msgid "Show all programs" +msgid "Selected program" msgstr "" -msgid "Choose a program" +msgid "Search {{uniqueAttrName}}" msgstr "" -msgid "Results found" +msgid "Saved lists in this program" msgstr "" -msgid "Selected program" +msgid "Saved lists offer quick access to your most used views in a program." msgstr "" -msgid "Search {{uniqueAttrName}}" +msgid "" +"There are no saved lists in this program yet, create one using the button " +"below." msgstr "" -msgid "Fill in at least {{minAttributesRequired}} attributes to search" +msgid "Create saved list" msgstr "" msgid "New {{trackedEntityName}} in {{programName}}" @@ -1092,6 +1124,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Дата зачисления" @@ -1180,22 +1215,12 @@ 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] "" - 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] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1239,9 +1264,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1254,10 +1276,13 @@ msgstr "" msgid "Edit" msgstr "တည်းဖြတ်သည်" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" -msgid "This event is not yet preserved and cannot be edited" +msgid "To open this event, please wait until saving is complete" msgstr "" msgid "Show {{ rest }} more" @@ -1308,6 +1333,9 @@ msgstr "" msgid "an error occurred loading working lists" msgstr "" +msgid "Assigned to" +msgstr "" + msgid "Registration Date" msgstr "စာရင်းသွင်းသော နေ့စွဲ" @@ -1317,10 +1345,16 @@ msgstr "" msgid "Enrollment status" msgstr "" -msgid "Assigned to" +msgid "Choose a program stage to filter by {{label}}" msgstr "" -msgid "Choose a program stage to filter by {{label}}" +msgid "Active enrollments" +msgstr "" + +msgid "Completed enrollments" +msgstr "" + +msgid "Cancelled enrollments" msgstr "" msgid "Working list could not be updated" @@ -1434,9 +1468,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "ရက်စွဲ" @@ -1455,10 +1486,7 @@ msgstr "နေ့စွဲ သို့" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" @@ -1467,5 +1495,8 @@ msgstr "" msgid "Set area" msgstr "" +msgid "Area on map saved" +msgstr "" + msgid "Compatibility mode" msgstr "" diff --git a/i18n/nb.po b/i18n/nb.po index 8839054d57..036767eb33 100644 --- a/i18n/nb.po +++ b/i18n/nb.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Karoline Tufte Lien , 2023\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/hisp-uio/teams/100509/nb/)\n" @@ -381,9 +381,6 @@ msgstr "Noen operasjoner kjører fortsatt. Vennligst vent.." msgid "Operations running" msgstr "Operasjoner kjører" -msgid "Sort" -msgstr "Sorter" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -776,7 +773,7 @@ msgstr "Planlegg" msgid "Refer" msgstr "Henvis" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -1160,6 +1157,9 @@ msgstr "Fjern merk for oppfølging" msgid "Mark for follow-up" msgstr "Merk for oppfølging" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Registreringsdato" @@ -1507,9 +1507,6 @@ msgstr "Feil under redigering av hendelsen, endringer ble ikke lagret" msgid "Set coordinate" msgstr "Sett koordinater" -msgid "Page {{currentPage}}" -msgstr "Side {{currentPage}}" - msgid "Date" msgstr "Dato" @@ -1528,6 +1525,9 @@ msgstr "Til dato" msgid "To time" msgstr "Til klokkeslett" +msgid "Page {{currentPage}}" +msgstr "Side {{currentPage}}" + msgid "Delete polygon" msgstr "Slett polygon" diff --git a/i18n/nl.po b/i18n/nl.po index 6d1c23709e..a8a6c3ffe5 100644 --- a/i18n/nl.po +++ b/i18n/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Charel van den Elsen, 2023\n" "Language-Team: Dutch (https://app.transifex.com/hisp-uio/teams/100509/nl/)\n" @@ -391,9 +391,6 @@ msgstr "Sommige operaties lopen nog. Even geduld aub.." msgid "Operations running" msgstr "Operaties lopen" -msgid "Sort" -msgstr "Soort" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -808,8 +805,8 @@ msgstr "Schema" msgid "Refer" msgstr "Refereren" -msgid "You can’t add any more {{ programStageName }} events" -msgstr "Je kunt geen {{ programStageNaam }} evenementen meer toevoegen" +msgid "You can't add any more {{ programStageName }} events" +msgstr "" msgid "Cancel without saving" msgstr "Annuleer zonder op te slaan" @@ -1205,6 +1202,9 @@ msgstr "Markering verwijderen voor vervolg" msgid "Mark for follow-up" msgstr "Markeer voor vervolg" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Inschrijvingsdatum" @@ -1563,9 +1563,6 @@ msgstr "" msgid "Set coordinate" msgstr "Coördinaat instellen" -msgid "Page {{currentPage}}" -msgstr "Pagina {{huidigePagina}}" - msgid "Date" msgstr "Datum" @@ -1584,6 +1581,9 @@ msgstr "Daten" msgid "To time" msgstr "Timen" +msgid "Page {{currentPage}}" +msgstr "Pagina {{huidigePagina}}" + msgid "Delete polygon" msgstr "Polygoon verwijderen" diff --git a/i18n/prs.po b/i18n/prs.po index bc61edb4c3..6bf95b4907 100644 --- a/i18n/prs.po +++ b/i18n/prs.po @@ -1,13 +1,13 @@ # # Translators: -# phil_dhis2, 2023 +# Philip Larsen Donnelly, 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: phil_dhis2, 2023\n" +"Last-Translator: Philip Larsen Donnelly, 2023\n" "Language-Team: Persian (Afghanistan) (https://app.transifex.com/hisp-uio/teams/100509/fa_AF/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -66,6 +66,16 @@ msgstr "تاریخ ثبت" msgid "Last updated" msgstr "تجدید آخیر" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -355,9 +365,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "تنظیم" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -471,6 +478,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "جستجو" @@ -736,7 +749,7 @@ msgstr "تقسیم اوقات" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -800,6 +813,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -953,11 +969,6 @@ msgstr "" msgid "Choose a type to start searching" 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 "Search {{name}}" msgstr "" @@ -1110,6 +1121,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "نشانی برای پیگیری" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "تاریخ شمولیت" @@ -1198,24 +1212,12 @@ 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 "" @@ -1259,9 +1261,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1274,6 +1273,9 @@ msgstr "" msgid "Edit" msgstr "تجدید" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" @@ -1463,9 +1465,6 @@ msgstr "" msgid "Set coordinate" msgstr "تعین مختصات" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "تاریخ" @@ -1484,10 +1483,7 @@ msgstr "تا تاریخ" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/pt.po b/i18n/pt.po index 5fa7e96cad..eb4e766806 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -1,7 +1,7 @@ # # Translators: # David Júnior , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Ge Joao , 2022 # Gabriela Rodriguez , 2022 # Viktor Varland , 2023 @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Sheila André , 2023\n" "Language-Team: Portuguese (https://app.transifex.com/hisp-uio/teams/100509/pt/)\n" @@ -389,9 +389,6 @@ msgstr "Algumas operações ainda estão em execução. Por favor, espere.." msgid "Operations running" msgstr "Operações em execução" -msgid "Sort" -msgstr "Ordenar" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -801,8 +798,8 @@ msgstr "Cronograma" msgid "Refer" msgstr "Referir" -msgid "You can’t add any more {{ programStageName }} events" -msgstr "Não pode adicionar mais eventos {{ programStageName }}" +msgid "You can't add any more {{ programStageName }} events" +msgstr "" msgid "Cancel without saving" msgstr "Cancelar sem gravar" @@ -1196,6 +1193,9 @@ msgstr "Remova a marca para acompanhamento" msgid "Mark for follow-up" msgstr "Marcar para acompanhamento" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Data de inscrição" @@ -1555,9 +1555,6 @@ msgstr "Erro ao editar o evento, as alterações feitas não foram gravadas" msgid "Set coordinate" msgstr "Definir coordenada" -msgid "Page {{currentPage}}" -msgstr "Página {{currentPage}}" - msgid "Date" msgstr "Encontro" @@ -1576,6 +1573,9 @@ msgstr "Até à data" msgid "To time" msgstr "Para o tempo" +msgid "Page {{currentPage}}" +msgstr "Página {{currentPage}}" + msgid "Delete polygon" msgstr "Excluir polígono" diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po index b87666a42c..0ec8fcac15 100644 --- a/i18n/pt_BR.po +++ b/i18n/pt_BR.po @@ -2,14 +2,14 @@ # Translators: # Oscar Mesones Lapouble , 2021 # Viktor Varland , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-05-15T10:06:53.276Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: phil_dhis2, 2022\n" +"Last-Translator: Philip Larsen Donnelly, 2022\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" @@ -68,6 +68,16 @@ msgstr "Data de Inscrição" msgid "Last updated" msgstr "Última actualização" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -252,7 +262,7 @@ msgstr "" msgid "Go back to event without saving relationship" msgstr "" -msgid "Unsaved changes" +msgid "Discard unsaved changes?" msgstr "" msgid "" @@ -260,10 +270,10 @@ msgid "" "relationship" msgstr "" -msgid "Yes, discard" +msgid "Yes, discard changes" msgstr "" -msgid "No, stay here" +msgid "No, cancel" msgstr "" msgid "New event" @@ -333,21 +343,9 @@ msgstr "" msgid "Do you want to create another event?" msgstr "" -msgid "No, cancel" -msgstr "" - msgid "Yes, create new event" msgstr "" -msgid "Leaving this page will discard the changes you made to this event." -msgstr "" - -msgid "Warnings found" -msgstr "" - -msgid "Abort" -msgstr "" - msgid "Back to form" msgstr "" @@ -369,8 +367,10 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "Ordenar" +msgid "" +"This event has unsaved changes. Leaving this page without saving will lose " +"these changes. Are you sure you want to discard unsaved changes?" +msgstr "" msgid "No events to display" msgstr "" @@ -480,6 +480,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Pesquisar" @@ -576,12 +582,42 @@ msgstr "" msgid "Write comment" msgstr "" +msgid "was blanked out and hidden by your last action" +msgstr "" + +msgid "Notice" +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 "" @@ -715,7 +751,7 @@ msgstr "Programar" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -779,6 +815,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -827,196 +866,189 @@ msgstr "" msgid "Register" msgstr "" -msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} attributes to search" -msgstr "" +msgid "Back" +msgstr "Voltar" -msgid "Search {{name}}" +msgid "events" msgstr "" -msgid "Search by {{name}}" +msgid "event" msgstr "" -msgid "Search by attributes" +msgid "You don't have access to edit this event" msgstr "" -msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" +msgid "Edit event" msgstr "" -msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " -"search{{escape}} {{searchableAttributes}}" +msgid "Event details" msgstr "" -msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" +msgid "" +"Leaving this page will discard any selections you made for a new " +"relationship" msgstr "" -msgid "No results found" +msgid "No one is assigned to this event" msgstr "" -msgid "" -"You can change your search terms and search again to find what you are " -"looking for." -msgstr "" +msgid "Assign" +msgstr "Atribuir" -msgid "Register a user" +msgid "Event assigned to {{name}}" msgstr "" -msgid "Back to search" +msgid "Feedbacks" msgstr "" -msgid "An error has occurred" +msgid "Show all events" msgstr "" -msgid "Too many results" +msgid "Event could not be loaded. Are you sure it exists?" msgstr "" -msgid "Cannot search in all programs" +msgid "Event could not be loaded" msgstr "" -msgid "Back" -msgstr "Voltar" - -msgid "Search for {{titleText}}" +msgid "Organisation unit could not be loaded" msgstr "" -msgid "Search for" +msgid "Possible duplicates found" msgstr "" -msgid "" -"You can also choose a program from the top bar and search in that program" +msgid "No results found" msgstr "" -msgid "Choose a type to start searching" +msgid "An error occurred loading possible duplicates" msgstr "" -msgid "all programs" +msgid "You don't have access to delete this relationship" msgstr "" -msgid "" -"Not finding the results you were looking for? Try to search all programs " -"that use type " +msgid "You don't have access to create any relationships" msgstr "" -msgid "Search in all programs" +msgid "Add relationship" msgstr "" -msgid "If none of search results match, you can create a new " +msgid "No results found for " msgstr "" -msgid "Create new" +msgid "Registering unit" msgstr "" -msgid "Saved lists in this program" +msgid "Choose a registering unit" msgstr "" -msgid "Saved lists offer quick access to your most used views in a program." +msgid "Clear selection" msgstr "" -msgid "" -"There are no saved lists in this program yet, create one using the button " -"below." +msgid "No programs available." msgstr "" -msgid "Create saved list" +msgid "Search for a program" msgstr "" -msgid "events" +msgid "Some programs are being filtered by the chosen registering unit" msgstr "" -msgid "event" +msgid "Show all programs" msgstr "" -msgid "You don't have access to edit this event" +msgid "Choose a program" msgstr "" -msgid "Edit event" +msgid "Search for {{titleText}}" msgstr "" -msgid "Event details" +msgid "Search for" msgstr "" msgid "" -"Leaving this page will discard any selections you made for a new " -"relationship" +"You can also choose a program from the top bar and search in that program" msgstr "" -msgid "No one is assigned to this event" +msgid "Choose a type to start searching" msgstr "" -msgid "Assign" -msgstr "Atribuir" - -msgid "Event assigned to {{name}}" +msgid "Search {{name}}" msgstr "" -msgid "Feedbacks" +msgid "Search by {{name}}" msgstr "" -msgid "Show all events" +msgid "Search by attributes" msgstr "" -msgid "Event could not be loaded. Are you sure it exists?" +msgid "all programs" msgstr "" -msgid "Event could not be loaded" +msgid "" +"Not finding the results you were looking for? Try to search all programs " +"that use type " msgstr "" -msgid "Organisation unit could not be loaded" +msgid "Search in all programs" msgstr "" -msgid "Possible duplicates found" +msgid "If none of search results match, you can create a new " msgstr "" -msgid "An error occurred loading possible duplicates" +msgid "Create new" msgstr "" -msgid "You don't have access to delete this relationship" +msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" msgstr "" -msgid "You don't have access to create any relationships" +msgid "" +"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " +"search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "Add relationship" +msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "No results found for " +msgid "" +"You can change your search terms and search again to find what you are " +"looking for." msgstr "" -msgid "Registering unit" +msgid "Back to search" msgstr "" -msgid "Choose a registering unit" +msgid "An error has occurred" msgstr "" -msgid "Clear selection" +msgid "Too many results" msgstr "" -msgid "No programs available." +msgid "Cannot search in all programs" msgstr "" -msgid "Search for a program" +msgid "Missing search criteria" msgstr "" -msgid "Some programs are being filtered by the chosen registering unit" +msgid "Results found" msgstr "" -msgid "Show all programs" +msgid "Selected program" msgstr "" -msgid "Choose a program" +msgid "Search {{uniqueAttrName}}" msgstr "" -msgid "Results found" +msgid "Saved lists in this program" msgstr "" -msgid "Selected program" +msgid "Saved lists offer quick access to your most used views in a program." msgstr "" -msgid "Search {{uniqueAttrName}}" +msgid "" +"There are no saved lists in this program yet, create one using the button " +"below." msgstr "" -msgid "Fill in at least {{minAttributesRequired}} attributes to search" +msgid "Create saved list" msgstr "" msgid "New {{trackedEntityName}} in {{programName}}" @@ -1091,6 +1123,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "" @@ -1179,26 +1214,12 @@ 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] "" -msgstr[2] "" - 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] "" -msgstr[2] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1242,9 +1263,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1257,10 +1275,13 @@ msgstr "" msgid "Edit" msgstr "Editar" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" -msgid "This event is not yet preserved and cannot be edited" +msgid "To open this event, please wait until saving is complete" msgstr "" msgid "Show {{ rest }} more" @@ -1311,6 +1332,9 @@ msgstr "" msgid "an error occurred loading working lists" msgstr "" +msgid "Assigned to" +msgstr "Atribuido a" + msgid "Registration Date" msgstr "Data do Registo" @@ -1320,12 +1344,18 @@ msgstr "" msgid "Enrollment status" msgstr "" -msgid "Assigned to" -msgstr "Atribuido a" - msgid "Choose a program stage to filter by {{label}}" msgstr "" +msgid "Active enrollments" +msgstr "" + +msgid "Completed enrollments" +msgstr "" + +msgid "Cancelled enrollments" +msgstr "" + msgid "Working list could not be updated" msgstr "" @@ -1437,9 +1467,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "Data" @@ -1458,10 +1485,7 @@ msgstr "Até à data" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" @@ -1470,5 +1494,8 @@ msgstr "" msgid "Set area" msgstr "" +msgid "Area on map saved" +msgstr "" + msgid "Compatibility mode" msgstr "" diff --git a/i18n/ro.po b/i18n/ro.po index 369ff6f464..c0eda2217d 100644 --- a/i18n/ro.po +++ b/i18n/ro.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Valeriu Plesca , 2022\n" "Language-Team: Romanian (https://app.transifex.com/hisp-uio/teams/100509/ro/)\n" @@ -73,6 +73,16 @@ msgstr "Data înrolării" msgid "Last updated" msgstr "Ultima actualizare" +msgid "error encountered during field validation" +msgstr "eroare întâlnită în timpul validării câmpului" + +msgid "error" +msgstr "eroare" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "Această valoare se validează" @@ -370,9 +380,6 @@ msgstr "Unele operațiuni sunt încă în desfășurare. Așteptați.." msgid "Operations running" msgstr "Operațiuni în derulare" -msgid "Sort" -msgstr "Sortare" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -486,6 +493,12 @@ msgstr "Încărcare imagine" msgid "Select image" msgstr "Selectați imaginea" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Căutare" @@ -751,7 +764,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -817,6 +830,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -972,12 +988,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - msgid "Search {{name}}" msgstr "Căutare {{name}}" @@ -1132,6 +1142,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Data înrolării" @@ -1220,26 +1233,12 @@ 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] "" -msgstr[2] "" - msgid "after" msgstr "după" msgid "before" msgstr "pînă la" -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] "" -msgstr[2] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1284,9 +1283,6 @@ msgid "Try again or contact your system administrator for support" msgstr "" "Încercați din nou sau contactați administratorul de sistem pentru asistență" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "Corectați erorile din formular pentru a continua." @@ -1299,6 +1295,9 @@ msgstr "" msgid "Edit" msgstr "Editare" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "Eveniment nou {{ eventName }}" @@ -1488,9 +1487,6 @@ msgstr "" msgid "Set coordinate" msgstr "Setarea coordonatelor" -msgid "Page {{currentPage}}" -msgstr "Pagina {{currentPage}}" - msgid "Date" msgstr "Data" @@ -1509,11 +1505,8 @@ msgstr "Până la data" msgid "To time" msgstr "Pînă la ora" -msgid "error encountered during field validation" -msgstr "eroare întâlnită în timpul validării câmpului" - -msgid "error" -msgstr "eroare" +msgid "Page {{currentPage}}" +msgstr "Pagina {{currentPage}}" msgid "Delete polygon" msgstr "Lichidare poligon" diff --git a/i18n/ru.po b/i18n/ru.po index fed0935162..fd40060b7b 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -2,14 +2,14 @@ # Translators: # Ulanbek Abakirov , 2020 # Wanda , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Valeriu Plesca , 2022 # Viktor Varland , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2023\n" "Language-Team: Russian (https://app.transifex.com/hisp-uio/teams/100509/ru/)\n" @@ -77,6 +77,16 @@ msgstr "Дата включения" msgid "Last updated" msgstr "Последнее обновление" +msgid "error encountered during field validation" +msgstr "Произошла ошибка во время валидации поля" + +msgid "error" +msgstr "ошибка" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "Идет валидация значения" @@ -378,9 +388,6 @@ msgstr "Некоторые операции еще не заверщены. По msgid "Operations running" msgstr "Операции запущены..." -msgid "Sort" -msgstr "Сортировать" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -494,6 +501,12 @@ msgstr "Передача изображения" msgid "Select image" msgstr "Выберите изображение" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Поиск" @@ -760,7 +773,7 @@ msgstr "Расписание" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -824,6 +837,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -979,13 +995,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - msgid "Search {{name}}" msgstr "Искать {{name}}" @@ -1138,6 +1147,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "Отметить для последующего наблюдения" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Дата зачисления" @@ -1226,28 +1238,12 @@ 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] "" -msgstr[2] "" -msgstr[3] "" - 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] "" -msgstr[2] "" -msgstr[3] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1291,9 +1287,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "Элемент отслеживаемого объекта" - msgid "Fix errors in the form to continue." msgstr "" @@ -1306,6 +1299,9 @@ msgstr "" msgid "Edit" msgstr "Редактировать" +msgid "tracked entity instance" +msgstr "Элемент отслеживаемого объекта" + msgid "New {{ eventName }} event" msgstr "" @@ -1495,9 +1491,6 @@ msgstr "" msgid "Set coordinate" msgstr "Выставить координату" -msgid "Page {{currentPage}}" -msgstr "Страница {{currentPage}}" - msgid "Date" msgstr "Дата" @@ -1516,11 +1509,8 @@ msgstr "До даты" msgid "To time" msgstr "ко времени" -msgid "error encountered during field validation" -msgstr "Произошла ошибка во время валидации поля" - -msgid "error" -msgstr "ошибка" +msgid "Page {{currentPage}}" +msgstr "Страница {{currentPage}}" msgid "Delete polygon" msgstr "Удалить полигон" diff --git a/i18n/si.po b/i18n/si.po index cd630b70ec..13abf7e784 100644 --- a/i18n/si.po +++ b/i18n/si.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Malinda Wijeratne, 2023\n" "Language-Team: Sinhala (https://app.transifex.com/hisp-uio/teams/100509/si/)\n" @@ -66,6 +66,16 @@ msgstr "" msgid "Last updated" msgstr "" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -355,9 +365,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "පෙළ ගස්වන්න" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -471,6 +478,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "සොයන්න" @@ -736,7 +749,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -800,6 +813,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -953,11 +969,6 @@ msgstr "" msgid "Choose a type to start searching" 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 "Search {{name}}" msgstr "" @@ -1110,6 +1121,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "" @@ -1198,24 +1212,12 @@ 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 "" @@ -1259,9 +1261,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1274,6 +1273,9 @@ msgstr "" msgid "Edit" msgstr "වෙනස් කරන්න" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" @@ -1463,9 +1465,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "දිනය" @@ -1484,10 +1483,7 @@ msgstr "" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/sv.po b/i18n/sv.po index a7adbe92ff..095c7c794d 100644 --- a/i18n/sv.po +++ b/i18n/sv.po @@ -1,14 +1,15 @@ # # Translators: -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Viktor Varland , 2023 +# Jason Pickering , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: Viktor Varland , 2023\n" +"Last-Translator: Jason Pickering , 2023\n" "Language-Team: Swedish (https://app.transifex.com/hisp-uio/teams/100509/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -67,6 +68,16 @@ msgstr "" msgid "Last updated" msgstr "" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -356,9 +367,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -472,6 +480,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "ingen matchning hittad" + msgid "Search" msgstr "Sök" @@ -737,7 +751,7 @@ msgstr "" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -801,6 +815,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -954,11 +971,6 @@ msgstr "" msgid "Choose a type to start searching" 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 "Search {{name}}" msgstr "" @@ -1111,6 +1123,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "inskrivning datum" @@ -1199,24 +1214,12 @@ 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 "" @@ -1260,9 +1263,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1275,6 +1275,9 @@ msgstr "" msgid "Edit" msgstr "Redigera" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" @@ -1318,7 +1321,7 @@ msgid "Download as XML" msgstr "" msgid "Download as CSV" -msgstr "" +msgstr "Ladda ner som CSV" msgid "Download with current filters" msgstr "" @@ -1464,9 +1467,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "Datum" @@ -1485,10 +1485,7 @@ msgstr "" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/tg.po b/i18n/tg.po index d92074a42d..6280c6636c 100644 --- a/i18n/tg.po +++ b/i18n/tg.po @@ -1,14 +1,14 @@ # # Translators: # Viktor Varland , 2022 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-05-15T10:06:53.276Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" -"Last-Translator: phil_dhis2, 2022\n" +"Last-Translator: Philip Larsen Donnelly, 2022\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" @@ -67,6 +67,16 @@ msgstr "Санаи номнавис" msgid "Last updated" msgstr "Навсозии охирин" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -251,7 +261,7 @@ msgstr "" msgid "Go back to event without saving relationship" msgstr "" -msgid "Unsaved changes" +msgid "Discard unsaved changes?" msgstr "" msgid "" @@ -259,10 +269,10 @@ msgid "" "relationship" msgstr "" -msgid "Yes, discard" +msgid "Yes, discard changes" msgstr "" -msgid "No, stay here" +msgid "No, cancel" msgstr "" msgid "New event" @@ -332,21 +342,9 @@ msgstr "" msgid "Do you want to create another event?" msgstr "" -msgid "No, cancel" -msgstr "" - msgid "Yes, create new event" msgstr "" -msgid "Leaving this page will discard the changes you made to this event." -msgstr "" - -msgid "Warnings found" -msgstr "" - -msgid "Abort" -msgstr "" - msgid "Back to form" msgstr "" @@ -368,8 +366,10 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "Ҷудокунӣ" +msgid "" +"This event has unsaved changes. Leaving this page without saving will lose " +"these changes. Are you sure you want to discard unsaved changes?" +msgstr "" msgid "No events to display" msgstr "" @@ -479,6 +479,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Ҷустуҷӯ" @@ -575,12 +581,42 @@ msgstr "" msgid "Write comment" msgstr "" +msgid "was blanked out and hidden by your last action" +msgstr "" + +msgid "Notice" +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 "" @@ -714,7 +750,7 @@ msgstr "Ҷадвал" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -778,6 +814,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -826,196 +865,189 @@ msgstr "" msgid "Register" msgstr "" -msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} attributes to search" -msgstr "" +msgid "Back" +msgstr "Ба қафо" -msgid "Search {{name}}" +msgid "events" msgstr "" -msgid "Search by {{name}}" +msgid "event" msgstr "" -msgid "Search by attributes" +msgid "You don't have access to edit this event" msgstr "" -msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" +msgid "Edit event" msgstr "" -msgid "" -"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " -"search{{escape}} {{searchableAttributes}}" +msgid "Event details" msgstr "" -msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" +msgid "" +"Leaving this page will discard any selections you made for a new " +"relationship" msgstr "" -msgid "No results found" +msgid "No one is assigned to this event" msgstr "" -msgid "" -"You can change your search terms and search again to find what you are " -"looking for." -msgstr "" +msgid "Assign" +msgstr "Таъин" -msgid "Register a user" +msgid "Event assigned to {{name}}" msgstr "" -msgid "Back to search" +msgid "Feedbacks" msgstr "" -msgid "An error has occurred" +msgid "Show all events" msgstr "" -msgid "Too many results" +msgid "Event could not be loaded. Are you sure it exists?" msgstr "" -msgid "Cannot search in all programs" +msgid "Event could not be loaded" msgstr "" -msgid "Back" -msgstr "Ба қафо" - -msgid "Search for {{titleText}}" +msgid "Organisation unit could not be loaded" msgstr "" -msgid "Search for" +msgid "Possible duplicates found" msgstr "" -msgid "" -"You can also choose a program from the top bar and search in that program" +msgid "No results found" msgstr "" -msgid "Choose a type to start searching" +msgid "An error occurred loading possible duplicates" msgstr "" -msgid "all programs" +msgid "You don't have access to delete this relationship" msgstr "" -msgid "" -"Not finding the results you were looking for? Try to search all programs " -"that use type " +msgid "You don't have access to create any relationships" msgstr "" -msgid "Search in all programs" +msgid "Add relationship" msgstr "" -msgid "If none of search results match, you can create a new " +msgid "No results found for " msgstr "" -msgid "Create new" +msgid "Registering unit" msgstr "" -msgid "Saved lists in this program" +msgid "Choose a registering unit" msgstr "" -msgid "Saved lists offer quick access to your most used views in a program." +msgid "Clear selection" msgstr "" -msgid "" -"There are no saved lists in this program yet, create one using the button " -"below." +msgid "No programs available." msgstr "" -msgid "Create saved list" +msgid "Search for a program" msgstr "" -msgid "events" +msgid "Some programs are being filtered by the chosen registering unit" msgstr "" -msgid "event" +msgid "Show all programs" msgstr "" -msgid "You don't have access to edit this event" +msgid "Choose a program" msgstr "" -msgid "Edit event" +msgid "Search for {{titleText}}" msgstr "" -msgid "Event details" +msgid "Search for" msgstr "" msgid "" -"Leaving this page will discard any selections you made for a new " -"relationship" +"You can also choose a program from the top bar and search in that program" msgstr "" -msgid "No one is assigned to this event" +msgid "Choose a type to start searching" msgstr "" -msgid "Assign" -msgstr "Таъин" - -msgid "Event assigned to {{name}}" +msgid "Search {{name}}" msgstr "" -msgid "Feedbacks" +msgid "Search by {{name}}" msgstr "" -msgid "Show all events" +msgid "Search by attributes" msgstr "" -msgid "Event could not be loaded. Are you sure it exists?" +msgid "all programs" msgstr "" -msgid "Event could not be loaded" +msgid "" +"Not finding the results you were looking for? Try to search all programs " +"that use type " msgstr "" -msgid "Organisation unit could not be loaded" +msgid "Search in all programs" msgstr "" -msgid "Possible duplicates found" +msgid "If none of search results match, you can create a new " msgstr "" -msgid "An error occurred loading possible duplicates" +msgid "Create new" msgstr "" -msgid "You don't have access to delete this relationship" +msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" msgstr "" -msgid "You don't have access to create any relationships" +msgid "" +"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " +"search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "Add relationship" +msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" msgstr "" -msgid "No results found for " +msgid "" +"You can change your search terms and search again to find what you are " +"looking for." msgstr "" -msgid "Registering unit" +msgid "Back to search" msgstr "" -msgid "Choose a registering unit" +msgid "An error has occurred" msgstr "" -msgid "Clear selection" +msgid "Too many results" msgstr "" -msgid "No programs available." +msgid "Cannot search in all programs" msgstr "" -msgid "Search for a program" +msgid "Missing search criteria" msgstr "" -msgid "Some programs are being filtered by the chosen registering unit" +msgid "Results found" msgstr "" -msgid "Show all programs" +msgid "Selected program" msgstr "" -msgid "Choose a program" +msgid "Search {{uniqueAttrName}}" msgstr "" -msgid "Results found" +msgid "Saved lists in this program" msgstr "" -msgid "Selected program" +msgid "Saved lists offer quick access to your most used views in a program." msgstr "" -msgid "Search {{uniqueAttrName}}" +msgid "" +"There are no saved lists in this program yet, create one using the button " +"below." msgstr "" -msgid "Fill in at least {{minAttributesRequired}} attributes to search" +msgid "Create saved list" msgstr "" msgid "New {{trackedEntityName}} in {{programName}}" @@ -1090,6 +1122,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Санаи номнавис" @@ -1178,24 +1213,12 @@ 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 "" @@ -1239,9 +1262,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1254,10 +1274,13 @@ msgstr "" msgid "Edit" msgstr "Таҳрир" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" -msgid "This event is not yet preserved and cannot be edited" +msgid "To open this event, please wait until saving is complete" msgstr "" msgid "Show {{ rest }} more" @@ -1308,6 +1331,9 @@ msgstr "" msgid "an error occurred loading working lists" msgstr "" +msgid "Assigned to" +msgstr "таъиншуда ба" + msgid "Registration Date" msgstr "Санаи бақайдгирӣ" @@ -1317,12 +1343,18 @@ msgstr "" msgid "Enrollment status" msgstr "" -msgid "Assigned to" -msgstr "таъиншуда ба" - msgid "Choose a program stage to filter by {{label}}" msgstr "" +msgid "Active enrollments" +msgstr "" + +msgid "Completed enrollments" +msgstr "" + +msgid "Cancelled enrollments" +msgstr "" + msgid "Working list could not be updated" msgstr "" @@ -1434,9 +1466,6 @@ msgstr "" msgid "Set coordinate" msgstr "" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "Сана" @@ -1455,10 +1484,7 @@ msgstr "То санаи" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" @@ -1467,5 +1493,8 @@ msgstr "" msgid "Set area" msgstr "" +msgid "Area on map saved" +msgstr "" + msgid "Compatibility mode" msgstr "" diff --git a/i18n/ur.po b/i18n/ur.po index e9b20d7c34..1165076415 100644 --- a/i18n/ur.po +++ b/i18n/ur.po @@ -1,12 +1,12 @@ # # Translators: -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Viktor Varland , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2023\n" "Language-Team: Urdu (https://app.transifex.com/hisp-uio/teams/100509/ur/)\n" @@ -67,6 +67,16 @@ msgstr "اندراج کی تاریخ" msgid "Last updated" msgstr "آخری اپ ڈیٹ" +msgid "error encountered during field validation" +msgstr "" + +msgid "error" +msgstr "" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "" @@ -356,9 +366,6 @@ msgstr "" msgid "Operations running" msgstr "" -msgid "Sort" -msgstr "ترتیب دیں" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -472,6 +479,12 @@ msgstr "" msgid "Select image" msgstr "" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "تلاش کریں" @@ -737,7 +750,7 @@ msgstr "شیڈول" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -801,6 +814,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -954,11 +970,6 @@ msgstr "" msgid "Choose a type to start searching" 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 "Search {{name}}" msgstr "" @@ -1111,6 +1122,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "اپ کے لئے نشان زد کریں" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "اندراج کی تاریخ" @@ -1199,24 +1213,12 @@ 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 "" @@ -1260,9 +1262,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "" - msgid "Fix errors in the form to continue." msgstr "" @@ -1275,6 +1274,9 @@ msgstr "" msgid "Edit" msgstr "ترمیم" +msgid "tracked entity instance" +msgstr "" + msgid "New {{ eventName }} event" msgstr "" @@ -1464,9 +1466,6 @@ msgstr "" msgid "Set coordinate" msgstr "ہم آہنگی مقرر کریں" -msgid "Page {{currentPage}}" -msgstr "" - msgid "Date" msgstr "تاریخ" @@ -1485,10 +1484,7 @@ msgstr "تاریخ تک" msgid "To time" msgstr "" -msgid "error encountered during field validation" -msgstr "" - -msgid "error" +msgid "Page {{currentPage}}" msgstr "" msgid "Delete polygon" diff --git a/i18n/uz.po b/i18n/uz_UZ_Cyrl.po similarity index 99% rename from i18n/uz.po rename to i18n/uz_UZ_Cyrl.po index 2165735667..3c0495f761 100644 --- a/i18n/uz.po +++ b/i18n/uz_UZ_Cyrl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Ibatov , 2023\n" "Language-Team: Uzbek (Cyrillic) (https://app.transifex.com/hisp-uio/teams/100509/uz@Cyrl/)\n" @@ -383,9 +383,6 @@ msgstr "Баъзи операциялар ҳали ҳам бажарилмоқд msgid "Operations running" msgstr "Амалиётлар бажарилмоқда" -msgid "Sort" -msgstr "Саралаш" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -777,7 +774,7 @@ msgstr "Режа" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -1159,6 +1156,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "Кузатув учун белгиланг" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Қайд этилган сана" @@ -1502,9 +1502,6 @@ msgstr "" msgid "Set coordinate" msgstr "Координатани ўрнатинг" -msgid "Page {{currentPage}}" -msgstr "{{currentPage}} саҳифаси" - msgid "Date" msgstr "Сана" @@ -1523,6 +1520,9 @@ msgstr "Шу кунгача" msgid "To time" msgstr "Шу вақтгача" +msgid "Page {{currentPage}}" +msgstr "{{currentPage}} саҳифаси" + msgid "Delete polygon" msgstr "Полигон (кўпбурчак) ни ўчириб ташлаш" diff --git a/i18n/uz_UZ_Latn.po b/i18n/uz_UZ_Latn.po new file mode 100644 index 0000000000..76fee00b45 --- /dev/null +++ b/i18n/uz_UZ_Latn.po @@ -0,0 +1,1529 @@ +# +# Translators: +# Yury Rogachev , 2023 +# +msgid "" +msgstr "" +"Project-Id-Version: i18next-conv\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" +"PO-Revision-Date: 2019-06-27 07:31+0000\n" +"Last-Translator: Yury Rogachev , 2023\n" +"Language-Team: Uzbek (Latin) (https://app.transifex.com/hisp-uio/teams/100509/uz@Latn/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uz@Latn\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "Choose one or more dates..." +msgstr "Bir yoki bir necha sanalarni tanlang..." + +msgid "Choose a date..." +msgstr "Sanani tanlang ..." + +msgid "Today" +msgstr "Bugun" + +msgid "" +"A possible reason for this is that the browser or mode (e.g. privacy mode) " +"is not supported. See log for details." +msgstr "" +"Buning mumkin boʼlgan sabablari quyidagilar; brauzer yoki rejim (masalan, " +"maxfiylik rejimi) qoʼllab quvvatlanmasligi. Tafsilotlar uchun jurnalga " +"qarang." + +msgid "" +"You opened another version of the Capture App in the same domain. Currently," +" the Capture App only supports running one version concurrently (in the same" +" domain). Please refresh this page if you would like to use this version " +"again, but be aware that this will close other versions." +msgstr "" +"Siz ayni shu domenda Nazorat Ilovasining boshqa versiyasini ochdingiz. " +"Hozirda Nazorat Ilovasi faqat bitta versiyani bir vaqtda (bir xil " +"ddomendagi) ishlashini qoʼllab quvvatlaydi. Ushbu versiyani qayta " +"ishlatmoqchi boʼlsangiz, Iltimos, sahifani yangilang, ammo boshqa versiyalar" +" yopilishini unutmang." + +msgid "View {{programName}} dashboard" +msgstr "" + +msgid "View dashboard" +msgstr "Boshqaruv panelini koʼrish" + +msgid "View active enrollment" +msgstr "Faol roʼyxatdan oʼtayotganlarni koʼrish" + +msgid "Re-enroll" +msgstr "Qayta roʼyxatdan oʼtish" + +msgid "in" +msgstr "ichida" + +msgid "Enrolled" +msgstr "Roʼyxatga kiritilgan" + +msgid "Previously enrolled" +msgstr "Ilgari roʼyxatga kiritilgan" + +msgid "Organisation unit" +msgstr "Tashkiliy birlik" + +msgid "Date of enrollment" +msgstr "Roʼyxatga kiritilgan sana" + +msgid "Last updated" +msgstr "Oxirgi yangilangan" + +msgid "error encountered during field validation" +msgstr "maydonni tekshirish vaqtida xatolik yuz berdi" + +msgid "error" +msgstr "xato" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + +msgid "This value is validating" +msgstr "Ushbu qiymat tasdiqlanmoqda" + +msgid "Async field update failed" +msgstr "Аsinxron maydon yangilanishi amalga oshmadi" + +msgid "A value is required" +msgstr "Qiymat talab qilinadi" + +msgid "Please provide a valid number" +msgstr "Iltimos, toʼgʼri raqamni koʼrsating" + +msgid "Please provide a valid integer" +msgstr "Iltimos, toʼgʼri butun sonni koʼrsating" + +msgid "Please provide a positive integer" +msgstr "Iltimos, butun musbat sonni koʼrsating" + +msgid "Please provide zero or a positive integer" +msgstr "Iltimos, Nol yoki butun musbat sonni koʼrsating" + +msgid "Please provide a negative integer" +msgstr "Iltimos, butun manfiy sonni koʼrsating" + +msgid "Please provide a valid date" +msgstr "Iltimos, toʼgʼri sanani koʼrsating" + +msgid "A date in the future is not allowed" +msgstr "Kelajakdagi sana qabul qilinmaydi" + +msgid "Please provide a valid date and time" +msgstr "Iltimos, tegishli sana va vaqtni koʼrsating" + +msgid "Please provide a valid time" +msgstr "Iltimos, toʼgʼri vaqtni koʼrsating" + +msgid "Please provide an integer between 0 and 100" +msgstr "" + +msgid "Please provide a valid url" +msgstr "Iltimos, haqiqiy URL manzilni koʼrsating" + +msgid "Please provide a valid email address" +msgstr "Iltimos, amaldagi ye-pochta manzilini koʼrsating" + +msgid "Please provide a valid age" +msgstr "Iltimos, toʼgʼri yoshni koʼrsating" + +msgid "Please provide a valid phone number" +msgstr "Iltimos, toʼgʼri telefon raqamini koʼrsating" + +msgid "Please provide a valid organisation unit" +msgstr "Iltimos, toʼgʼri tashkiliy boʼlimni koʼrsating" + +msgid "Please provide valid coordinates" +msgstr "Iltimos, toʼgʼri koordinatalarni koʼrsating" + +msgid "This value already exists" +msgstr "Bu qiymat allaqachon mavjud" + +msgid "\"From\" cannot be greater than \"To\"" +msgstr "Sana \"gacha\" katta boʼlishi mumkin emas sana \"dan\"" + +msgid "Checking..." +msgstr "Tekshirilmoqda..." + +msgid "Area" +msgstr "Maydon" + +msgid "Coordinate" +msgstr "Muvofiqlashtirish" + +msgid "Enrollment" +msgstr "Roʼyxatga olish" + +msgid "Please select {{categoryName}}" +msgstr "" + +msgid "A future date is not allowed" +msgstr "Kelajakdagi sana tanloviga ruxsat berilmaydi" + +msgid "Saving a new enrollment in {{programName}} in {{orgUnitName}}." +msgstr "" + +msgid "Saving a {{trackedEntityName}} in {{programName}} in {{orgUnitName}}." +msgstr "" + +msgid "Cancel" +msgstr "Bekor qilish" + +msgid "Metadata error. see log for details" +msgstr "MetaMaʼlumotda xatolik. Tafsilotlar uchun jurnalga qarang." + +msgid "Assigned user" +msgstr "Tavsiya etilgan foydalanuvchi" + +msgid "Search for user" +msgstr "Foydalanuvchini izlash" + +msgid "Complete event" +msgstr "" + +msgid "Basic info" +msgstr "Аsosiy maʼlumot" + +msgid "Status" +msgstr "Status" + +msgid "Comments" +msgstr "Izohlar" + +msgid "Relationships" +msgstr "Oʼzaro aloqalar" + +msgid "Assignee" +msgstr "Vakolat berilgan shaxs" + +msgid "Saving to {{programName}} in {{orgUnitName}}" +msgstr "" + +msgid "" +"This is not an event program or the metadata is corrupt. See log for " +"details." +msgstr "" +"Bu hodisa/tadbir dasturi emas yoki metamaʼlumotlar buzilgan. Tafsilotlar " +"uchun jurnalga qarang." + +msgid "This event" +msgstr "Ushbu hodisa/tadbir" + +msgid "" +"Relationship of type {{relationshipTypeName}} to {{entityName}} already " +"exists" +msgstr "" +"{{relationshipTypeName}} turining {{entityName}} bilan aloqasi allaqachon " +"mavjud" + +msgid "Active" +msgstr "Faol" + +msgid "Completed" +msgstr "Toʼldirildi" + +msgid "Please add or cancel comment before saving the event" +msgstr "" +"Iltimos, hodisa/tadbirni saqlashdan oldin sharh yozing yoki bekor qiling" + +msgid "Save and add another" +msgstr "Saqlash va boshqasini qoʼshish" + +msgid "Save and exit" +msgstr "Saqlash va chiqish" + +msgid "Finish" +msgstr "Tugatish" + +msgid "Save without completing" +msgstr "" + +msgid "Complete" +msgstr "Toʼldirish" + +msgid "No write access" +msgstr "Yozuv kiritish uchun ruxsat yoʼq" + +msgid "New {{titleText}}" +msgstr "" + +msgid "Switch to form view" +msgstr "Shakl koʼrinishiga oʼtish" + +msgid "Switch to row view" +msgstr "Jadval koʼrinishiga oʼtish" + +msgid "events added" +msgstr "hodisa/tadbirlar qoʼshildi" + +msgid "No events added" +msgstr "Hech qanday hodisa/tadbir qoʼshilmagan" + +msgid "New event relationship" +msgstr "Yangi hodisa/tadbir munosabatlari" + +msgid "Adding relationship to event." +msgstr "Hodisa/tadbirga aloqa-munosabatlar qoʼshish" + +msgid "Go back to event without saving relationship" +msgstr "Аloqa-munosabatlarni saqlamasdan hodisa/tadbirga qaytish" + +msgid "Discard unsaved changes?" +msgstr "Saqlanmagan oʼzgarishlar bekor qilinsinmi?" + +msgid "" +"Leaving this page will discard the selections you made for a new " +"relationship" +msgstr "" +"Ushbu sahifani tark etsangiz, yangi munosabatlar uchun qilgan tanlovingiz " +"bekor qilinadi." + +msgid "Yes, discard changes" +msgstr "" + +msgid "No, cancel" +msgstr "Yoʼq, bekor qiling" + +msgid "New event" +msgstr "Yangi hodisa" + +msgid "You don't have access to create an event in the current selections" +msgstr "" + +msgid "Save" +msgstr "Saqlash" + +msgid "Saving a {{trackedEntityName}}" +msgstr "" + +msgid "without" +msgstr "" + +msgid "enrollment" +msgstr "" + +msgid "Enroll in a program by selecting a program from the top bar." +msgstr "" + +msgid "An error has occurred. See log for details" +msgstr "Xatolik yuz berdi. Tafsilotlar uchun jurnalga qarang" + +msgid "A duplicate exists (but there were some errors, see log for details" +msgstr "" +"Ikki nusxasi mavjud (lekin xatolar boʼlgan, batafsil maʼlumot uchun jurnalga" +" qarang" + +msgid "" +"An item with this {{attributeName}} is already registered, but you don't " +"have access to it" +msgstr "" +"Ushbu {{attributeName}} element allaqachon roʼyxatdan oʼtgan, ammo siz unga " +"kirish huquqiga ega emassiz" + +msgid "You have already registered this {{attributeName}}" +msgstr "Siz allaqachon {{attributeName}} da roʼyxatdan oʼtgansiz" + +msgid "" +"A {{trackedEntityTypeName}} with this {{attributeName}} is already " +"registered" +msgstr "" +"{{trackedEntityTypeName}} ushbu {{attributeName}} bilan allaqachon " +"roʼyxatdan oʼtgan" + +msgid "Show registered {{trackedEntityTypeName}}" +msgstr "Roʼyxatdan oʼtgan {{trackedEntityTypeName}} ni koʼrsatish" + +msgid "Registered person" +msgstr "Roʼyxatdan oʼtgan shaxs" + +msgid "validation failed" +msgstr "Tasdiqlash amalga oshmadi" + +msgid "Errors" +msgstr "Xatoliklar" + +msgid "Feedback" +msgstr "Qayta aloqa" + +msgid "Indicators" +msgstr "Indikatorlar" + +msgid "Warnings" +msgstr "Ogohlantirishlar" + +msgid "Generate new event" +msgstr "Yangi hodisa/tadbir yaratish" + +msgid "Do you want to create another event?" +msgstr "Haqiqatdan ham boshqa hodisa/tadbir yaratmoqchimisiz?" + +msgid "Yes, create new event" +msgstr "" + +msgid "Back to form" +msgstr "Shaklga qaytish" + +msgid "Save anyway" +msgstr "Nima boʼlganda ham saqlash" + +msgid "Validation errors and warnings" +msgstr "Tasdiqlash xatoliklari va ogohlantirishlari" + +msgid "Validation errors" +msgstr "Tasdiqlashda xatoliklar" + +msgid "Validation warnings" +msgstr "Tasdiqlash toʼgʼrisida ogohlantirishlar" + +msgid "Some operations are still runnning. Please wait.." +msgstr "Baʼzi operatsiyalar hali ham bajarilmoqda. Iltimos, kuting ..." + +msgid "Operations running" +msgstr "Аmaliyotlar bajarilmoqda" + +msgid "" +"This event has unsaved changes. Leaving this page without saving will lose " +"these changes. Are you sure you want to discard unsaved changes?" +msgstr "" + +msgid "No events to display" +msgstr "Koʼrsatiladigan hech qanday hodisa/tadbir yoʼq" + +msgid "Data for offline list not present" +msgstr "Offlayn roʼyxat uchun maʼlumotlar mavjud emas" + +msgid "Close" +msgstr "Yopmoq" + +msgid "Please select the user" +msgstr "Iltimos, foydalanuvchini tanlang" + +msgid "Me" +msgstr "Men" + +msgid "Anyone" +msgstr "Kimdir" + +msgid "None" +msgstr "Yoʼq" + +msgid "Select user" +msgstr "Foydalanuvchini tanlang" + +msgid "to" +msgstr "ga" + +msgid "Days in the future" +msgstr "" + +msgid "From" +msgstr "Dan" + +msgid "Days in the past" +msgstr "" + +msgid "To" +msgstr "Kimga" + +msgid "This week" +msgstr "Ushbu hafta" + +msgid "This month" +msgstr "Ushbu oy" + +msgid "This Year" +msgstr "" + +msgid "Last week" +msgstr "Oxirgi hafta" + +msgid "Last month" +msgstr "Oxirgi oy" + +msgid "Last 3 months" +msgstr "Oxirgi 3 oy" + +msgid "Absolute range" +msgstr "" + +msgid "Relative range" +msgstr "" + +msgid "Max" +msgstr "Maksimum" + +msgid "Min" +msgstr "Minimum" + +msgid "Contains text" +msgstr "Matnni oʼz ichiga oladi" + +msgid "Yes" +msgstr "Ha" + +msgid "mm/dd/yyyy" +msgstr "kun/oy/yil" + +msgid "Years" +msgstr "Yillar" + +msgid "Months" +msgstr "Oylar" + +msgid "Days" +msgstr "Kunlar" + +msgid "Uploading file" +msgstr "Fayl yuklanmoqda" + +msgid "selected" +msgstr "tanlangan" + +msgid "Delete" +msgstr "Oʼchirib tashlash" + +msgid "Select file" +msgstr "Faylni tanlash" + +msgid "No" +msgstr "Yoʼq" + +msgid "Uploading image" +msgstr "Rasm yuklanmoqda" + +msgid "Select image" +msgstr "Rasmni tanlang" + +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + +msgid "Search" +msgstr "Izlash" + +msgid "Clear" +msgstr "Tozalash" + +msgid "No results" +msgstr "Natija yoʼq" + +msgid "Description" +msgstr "Tavsif" + +msgid "URL" +msgstr "URL" + +msgid "Icon for {{field}}" +msgstr "" + +msgid "start typing to search" +msgstr "qidirish uchun yozishni boshlang" + +msgid "suggestions could not be retrieved" +msgstr "takliflar qabul qilinmadi" + +msgid "No items to display" +msgstr "Koʼrsatiladigan axborot yoʼq" + +msgid "Select columns" +msgstr "Ustunlarni tanlang" + +msgid "Columns to show in table" +msgstr "Jadvalda koʼrsatiladigan ustunlar" + +msgid "Column" +msgstr "Ustun" + +msgid "Update" +msgstr "Янгилаш" + +msgid "Reset filter" +msgstr "" + +msgid "Remove filter" +msgstr "Filtrni olib tashlash" + +msgid "{{fromDate}} to {{toDate}}" +msgstr "{{fromDate}} dan {{toDate}} ga" + +msgid "after or equal to {{date}}" +msgstr "{{date}} dan keyin yoki unga teng" + +msgid "before or equal to {{date}}" +msgstr "{{date}} dan oldin yoki unga teng" + +msgid "greater than or equal to" +msgstr "dan katta yoki teng" + +msgid "less than or equal to" +msgstr "dan kam yoki teng" + +msgid "More filters" +msgstr "Koʼproq Filtr" + +msgid "Stage filters" +msgstr "" + +msgid "Rows per page" +msgstr "Sahifada qatorlar" + +msgid "Could not get organisation unit" +msgstr "Tashkiliy boʼlimni olib boʼlmadi" + +msgid "Program doesn't exist" +msgstr "Dastur mavjud emas" + +msgid "Selected program is invalid for selected registering unit" +msgstr "" +"Tanlangan dastur tanlangan roʼyxatdan olinadigan boʼlim uchun yaroqsiz" + +msgid "Online" +msgstr "Onlayn" + +msgid "Offline" +msgstr "Offlayn" + +msgid "Syncing" +msgstr "Sinxronlashmoqda" + +msgid "Add comment" +msgstr "Izoh qoʼshish" + +msgid "You don't have access to write comments" +msgstr "" + +msgid "Write comment" +msgstr "Fikr yozing" + +msgid "was blanked out and hidden by your last action" +msgstr "" + +msgid "Notice" +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 "Tracked entity instance with id \"{{teiId}}\" does not exist" +msgstr "" + +msgid "" +"There is an error while opening this enrollment. Please enter a valid url." +msgstr "" + +msgid "" +"An error occurred while fetching enrollments. Please enter a valid url." +msgstr "" + +msgid "Enrollment Dashboard" +msgstr "" + +msgid "No indicator output for this enrollment yet" +msgstr "" + +msgid "No feedback for this enrollment yet" +msgstr "" + +msgid "Quick actions" +msgstr "" + +msgid "New Event" +msgstr "" + +msgid "Schedule an event" +msgstr "" + +msgid "Make referral" +msgstr "Yoʼnalish yarating" + +msgid "No available program stages" +msgstr "" + +msgid "Program stage not found" +msgstr "" + +msgid "" +"Choose a program to add new or see existing enrollments for " +"{{teiDisplayName}}" +msgstr "" + +msgid "" +"{{programName}} has categories. Choose all categories to view dashboard." +msgstr "" + +msgid "Invalid enrollment id {{enrollmentId}}." +msgstr "" + +msgid "Choose an enrollment to view the dashboard." +msgstr "" + +msgid "There are no active enrollments." +msgstr "" + +msgid "Add new enrollment for {{teiDisplayName}} in this program." +msgstr "" + +msgid "No access to program owner." +msgstr "" + +msgid "{{teiDisplayName}} is not enrolled in this program." +msgstr "" + +msgid "Enroll {{teiDisplayName}} in this program." +msgstr "" + +msgid "" +"{{teiDisplayName}} is a {{tetName}} and cannot be enrolled in the " +"{{programName}}. Choose another program that allows {{tetName}} enrollment. " +msgstr "" + +msgid "Enroll a new {{selectedTetName}} in this program." +msgstr "" + +msgid "{{programName}} is an event program and does not have enrollments." +msgstr "" + +msgid "Create a new event in this program." +msgstr "" + +msgid "View working list in this program." +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 "" + +msgid "There was an error opening the Page" +msgstr "" + +msgid "Enrollment{{escape}} New Event" +msgstr "" + +msgid "There was an error loading the page" +msgstr "" + +msgid "Choose a registering unit to start reporting" +msgstr "Xisobot boshlash uchun roʼyxatdan oʼtishni tanlang" + +msgid "There are no feedbacks for this event" +msgstr "" + +msgid "There are no indicators for this event" +msgstr "" + +msgid "Program stage is invalid" +msgstr "" + +msgid "Report" +msgstr "Hisobot" + +msgid "Schedule" +msgstr "Reja" + +msgid "Refer" +msgstr "" + +msgid "You can't add any more {{ programStageName }} events" +msgstr "" + +msgid "Cancel without saving" +msgstr "" + +msgid "Choose a stage for a new event" +msgstr "" + +msgid "Program Stages could not be loaded" +msgstr "" + +msgid "Stage" +msgstr "Босқич" + +msgid "Enrollment{{escape}} View Event" +msgstr "" + +msgid "Enrollment{{escape}} Edit Event" +msgstr "" + +msgid "The enrollment event data could not be found" +msgstr "" + +msgid "There are no feedback for this event" +msgstr "" + +msgid "Registered events" +msgstr "Roʼyxatdan oʼtgan hodisa/tadbirlar" + +msgid "Please select {{category}}." +msgstr "" + +msgid "Or see all records accessible to you in {{program}} " +msgstr "" + +msgid "Or see all events accessible to you in {{program}}" +msgstr "" + +msgid "Please select an organisation unit." +msgstr "" + +msgid "New" +msgstr "Yangi" + +msgid "Choose the {{missingCategories}} to start reporting" +msgstr "" + +msgid "Save as new" +msgstr "" + +msgid "View enrollment" +msgstr "" + +msgid "Create for" +msgstr "" + +msgid "" +"You can also choose a program from the top bar and create in that program" +msgstr "" + +msgid "New Enrollment in program{{escape}} {{programName}}" +msgstr "" + +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + +msgid "Save {{trackedEntityName}}" +msgstr "" + +msgid "Save new {{trackedEntityTypeName}} and link" +msgstr "" + +msgid "Link" +msgstr "Havola" + +msgid "Save as new {{trackedEntityName}}" +msgstr "" + +msgid "Some programs are being filtered." +msgstr "Baʼzi dasturlar Filtrlanmoqda." + +msgid "Show all" +msgstr "Barchaga koʼrsatish" + +msgid "Program" +msgstr "Programma" + +msgid "Organisation Unit" +msgstr "Tashkiliy birlik" + +msgid "Registration" +msgstr "Roʼyxatdan oʼtish" + +msgid "Search results" +msgstr "Qidiruv natijalari" + +msgid "No {{trackedEntityTypeName}} found." +msgstr "Hech qanday {{trackedEntityTypeName}} topilmadi" + +msgid "New search" +msgstr "Yangi qidiruv" + +msgid "Edit search" +msgstr "Qidiruvni tahrirlash" + +msgid "Link to an existing {{trackedEntityType}}" +msgstr "Mavjud {{trackedEntityType}} ga havola" + +msgid "Create new {{trackedEntityType}}" +msgstr "Yangi {{trackedEntityType}} yaratish" + +msgid "Register" +msgstr "Roʼyxatga olish" + +msgid "Back" +msgstr "Orqaga" + +msgid "events" +msgstr "" + +msgid "event" +msgstr "" + +msgid "You don't have access to edit this event" +msgstr "" + +msgid "Edit event" +msgstr "Hodisa/tadbirni tahrirlang" + +msgid "Event details" +msgstr "" + +msgid "" +"Leaving this page will discard any selections you made for a new " +"relationship" +msgstr "" +"Ushbu sahifani tark etsangiz, yangi aloqa-munosabatlar uchun qilingan barcha" +" tanlovlar bekor qilinadi" + +msgid "No one is assigned to this event" +msgstr "Ushbu hodisa/tadbirga hech kim biriktirilmagan" + +msgid "Assign" +msgstr "Tayinlangan" + +msgid "Event assigned to {{name}}" +msgstr "Hodisa/tadbir {{name}} ga biriktirildi" + +msgid "Feedbacks" +msgstr "Qayta aloqalar" + +msgid "Show all events" +msgstr "Barcha hodisa/tadbirlarni koʼrsatish" + +msgid "Event could not be loaded. Are you sure it exists?" +msgstr "" +"Hodisa/tadbirni yuklab boʼlmadi. Uning mavjudligiga ishonchingiz komilmi?" + +msgid "Event could not be loaded" +msgstr "Hodisa/tadbirni yuklab boʼlmadi" + +msgid "Organisation unit could not be loaded" +msgstr "Tashkiliy boʼlimni yuklab boʼlmadi" + +msgid "Possible duplicates found" +msgstr "Boʼlishi mumkin boʼlgan nusxalar topildi" + +msgid "No results found" +msgstr "Hech qanday natija topilmadi" + +msgid "An error occurred loading possible duplicates" +msgstr "" + +msgid "You don't have access to delete this relationship" +msgstr "" + +msgid "You don't have access to create any relationships" +msgstr "" + +msgid "Add relationship" +msgstr "Oʼzaro aloqa kiritish" + +msgid "No results found for " +msgstr "" + +msgid "Registering unit" +msgstr "Roʼyxatga olish muassasasi" + +msgid "Choose a registering unit" +msgstr "" + +msgid "Clear selection" +msgstr "" + +msgid "No programs available." +msgstr "Hech qanday dastur mavjud emas." + +msgid "Search for a program" +msgstr "" + +msgid "Some programs are being filtered by the chosen registering unit" +msgstr "" + +msgid "Show all programs" +msgstr "" + +msgid "Choose a program" +msgstr "" + +msgid "Search for {{titleText}}" +msgstr "" + +msgid "Search for" +msgstr "Qidirish" + +msgid "" +"You can also choose a program from the top bar and search in that program" +msgstr "" +"Bundan tashqari, yuqori satrda dasturni tanlashingiz va ushbu dastur ichida " +"qidirishingiz mumkin" + +msgid "Choose a type to start searching" +msgstr "Qidiruv turini tanlang va qidirishni boshlang" + +msgid "Search {{name}}" +msgstr "{{name}} orqali qidirish" + +msgid "Search by {{name}}" +msgstr "" + +msgid "Search by attributes" +msgstr "Аtribut orqali qidirish" + +msgid "all programs" +msgstr "" + +msgid "" +"Not finding the results you were looking for? Try to search all programs " +"that use type " +msgstr "" + +msgid "Search in all programs" +msgstr "Barcha dasturlarda qidirish" + +msgid "If none of search results match, you can create a new " +msgstr "" + +msgid "Create new" +msgstr "Yangisini yaratish" + +msgid "Fill in these fields to search{{escape}} {{ searchableAttributes }}" +msgstr "" + +msgid "" +"Fill in at least {{minAttributesRequiredToSearch}} of these fields to " +"search{{escape}} {{searchableAttributes}}" +msgstr "" + +msgid "Fill in this field to search{{escape}} {{searchableAttributes}}" +msgstr "" + +msgid "" +"You can change your search terms and search again to find what you are " +"looking for." +msgstr "" +"Qidiruv soʼzlarini oʼzgartirib, qidirilayotgan axborotni qayta qidiruvga " +"topshirishingiz mumkin." + +msgid "Back to search" +msgstr "Qidiruvga qaytish" + +msgid "An error has occurred" +msgstr "Xatolik yuz berdi" + +msgid "Too many results" +msgstr "Natija juda koʼp" + +msgid "Cannot search in all programs" +msgstr "" + +msgid "Missing search criteria" +msgstr "" + +msgid "Results found" +msgstr "Natijalar topildi" + +msgid "Selected program" +msgstr "Tanlangan dastur" + +msgid "Search {{uniqueAttrName}}" +msgstr "{{uniqueAttrName}} orqali qidirish" + +msgid "Saved lists in this program" +msgstr "" + +msgid "Saved lists offer quick access to your most used views in a program." +msgstr "" + +msgid "" +"There are no saved lists in this program yet, create one using the button " +"below." +msgstr "" + +msgid "Create saved list" +msgstr "" + +msgid "New {{trackedEntityName}} in {{programName}}" +msgstr "" + +msgid "Search for a {{trackedEntityName}} in {{programName}}" +msgstr "" + +msgid "To work with the selected program," +msgstr "Tanlangan dastur bilan ishlash uchun," + +msgid "open the Tracker Capture app" +msgstr "Kuzatuv-Nazorat dasturini oching" + +msgid "This program is protected" +msgstr "" + +msgid "Reason to check for enrollments" +msgstr "" + +msgid "" +"Describe the reason you are checking for enrollments in this protected " +"program" +msgstr "" + +msgid "Check for enrollments" +msgstr "" + +msgid "" +"You must provide a reason to check for enrollments in this protected " +"program. All activity will be logged." +msgstr "" + +msgid "Save comment" +msgstr "Fikr/izohni saqlang" + +msgid "Enrollment actions" +msgstr "" + +msgid "We are processing your request." +msgstr "" + +msgid "Only one enrollment per {{tetName}} is allowed in this program" +msgstr "" + +msgid "Add new" +msgstr "Янгисини қўшиш" + +msgid "Reactivate" +msgstr "" + +msgid "Mark as cancelled" +msgstr "" + +msgid "Mark incomplete" +msgstr "" + +msgid "Delete enrollment" +msgstr "Roʼyxatdan oʼtkazish oʼchirilsin" + +msgid "" +"Are you sure you want to delete this enrollment? This will permanently " +"remove the current enrollment." +msgstr "" + +msgid "Yes, delete enrollment." +msgstr "" + +msgid "Remove mark for follow-up" +msgstr "" + +msgid "Mark for follow-up" +msgstr "Kuzatuv uchun belgilang" + +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + +msgid "Enrollment date" +msgstr "Qayd qilingan sana" + +msgid "Incident date" +msgstr "Hodisa sanasi" + +msgid "Enrollment widget could not be loaded. Please try again later" +msgstr "" + +msgid "Follow-up" +msgstr "Kuzatish" + +msgid "Started at {{orgUnitName}}" +msgstr "" + +msgid "Owned by {{ownerOrgUnit}}" +msgstr "" + +msgid "Last updated {{date}}" +msgstr "" + +msgid "Cancelled" +msgstr "Bekor qilindi" + +msgid "Comments about this enrollment" +msgstr "" + +msgid "Write a comment about this enrollment" +msgstr "" + +msgid "This enrollment doesn't have any comments" +msgstr "" + +msgid "organisation unit could not be retrieved. Please try again later." +msgstr "" + +msgid "Saving to {{stageName}} for {{programName}} in {{orgUnitName}}" +msgstr "" + +msgid "program or stage is invalid" +msgstr "" + +msgid "Error" +msgstr "Xatolik" + +msgid "Warning" +msgstr "Ogohlantirish" + +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 "" + +msgid "Delete event" +msgstr "Hodisa/tadbirni oʼchirib tashlash" + +msgid "Yes, delete event" +msgstr "" + +msgid "Go to “Schedule” tab to reschedule this event" +msgstr "" + +msgid "Scheduled date cannot be changed for {{ eventStatus }} events" +msgstr "" + +msgid "Event completed" +msgstr "" + +msgid "Back to all stages and events" +msgstr "" + +msgid "Schedule date info" +msgstr "" + +msgid "Scheduled automatically for {{suggestedScheduleDate}}" +msgstr "" + +msgid "" +"The scheduled date matches the suggested date, but can be changed if needed." +msgstr "" + +msgid "after" +msgstr "" + +msgid "before" +msgstr "" + +msgid "" +"Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" +msgstr "" + +msgid "Schedule info" +msgstr "" + +msgid "Schedule date / Due date" +msgstr "" + +msgid "Event comments" +msgstr "" + +msgid "Write a comment about this scheduled event" +msgstr "" + +msgid "" +"Change information about this {{trackedEntityName}} here. To change " +"information about this enrollment, use the Edit button in the in the " +"Enrollment box on this dashboard" +msgstr "" + +msgid " Loading..." +msgstr "" + +msgid "Save changes" +msgstr "Oʼzgartirishni saqlash" + +msgid "Profile" +msgstr "Profil" + +msgid "There is a problem with this form" +msgstr "" + +msgid "There are warnings in this form" +msgstr "" + +msgid "There was a problem saving changes" +msgstr "" + +msgid "Try again or contact your system administrator for support" +msgstr "" + +msgid "Fix errors in the form to continue." +msgstr "" + +msgid "Profile widget could not be loaded. Please try again later" +msgstr "" + +msgid "{{TETName}} profile" +msgstr "" + +msgid "Edit" +msgstr "Tahrirlash" + +msgid "tracked entity instance" +msgstr "kuzatilayotgan obʼekt namunasi" + +msgid "New {{ eventName }} event" +msgstr "" + +msgid "To open this event, please wait until saving is complete" +msgstr "" + +msgid "Show {{ rest }} more" +msgstr "" + +msgid "Reset list" +msgstr "" + +msgid "Go to full {{ eventName }}" +msgstr "" + +msgid "This stage can only have one event" +msgstr "" + +msgid "Events could not be retrieved. Please try again later." +msgstr "" + +msgid "{{ totalEvents }} events" +msgstr "" + +msgid "{{ overdueEvents }} overdue" +msgstr "" + +msgid "{{ scheduledEvents }} scheduled" +msgstr "" + +msgid "Stages and Events" +msgstr "" + +msgid "Working list could not be loaded" +msgstr "Ishchi roʼyxatni yuklab boʼlmadi" + +msgid "Download as JSON" +msgstr "JSON sifatida yuklash" + +msgid "Download as XML" +msgstr "XML sifatida yuklash" + +msgid "Download as CSV" +msgstr "CSV sifatida yuklang" + +msgid "Download with current filters" +msgstr "Joriy Filtrlar asosida yuklash" + +msgid "Download data..." +msgstr "Maʼlumotlarni yuklab olish ..." + +msgid "an error occurred loading working lists" +msgstr "ishchi roʼyxatni yuklashda xatolik yuz berdi" + +msgid "Assigned to" +msgstr "" + +msgid "Registration Date" +msgstr "Roʼyxatga olingan sana" + +msgid "Inactive" +msgstr "Faol emas" + +msgid "Enrollment status" +msgstr "Roʼyxatga olish holati" + +msgid "Choose a program stage to filter by {{label}}" +msgstr "" + +msgid "Active enrollments" +msgstr "" + +msgid "Completed enrollments" +msgstr "" + +msgid "Cancelled enrollments" +msgstr "" + +msgid "Working list could not be updated" +msgstr "" + +msgid "an error occurred loading the working lists" +msgstr "" + +msgid "an error occurred loading Tracked entity instance lists" +msgstr "" + +msgid "Update view" +msgstr "Yangilangan koʼrinish" + +msgid "Save current view..." +msgstr "Joriy koʼrinishni saqlash ..." + +msgid "Save current view as..." +msgstr "Ushbu joriy koʼrinish sifatida saqlash" + +msgid "Delete view" +msgstr "Koʼzdan kechirishni oʼchirib tashlash" + +msgid "Share view..." +msgstr "Koʼrinish bilan boʼlishish ..." + +msgid "Do you really want to delete the '{{templateName}}' view?" +msgstr "" +"Haqiqatdan ham '{{templateName}}' koʼrinishini oʼchirib tashlamoqchimisiz?" + +msgid "Confirm" +msgstr "Tasdiqlang" + +msgid "Save As view" +msgstr "Ushbu koʼrinish sifatida saqlash" + +msgid "View name" +msgstr "Ismini koʼrish" + +msgid "Show Less" +msgstr "" + +msgid "Show All" +msgstr "Barchasini koʼrsatish" + +msgid "An error has occured. See log for details" +msgstr "Xatolik yuz berdi. Tafsilotlarni jurnaldan koʼring." + +msgid "Scheduled{{ escape }} due {{ time }}" +msgstr "" + +msgid "Scheduled" +msgstr "Reja boʼyicha" + +msgid "Overdue{{ escape }} due {{ time }}" +msgstr "" + +msgid "Overdue" +msgstr "Muddat oʼtgan" + +msgid "Skipped" +msgstr "Oʼtkazib yuborildi" + +msgid "Visited" +msgstr "Tashrif buyurdi" + +msgid "{{trackedEntityName}} in program{{escape}} {{programName}}" +msgstr "" + +msgid "Program not found" +msgstr "Dastur topilmadi" + +msgid "Program is not a tracker program" +msgstr "Dastur kuzatuv dasturi emas" + +msgid "Error saving event" +msgstr "Hodisa/tadbirni saqlashda xato" + +msgid "Could not save event" +msgstr "" + +msgid "Could not delete event" +msgstr "Hodisa/tadbirni oʼchirib tashlab boʼlmadi" + +msgid "Could not save working list" +msgstr "Ishchi roʼyxat saqlanmadi" + +msgid "Could not add working list" +msgstr "Ishchi roʼyxatni qoʼshib boʼlmadi" + +msgid "Could not delete working list" +msgstr "Ishchi roʼyxatni oʼchirib tashlab boʼlmadi" + +msgid "Organisation unit search failed." +msgstr "" + +msgid "Error saving tracked entity instance" +msgstr "" + +msgid "Error saving enrollment" +msgstr "" + +msgid "Error saving the enrollment event" +msgstr "" + +msgid "Error deleting the enrollment event" +msgstr "" + +msgid "Error editing the event, the changes made were not saved" +msgstr "" + +msgid "Set coordinate" +msgstr "Koordinatani oʼrnating" + +msgid "Date" +msgstr "Sana" + +msgid "Time" +msgstr "Vaqt" + +msgid "From date" +msgstr "Sanadan boshlab" + +msgid "From time" +msgstr "Vaqtdan boshlab" + +msgid "To date" +msgstr "Shu kungacha" + +msgid "To time" +msgstr "Shu vaqtgacha" + +msgid "Page {{currentPage}}" +msgstr "{{currentPage}} sahifasi" + +msgid "Delete polygon" +msgstr "Poligon (koʼpburchak) ni oʼchirib tashlash" + +msgid "Set area" +msgstr "Hududni belgilang" + +msgid "Area on map saved" +msgstr "" + +msgid "Compatibility mode" +msgstr "Muvofiqlik rejimi" diff --git a/i18n/vi.po b/i18n/vi.po index 754ecf982e..83fb30e45c 100644 --- a/i18n/vi.po +++ b/i18n/vi.po @@ -1,6 +1,6 @@ # # Translators: -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # Mai Nguyen , 2022 # Thuy Nguyen , 2023 # Viktor Varland , 2023 @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-27T06:20:33.460Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: Viktor Varland , 2023\n" "Language-Team: Vietnamese (https://app.transifex.com/hisp-uio/teams/100509/vi/)\n" @@ -75,6 +75,16 @@ msgstr "Ngày đăng ký" msgid "Last updated" msgstr "Lần cập nhật cuối" +msgid "error encountered during field validation" +msgstr "gặp lỗi trong quá trình xác thực trường" + +msgid "error" +msgstr "lỗi" + +msgid "" +"Plugins are not yet available - Please contact your system administrator" +msgstr "" + msgid "This value is validating" msgstr "Giá trị này đang xác thực" @@ -372,9 +382,6 @@ msgstr "Một số hoạt động vẫn đang chạy. Vui lòng đợi .." msgid "Operations running" msgstr "Hoạt động đang chạy" -msgid "Sort" -msgstr "Sắp xếp" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -488,6 +495,12 @@ msgstr "Đang tải ảnh lên" msgid "Select image" msgstr "Chọn ảnh" +msgid "Type to filter options" +msgstr "" + +msgid "No match found" +msgstr "" + msgid "Search" msgstr "Tìm kiếm" @@ -753,7 +766,7 @@ msgstr "Lịch biểu" msgid "Refer" msgstr "" -msgid "You can’t add any more {{ programStageName }} events" +msgid "You can't add any more {{ programStageName }} events" msgstr "" msgid "Cancel without saving" @@ -817,6 +830,9 @@ msgstr "" msgid "New Enrollment in program{{escape}} {{programName}}" msgstr "" +msgid "Save {{trackedEntityTypeName}}" +msgstr "" + msgid "Save {{trackedEntityName}}" msgstr "" @@ -974,10 +990,6 @@ msgstr "" msgid "Choose a type to start searching" msgstr "Chọn một loại để bắt đầu tìm kiếm" -msgid "Fill in at least {{count}} attribute to search" -msgid_plural "Fill in at least {{count}} attribute to search" -msgstr[0] "" - msgid "Search {{name}}" msgstr "Tim kiêm {{name}}" @@ -1134,6 +1146,9 @@ msgstr "" msgid "Mark for follow-up" msgstr "Đánh dấu để theo-dõi" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "Ngày ghi vào" @@ -1222,22 +1237,12 @@ 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] "" - 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] "" - msgid "" "Scheduling an event in {{stageName}} for {{programName}} in {{orgUnitName}}" msgstr "" @@ -1281,9 +1286,6 @@ msgstr "" msgid "Try again or contact your system administrator for support" msgstr "" -msgid "tracked entity instance" -msgstr "thực thể được theo dõi" - msgid "Fix errors in the form to continue." msgstr "" @@ -1296,6 +1298,9 @@ msgstr "" msgid "Edit" msgstr "Chỉnh sửa" +msgid "tracked entity instance" +msgstr "thực thể được theo dõi" + msgid "New {{ eventName }} event" msgstr "" @@ -1485,9 +1490,6 @@ msgstr "" msgid "Set coordinate" msgstr "Đặt tọa độ" -msgid "Page {{currentPage}}" -msgstr "Trang {{currentPage}}" - msgid "Date" msgstr "Ngày" @@ -1506,11 +1508,8 @@ msgstr "Đến ngày" msgid "To time" msgstr "Đến " -msgid "error encountered during field validation" -msgstr "gặp lỗi trong quá trình xác thực trường" - -msgid "error" -msgstr "lỗi" +msgid "Page {{currentPage}}" +msgstr "Trang {{currentPage}}" msgid "Delete polygon" msgstr "Xóa đa giác" diff --git a/i18n/zh.po b/i18n/zh.po index 0253648916..3776db9b73 100644 --- a/i18n/zh.po +++ b/i18n/zh.po @@ -1,14 +1,14 @@ # # Translators: # Viktor Varland , 2021 -# phil_dhis2, 2022 +# Philip Larsen Donnelly, 2022 # 晓东 林 <13981924470@126.com>, 2023 # easylin , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: easylin , 2023\n" "Language-Team: Chinese (https://app.transifex.com/hisp-uio/teams/100509/zh/)\n" @@ -320,7 +320,7 @@ msgid "" msgstr "一个具有 {{attributeName}} 的 {{trackedEntityTypeName}} 实体已经登记" msgid "Show registered {{trackedEntityTypeName}}" -msgstr "显示登记的 {{attributeName}} " +msgstr "显示已注册的{{trackedEntityTypeName}}" msgid "Registered person" msgstr "登记的人" @@ -370,9 +370,6 @@ msgstr "有些操作一直在运行,请等待" msgid "Operations running" msgstr "运作中" -msgid "Sort" -msgstr "排序" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -760,8 +757,8 @@ msgstr "调度" msgid "Refer" msgstr "转诊" -msgid "You can’t add any more {{ programStageName }} events" -msgstr "您不能再添加 {{ programStageName }} 事件" +msgid "You can't add any more {{ programStageName }} events" +msgstr "您无法添加更多的 {{ programStageName }} 事件" msgid "Cancel without saving" msgstr "取消而不保存" @@ -1072,7 +1069,7 @@ msgid "To work with the selected program," msgstr "基于选择的项目工作" msgid "open the Tracker Capture app" -msgstr "打开跟踪随访采集APP" +msgstr "打开跟踪记录APP" msgid "This program is protected" msgstr "该项目受保护" @@ -1134,6 +1131,9 @@ msgstr "删除标记以进行后续操作" msgid "Mark for follow-up" msgstr "后续标记" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "自动生成的事件的现有日期将不会更新。" + msgid "Enrollment date" msgstr "报名日期" @@ -1257,7 +1257,7 @@ msgid "Save changes" msgstr "保存修改" msgid "Profile" -msgstr "简历" +msgstr "基本信息" msgid "There is a problem with this form" msgstr "这个表单有问题" @@ -1278,7 +1278,7 @@ msgid "Profile widget could not be loaded. Please try again later" msgstr "无法加载个人资料窗口小部件。请稍后再试" msgid "{{TETName}} profile" -msgstr "{{TETName}} 基本资料" +msgstr "{{TETName}} 基本信息" msgid "Edit" msgstr "编辑" @@ -1314,7 +1314,7 @@ msgid "{{ overdueEvents }} overdue" msgstr "{{ overdueEvents }} 逾期" msgid "{{ scheduledEvents }} scheduled" -msgstr "{{scheduledEvents}} 已调度" +msgstr "{{ ScheduledEvents }} 已安排" msgid "Stages and Events" msgstr "阶段与活动" @@ -1416,7 +1416,7 @@ msgid "Scheduled" msgstr "已经调度" msgid "Overdue{{ escape }} due {{ time }}" -msgstr "逾期{{逃脱}}到期{{时间}}" +msgstr "逾期{{ escape }}到期{{ time }}" msgid "Overdue" msgstr "逾期" @@ -1475,9 +1475,6 @@ msgstr "编辑事件时出错,所做的更改未保存" msgid "Set coordinate" msgstr "设置坐标" -msgid "Page {{currentPage}}" -msgstr "第{{currentPage}}页" - msgid "Date" msgstr "日期" @@ -1496,6 +1493,9 @@ msgstr "到目前为止" msgid "To time" msgstr "到时间" +msgid "Page {{currentPage}}" +msgstr "第{{currentPage}}页" + msgid "Delete polygon" msgstr "删除多边形" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po index ada7c7ad4f..a489a00929 100644 --- a/i18n/zh_CN.po +++ b/i18n/zh_CN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2023-06-01T08:11:59.116Z\n" +"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" "PO-Revision-Date: 2019-06-27 07:31+0000\n" "Last-Translator: 晓东 林 <13981924470@126.com>, 2023\n" "Language-Team: Chinese (China) (https://app.transifex.com/hisp-uio/teams/100509/zh_CN/)\n" @@ -368,9 +368,6 @@ msgstr "有些操作一直在运行,请等待" msgid "Operations running" msgstr "运作中" -msgid "Sort" -msgstr "排序" - msgid "" "This event has unsaved changes. Leaving this page without saving will lose " "these changes. Are you sure you want to discard unsaved changes?" @@ -758,8 +755,8 @@ msgstr "调度" msgid "Refer" msgstr "转诊" -msgid "You can’t add any more {{ programStageName }} events" -msgstr "您不能再添加 {{ programStageName }} 事件" +msgid "You can't add any more {{ programStageName }} events" +msgstr "" msgid "Cancel without saving" msgstr "取消而不保存" @@ -1132,6 +1129,9 @@ msgstr "删除标记以进行后续操作" msgid "Mark for follow-up" msgstr "后续标记" +msgid "Existing dates for auto-generated events will not be updated." +msgstr "" + msgid "Enrollment date" msgstr "报名日期" @@ -1473,9 +1473,6 @@ msgstr "编辑事件时出错,所做的更改未保存" msgid "Set coordinate" msgstr "设置坐标" -msgid "Page {{currentPage}}" -msgstr "第{{currentPage}}页" - msgid "Date" msgstr "日期" @@ -1494,6 +1491,9 @@ msgstr "到目前为止" msgid "To time" msgstr "到时间" +msgid "Page {{currentPage}}" +msgstr "第{{currentPage}}页" + msgid "Delete polygon" msgstr "删除多边形" diff --git a/package.json b/package.json index 8c32666813..fbf2ef4982 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.39.0", + "version": "100.41.0", "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.39.0", + "@dhis2/rules-engine-javascript": "100.41.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 760850a4a9..411dcf5450 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.39.0", + "version": "100.41.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { diff --git a/src/core_modules/capture-core/components/D2Form/D2Form.component.js b/src/core_modules/capture-core/components/D2Form/D2Form.component.js index 5d24c11bba..4f17677b07 100644 --- a/src/core_modules/capture-core/components/D2Form/D2Form.component.js +++ b/src/core_modules/capture-core/components/D2Form/D2Form.component.js @@ -116,11 +116,21 @@ class D2Form extends React.PureComponent { id, classes, isFormInReduxStore, + getCustomContent, ...passOnProps } = this.props; const metaDataSectionsAsArray = Array.from(formFoundation.sections.entries()).map(entry => entry[1]); - const sections = metaDataSectionsAsArray.map(section => (passOnProps.formHorizontal ? this.renderHorizontal(section, passOnProps) : this.renderVertical(section, passOnProps))); + const sections = metaDataSectionsAsArray.map(section => ( + passOnProps.formHorizontal + ? this.renderHorizontal(section, passOnProps) + : ( + <> + {getCustomContent && getCustomContent(section.id) } + {this.renderVertical(section, passOnProps)} + + ) + )); return ( <> diff --git a/src/core_modules/capture-core/components/D2Form/D2Form.types.js b/src/core_modules/capture-core/components/D2Form/D2Form.types.js index 59f5065222..9671d8309f 100644 --- a/src/core_modules/capture-core/components/D2Form/D2Form.types.js +++ b/src/core_modules/capture-core/components/D2Form/D2Form.types.js @@ -1,5 +1,5 @@ // @flow - +import * as React from 'react'; import type { RenderFoundation } from '../../metaData'; export type FormRef = $ReadOnly<{| @@ -10,6 +10,7 @@ export type OwnProps = $ReadOnly<{| formFoundation: RenderFoundation, id: string, formHorizontal?: boolean, + getCustomContent?: (beforeSectionId: string) => React.Node, ...FormRef |}> diff --git a/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.container.js b/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.container.js index 7f4b193646..65e4cf82e8 100644 --- a/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.container.js +++ b/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.container.js @@ -6,11 +6,13 @@ import { usePluginMessages } from './hooks/usePluginMessages'; import { usePluginCallbacks } from './hooks/usePluginCallbacks'; import { usePluginValues } from './hooks/usePluginValues'; import { formatPluginConfig } from './formatPluginConfig'; +import { useLocationQuery } from '../../../utils/routing'; export const FormFieldPlugin = (props: ContainerProps) => { const { pluginSource, fieldsMetadata, formId, onUpdateField, pluginContext } = props; const metadataByPluginId = useMemo(() => Object.fromEntries(fieldsMetadata), [fieldsMetadata]); const configuredPluginIds = useMemo(() => Object.keys(metadataByPluginId), [metadataByPluginId]); + const { orgUnitId } = useLocationQuery(); // Plugin related functionality and feedback const { pluginValues } = usePluginValues(formId, metadataByPluginId, pluginContext); @@ -39,6 +41,7 @@ export const FormFieldPlugin = (props: ContainerProps) => { return ( { /> ); }; + diff --git a/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.types.js b/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.types.js index 3aa8638400..9a97d2e42a 100644 --- a/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.types.js +++ b/src/core_modules/capture-core/components/D2Form/FormFieldPlugin/FormFieldPlugin.types.js @@ -64,6 +64,7 @@ export type ComponentProps = {| fieldsMetadata: MetadataByPluginId, formSubmitted: boolean, values: { [id: string]: any }, + orgUnitId: string, setFieldValue: (SetFieldValueProps) => void, errors: { [id: string]: Array }, warnings: { [id: string]: Array }, diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js index aa756a6f5a..afb0561e04 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js @@ -33,7 +33,8 @@ import { getIncidentDateValidatorContainer, } from './fieldValidators'; import { sectionKeysForEnrollmentDataEntry } from './constants/sectionKeys.const'; -import { type Enrollment, getProgramThrowIfNotFound } from '../../../metaData'; +import { type Enrollment, ProgramStage, RenderFoundation, getProgramThrowIfNotFound } from '../../../metaData'; +import { EnrollmentWithFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry'; import { getCategoryOptionsValidatorContainers, attributeOptionsKey, @@ -41,7 +42,6 @@ import { withAOCFieldBuilder, withDataEntryFields, } from '../../DataEntryDhis2Helpers'; -import { shouldUseNewDashboard } from '../../../utils/routing'; const overrideMessagePropNames = { errorMessage: 'validationError', @@ -290,40 +290,35 @@ const getCategoryOptionsSettingsFn = () => { getPropName: (props: Object, fieldId?: string) => (fieldId ? `${attributeOptionsKey}-${fieldId}` : attributeOptionsKey), getFieldIds: (props: Object) => props.categories?.map(category => category.id), getValidatorContainers: (props: Object, fieldId?: string) => getCategoryOptionsValidatorContainers(props, fieldId), - getMeta: (props: Object) => ({ - section: AOCsectionKey, - placement: placements.BOTTOM, - sectionName: props.programCategory?.displayName, - }), + getMeta: (props: Object) => { + const { firstStageMetaData, programCategory } = props; + + return { + section: AOCsectionKey, + placement: placements.BOTTOM, + sectionName: firstStageMetaData + ? `${firstStageMetaData.stage.name} - ${programCategory?.displayName}` + : programCategory?.displayName, + }; + }, }; return categoryOptionsSettings; }; const getAOCSettingsFn = () => ({ - hideAOC: ({ programId, newDashboardConfig }) => { - const { stages: stagesMap } = getProgramThrowIfNotFound(programId); + hideAOC: ({ programId }) => { + const { stages: stagesMap, useFirstStageDuringRegistration } = getProgramThrowIfNotFound(programId); /* Show AOC selection if: - - There are any program stages in the program with “Auto-generate" event and NOT “Open data entry form after enrollment”. - - There are multiple program stages with "Auto-generate" event and "Open data entry form after enrollment" - (in this scenario we are currently generating events for the program stages that are not the first one) - - Using the old dashboard and we have a stage with auto generate event. + - There are any program stages in the program with “Auto-generate" + - The "Show first stage on registration page" is selected for the program */ const stages = [...stagesMap.values()]; - const usingNewDashboardForProgram = shouldUseNewDashboard( - newDashboardConfig.userDataStore, - newDashboardConfig.dataStore, - newDashboardConfig.temp, - programId, - ); - - const shouldShowAOC = (!usingNewDashboardForProgram && stages.some(stage => stage.autoGenerateEvent)) || - stages.some(stage => stage.autoGenerateEvent && !stage.openAfterEnrollment) || - stages.filter(stage => stage.autoGenerateEvent && stage.openAfterEnrollment).length > 1; + const shouldShowAOC = stages.some(stage => stage.autoGenerateEvent) || useFirstStageDuringRegistration; return !shouldShowAOC; }, @@ -336,7 +331,9 @@ type FinalTeiDataEntryProps = { orgUnitId: string, onUpdateDataEntryField: Function, onUpdateFormFieldAsync: Function, - onUpdateFormField: Function + onUpdateFormField: Function, + firstStageMetaData?: ?{ stage: ProgramStage }, + formFoundation: RenderFoundation, }; // final step before the generic dataEntry is inserted class FinalEnrollmentDataEntry extends React.Component { @@ -355,14 +352,21 @@ class FinalEnrollmentDataEntry extends React.Component { }; render() { - const { enrollmentMetadata, ...passOnProps } = this.props; + const { enrollmentMetadata, firstStageMetaData, ...passOnProps } = this.props; + return ( // $FlowFixMe[cannot-spread-inexact] automated comment - + firstStageMetaData ? ( + + ) : ( + + ) ); } } @@ -385,6 +389,8 @@ type PreEnrollmentDataEntryProps = { onStartAsyncUpdateField: Function, onGetUnsavedAttributeValues?: ?Function, teiId?: ?string, + firstStageMetaData?: ?{ stage: ProgramStage }, + formFoundation: RenderFoundation, }; class PreEnrollmentDataEntryPure extends React.PureComponent { @@ -409,18 +415,18 @@ export class EnrollmentDataEntryComponent extends React.Component) => { - const { programId, orgUnit } = this.props; - this.props.onUpdateField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } handleUpdateDataEntryField = (...args: Array) => { - const { programId, orgUnit } = this.props; - this.props.onUpdateDataEntryField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onUpdateDataEntryField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } handleStartAsyncUpdateField = (...args: Array) => { - const { programId, orgUnit } = this.props; - this.props.onStartAsyncUpdateField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onStartAsyncUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } render() { @@ -432,6 +438,7 @@ export class EnrollmentDataEntryComponent extends React.Component ({ - newDashboardConfig: useNewDashboard, -}); - const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ onUpdateDataEntryField: ( innerAction: ReduxAction, data: any, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { - dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit)); + dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit, stage, formFoundation)); }, onUpdateField: ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { - dispatch(updateFieldBatch(innerAction, programId, orgUnit)); + dispatch(updateFieldBatch(innerAction, programId, orgUnit, stage, formFoundation)); }, onStartAsyncUpdateField: ( innerAction: ReduxAction, @@ -31,9 +32,11 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ itemId: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const onAsyncUpdateSuccess = (successInnerAction: ReduxAction) => - asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit); + asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit, stage, formFoundation); const onAsyncUpdateError = (errorInnerAction: ReduxAction) => errorInnerAction; dispatch(startAsyncUpdateFieldForNewEnrollment(innerAction, onAsyncUpdateSuccess, onAsyncUpdateError)); @@ -41,5 +44,5 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ }); // $FlowFixMe -export const EnrollmentDataEntry = connect(mapStateToProps, mapDispatchToProps)(EnrollmentDataEntryComponent); +export const EnrollmentDataEntry = connect(() => ({}), mapDispatchToProps)(EnrollmentDataEntryComponent); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js new file mode 100644 index 0000000000..c1b0b328b0 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js @@ -0,0 +1,231 @@ +// @flow +import i18n from '@dhis2/d2-i18n'; +import { DataEntry } from '../../../DataEntry'; +import { + withInternalChangeHandler, + withLabel, + withFocusSaver, + DateField, + PolygonField, + CoordinateField, + withCalculateMessages, + withDisplayMessages, + withFilterProps, + withDefaultFieldContainer, + withDefaultShouldUpdateInterface, + TrueOnlyField, + orientations, +} from '../../../FormFields/New'; +import { placements } from '../../../DataEntry/constants/placements.const'; +import { withDataEntryFieldIfApplicable } from '../../../DataEntry/dataEntryField/withDataEntryFieldIfApplicable'; +import { sectionKeysForFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.constants'; +import labelTypeClasses from './fieldLabels.module.css'; +import { withCleanUp } from './withCleanUp'; +import { getEventDateValidatorContainers } from './fieldValidators/eventDate.validatorContainersGetter'; +import { stageMainDataIds } from './getDataEntryPropsToInclude'; + +const overrideMessagePropNames = { + errorMessage: 'validationError', +}; + +const getCalendarAnchorPosition = (formHorizontal: ?boolean) => (formHorizontal ? 'center' : 'left'); + +const baseComponentStyles = { + labelContainerStyle: { + flexBasis: 200, + }, + inputContainerStyle: { + flexBasis: 150, + }, +}; +const baseComponentStylesVertical = { + labelContainerStyle: { + width: 150, + }, + inputContainerStyle: { + width: 150, + }, +}; + +function defaultFilterProps(props: Object) { + const { formHorizontal, fieldOptions, validationError, modified, ...passOnProps } = props; + return passOnProps; +} + +const getBaseComponentProps = (props: Object) => ({ + fieldOptions: props.fieldOptions, + formHorizontal: props.formHorizontal, + styles: props.formHorizontal ? baseComponentStylesVertical : baseComponentStyles, +}); + +const createComponentProps = (props: Object, componentProps: Object) => ({ + ...getBaseComponentProps(props), + ...componentProps, +}); + +const getOrientation = (formHorizontal: ?boolean) => (formHorizontal ? orientations.VERTICAL : orientations.HORIZONTAL); + +const pointComponent = withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.coordinateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(CoordinateField), + ), + ), + ), + ), + ), + ), +); + +const polygonComponent = withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.coordinateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(PolygonField), + ), + ), + ), + ), + ), + ), +); + +const getStageGeometrySettings = () => ({ + isApplicable: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + return ['Polygon', 'Point'].includes(featureType); + }, + getComponent: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + if (featureType === 'Polygon') { + return polygonComponent; + } + return pointComponent; + }, + getComponentProps: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + if (featureType === 'Polygon') { + return createComponentProps(props, { + width: props && props.formHorizontal ? 150 : 350, + label: i18n.t('Area'), + dialogLabel: i18n.t('Area'), + required: false, + orientation: getOrientation(props.formHorizontal), + }); + } + + return createComponentProps(props, { + width: props && props.formHorizontal ? 150 : 350, + label: i18n.t('Coordinate'), + dialogLabel: i18n.t('Coordinate'), + required: false, + orientation: getOrientation(props.formHorizontal), + shrinkDisabled: props.formHorizontal, + }); + }, + getPropName: () => stageMainDataIds.GEOMETRY, + getValidatorContainers: () => [], + getMeta: () => ({ + section: sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO, + }), +}); + +const getCompleteFieldSettingsFn = () => { + const completeComponent = + withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.trueOnlyLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(TrueOnlyField), + ), + ), + ), + ), + ), + ), + ); + const completeSettings = { + isApplicable: (props: Object) => props.firstStageMetaData && props.firstStageMetaData.stage?.stageForm, + getComponent: () => completeComponent, + getComponentProps: (props: Object) => createComponentProps(props, { + label: i18n.t('Complete event'), + id: 'complete', + }), + getPropName: () => stageMainDataIds.COMPLETE, + getValidatorContainers: () => [], + getMeta: () => ({ + placement: placements.BOTTOM, + section: sectionKeysForFirstStageDataEntry.STATUS, + }), + getPassOnFieldData: () => true, + }; + + return completeSettings; +}; + +const getReportDateSettingsFn = () => { + const reportDateComponent = + withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.dateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(DateField), + ), + ), + ), + ), + ), + ), + ); + const reportDateSettings = { + isApplicable: (props: Object) => props.firstStageMetaData?.stage?.stageForm, + getComponent: () => reportDateComponent, + getComponentProps: (props: Object) => createComponentProps(props, { + width: props && props.formHorizontal ? 150 : '100%', + label: props.firstStageMetaData?.stage?.stageForm?.getLabel('occurredAt'), + required: true, + calendarWidth: props.formHorizontal ? 250 : 350, + popupAnchorPosition: getCalendarAnchorPosition(props.formHorizontal), + }), + getPropName: () => stageMainDataIds.OCCURRED_AT, + getValidatorContainers: () => getEventDateValidatorContainers(), + getMeta: () => ({ + section: sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO, + }), + }; + + return reportDateSettings; +}; + +const StageLocationHOC = withDataEntryFieldIfApplicable(getStageGeometrySettings())(withCleanUp()(DataEntry)); +const CompleteHOC = withDataEntryFieldIfApplicable(getCompleteFieldSettingsFn())(StageLocationHOC); +export const FirstStageDataEntry = withDataEntryFieldIfApplicable(getReportDateSettingsFn())(CompleteHOC); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js new file mode 100644 index 0000000000..1abc295aa9 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js @@ -0,0 +1,7 @@ +// @flow + +export const sectionKeysForFirstStageDataEntry = { + ENROLLMENT: 'enrollment', + STATUS: 'status', + STAGE_BASIC_INFO: 'stageBasicInfo', +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js new file mode 100644 index 0000000000..b831b9f197 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js @@ -0,0 +1,28 @@ +// @flow +import React from 'react'; +import type { Props } from './EnrollmentWithFirstStageDataEntry.types'; +import { FirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.component'; +import { useDataEntrySections } from './hooks'; +import { Section } from '../../../../metaData'; + +const getSectionId = sectionId => + (sectionId === Section.MAIN_SECTION_ID ? `${Section.MAIN_SECTION_ID}-stage` : sectionId); + +export const EnrollmentWithFirstStageDataEntry = (props: Props) => { + const { firstStageMetaData, ...passOnProps } = props; + const { + stage: { stageForm: firstStageFormFoundation, name: stageName }, + } = firstStageMetaData; + // $FlowFixMe[incompatible-type] + const [[firstSectionId]] = firstStageFormFoundation.sections; + const beforeSectionId = getSectionId(firstSectionId); + const dataEntrySections = useDataEntrySections(stageName, beforeSectionId); + + return ( + + ); +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js new file mode 100644 index 0000000000..6c2a054867 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js @@ -0,0 +1,9 @@ +// @flow +import type { ProgramStage, RenderFoundation } from '../../../../metaData'; + +export type Props = { + firstStageMetaData: { + stage: ProgramStage, + }, + formFoundation: RenderFoundation, +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css new file mode 100644 index 0000000000..faa712abaf --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css @@ -0,0 +1,45 @@ +.booleanLabel { + padding-top: 13px; +} + +.trueOnlyLabel { + padding-top: 13px; +} +.noteLabel { + padding-top: 13px; +} + +.textLabel { + padding-top: 13px; +} + +.ageLabel { + padding-top: 13px; +} + +.coordinateLabel { + padding-top: 13px; +} +.polygonLabel { + padding-top: 4px; +} + +.dateLabel { + padding-top: 13px; +} + +.dateTimeLabel { + padding-top: 13px; +} + +.imageLabel { + padding-top: 9px; +} + +.fileLabel { + padding-top: 9px; +} + +.orgUnitLabel { + padding-top: 3px; +} \ No newline at end of file diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js new file mode 100644 index 0000000000..3cb0a56c19 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js @@ -0,0 +1,26 @@ +// @flow +import { hasValue } from 'capture-core-utils/validators/form'; +import i18n from '@dhis2/d2-i18n'; +import { isValidDate } from '../../../../../utils/validators/form'; + +const preValidateDate = (value?: ?string) => { + if (!value) { + return true; + } + + return isValidDate(value); +}; + +export const getEventDateValidatorContainers = () => { + const validatorContainers = [ + { + validator: hasValue, + message: i18n.t('A value is required'), + }, + { + validator: preValidateDate, + message: i18n.t('Please provide a valid date'), + }, + ]; + return validatorContainers; +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js new file mode 100644 index 0000000000..5399d49334 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js @@ -0,0 +1,3 @@ +// @flow + +export { getEventDateValidatorContainers } from './eventDate.validatorContainersGetter'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js new file mode 100644 index 0000000000..aef6ec85cf --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js @@ -0,0 +1,39 @@ +// @flow +import type { RenderFoundation } from '../../../../metaData'; +import { getEventDateValidatorContainers } from './fieldValidators'; +import { getConvertGeometryIn, convertGeometryOut, convertStatusIn, convertStatusOut } from '../../converters'; + +export const stageMainDataIds = { + OCCURRED_AT: 'stageOccurredAt', + COMPLETE: 'stageComplete', + GEOMETRY: 'stageGeometry', +}; + +const stageMainDataRulesEngineIds = { + OCCURRED_AT: 'occurredAt', + COMPLETE: 'complete', + GEOMETRY: 'geometry', +}; + +export const convertToRulesEngineIds = (id: string) => stageMainDataRulesEngineIds[id]; + +export const getDataEntryPropsToInclude = (formFoundation: RenderFoundation) => [ + { + id: stageMainDataIds.OCCURRED_AT, + type: 'DATE', + validatorContainers: getEventDateValidatorContainers(), + }, + { + clientId: stageMainDataIds.COMPLETE, + dataEntryId: stageMainDataIds.COMPLETE, + onConvertIn: convertStatusIn, + onConvertOut: convertStatusOut, + }, + { + clientId: stageMainDataIds.GEOMETRY, + dataEntryId: stageMainDataIds.GEOMETRY, + onConvertIn: getConvertGeometryIn(formFoundation), + onConvertOut: convertGeometryOut, + featureType: formFoundation.featureType, + }, +]; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js new file mode 100644 index 0000000000..83d6e81265 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js @@ -0,0 +1,3 @@ +// @flow + +export { useDataEntrySections } from './useDataEntrySections'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js new file mode 100644 index 0000000000..3aab5bd6d2 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js @@ -0,0 +1,34 @@ +// @flow +import { useMemo } from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { placements } from '../../../../DataEntry/constants/placements.const'; +import { sectionKeysForFirstStageDataEntry } from '../EnrollmentWithFirstStageDataEntry.constants'; +import { AOCsectionKey } from '../../../../DataEntryDhis2Helpers'; + +export const useDataEntrySections = (stageName: string, beforeSectionId: string) => + useMemo( + () => ({ + [sectionKeysForFirstStageDataEntry.ENROLLMENT]: { + placement: placements.TOP, + name: i18n.t('Enrollment'), + }, + [sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO]: { + beforeSectionId, + placement: placements.BEFORE_METADATA_BASED_SECTION, + name: i18n.t('{{ stageName }} - Basic info', { + stageName, + }), + }, + [AOCsectionKey]: { + beforeSectionId, + placement: placements.BEFORE_METADATA_BASED_SECTION, + }, + [sectionKeysForFirstStageDataEntry.STATUS]: { + placement: placements.BOTTOM, + name: i18n.t('{{ stageName }} - Status', { + stageName, + }), + }, + }), + [stageName, beforeSectionId], + ); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js new file mode 100644 index 0000000000..9570ba1aba --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js @@ -0,0 +1,4 @@ +// @flow + +export { EnrollmentWithFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.container'; +export { getDataEntryPropsToInclude, stageMainDataIds, convertToRulesEngineIds } from './getDataEntryPropsToInclude'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js new file mode 100644 index 0000000000..5b2cc24c0e --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js @@ -0,0 +1,21 @@ +// @flow +import * as React from 'react'; + +const getCleanUpHOC = (InnerComponent: React.ComponentType) => + (props: Object) => { + const { + dataEntryFieldRef, + firstStageMetaData, + ...passOnProps + } = props; + + return ( + + ); + }; + +export const withCleanUp = () => + (InnerComponent: React.ComponentType) => + getCleanUpHOC(InnerComponent); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js index c59fa959ee..f84452c7fe 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js @@ -8,7 +8,7 @@ import type { } from '@dhis2/rules-engine-javascript'; import { getApplicableRuleEffectsForTrackerProgram, updateRulesEffects } from '../../../../rules'; import { rulesExecutedPostUpdateField } from '../../../DataEntry/actions/dataEntry.actions'; -import type { TrackerProgram, RenderFoundation } from '../../../../metaData'; +import { TrackerProgram, RenderFoundation, ProgramStage } from '../../../../metaData'; import { startRunRulesPostUpdateField } from '../../../DataEntry'; import { startRunRulesOnUpdateForNewEnrollment } from './enrollment.actions'; @@ -18,25 +18,42 @@ export const batchActionTypes = { UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH: 'UpdateDataEntryFieldNewEnrollmentActionBatch', }; -export const runRulesOnUpdateFieldBatch = ( +export const runRulesOnUpdateFieldBatch = ({ + program, + formId, + dataEntryId, + itemId, + orgUnit, + enrollmentData, + attributeValues, + extraActions = [], + uid, + stage, + formFoundation, + currentEvent, +}: { program: TrackerProgram, - foundation: RenderFoundation, formId: string, dataEntryId: string, itemId: string, orgUnit: OrgUnit, enrollmentData?: Enrollment, attributeValues?: TEIValues, - extraActions: Array> = [], + extraActions: Array>, uid: string, -) => { + stage?: ProgramStage, + formFoundation?: RenderFoundation, + currentEvent?: {[id: string]: any}, +}) => { const effects = getApplicableRuleEffectsForTrackerProgram({ program, + stage, orgUnit, + currentEvent, enrollmentData, attributeValues, + formFoundation, }); - return batchActions([ updateRulesEffects(effects, formId), rulesExecutedPostUpdateField(dataEntryId, itemId, uid), @@ -48,6 +65,8 @@ export const updateDataEntryFieldBatch = ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const { dataEntryId, itemId } = innerAction.payload; const uid = uuid(); @@ -55,7 +74,7 @@ export const updateDataEntryFieldBatch = ( return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; @@ -63,6 +82,8 @@ export const updateFieldBatch = ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const { dataEntryId, itemId } = innerAction.payload; const uid = uuid(); @@ -70,7 +91,7 @@ export const updateFieldBatch = ( return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; @@ -80,12 +101,14 @@ export const asyncUpdateSuccessBatch = ( itemId: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const uid = uuid(); return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js index b259a5821c..68d8a8cb7e 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js @@ -1,6 +1,7 @@ // @flow import type { OrgUnit } from '@dhis2/rules-engine-javascript'; import { actionCreator, actionPayloadAppender } from '../../../../actions/actions.utils'; +import { ProgramStage, RenderFoundation } from '../../../../metaData'; export const actionTypes = { START_RUN_RULES_ON_UPDATE: 'StartRunRulesOnUpdateForNewEnrollment', @@ -11,9 +12,11 @@ export const startRunRulesOnUpdateForNewEnrollment = ( uid: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => actionCreator(actionTypes.START_RUN_RULES_ON_UPDATE)( - { innerPayload: payload, uid, programId, orgUnit }); + { innerPayload: payload, uid, programId, orgUnit, stage, formFoundation }); export const startAsyncUpdateFieldForNewEnrollment = ( innerAction: ReduxAction, diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js index f83897ebfa..2507d1c474 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js @@ -2,21 +2,26 @@ import { batchActions } from 'redux-batched-actions'; import type { OrgUnit } from '@dhis2/rules-engine-javascript'; import { getApplicableRuleEffectsForTrackerProgram, updateRulesEffects } from '../../../../rules'; -import type { TrackerProgram } from '../../../../metaData'; +import type { ProgramStage, TrackerProgram, RenderFoundation } from '../../../../metaData'; import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey'; import { loadNewDataEntry } from '../../../DataEntry/actions/dataEntryLoadNew.actions'; import { openDataEntryForNewEnrollment } from './open.actions'; -import { getEnrollmentDateValidatorContainer, getIncidentDateValidatorContainer, getCategoryOptionsValidatorContainers } from '../fieldValidators'; +import { + getEnrollmentDateValidatorContainer, + getIncidentDateValidatorContainer, + getCategoryOptionsValidatorContainers, +} from '../fieldValidators'; import { convertGeometryOut } from '../../converters'; import { convertDateObjectToDateFormatString } from '../../../../utils/converters/date'; import { addFormData } from '../../../D2Form/actions/form.actions'; import type { ProgramCategory } from '../../../WidgetEventSchedule/CategoryOptions/CategoryOptions.types'; +import { getDataEntryPropsToInclude } from '../EnrollmentWithFirstStageDataEntry'; const itemId = 'newEnrollment'; type DataEntryPropsToInclude = Array; -const dataEntryPropsToInclude: DataEntryPropsToInclude = [ +const enrollmentDataEntryPropsToInclude: DataEntryPropsToInclude = [ { id: 'enrolledAt', type: 'DATE', @@ -48,7 +53,9 @@ export const openDataEntryForNewEnrollmentBatchAsync = async ({ extraDataEntryProps = [], formValues, clientValues, + firstStage, programCategory, + formFoundation, }: { program: TrackerProgram, orgUnit: OrgUnit, @@ -57,30 +64,39 @@ export const openDataEntryForNewEnrollmentBatchAsync = async ({ extraDataEntryProps?: Array, formValues: { [key: string]: any }, clientValues: { [key: string]: any }, + firstStage?: ProgramStage, programCategory?: ProgramCategory, + formFoundation: RenderFoundation, }) => { const formId = getDataEntryKey(dataEntryId, itemId); - - if (programCategory && programCategory.categories) { - dataEntryPropsToInclude.push(...programCategory.categories.map(category => ({ + const addFormDataActions = addFormData(`${dataEntryId}-${itemId}`, formValues); + const firstStageDataEntryPropsToInclude = firstStage && getDataEntryPropsToInclude(firstStage.stageForm); + const dataEntryPropsToInclude = [ + ...enrollmentDataEntryPropsToInclude, + ...extraDataEntryProps, + ...(firstStageDataEntryPropsToInclude || []), + ...(programCategory && programCategory.categories ? programCategory.categories.map(category => ({ id: `attributeCategoryOptions-${category.id}`, type: 'TEXT', - validatorContainers: getCategoryOptionsValidatorContainers({ categories: programCategory.categories }, category.id), - }))); - } + validatorContainers: + getCategoryOptionsValidatorContainers({ categories: programCategory.categories }, category.id), + })) : []), + ]; + const dataEntryActions = loadNewDataEntry( dataEntryId, itemId, - [...dataEntryPropsToInclude, ...extraDataEntryProps], + dataEntryPropsToInclude, { enrolledAt: convertDateObjectToDateFormatString(new Date()) }, ); - const addFormDataActions = addFormData(`${dataEntryId}-${itemId}`, formValues); const effects = getApplicableRuleEffectsForTrackerProgram({ program, orgUnit, + stage: firstStage, attributeValues: clientValues, + formFoundation, }); return batchActions([ diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js index f5b11285e8..9bc4da634a 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js @@ -4,9 +4,11 @@ import { ofType } from 'redux-observable'; import { map } from 'rxjs/operators'; import { batchActionTypes, runRulesOnUpdateFieldBatch } from '../actions/enrollment.actionBatchs'; import { actionTypes } from '../actions/enrollment.actions'; -import { getTrackerProgramThrowIfNotFound } from '../../../../metaData'; -import { getCurrentClientValues, getCurrentClientMainData, type FieldData } from '../../../../rules'; +import { getTrackerProgramThrowIfNotFound, ProgramStage, RenderFoundation, Section } from '../../../../metaData'; +import { getCurrentClientMainData, type FieldData } from '../../../../rules'; import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey'; +import { convertFormToClient } from '../../../../converters'; +import { stageMainDataIds, convertToRulesEngineIds } from '../EnrollmentWithFirstStageDataEntry'; type Context = { dataEntryId: string, @@ -14,31 +16,59 @@ type Context = { uid: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, } +const splitCurrentClientMainData = (stage, currentClientMainData) => { + if (!stage) { + return { currentEnrollmentValues: currentClientMainData, currentEventMainData: {} }; + } + return Object.keys(currentClientMainData).reduce((acc, id) => { + const stageMainDataId = Object.keys(stageMainDataIds).find(key => stageMainDataIds[key] === id); + if (stageMainDataId) { + acc.currentEventMainData = { + ...acc.currentEventMainData, + [convertToRulesEngineIds(stageMainDataId)]: currentClientMainData[id], + }; + } else { + acc.currentEnrollmentValues = { ...acc.currentEnrollmentValues, [id]: currentClientMainData[id] }; + } + return acc; + }, { currentEnrollmentValues: {}, currentEventMainData: {} }); +}; + const runRulesOnEnrollmentUpdate = (store: ReduxStore, context: Context, fieldData?: ?FieldData, searchActions?: any = []) => { const state = store.value; - const { programId, dataEntryId, itemId, orgUnit, uid } = context; + const { programId, dataEntryId, itemId, orgUnit, uid, stage, formFoundation } = context; const formId = getDataEntryKey(dataEntryId, itemId); const program = getTrackerProgramThrowIfNotFound(programId); - const foundation = program.enrollment.enrollmentForm; - const currentTEIValues = getCurrentClientValues(state, foundation, formId, fieldData); - const currentEnrollmentValues = - getCurrentClientMainData(state, itemId, dataEntryId, foundation); + const currentFormData = state.formsValues[formId] || {}; + const convertedValues = formFoundation.convertAndGroupBySection(currentFormData, convertFormToClient); + const attributeValues = convertedValues[Section.groups.ENROLLMENT]; + const currentEventValues = convertedValues[Section.groups.EVENT] || {}; + const currentClientMainData = + getCurrentClientMainData(state, itemId, dataEntryId, formFoundation) || {}; + const { currentEnrollmentValues, currentEventMainData } + = splitCurrentClientMainData(state, currentClientMainData); + const currentEvent = stage + ? { ...currentEventValues, ...currentEventMainData, programStageId: stage.id } : undefined; - return runRulesOnUpdateFieldBatch( + return runRulesOnUpdateFieldBatch({ program, - foundation, formId, dataEntryId, itemId, orgUnit, - currentEnrollmentValues, - currentTEIValues ?? undefined, - searchActions, + enrollmentData: currentEnrollmentValues, + attributeValues, + currentEvent, + extraActions: searchActions, uid, - ); + stage, + formFoundation: stage ? formFoundation : undefined, + }); }; @@ -53,6 +83,8 @@ export const runRulesOnEnrollmentDataEntryFieldUpdateEpic = (action$: InputObser programId, orgUnit, innerPayload, + stage, + formFoundation, } = action.payload; const { @@ -66,6 +98,8 @@ export const runRulesOnEnrollmentDataEntryFieldUpdateEpic = (action$: InputObser uid, programId, orgUnit, + stage, + formFoundation, }); })); @@ -75,7 +109,7 @@ export const runRulesOnEnrollmentFieldUpdateEpic = (action$: InputObservable, st map(actionBatch => actionBatch.payload.find(action => action.type === actionTypes.START_RUN_RULES_ON_UPDATE)), map((action) => { - const { innerPayload: payload, searchActions, uid, programId, orgUnit } = action.payload; + const { innerPayload: payload, searchActions, uid, programId, orgUnit, stage, formFoundation } = action.payload; const { dataEntryId, itemId, elementId, value, uiState } = payload; const fieldData: FieldData = { @@ -90,6 +124,8 @@ export const runRulesOnEnrollmentFieldUpdateEpic = (action$: InputObservable, st dataEntryId, itemId, uid, + stage, + formFoundation, }, fieldData, searchActions); }), ); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js index 4e74581537..2a54784b45 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js @@ -5,6 +5,23 @@ export const enrollmentRegistrationEntryActionTypes = { TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START: 'StartInitForEnrollmentRegistrationForm', }; -export const startNewEnrollmentDataEntryInitialisation = ({ selectedOrgUnit, selectedScopeId, dataEntryId, formValues, clientValues, programCategory }: Object) => - actionCreator(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START)({ selectedOrgUnit, selectedScopeId, dataEntryId, formValues, clientValues, programCategory }); - +export const startNewEnrollmentDataEntryInitialisation = ({ + selectedOrgUnit, + selectedScopeId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, +}: Object) => + actionCreator(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START)({ + selectedOrgUnit, + selectedScopeId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, + }); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js index 18268895d6..a439eee13d 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js @@ -7,7 +7,6 @@ import type { OwnProps } from './EnrollmentRegistrationEntry.types'; import { useLifecycle } from './hooks'; import { useRulesEngineOrgUnit } from '../../../hooks'; import { dataEntryHasChanges } from '../../DataEntry/common/dataEntryHasChanges'; -import { useMetadataForRegistrationForm } from '../common/TEIAndEnrollment/useMetadataForRegistrationForm'; export const EnrollmentRegistrationEntry: ComponentType = ({ selectedScopeId, @@ -16,15 +15,18 @@ export const EnrollmentRegistrationEntry: ComponentType = ({ trackedEntityInstanceAttributes, orgUnitId, teiId, + onSave, ...passOnProps }) => { const { orgUnit, error } = useRulesEngineOrgUnit(orgUnitId); - const { ready, skipDuplicateCheck } = useLifecycle(selectedScopeId, id, trackedEntityInstanceAttributes, orgUnit, teiId); const { + ready, + skipDuplicateCheck, + firstStageMetaData, formId, - registrationMetaData: enrollmentMetadata, + enrollmentMetadata, formFoundation, - } = useMetadataForRegistrationForm({ selectedScopeId }); + } = useLifecycle(selectedScopeId, id, trackedEntityInstanceAttributes, orgUnit); const isUserInteractionInProgress: boolean = useSelector( state => @@ -35,7 +37,6 @@ export const EnrollmentRegistrationEntry: ComponentType = ({ ); const trackedEntityTypeNameLC = enrollmentMetadata?.trackedEntityType?.name.toLocaleLowerCase() ?? ''; - const isSavingInProgress = useSelector(({ possibleDuplicates, newPage }) => possibleDuplicates.isLoading || possibleDuplicates.isUpdating || !!newPage.uid); @@ -46,6 +47,7 @@ export const EnrollmentRegistrationEntry: ComponentType = ({ return ( = ({ orgUnit={orgUnit} isUserInteractionInProgress={isUserInteractionInProgress} isSavingInProgress={isSavingInProgress} + onSave={() => onSave(formFoundation, firstStageMetaData)} /> ); }; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js index 5737a4988b..44e25f9bc4 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js @@ -15,7 +15,16 @@ export const startNewEnrollmentDataEntrySelfInitialisationEpic = (action$: Input action$.pipe( ofType(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START), pluck('payload'), - switchMap(({ selectedOrgUnit, selectedScopeId: programId, dataEntryId, formValues, clientValues, programCategory }) => { + switchMap(({ + selectedOrgUnit, + selectedScopeId: programId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, + }) => { if (selectedOrgUnit) { let trackerProgram: ?TrackerProgram; try { @@ -33,7 +42,9 @@ export const startNewEnrollmentDataEntrySelfInitialisationEpic = (action$: Input dataEntryId, formValues, clientValues, + firstStage, programCategory, + formFoundation, }); return from(openEnrollmentPromise); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js index 7242d3963d..bda753f1ba 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js @@ -6,7 +6,7 @@ import type { RenderCustomCardActions } from '../../CardList'; import type { SaveForDuplicateCheck } from '../common/TEIAndEnrollment/DuplicateCheckOnSave'; import type { ExistingUniqueValueDialogActionsComponent } from '../withErrorMessagePostProcessor'; import type { InputAttribute } from './hooks/useFormValues'; -import { RenderFoundation } from '../../../metaData'; +import { RenderFoundation, ProgramStage } from '../../../metaData'; export type OwnProps = $ReadOnly<{| id: string, @@ -22,6 +22,7 @@ export type OwnProps = $ReadOnly<{| skipDuplicateCheck?: ?boolean, trackedEntityInstanceAttributes?: Array, saveButtonText: (trackedEntityName: string) => string, + firstStageMetaData?: ?{ stage: ?ProgramStage }, |}>; type ContainerProps = {| diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js new file mode 100644 index 0000000000..4bd04e8f62 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js @@ -0,0 +1,32 @@ +// @flow +import { useMemo } from 'react'; +import { getProgramAndStageForProgram } from '../../../../metaData'; +import { useProgramFromIndexedDB } from '../../../../utils/cachedDataHooks/useProgramFromIndexedDB'; + +export const useBuildFirstStageRegistration = (programId: string, skip: boolean = false) => { + const { program, isLoading } = useProgramFromIndexedDB(programId, { enabled: !skip }); + + const firstStage = useMemo(() => { + if (!isLoading && program?.useFirstStageDuringRegistration) { + const { programStages } = program; + const programStagesWithAccess = programStages + .filter((stage) => { + const access = { + read: stage.access.data.read, + write: stage.access.data.write, + }; + return access.write; + }) + .sort((a, b) => a.sortOrder - b.sortOrder); + return programStagesWithAccess[0]?.id; + } + return null; + }, [program, isLoading]); + + const firstStageMetaData = useMemo( + () => (firstStage && programId ? getProgramAndStageForProgram(programId, firstStage) : null), + [firstStage, programId], + ); + + return { loading: isLoading, firstStageMetaData }; +}; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js index fa71aaf6df..24b68e9351 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js @@ -8,8 +8,10 @@ import { useLocationQuery } from '../../../../utils/routing'; import { useScopeInfo } from '../../../../hooks/useScopeInfo'; import { useFormValues } from './index'; import type { InputAttribute } from './useFormValues'; +import { useBuildFirstStageRegistration } from './useBuildFirstStageRegistration'; import { useMetadataForRegistrationForm } from '../../common/TEIAndEnrollment/useMetadataForRegistrationForm'; import { useCategoryCombinations } from '../../../DataEntryDhis2Helpers/AOC/useCategoryCombinations'; +import { useMergeFormFoundationsIfApplicable } from './useMergeFormFoundationsIfApplicable'; export const useLifecycle = ( selectedScopeId: string, @@ -25,7 +27,14 @@ export const useLifecycle = ( const ready = useSelector(({ dataEntries }) => !!dataEntries[dataEntryId]) && !!orgUnit; const searchTerms = useSelector(({ searchDomain }) => searchDomain.currentSearchInfo.currentSearchTerms); const { scopeType } = useScopeInfo(selectedScopeId); - const { formFoundation } = useMetadataForRegistrationForm({ selectedScopeId }); + const { firstStageMetaData } = useBuildFirstStageRegistration(programId, scopeType !== scopeTypes.TRACKER_PROGRAM); + const { + formId, + registrationMetaData: enrollmentMetadata, + formFoundation: enrollmentFormFoundation, + } = useMetadataForRegistrationForm({ selectedScopeId }); + + const { formFoundation } = useMergeFormFoundationsIfApplicable(enrollmentFormFoundation, firstStageMetaData); const { programCategory } = useCategoryCombinations(programId, scopeType !== scopeTypes.TRACKER_PROGRAM); const { formValues, clientValues, formValuesReadyRef } = useFormValues({ program, @@ -44,7 +53,8 @@ export const useLifecycle = ( dataEntryReadyRef.current === false && formValuesReadyRef.current === true && orgUnit && - scopeType === scopeTypes.TRACKER_PROGRAM + scopeType === scopeTypes.TRACKER_PROGRAM && + formFoundation ) { dataEntryReadyRef.current = true; dispatch( @@ -55,10 +65,32 @@ export const useLifecycle = ( formValues, clientValues, programCategory, + firstStage: firstStageMetaData?.stage, + formFoundation, }), ); } - }, [scopeType, dataEntryId, selectedScopeId, orgUnit, formValuesReadyRef, formValues, clientValues, programCategory, dispatch]); + }, [ + formFoundation, + scopeType, + dataEntryId, + selectedScopeId, + orgUnit, + formValuesReadyRef, + formValues, + clientValues, + programCategory, + firstStageMetaData, + dispatch, + ]); - return { teiId, ready, skipDuplicateCheck: !!teiId }; + return { + teiId, + ready, + skipDuplicateCheck: !!teiId, + firstStageMetaData, + formId, + enrollmentMetadata, + formFoundation, + }; }; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js new file mode 100644 index 0000000000..77235be403 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js @@ -0,0 +1,72 @@ +// @flow +import { useMemo } from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { RenderFoundation, Section, ProgramStage } from '../../../../metaData'; + +const addElements = (section, newSection) => + Array.from(section.elements.entries()) + .map(entry => entry[1]) + .forEach((element) => { + // $FlowFixMe[prop-missing] section is missing in FormFieldPluginConfig + element.section = newSection; + newSection.addElement(element); + }); + +const getSectionId = sectionId => + (sectionId === Section.MAIN_SECTION_ID ? `${Section.MAIN_SECTION_ID}-stage` : sectionId); + +export const useMergeFormFoundationsIfApplicable = ( + enrollmentFormFoundation?: ?RenderFoundation, + firstStageMetaData?: ?{ stage: ?ProgramStage }, +) => { + const enrollmentSectionsSize = enrollmentFormFoundation?.sections.size; + + return useMemo(() => { + const firstStageFormFoundation = firstStageMetaData?.stage?.stageForm; + if (!enrollmentFormFoundation) { + return { formFoundation: null }; + } + + if (!firstStageFormFoundation || enrollmentSectionsSize === 0) { + return { formFoundation: enrollmentFormFoundation }; + } + + const stageName = firstStageMetaData?.stage?.name; + const { id, name, access, description, featureType, validationStrategy } = enrollmentFormFoundation; + const renderFoundation = new RenderFoundation((o) => { + o.id = id; + o.name = name; + o.access = access; + o.description = description; + o.featureType = featureType; + o.validationStrategy = validationStrategy; + }); + + enrollmentFormFoundation.sections.forEach(section => renderFoundation.addSection(section)); + + firstStageFormFoundation.sections.forEach((section) => { + const isMainSection = section.id === Section.MAIN_SECTION_ID; + const newSection = new Section((o) => { + o.id = getSectionId(section.id); + o.name = isMainSection + ? i18n.t('{{ stageName }} - Details', { + stageName, + }) + : i18n.t('{{ stageName }} - {{ sectionName }}', { + stageName, + sectionName: section.name, + }); + o.group = Section.groups.EVENT; + o.customForm = section.customForm; + o.showContainer = section.showContainer; + o.open = section.open; + o.visible = section.visible; + o.displayDescription = section.displayDescription; + }); + addElements(section, newSection); + renderFoundation.addSection(newSection); + }); + + return { formFoundation: renderFoundation }; + }, [enrollmentFormFoundation, firstStageMetaData, enrollmentSectionsSize]); +}; diff --git a/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js b/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js index 83ab589551..a727db9ec2 100644 --- a/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js +++ b/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js @@ -1,3 +1,7 @@ // @flow +import { ProgramStage, RenderFoundation } from '../../../../../../metaData'; -export type SaveForDuplicateCheck = () => void; +export type SaveForDuplicateCheck = ( + formFoundation?: RenderFoundation, + firstStageMetaData?: { stage: ProgramStage }, +) => void; diff --git a/src/core_modules/capture-core/components/DataEntries/converters/converters.js b/src/core_modules/capture-core/components/DataEntries/converters/converters.js index 64b17bc514..a0efa43b3a 100644 --- a/src/core_modules/capture-core/components/DataEntries/converters/converters.js +++ b/src/core_modules/capture-core/components/DataEntries/converters/converters.js @@ -1,14 +1,15 @@ // @flow import type { RenderFoundation } from '../../../metaData'; -export function convertGeometryOut(dataEntryValue: any, foundation: RenderFoundation) { - if (!dataEntryValue || !['Polygon', 'Point'].includes(foundation.featureType)) return null; +export function convertGeometryOut(dataEntryValue: any, foundation: RenderFoundation, customFeatureType: string) { + const featureType = customFeatureType || foundation.featureType; + if (!dataEntryValue || !['Polygon', 'Point'].includes(featureType)) return null; let coordinates = dataEntryValue; - if (foundation.featureType === 'Point') { + if (featureType === 'Point') { coordinates = [dataEntryValue.longitude, dataEntryValue.latitude]; } return { - type: foundation.featureType, + type: featureType, coordinates, }; } diff --git a/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js b/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js index b554fb3b2b..c0c818c491 100644 --- a/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js +++ b/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js @@ -10,7 +10,7 @@ import { getDataEntryKey } from './common/getDataEntryKey'; import { StickyOnScroll } from '../Sticky/StickyOnScroll.component'; import { Section } from '../Section/Section.component'; import { SectionHeaderSimple } from '../Section/SectionHeaderSimple.component'; -import { FieldSection } from './FieldSection.component'; +import { Field } from './Field.component'; const styles = theme => ({ loadingContainer: { @@ -69,11 +69,17 @@ const styles = theme => ({ verticalOutputsContainer: { marginBottom: theme.typography.pxToRem(10), }, - dataEntryFieldSectionContainer: { + dataEntrySectionContainer: { marginBottom: spacers.dp16, }, }); +type DataEntrySection = { + placement: $Values, + name: string, + beforeSectionId?: string +}; + type FieldContainer = { field: React.Element, placement: $Values, @@ -120,7 +126,7 @@ type Props = { dataEntryId: string, itemId: string, ) => void, - dataEntrySections?: { [string]: {name: string, placement: $Values}}, + dataEntrySections?: { [string]: DataEntrySection }, dataEntryFieldRef: any, onAddNote?: ?Function, onOpenAddRelationship?: ?Function, @@ -159,22 +165,34 @@ class DataEntryPlain extends React.Component { }; } + hasPlacement = ( + dataEntrySection: DataEntrySection, + placement: $Values, + beforeSectionId?: string, + ) => + dataEntrySection.placement === placement && + (dataEntrySection.placement !== placements.BEFORE_METADATA_BASED_SECTION || + (dataEntrySection.placement === placements.BEFORE_METADATA_BASED_SECTION && + dataEntrySection.beforeSectionId === beforeSectionId + ) + ); + handleUpdateFieldAsync = (...args) => { this.props.onUpdateFormFieldAsync(...args, this.props.id, this.props.itemId); } - getFieldSectionsWithPlacement(placement: $Values) { + getSectionsWithPlacement(placement: $Values, beforeSectionId?: string) { const fields = this.props.fields || []; const sections = this.props.dataEntrySections || {}; return this.props.dataEntrySections ? Object.keys(this.props.dataEntrySections).reduce((accSections, sectionKey) => { const section = sections[sectionKey]; - if (section.placement === placement) { + if (this.hasPlacement(section, placement, beforeSectionId)) { const sectionFields = fields .filter(fieldContainer => fieldContainer.section === sectionKey); const sectionFieldsContainer = sectionFields.map((fieldContainer, index, array) => ( - { accSections.push(
{ : []; } - renderDataEntryFieldsByPlacement = (placement: $Values) => { + renderDataEntryFieldsByPlacement = (placement: $Values, beforeSectionId?: string) => { const fields = this.props.fields || []; const fieldFilter = this.props.formHorizontal ? fieldHorizontalFilter(placement) : fieldVerticalFilter(placement); const fieldsByPlacement = fields ? fields .filter(fieldFilter) - .map((fieldContainer, index, array) => ( ( { : []; if (!this.props.formHorizontal) { - return [...fieldsByPlacement, ...this.getFieldSectionsWithPlacement(placement)]; + return [...fieldsByPlacement, ...this.getSectionsWithPlacement(placement, beforeSectionId)]; } return fieldsByPlacement; } @@ -258,6 +276,9 @@ class DataEntryPlain extends React.Component { validationAttempted={completionAttempted || saveAttempted} onUpdateField={this.handleUpdateField} onUpdateFieldAsync={this.handleUpdateFieldAsync} + getCustomContent={beforeSectionId => ( + this.renderDataEntryFieldsByPlacement(placements.BEFORE_METADATA_BASED_SECTION, beforeSectionId) + )} {...passOnProps} /> ); diff --git a/src/core_modules/capture-core/components/DataEntry/FieldSection.component.js b/src/core_modules/capture-core/components/DataEntry/Field.component.js similarity index 91% rename from src/core_modules/capture-core/components/DataEntry/FieldSection.component.js rename to src/core_modules/capture-core/components/DataEntry/Field.component.js index a67eb08b33..d53831c878 100644 --- a/src/core_modules/capture-core/components/DataEntry/FieldSection.component.js +++ b/src/core_modules/capture-core/components/DataEntry/Field.component.js @@ -24,7 +24,7 @@ type Props = { ...CssClasses } -const FieldSectionPlain = (props: Props) => { +const FieldPlain = (props: Props) => { const { formHorizontal, index, fieldContainer, total, classes } = props; const className = !formHorizontal ? index % 2 !== 0 && classes.evenNumbers : null; @@ -44,4 +44,4 @@ const FieldSectionPlain = (props: Props) => { ); }; -export const FieldSection = withStyles(styles)(FieldSectionPlain); +export const Field = withStyles(styles)(FieldPlain); diff --git a/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js b/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js index 5fb8fccaec..88e7bb9208 100644 --- a/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js +++ b/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js @@ -17,7 +17,8 @@ type DataEntryPropToIncludeSpecial = {| clientId: string, dataEntryId: string, onConvertIn: (value: any) => any, - onConvertOut: (dataEntryValue: any, prevValue: any, foundation: RenderFoundation) => any, + onConvertOut: (dataEntryValue: any, foundation: RenderFoundation, customFeatureType: string) => any, + featureType?: string, validatorContainers?: ?Array, |}; @@ -30,7 +31,11 @@ export function getDataEntryMeta(dataEntryPropsToInclude: Array { const error = useSelector(({ activePage }) => activePage.viewEventLoadError?.error); const { loading, event } = useEvent(eventId); const { program: programId, programStage: stageId, trackedEntity: teiId, enrollment: enrollmentId } = event; - const { orgUnitId, eventId: urlEventId } = useLocationQuery(); + const { orgUnitId, eventId: urlEventId, initMode } = useLocationQuery(); useEffect(() => { if (!urlEventId) { @@ -74,11 +74,20 @@ export const EnrollmentEditEventPage = () => { orgUnitId={orgUnitId} eventId={eventId} error={error} + initMode={initMode} /> ) : ; }; -const EnrollmentEditEventPageWithContextPlain = ({ programId, stageId, teiId, enrollmentId, orgUnitId, eventId }: Props) => { +const EnrollmentEditEventPageWithContextPlain = ({ + programId, + stageId, + teiId, + enrollmentId, + orgUnitId, + eventId, + initMode, +}: Props) => { const history = useHistory(); const dispatch = useDispatch(); @@ -101,9 +110,14 @@ const EnrollmentEditEventPageWithContextPlain = ({ programId, stageId, teiId, en const onAddNew = () => { history.push(`/new?${buildUrlQueryString({ programId, orgUnitId, teiId })}`); }; - const onCancelEditEvent = () => { - history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`); - }; + const onCancelEditEvent = useCallback((isScheduled: boolean) => { + if (isScheduled) { + history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`); + } + if (initMode) { + history.push(`/enrollmentEventEdit?${buildUrlQueryString({ eventId, orgUnitId })}`); + } + }, [initMode, enrollmentId, eventId, orgUnitId, history]); const { enrollment: enrollmentSite } = useCommonEnrollmentDomainData(teiId, enrollmentId, programId); const onGoBack = () => diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js index 9b748c190f..8f269fed00 100644 --- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js +++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js @@ -24,7 +24,7 @@ export type PlainProps = {| onLinkedRecordClick: LinkedRecordClick, onEnrollmentError: (message: string) => void, onEnrollmentSuccess: () => void, - onCancelEditEvent: () => void, + onCancelEditEvent: (isScheduled: boolean) => void, onHandleScheduleSave: (eventData: Object) => void, pageStatus: string, eventStatus?: string, @@ -38,4 +38,5 @@ export type Props = {| enrollmentId: string, orgUnitId: string, eventId: string, + initMode?: string, |}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js index 74753cb8b0..e716f71741 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js @@ -1,5 +1,5 @@ // @flow -import type { RenderFoundation } from '../../../../metaData'; +import type { ProgramStage, RenderFoundation } from '../../../../metaData'; import { actionCreator } from '../../../../actions/actions.utils'; import { effectMethods } from '../../../../trackerOffline'; @@ -41,23 +41,26 @@ export const saveNewTrackedEntityInstance = (candidateForRegistration: any) => ); // with enrollment -export const startSavingNewTrackedEntityInstanceWithEnrollment = (formFoundation: RenderFoundation, teiId: string, uid: string) => +export const startSavingNewTrackedEntityInstanceWithEnrollment = (formFoundation: RenderFoundation, teiId: string, uid: string, firstStage?: ProgramStage) => actionCreator(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_START)({ formFoundation, teiId, + firstStage, uid, }); export const saveNewTrackedEntityInstanceWithEnrollment = ({ candidateForRegistration, - redirectToEnrollmentEventNew, + redirectTo, uid, stageId, + eventIndex, }: { candidateForRegistration: any, - redirectToEnrollmentEventNew: boolean, + redirectTo: string, uid: string, stageId?: string, + eventIndex: number, }) => actionCreator(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE)( { ...candidateForRegistration }, @@ -70,7 +73,7 @@ export const saveNewTrackedEntityInstanceWithEnrollment = ({ }, commit: { type: registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_COMPLETED, - meta: { redirectToEnrollmentEventNew, stageId, uid }, + meta: { redirectTo, stageId, uid, eventIndex }, }, rollback: { type: registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_FAILED, diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js index 2f3366659e..599414df09 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js @@ -183,7 +183,9 @@ const RegistrationDataEntryPlain = ({ orgUnitId={reduxOrgUnitId} teiId={teiId} selectedScopeId={selectedScopeId} - onSave={() => onSaveWithEnrollment(formFoundation)} + onSave={(customFormFoundation, firstStageMetaData) => + onSaveWithEnrollment(customFormFoundation, firstStageMetaData?.stage) + } saveButtonText={(trackedEntityTypeNameLC: string) => i18n.t('Save {{trackedEntityTypeName}}', { trackedEntityTypeName: trackedEntityTypeNameLC, interpolation: { escapeValue: false }, diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js index bdebbcb962..41f5a864d5 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js @@ -30,9 +30,9 @@ export const RegistrationDataEntry: ComponentType = ({ [dispatch]); const dispatchOnSaveWithEnrollment = useCallback( - (formFoundation) => { + (formFoundation, firstStage) => { const uid = uuid(); - dispatch(startSavingNewTrackedEntityInstanceWithEnrollment(formFoundation, teiId, uid)); + dispatch(startSavingNewTrackedEntityInstanceWithEnrollment(formFoundation, teiId, uid, firstStage)); }, [dispatch, teiId]); 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 7fab7c500f..004adb75f7 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 @@ -3,46 +3,30 @@ import { ofType } from 'redux-observable'; import { pipe } from 'capture-core-utils'; import { flatMap, map } from 'rxjs/operators'; import { of, EMPTY } from 'rxjs'; -import moment from 'moment'; +import { FEATURETYPE, dataEntryKeys } from 'capture-core/constants'; import { registrationFormActionTypes, saveNewTrackedEntityInstance, saveNewTrackedEntityInstanceWithEnrollment, } from './RegistrationDataEntry.actions'; -import { getTrackerProgramThrowIfNotFound, dataElementTypes } from '../../../../metaData'; +import { getTrackerProgramThrowIfNotFound, dataElementTypes, Section } from '../../../../metaData'; import { navigateToEnrollmentOverview, } from '../../../../actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.actions'; import { convertFormToClient, convertClientToServer } from '../../../../converters'; -import { FEATURETYPE } from '../../../../constants'; import { buildUrlQueryString, shouldUseNewDashboard } from '../../../../utils/routing'; -import { convertCategoryOptionsToServer } from '../../../../converters/clientToServer'; +import { + deriveAutoGenerateEvents, + deriveFirstStageDuringRegistrationEvent, + getStageWithOpenAfterEnrollment, + standardGeoJson, + PAGES, +} from './helpers'; const convertFn = pipe(convertFormToClient, convertClientToServer); const geometryType = formValuesKey => Object.values(FEATURETYPE).find(geometryKey => geometryKey === formValuesKey); -const standardGeoJson = (geometry) => { - if (!geometry) { - return undefined; - } - if (Array.isArray(geometry)) { - return { - type: 'Polygon', - coordinates: geometry, - }; - } else if (geometry.longitude && geometry.latitude) { - return { - type: 'Point', - coordinates: [geometry.longitude, geometry.latitude], - }; - } - return undefined; -}; - -const getStageWithOpenAfterEnrollment = stages => - [...stages.values()].find(({ openAfterEnrollment }) => openAfterEnrollment); - const deriveAttributesFromFormValues = (formValues = {}) => Object.keys(formValues) .filter(key => !geometryType(key)) @@ -53,64 +37,6 @@ const deriveGeometryFromFormValues = (formValues = {}) => .filter(key => geometryType(key)) .reduce((acc, currentKey) => (standardGeoJson(formValues[currentKey])), undefined); - -const deriveEvents = ({ - stages, - enrolledAt, - occurredAt, - programId, - orgUnitId, - redirectToEnrollmentEventNew, - redirectToStageId, - attributeCategoryOptions, -}) => { - // in case we have a program that does not have an incident date (occurredAt), such as Malaria case diagnosis, - // we want the incident to default to enrollmentDate (enrolledAt) - const sanitizedOccurredAt = occurredAt || enrolledAt; - return [...stages.values()] - .filter(({ id }) => (redirectToEnrollmentEventNew && id !== redirectToStageId) || !redirectToEnrollmentEventNew) - .filter(({ autoGenerateEvent }) => autoGenerateEvent) - .map(({ - id: programStage, - reportDateToUse: reportDateToUseInActiveStatus, - generatedByEnrollmentDate: generateScheduleDateByEnrollmentDate, - openAfterEnrollment, - minDaysFromStart, - }) => { - const dateToUseInActiveStatus = - reportDateToUseInActiveStatus === 'enrolledAt' ? enrolledAt : sanitizedOccurredAt; - const dateToUseInScheduleStatus = generateScheduleDateByEnrollmentDate ? enrolledAt : sanitizedOccurredAt; - const eventAttributeCategoryOptions = {}; - if (attributeCategoryOptions) { - eventAttributeCategoryOptions.attributeCategoryOptions = convertCategoryOptionsToServer(attributeCategoryOptions); - } - const eventInfo = - openAfterEnrollment - ? - { - status: 'ACTIVE', - occurredAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), - scheduledAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), - } - : - { - status: 'SCHEDULE', - // for schedule type of events we want to add the standard interval days to the date - scheduledAt: moment(convertFn(dateToUseInScheduleStatus, dataElementTypes.DATE)) - .add(minDaysFromStart, 'days') - .format('YYYY-MM-DD'), - }; - - return { - ...eventInfo, - ...eventAttributeCategoryOptions, - programStage, - program: programId, - orgUnit: orgUnitId, - }; - }); -}; - export const startSavingNewTrackedEntityInstanceEpic: Epic = (action$: InputObservable, store: ReduxStore) => action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_SAVE_START), @@ -154,9 +80,11 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_START), map((action) => { + const formId = 'newPageDataEntryId-newEnrollment'; const { currentSelections: { orgUnitId, programId }, formsValues, dataEntriesFieldsValue } = store.value; const { dataStore, userDataStore, temp } = store.value.useNewDashboard; - const fieldsValue = dataEntriesFieldsValue['newPageDataEntryId-newEnrollment'] || {}; + const { formFoundation, teiId: trackedEntity, firstStage: firstStageMetadata, uid } = action.payload; + const fieldsValue = dataEntriesFieldsValue[formId] || {}; const { occurredAt, enrolledAt, geometry } = fieldsValue; const attributeCategoryOptionsId = 'attributeCategoryOptions'; const attributeCategoryOptions = Object.keys(fieldsValue) @@ -167,29 +95,47 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( return acc; }, {}); const { trackedEntityType, stages } = getTrackerProgramThrowIfNotFound(programId); - const values = formsValues['newPageDataEntryId-newEnrollment'] || {}; - const stageWithOpenAfterEnrollment = getStageWithOpenAfterEnrollment(stages); - const redirectToEnrollmentEventNew = - shouldUseNewDashboard(userDataStore, dataStore, temp, programId) && stageWithOpenAfterEnrollment !== undefined; - const events = deriveEvents({ + const currentFormData = formsValues[formId] || {}; + const shouldRedirect = shouldUseNewDashboard(userDataStore, dataStore, temp, programId); + const { stageWithOpenAfterEnrollment, redirectTo } = getStageWithOpenAfterEnrollment( + stages, + firstStageMetadata, + shouldRedirect, + ); + const convertedValues = formFoundation.convertAndGroupBySection(currentFormData, convertFn); + const formServerValues = convertedValues[Section.groups.ENROLLMENT]; + const currentEventValues = convertedValues[Section.groups.EVENT]; + + const firstStageDuringRegistrationEvent = deriveFirstStageDuringRegistrationEvent({ + firstStageMetadata, + programId, + orgUnitId, + currentEventValues, + fieldsValue, + attributeCategoryOptions, + }); + const autoGenerateEvents = deriveAutoGenerateEvents({ stages, enrolledAt, occurredAt, programId, orgUnitId, - redirectToEnrollmentEventNew, - redirectToStageId: stageWithOpenAfterEnrollment?.id, + firstStageMetadata, attributeCategoryOptions, }); - const { formFoundation, teiId: trackedEntity, uid } = action.payload; - const formServerValues = formFoundation?.convertValues(values, convertFn); + const allEventsToBeCreated = firstStageDuringRegistrationEvent + ? [firstStageDuringRegistrationEvent, ...autoGenerateEvents] + : autoGenerateEvents; + const eventIndex = allEventsToBeCreated.findIndex( + eventsToBeCreated => eventsToBeCreated.programStage === stageWithOpenAfterEnrollment?.id, + ); return saveNewTrackedEntityInstanceWithEnrollment({ candidateForRegistration: { trackedEntities: [ { - geometry: deriveGeometryFromFormValues(values), + geometry: deriveGeometryFromFormValues(currentFormData), enrollments: [ { geometry: standardGeoJson(geometry), @@ -199,7 +145,7 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( orgUnit: orgUnitId, attributes: deriveAttributesFromFormValues(formServerValues), status: 'ACTIVE', - events, + events: allEventsToBeCreated, }, ], orgUnit: orgUnitId, @@ -208,7 +154,8 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( }, ], }, - redirectToEnrollmentEventNew, + redirectTo, + eventIndex, stageId: stageWithOpenAfterEnrollment?.id, uid, }); @@ -223,7 +170,12 @@ export const completeSavingNewTrackedEntityInstanceWithEnrollmentEpic = ( action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_COMPLETED), flatMap((action) => { - const { payload: { bundleReport: { typeReportMap } }, meta } = action; + const { + payload: { + bundleReport: { typeReportMap }, + }, + meta: { uid, redirectTo, stageId, eventIndex }, + } = action; const { currentSelections: { orgUnitId, programId }, newPage, @@ -231,19 +183,31 @@ export const completeSavingNewTrackedEntityInstanceWithEnrollmentEpic = ( const { uid: stateUid } = newPage || {}; const teiId = typeReportMap.TRACKED_ENTITY.objectReports[0].uid; const enrollmentId = typeReportMap.ENROLLMENT.objectReports[0].uid; + const eventId = typeReportMap.EVENT.objectReports?.[eventIndex]?.uid; - if (stateUid !== meta.uid) { + if (stateUid !== uid) { return EMPTY; } - if (meta?.redirectToEnrollmentEventNew) { + if (redirectTo === PAGES.enrollmentEventNew) { history.push( - `/enrollmentEventNew?${buildUrlQueryString({ + `/${redirectTo}?${buildUrlQueryString({ programId, orgUnitId, teiId, enrollmentId, - stageId: meta?.stageId, + stageId, + })}`, + ); + return EMPTY; + } + + if (redirectTo === PAGES.enrollmentEventEdit) { + history.push( + `/${redirectTo}?${buildUrlQueryString({ + eventId, + orgUnitId, + initMode: dataEntryKeys.EDIT, })}`, ); return EMPTY; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js new file mode 100644 index 0000000000..a38c30e4e5 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js @@ -0,0 +1,79 @@ +// @flow +import { pipe } from 'capture-core-utils'; +import moment from 'moment'; +import { dataElementTypes, ProgramStage } from '../../../../../metaData'; +import { convertFormToClient, convertClientToServer } from '../../../../../converters'; +import { convertCategoryOptionsToServer } from '../../../../../converters/clientToServer'; + +const convertFn = pipe(convertFormToClient, convertClientToServer); + +const ignoreAutoGenerateIfApplicable = (stage, firstStageDuringRegistrationEvent) => + !firstStageDuringRegistrationEvent || firstStageDuringRegistrationEvent.id !== stage.id; + +export const deriveAutoGenerateEvents = ({ + stages, + enrolledAt, + occurredAt, + programId, + orgUnitId, + firstStageMetadata, + attributeCategoryOptions, +}: { + stages: Map, + enrolledAt: string, + occurredAt: string, + programId: string, + orgUnitId: string, + firstStageMetadata: ProgramStage, + attributeCategoryOptions: { [categoryId: string]: string } | string, +}) => { + // in case we have a program that does not have an incident date (occurredAt), such as Malaria case diagnosis, + // we want the incident to default to enrollmentDate (enrolledAt) + const sanitizedOccurredAt = occurredAt || enrolledAt; + + // $FlowFixMe[missing-annot] + return [...stages.values()] + .filter(({ autoGenerateEvent }) => autoGenerateEvent) + .filter(stage => ignoreAutoGenerateIfApplicable(stage, firstStageMetadata)) + .map( + ({ + id: programStage, + reportDateToUse: reportDateToUseInActiveStatus, + generatedByEnrollmentDate: generateScheduleDateByEnrollmentDate, + openAfterEnrollment, + minDaysFromStart, + }) => { + const dateToUseInActiveStatus = + reportDateToUseInActiveStatus === 'enrolledAt' ? enrolledAt : sanitizedOccurredAt; + const dateToUseInScheduleStatus = generateScheduleDateByEnrollmentDate + ? enrolledAt + : sanitizedOccurredAt; + const eventAttributeCategoryOptions = {}; + if (attributeCategoryOptions) { + eventAttributeCategoryOptions.attributeCategoryOptions = + convertCategoryOptionsToServer(attributeCategoryOptions); + } + const eventInfo = openAfterEnrollment + ? { + status: 'ACTIVE', + occurredAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), + scheduledAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), + } + : { + status: 'SCHEDULE', + // for schedule type of events we want to add the standard interval days to the date + scheduledAt: moment(convertFn(dateToUseInScheduleStatus, dataElementTypes.DATE)) + .add(minDaysFromStart, 'days') + .format('YYYY-MM-DD'), + }; + + return { + ...eventInfo, + ...eventAttributeCategoryOptions, + programStage, + program: programId, + orgUnit: orgUnitId, + }; + }, + ); +}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js new file mode 100644 index 0000000000..bf40f45135 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js @@ -0,0 +1,55 @@ +// @flow +import { pipe } from 'capture-core-utils'; +import { dataElementTypes, ProgramStage } from '../../../../../metaData'; +import { convertFormToClient, convertClientToServer } from '../../../../../converters'; +import { convertCategoryOptionsToServer } from '../../../../../converters/clientToServer'; +import { convertStatusOut } from '../../../../DataEntries'; +import { standardGeoJson } from './standardGeoJson'; + +const convertFn = pipe(convertFormToClient, convertClientToServer); + +export const deriveFirstStageDuringRegistrationEvent = ({ + firstStageMetadata, + programId, + orgUnitId, + currentEventValues, + fieldsValue, + attributeCategoryOptions, +}: { + firstStageMetadata: ProgramStage, + programId: string, + orgUnitId: string, + currentEventValues?: { [id: string]: any }, + fieldsValue: { [id: string]: any }, + attributeCategoryOptions: { [categoryId: string]: string } | string, +}) => { + if (!firstStageMetadata) { + return null; + } + const { enrolledAt, stageComplete, stageOccurredAt, stageGeometry } = fieldsValue; + + const eventAttributeCategoryOptions = attributeCategoryOptions + ? { attributeCategoryOptions: convertCategoryOptionsToServer(attributeCategoryOptions) } + : {}; + + const event = { + status: convertStatusOut(stageComplete), + geometry: standardGeoJson(stageGeometry), + occurredAt: convertFn(stageOccurredAt, dataElementTypes.DATE), + scheduledAt: convertFn(enrolledAt, dataElementTypes.DATE), + programStage: firstStageMetadata.id, + program: programId, + orgUnit: orgUnitId, + ...eventAttributeCategoryOptions, + }; + + const dataValues = currentEventValues ? Object.keys(currentEventValues).reduce((acc, dataElement) => { + acc.push({ dataElement, value: currentEventValues[dataElement] }); + return acc; + }, []) : undefined; + + if (dataValues) { + return { ...event, dataValues }; + } + return event; +}; 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 new file mode 100644 index 0000000000..26bd03daad --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js @@ -0,0 +1,45 @@ +// @flow +import { ProgramStage } from '../../../../../metaData'; + +export const PAGES = { + enrollmentEventNew: 'enrollmentEventNew', + enrollmentEventEdit: 'enrollmentEventEdit', + enrollmentDashboard: 'enrollmentDashboard', +}; + +// an event can be created either during first stage registration or autogenerated +// when the event will be created redirect to enrollmentEventEdit +// when the event will not be created redirect to enrollmentEventNew +export const getStageWithOpenAfterEnrollment = ( + stages: Map, + firstStageMetadata: ProgramStage, + shouldRedirect: boolean, +) => { + const stagesArray = [...stages.values()]; + const [firstStageWithOpenAfterEnrollment] = stagesArray.filter(({ openAfterEnrollment }) => openAfterEnrollment); + + const redirectTo = (() => { + if (shouldRedirect && firstStageWithOpenAfterEnrollment) { + // event will be created during first stage registration + if ( + firstStageMetadata && + firstStageMetadata.id === firstStageWithOpenAfterEnrollment.id + ) { + return PAGES.enrollmentEventEdit; + } + // event will be autogenerated + if ( + stagesArray.find(stage => stage.autoGenerateEvent && stage.id === firstStageWithOpenAfterEnrollment.id) + ) { + return PAGES.enrollmentEventEdit; + } + return PAGES.enrollmentEventNew; + } + return PAGES.enrollmentDashboard; + })(); + + return { + stageWithOpenAfterEnrollment: firstStageWithOpenAfterEnrollment, + redirectTo, + }; +}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js new file mode 100644 index 0000000000..fe7c884a9e --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js @@ -0,0 +1,5 @@ +// @flow +export { deriveFirstStageDuringRegistrationEvent } from './deriveFirstStageDuringRegistrationEvent'; +export { deriveAutoGenerateEvents } from './deriveAutoGenerateEvents'; +export { getStageWithOpenAfterEnrollment, PAGES } from './getStageWithOpenAfterEnrollment'; +export { standardGeoJson } from './standardGeoJson'; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js new file mode 100644 index 0000000000..4342ab42c8 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js @@ -0,0 +1,19 @@ +// @flow + +export const standardGeoJson = (geometry: Array | { longitude: number, latitude: number }) => { + if (!geometry) { + return undefined; + } + if (Array.isArray(geometry)) { + return { + type: 'Polygon', + coordinates: geometry, + }; + } else if (geometry.longitude && geometry.latitude) { + return { + type: 'Point', + coordinates: [geometry.longitude, geometry.latitude], + }; + } + return undefined; +}; diff --git a/src/core_modules/capture-core/components/TeiSearch/epics/teiSearch.epics.js b/src/core_modules/capture-core/components/TeiSearch/epics/teiSearch.epics.js index fd38591735..4b0fd58a51 100644 --- a/src/core_modules/capture-core/components/TeiSearch/epics/teiSearch.epics.js +++ b/src/core_modules/capture-core/components/TeiSearch/epics/teiSearch.epics.js @@ -35,7 +35,7 @@ import type { QuerySingleResource } from '../../../utils/api/api.types'; const getOuQueryArgs = (orgUnit: ?Object, orgUnitScope: string) => (orgUnitScope !== 'ACCESSIBLE' ? - { ou: orgUnit && orgUnit.id, ouMode: orgUnitScope } : + { orgUnit: orgUnit && orgUnit.id, ouMode: orgUnitScope } : { ouMode: orgUnitScope }); const getContextQueryArgs = (programId: ?string, trackedEntityTypeId: string) => diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js index 6561b81018..5542c3e8d4 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js @@ -394,7 +394,7 @@ type Props = { }, theme: Theme, dataEntryId: string, - onCancelEditEvent?: () => void, + onCancelEditEvent?: (isScheduled: boolean) => void, eventStatus?: string, enrollmentId?: string, isCompleted?: boolean, diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js index eb4e6b0829..0a701bf622 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js @@ -103,7 +103,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props): any => ({ cancelEditEventDataEntry(), ...(isScheduled ? [] : [setCurrentDataEntry(props.dataEntryId, dataEntryKeys.VIEW)]), ])); - isScheduled && onCancelEditEvent && onCancelEditEvent(); + onCancelEditEvent && onCancelEditEvent(isScheduled); }, onDelete: () => { const { enrollmentId } = props; diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js b/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js index 16536ce27c..8dbc06e0c6 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js @@ -6,7 +6,7 @@ export type Props = {| programStage: ProgramStage, eventStatus?: string, onGoBack: () => void, - onCancelEditEvent: () => void, + onCancelEditEvent: (isScheduled: boolean) => void, onHandleScheduleSave: (eventData: Object) =>void, orgUnitId: string, programId: string, diff --git a/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js b/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js index 80b36d6210..c3a62fbb53 100644 --- a/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js +++ b/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js @@ -1,13 +1,22 @@ // @flow import { useSelector } from 'react-redux'; +import { useMemo } from 'react'; import { dataEntryKeys } from 'capture-core/constants'; import { statusTypes } from '../events/statusTypes'; +import { useLocationQuery } from '../utils/routing'; export const useEnrollmentEditEventPageMode = (eventStatus?: string) => { const showEditEvent = useSelector(({ viewEventPage }) => viewEventPage?.eventDetailsSection?.showEditEvent); + const { initMode } = useLocationQuery(); - if (eventStatus === statusTypes.SCHEDULE || eventStatus === statusTypes.OVERDUE) { - return { currentPageMode: dataEntryKeys.EDIT }; - } - return { currentPageMode: showEditEvent ? dataEntryKeys.EDIT : dataEntryKeys.VIEW }; + return useMemo(() => { + if (initMode) { + return { currentPageMode: initMode }; + } + + if (eventStatus === statusTypes.SCHEDULE || eventStatus === statusTypes.OVERDUE) { + return { currentPageMode: dataEntryKeys.EDIT }; + } + return { currentPageMode: showEditEvent ? dataEntryKeys.EDIT : dataEntryKeys.VIEW }; + }, [initMode, showEditEvent, eventStatus]); }; diff --git a/src/core_modules/capture-core/metaData/DataElement/DataElement.js b/src/core_modules/capture-core/metaData/DataElement/DataElement.js index c336e0f4f5..5555d4842e 100644 --- a/src/core_modules/capture-core/metaData/DataElement/DataElement.js +++ b/src/core_modules/capture-core/metaData/DataElement/DataElement.js @@ -11,6 +11,7 @@ import { OptionSet } from '../OptionSet/OptionSet'; import type { Unique } from './Unique'; import { dataElementTypes } from './dataElementTypes'; import type { CachedAttributeValue } from '../../storageControllers'; +import type { Section } from '../RenderFoundation'; // eslint-disable-next-line no-use-before-define export type ConvertFn = (value: any, type: $Keys, element: DataElement) => any; @@ -37,6 +38,7 @@ export class DataElement { _searchable: ?boolean; _url: ?string; _attributeValues: Array + _section: ?Section; constructor(initFn: ?(_this: DataElement) => void) { this._displayInReports = true; @@ -60,6 +62,13 @@ export class DataElement { return this._name; } + set section(section: ?Section) { + this._section = section; + } + get section(): ?Section { + return this._section; + } + set code(code: string) { this._code = code; } diff --git a/src/core_modules/capture-core/metaData/Program/Program.js b/src/core_modules/capture-core/metaData/Program/Program.js index e3d9645332..88ff443877 100644 --- a/src/core_modules/capture-core/metaData/Program/Program.js +++ b/src/core_modules/capture-core/metaData/Program/Program.js @@ -25,6 +25,7 @@ export class Program { _programRuleVariables: Array; _icon: Icon | void; _displayFrontPageList: boolean; + _useFirstStageDuringRegistration: boolean; _onlyEnrollOnce: boolean; constructor(initFn: ?(_this: Program) => void) { @@ -115,6 +116,14 @@ export class Program { return this._displayFrontPageList; } + set useFirstStageDuringRegistration(useFirstStageDuringRegistration: boolean) { + this._useFirstStageDuringRegistration = useFirstStageDuringRegistration; + } + + get useFirstStageDuringRegistration() { + return this._useFirstStageDuringRegistration; + } + set onlyEnrollOnce(onlyEnrollOnce: boolean) { this._onlyEnrollOnce = onlyEnrollOnce; } diff --git a/src/core_modules/capture-core/metaData/Program/ProgramStage.js b/src/core_modules/capture-core/metaData/Program/ProgramStage.js index 1c501643ca..403a2df333 100644 --- a/src/core_modules/capture-core/metaData/Program/ProgramStage.js +++ b/src/core_modules/capture-core/metaData/Program/ProgramStage.js @@ -20,6 +20,7 @@ export class ProgramStage { _openAfterEnrollment: boolean; _allowGenerateNextVisit: boolean; _generatedByEnrollmentDate: boolean; + _repeatable: boolean; _hideDueDate: boolean; _reportDateToUse: string; _minDaysFromStart: number; @@ -156,4 +157,12 @@ export class ProgramStage { get programRules(): Array { return this._programRules; } + + set repeatable(repeatable: boolean) { + this._repeatable = repeatable; + } + + get repeatable(): boolean { + return this._repeatable; + } } diff --git a/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js b/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js index 8c11e94144..9fdf44a12f 100644 --- a/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js +++ b/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js @@ -4,7 +4,7 @@ import log from 'loglevel'; import { errorCreator } from 'capture-core-utils'; import isFunction from 'd2-utilizr/lib/isFunction'; import { validationStrategies, validationStrategiesAsArray } from './renderFoundation.const'; -import type { Section } from './Section'; +import { Section } from './Section'; import type { ConvertFn } from '../DataElement/DataElement'; import type { Access } from '../Access'; import { convertDataElementsValues } from '../helpers'; @@ -163,4 +163,20 @@ export class RenderFoundation { const dataElements = this.getElements(); return convertDataElementsValues(values, dataElements, onConvert); } + + convertAndGroupBySection(currentFormData: {[id: string]: any}, onConvert: ConvertFn) { + const metaElements = [...this.getElements().values()]; + + return Object.keys(currentFormData).reduce((acc, id) => { + const metaElement = metaElements.find(o => o.id === id); + const rawValue = currentFormData[id]; + const convertedValue = metaElement ? metaElement.convertValue(rawValue, onConvert) : rawValue; + const group = metaElement?.section?.group; + if (group) { + acc[group] = { ...acc[group], [id]: convertedValue }; + return acc; + } + return { ...acc, [id]: convertedValue }; + }, {}); + } } diff --git a/src/core_modules/capture-core/metaData/RenderFoundation/Section.js b/src/core_modules/capture-core/metaData/RenderFoundation/Section.js index d312f59842..411067757b 100644 --- a/src/core_modules/capture-core/metaData/RenderFoundation/Section.js +++ b/src/core_modules/capture-core/metaData/RenderFoundation/Section.js @@ -15,6 +15,11 @@ export class Section { DATA_ELEMENT_NOT_FOUND: 'Data element was not found', }; + static groups = { + ENROLLMENT: 'ENROLLMENT', + EVENT: 'EVENT', + } + _id: string; _name: string; _displayDescription: string; @@ -24,6 +29,7 @@ export class Section { _elements: Map; _showContainer: boolean; _customForm: ?CustomForm; + _group: string; constructor(initFn: (_this: Section) => void) { this._visible = true; @@ -90,6 +96,13 @@ export class Section { return this._elements; } + set group(group: string) { + this._group = group; + } + get group(): string { + return this._group; + } + addElement(element: DataElement | FormFieldPluginConfig) { if (!this.elements.has(element.id)) { this.elements.set(element.id, element); diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js index 3fa73e1130..18e56e1869 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js @@ -15,6 +15,7 @@ import { DataElementUnique, dataElementUniqueScope, dataElementTypes, + Section, } from '../../../../metaData'; import { OptionSetFactory } from '../../../common/factory'; import { convertFormToClient, convertClientToServer } from '../../../../converters'; @@ -37,8 +38,9 @@ export class DataElementFactory { 'could not create the metadata because a MULIT_TEXT without associated option sets was found', }; - static buildtetFeatureType(featureType: 'POINT' | 'POLYGON') { + static buildtetFeatureType(featureType: 'POINT' | 'POLYGON', section: Section) { const dataElement = new DataElement((o) => { + o.section = section; o.id = `FEATURETYPE_${featureType}`; o.name = featureType === 'POINT' ? i18n.t('Coordinate') : i18n.t('Area'); o.formName = o.name; @@ -206,8 +208,10 @@ export class DataElementFactory { async _buildBaseDataElement( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute: CachedTrackedEntityAttribute, + section?: Section, ) { const dataElement = new DataElement(); + dataElement.section = section; dataElement.type = cachedTrackedEntityAttribute.valueType; await this._setBaseProperties( dataElement, @@ -224,10 +228,12 @@ export class DataElementFactory { async _buildDateDataElement( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute: CachedTrackedEntityAttribute, + section?: Section, ) { const dateDataElement = new DateDataElement(); dateDataElement.type = dataElementTypes.DATE; dateDataElement.allowFutureDate = cachedProgramTrackedEntityAttribute.allowFutureDate; + dateDataElement.section = section; await this._setBaseProperties( dateDataElement, cachedProgramTrackedEntityAttribute, @@ -238,6 +244,7 @@ export class DataElementFactory { build( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, + section?: Section, ) { const cachedTrackedEntityAttribute = cachedProgramTrackedEntityAttribute.trackedEntityAttributeId && this.cachedTrackedEntityAttributes.get( @@ -253,7 +260,7 @@ export class DataElementFactory { } return cachedTrackedEntityAttribute.valueType === dataElementTypes.DATE ? - this._buildDateDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute) : - this._buildBaseDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute); + this._buildDateDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute, section) : + this._buildBaseDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute, section); } } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js index 19230eace9..3358d5f648 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js @@ -78,7 +78,7 @@ export class EnrollmentFactory { }); } - _buildTetFeatureTypeField(trackedEntityTypeId: ?string) { + _buildTetFeatureTypeField(trackedEntityTypeId: ?string, section: Section) { const teType = trackedEntityTypeId && this.cachedTrackedEntityTypes.get(trackedEntityTypeId); if (!teType) { return null; @@ -90,23 +90,24 @@ export class EnrollmentFactory { } // $FlowFixMe - return DataElementFactory.buildtetFeatureType(featureType); + return DataElementFactory.buildtetFeatureType(featureType, section); } async _buildTetFeatureTypeSection( cachedProgramTrackedEntityTypeId: string, ) { - const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId); const trackedEntityType = this.cachedTrackedEntityTypes.get(cachedProgramTrackedEntityTypeId); - if (!featureTypeField) { - return null; - } - const section = new Section((o) => { o.id = cachedProgramTrackedEntityTypeId; o.name = trackedEntityType?.displayName || ''; + o.group = Section.groups.ENROLLMENT; }); + const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId, section); + + if (!featureTypeField) { + return null; + } featureTypeField && section.addElement(featureTypeField); return section; @@ -119,12 +120,13 @@ export class EnrollmentFactory { const section = new Section((o) => { o.id = Section.MAIN_SECTION_ID; o.name = i18n.t('Profile'); + o.group = Section.groups.ENROLLMENT; }); if (!cachedProgramTrackedEntityAttributes?.length) { return null; } if (cachedProgramTrackedEntityTypeId) { - const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId); + const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId, section); featureTypeField && section.addElement(featureTypeField); } @@ -166,7 +168,7 @@ export class EnrollmentFactory { element && section.addElement(element); } else { - const element = await this.dataElementFactory.build(trackedEntityAttribute); + const element = await this.dataElementFactory.build(trackedEntityAttribute, section); element && section.addElement(element); } }); @@ -185,6 +187,7 @@ export class EnrollmentFactory { const section = new Section((o) => { o.id = cachedSectionCustomId; o.name = cachedSectionCustomLabel; + o.group = Section.groups.ENROLLMENT; }); await this._buildElementsForSection(cachedProgramTrackedEntityAttributes, section); @@ -200,6 +203,7 @@ export class EnrollmentFactory { let section = new Section((o) => { o.id = Section.MAIN_SECTION_ID; + o.group = Section.groups.ENROLLMENT; }); section.showContainer = false; @@ -353,6 +357,7 @@ export class EnrollmentFactory { const foundation = new RenderFoundation(); const section = new Section((oSection) => { oSection.id = Section.MAIN_SECTION_ID; + oSection.group = Section.groups.ENROLLMENT; }); Array.from( searchGroupFoundation diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js index b76d755531..28ff91fe67 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js @@ -175,6 +175,7 @@ export class ProgramFactory { program.icon = buildIcon(cachedProgram.style); program.displayFrontPageList = cachedProgram.displayFrontPageList; program.onlyEnrollOnce = cachedProgram.onlyEnrollOnce; + program.useFirstStageDuringRegistration = cachedProgram.useFirstStageDuringRegistration; return program; } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js index 389b6dcc4c..6bd83c7f08 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js @@ -9,7 +9,7 @@ import type { CachedProgramStageDataElement, CachedOptionSet, } from '../../../../storageControllers/cache.types'; -import { DataElement, DateDataElement, dataElementTypes } from '../../../../metaData'; +import { DataElement, DateDataElement, dataElementTypes, Section } from '../../../../metaData'; import { buildIcon } from '../../../common/helpers'; import { OptionSetFactory } from '../../../common/factory'; import { isNotValidOptionSet } from '../../../../utils/isNotValidOptionSet'; @@ -99,8 +99,10 @@ export class DataElementFactory { cachedProgramStageDataElement: CachedProgramStageDataElement, cachedDataElement: CachedDataElement, dataElementType: $Keys, + section: ?Section, ) { const dataElement = new DataElement(); + dataElement.section = section; dataElement.type = dataElementType; await this._setBaseProperties(dataElement, cachedProgramStageDataElement, cachedDataElement); if (isNotValidOptionSet(dataElement.type, dataElement.optionSet)) { @@ -123,6 +125,7 @@ export class DataElementFactory { async build( cachedProgramStageDataElement: CachedProgramStageDataElement, + section: ?Section, ): Promise { const cachedDataElement = await getUserStorageController().get(userStores.DATA_ELEMENTS, cachedProgramStageDataElement.dataElementId); @@ -139,6 +142,6 @@ export class DataElementFactory { return dataElementType === dataElementTypes.DATE ? this._buildDateDataElement(cachedProgramStageDataElement, cachedDataElement) : - this._buildBaseDataElement(cachedProgramStageDataElement, cachedDataElement, dataElementType); + this._buildBaseDataElement(cachedProgramStageDataElement, cachedDataElement, dataElementType, section); } } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js index adc65c2f5a..83bc11b8ff 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js @@ -65,7 +65,7 @@ export class ProgramStageFactory { { sectionDataElement })); return; } - const element = await this.dataElementFactory.build(cachedProgramStageDataElement); + const element = await this.dataElementFactory.build(cachedProgramStageDataElement, section); element && section.addElement(element); }); } @@ -81,7 +81,7 @@ export class ProgramStageFactory { if (cachedProgramStageDataElements) { // $FlowFixMe await cachedProgramStageDataElements.asyncForEach((async (cachedProgramStageDataElement) => { - const element = await this.dataElementFactory.build(cachedProgramStageDataElement); + const element = await this.dataElementFactory.build(cachedProgramStageDataElement, section); element && section.addElement(element); })); } @@ -128,6 +128,7 @@ export class ProgramStageFactory { _stage.generatedByEnrollmentDate = !!cachedProgramStage.generatedByEnrollmentDate; _stage.reportDateToUse = cachedProgramStage.reportDateToUse; _stage.minDaysFromStart = cachedProgramStage.minDaysFromStart; + _stage.repeatable = cachedProgramStage.repeatable; _stage.stageForm = new RenderFoundation((_form) => { _form.id = cachedProgramStage.id; _form.name = cachedProgramStage.displayName; diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js index 1e04d03ec7..adebf39a14 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js @@ -80,7 +80,7 @@ const convert = (() => { }; })(); -const fieldsParam = 'id,displayName,displayShortName,description,programType,style,displayFrontPageList,onlyEnrollOnce,' + +const fieldsParam = 'id,displayName,displayShortName,description,programType,style,displayFrontPageList,useFirstStageDuringRegistration,onlyEnrollOnce,' + 'minAttributesRequiredToSearch,enrollmentDateLabel,incidentDateLabel,' + 'featureType,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,displayIncidentDate,' + 'dataEntryForm[id,htmlCode],' + diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js index 32c02464d8..70ac391972 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js @@ -140,6 +140,7 @@ type apiProgram = { featureType?: ?string, selectEnrollmentDatesInFuture: boolean, displayFrontPageList: boolean, + useFirstStageDuringRegistration: boolean, selectIncidentDatesInFuture: boolean, displayIncidentDate: boolean, dataEntryForm?: ?apiDataEntryForm, diff --git a/src/core_modules/capture-core/rules/getApplicableRuleEffects.js b/src/core_modules/capture-core/rules/getApplicableRuleEffects.js index 57ffddac38..2d261aef78 100644 --- a/src/core_modules/capture-core/rules/getApplicableRuleEffects.js +++ b/src/core_modules/capture-core/rules/getApplicableRuleEffects.js @@ -74,6 +74,7 @@ export const getApplicableRuleEffectsForTrackerProgram = ({ otherEvents, attributeValues, enrollmentData, + formFoundation, }: GetApplicableRuleEffectsForTrackerProgramInput, flattenedResult: boolean = false, ) => { @@ -82,6 +83,7 @@ flattenedResult: boolean = false, program.programRules, stage?.programRules, ); + const foundationForPostProcessing = formFoundation || (stage ? stage.stageForm : program.enrollment.enrollmentForm); if (!programRules.length) { return []; } @@ -103,7 +105,7 @@ flattenedResult: boolean = false, programRules, programRuleVariables, trackedEntityAttributes: getTrackedEntityAttributesForRulesExecution(program.attributes), - foundationForPostProcessing: stage ? stage.stageForm : program.enrollment.enrollmentForm, + foundationForPostProcessing, }); return flattenedResult ? effects : buildEffectsHierarchy(effects); diff --git a/src/core_modules/capture-core/rules/rules.types.js b/src/core_modules/capture-core/rules/rules.types.js index 606ae8336f..0249ee664c 100644 --- a/src/core_modules/capture-core/rules/rules.types.js +++ b/src/core_modules/capture-core/rules/rules.types.js @@ -19,6 +19,7 @@ export type GetApplicableRuleEffectsForTrackerProgramInput = {| otherEvents?: EventsData, attributeValues?: TEIValues, enrollmentData?: Enrollment, + formFoundation?: RenderFoundation, |}; export type GetApplicableRuleEffectsForEventProgramInput = {| diff --git a/src/core_modules/capture-core/storageControllers/cache.types.js b/src/core_modules/capture-core/storageControllers/cache.types.js index 18e2c3fbb0..49ce4a64ca 100644 --- a/src/core_modules/capture-core/storageControllers/cache.types.js +++ b/src/core_modules/capture-core/storageControllers/cache.types.js @@ -119,6 +119,7 @@ export type CachedProgramStage = { generatedByEnrollmentDate?: ?boolean, hideDueDate?: ?boolean, reportDateToUse: string, + repeatable: boolean, minDaysFromStart: number, style?: ?CachedStyle, }; @@ -204,6 +205,7 @@ export type CachedProgram = { selectIncidentDatesInFuture: boolean, displayIncidentDate: boolean, onlyEnrollOnce: boolean, + useFirstStageDuringRegistration: boolean, }; export type CachedProgramStageDataElementsAsObject = {