diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f8e81a1bc..f7f253ddd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,31 @@ +## [101.21.3](https://github.com/dhis2/capture-app/compare/v101.21.2...v101.21.3) (2025-01-12) + + +### Bug Fixes + +* [DHIS2-17613] Use new note endpoint ([#3908](https://github.com/dhis2/capture-app/issues/3908)) ([a9fdea8](https://github.com/dhis2/capture-app/commit/a9fdea8ac8284b28ec3c0acf0551e9cd1a68a180)) + +## [101.21.2](https://github.com/dhis2/capture-app/compare/v101.21.1...v101.21.2) (2025-01-09) + + +### Bug Fixes + +* [DHIS2-18569] Relationship widget limited to 50 entries ([#3927](https://github.com/dhis2/capture-app/issues/3927)) ([a1e493d](https://github.com/dhis2/capture-app/commit/a1e493d48179e7749d61f52504fdeb3c11dfa53e)) + +## [101.21.1](https://github.com/dhis2/capture-app/compare/v101.21.0...v101.21.1) (2025-01-08) + + +### Bug Fixes + +* [DHIS2-18632] Sorting stage detail table on orgunit breaks the app ([#3917](https://github.com/dhis2/capture-app/issues/3917)) ([15414cc](https://github.com/dhis2/capture-app/commit/15414cc73f7ce74d4d057acad13bf4855d358426)) + +# [101.21.0](https://github.com/dhis2/capture-app/compare/v101.20.3...v101.21.0) (2025-01-07) + + +### Features + +* [DHIS2-18328] Handle log entries for occurredAt, scheduledAt and geometry ([#3887](https://github.com/dhis2/capture-app/issues/3887)) ([f670971](https://github.com/dhis2/capture-app/commit/f670971808f49b75295c1d3c7ef25a747b4888df)) + ## [101.20.3](https://github.com/dhis2/capture-app/compare/v101.20.2...v101.20.3) (2024-12-29) diff --git a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature index e944741b2f..a18e595f6b 100644 --- a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature +++ b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.feature @@ -71,7 +71,7 @@ Feature: User interacts with Stages and Events Widget @with-restore-deleted-event Scenario: User can delete an event - Given you open the enrollment page by typing #/enrollment?enrollmentId=ikYMpSKXik1&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=Trc1H9T5C6f + Given you open the enrollment page by typing #/enrollment?enrollmentId=ITyaPVATEwc&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=wsk89u7zquT And there is an Active event in the TB visit stage When you click the Delete event overflow button on the Active event And you confirm you want to delete the event diff --git a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js index 35d8996ee7..bf5334da58 100644 --- a/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js +++ b/cypress/e2e/EnrollmentPage/StagesAndEventsWidget/StagesAndEventsWidget.js @@ -3,7 +3,7 @@ import { getCurrentYear } from '../../../support/date'; import '../sharedSteps'; After({ tags: '@with-restore-deleted-event' }, () => { - cy.visit('#/enrollment?enrollmentId=ikYMpSKXik1&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=Trc1H9T5C6f'); + cy.visit('#/enrollment?enrollmentId=ITyaPVATEwc&orgUnitId=DiszpKrYNg8&programId=ur1Edk5Oe2n&teiId=wsk89u7zquT'); cy.get('[data-test="stages-and-events-widget"]') .find('[data-test="widget-contents"]') @@ -215,7 +215,7 @@ When(/you click the (.*) event overflow button on the (.*) event$/, (buttonName, cy.get('[data-test="overflow-menu"]') .contains(buttonName) - .click(); + .click({ force: true }); }); Then('the event should be skipped', () => { diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js b/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js index 9f4148abf9..fe8fdfee12 100644 --- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js +++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetEnrollment/index.js @@ -9,10 +9,10 @@ After({ tags: '@with-transfer-ownership-data-cleanup' }, () => { }); const changeEnrollmentAndEventsStatus = () => ( - cy.buildApiUrl('tracker', 'trackedEntities/osF4RF4EiqP?program=IpHINAT79UW&fields=enrollments') + cy.buildApiUrl('tracker', 'trackedEntities/mPLqCVS27AD?program=IpHINAT79UW&fields=enrollments') .then(url => cy.request(url)) .then(({ body }) => { - const enrollment = body.enrollments && body.enrollments.find(e => e.enrollment === 'qyx7tscVpVB'); + const enrollment = body.enrollments && body.enrollments.find(e => e.enrollment === 'YqNTNLKmX4z'); const eventsToUpdate = enrollment.events.map(e => ({ ...e, status: 'ACTIVE', diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/WidgetsForEnrollmentAddEventPage.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/WidgetsForEnrollmentAddEventPage.feature index 0ab586b19f..cd6062c7fe 100644 --- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/WidgetsForEnrollmentAddEventPage.feature +++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/WidgetsForEnrollmentAddEventPage.feature @@ -68,7 +68,7 @@ Feature: The user interacts with the widgets on the enrollment add event page Then you can assign a user when scheduling the event Scenario: User can complete the enrollment and the active events - Given you land on the enrollment edit event page by having typed #/enrollmentEventNew?enrollmentId=qyx7tscVpVB&orgUnitId=DiszpKrYNg8&programId=IpHINAT79UW&teiId=osF4RF4EiqP + Given you land on the enrollment edit event page by having typed #/enrollmentEventNew?enrollmentId=YqNTNLKmX4z&orgUnitId=RzgSFJ9E46G&programId=IpHINAT79UW&teiId=mPLqCVS27AD And the enrollment widget should be opened And the user sees the enrollment status and the Baby Postnatal event status is active And the user opens the enrollment actions menu diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/WidgetsForEnrollmentDashboard.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/WidgetsForEnrollmentDashboard.feature index ffd0a56c1c..76b3465297 100644 --- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/WidgetsForEnrollmentDashboard.feature +++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/WidgetsForEnrollmentDashboard.feature @@ -127,7 +127,7 @@ Feature: The user interacts with the widgets on the enrollment dashboard Then the user can see the program rules effect in the indicator widget Scenario: User can complete the enrollment and the active events - Given you land on the enrollment dashboard page by having typed #/enrollment?enrollmentId=qyx7tscVpVB + Given you land on the enrollment dashboard page by having typed #/enrollment?enrollmentId=YqNTNLKmX4z And the enrollment widget should be opened And the user sees the enrollment status and the Baby Postnatal event status is active And the user opens the enrollment actions menu diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent/WidgetsForEnrollmentEditEvent.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent/WidgetsForEnrollmentEditEvent.feature index 39bd30c304..defa075922 100644 --- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent/WidgetsForEnrollmentEditEvent.feature +++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent/WidgetsForEnrollmentEditEvent.feature @@ -105,7 +105,7 @@ Feature: The user interacts with the widgets on the enrollment edit event Then the table footer should display page 2 Scenario: User can complete the enrollment and the active events - Given you land on the enrollment edit event page by having typed #/enrollmentEventEdit?eventId=OWpIzQ4xabC&orgUnitId=DiszpKrYNg8 + Given you land on the enrollment edit event page by having typed #/enrollmentEventEdit?eventId=PyXThVzWJzL&orgUnitId=RzgSFJ9E46G And the enrollment widget should be opened And the user sees the enrollment status and the Baby Postnatal event status is active And the user opens the enrollment actions menu diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiBulkActions/TeiBulkActions.feature b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiBulkActions/TeiBulkActions.feature index f79f4faf87..40b383e7b3 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiBulkActions/TeiBulkActions.feature +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiBulkActions/TeiBulkActions.feature @@ -31,6 +31,8 @@ Feature: User facing tests for bulk actions on Tracked Entity working lists When you select the first 5 rows Then the filters should be disabled +#DHIS2-18447 +@skip Scenario: The user should see an error message when trying to bulk complete enrollments with errors Given you open the main page with Ngelehun and Malaria focus investigation context And you select the first 3 rows diff --git a/i18n/en.pot b/i18n/en.pot index 2f414dc91a..0e6ac05309 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-12-05T11:39:04.447Z\n" -"PO-Revision-Date: 2024-12-05T11:39:04.447Z\n" +"POT-Creation-Date: 2024-12-15T15:25:38.375Z\n" +"PO-Revision-Date: 2024-12-15T15:25:38.375Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." @@ -101,6 +101,24 @@ msgstr "Date of enrollment" msgid "Last updated" msgstr "Last updated" +msgid "Lat" +msgstr "Lat" + +msgid "Long" +msgstr "Long" + +msgid "lat" +msgstr "lat" + +msgid "long" +msgstr "long" + +msgid "Show less" +msgstr "Show less" + +msgid "Show more" +msgstr "Show more" + msgid "error encountered during field validation" msgstr "error encountered during field validation" diff --git a/package.json b/package.json index e4caffa666..c2073915df 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "101.20.3", + "version": "101.21.3", "cacheVersion": "7", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "101.20.3", + "@dhis2/rules-engine-javascript": "101.21.3", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", @@ -130,7 +130,7 @@ "jsdoc-export-default-interop": "^0.3.1", "node-fetch": "2", "redux-devtools-extension": "^2.13.9", - "wait-on": "^7.2.0" + "wait-on": "^8.0.1" }, "resolutions": { "@dhis2/cli-app-scripts": "^10.4.0", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 0ae04d0315..b02dbbed4f 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "101.20.3", + "version": "101.21.3", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { diff --git a/src/core_modules/capture-core-utils/featuresSupport/support.js b/src/core_modules/capture-core-utils/featuresSupport/support.js index ff5fb4f11a..230d027a8d 100644 --- a/src/core_modules/capture-core-utils/featuresSupport/support.js +++ b/src/core_modules/capture-core-utils/featuresSupport/support.js @@ -11,6 +11,8 @@ export const FEATURES = Object.freeze({ trackedEntitiesCSV: 'trackedEntitiesCSV', newAocApiSeparator: 'newAocApiSeparator', newEntityFilterQueryParam: 'newEntityFilterQueryParam', + newNoteEndpoint: 'newNoteEndpoint', + newRelationshipQueryParam: 'newRelationshipQueryParam', }); // The first minor version that supports the feature @@ -26,6 +28,8 @@ const MINOR_VERSION_SUPPORT = Object.freeze({ [FEATURES.trackedEntitiesCSV]: 40, [FEATURES.newAocApiSeparator]: 41, [FEATURES.newEntityFilterQueryParam]: 41, + [FEATURES.newNoteEndpoint]: 42, + [FEATURES.newRelationshipQueryParam]: 41, }); export const hasAPISupportForFeature = (minorVersion: string | number, featureName: string) => diff --git a/src/core_modules/capture-core/components/MinimalCoordinates/MinimalCoordinates.js b/src/core_modules/capture-core/components/Coordinates/MinimalCoordinates/MinimalCoordinates.js similarity index 61% rename from src/core_modules/capture-core/components/MinimalCoordinates/MinimalCoordinates.js rename to src/core_modules/capture-core/components/Coordinates/MinimalCoordinates/MinimalCoordinates.js index 36af51e4f5..39b23b672c 100644 --- a/src/core_modules/capture-core/components/MinimalCoordinates/MinimalCoordinates.js +++ b/src/core_modules/capture-core/components/Coordinates/MinimalCoordinates/MinimalCoordinates.js @@ -1,5 +1,6 @@ // @flow import React from 'react'; +import i18n from '@dhis2/d2-i18n'; type Props = $ReadOnly<{| latitude: number | string, @@ -8,9 +9,10 @@ type Props = $ReadOnly<{| const toSixDecimal = value => (parseFloat(value) ? parseFloat(value).toFixed(6) : null); -export const MinimalCoordinates = ({ latitude, longitude }: Props) => - (
- lat: {toSixDecimal(latitude)}
- long: {toSixDecimal(longitude)} -
); +export const MinimalCoordinates = ({ latitude, longitude }: Props) => ( +
+ {i18n.t('Lat')}: {toSixDecimal(latitude)}
+ {i18n.t('Long')}: {toSixDecimal(longitude)} +
+); diff --git a/src/core_modules/capture-core/components/MinimalCoordinates/index.js b/src/core_modules/capture-core/components/Coordinates/MinimalCoordinates/index.js similarity index 100% rename from src/core_modules/capture-core/components/MinimalCoordinates/index.js rename to src/core_modules/capture-core/components/Coordinates/MinimalCoordinates/index.js diff --git a/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/PolygonCoordinates.js b/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/PolygonCoordinates.js new file mode 100644 index 0000000000..c019bdb5fe --- /dev/null +++ b/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/PolygonCoordinates.js @@ -0,0 +1,59 @@ +// @flow +import React, { useState } from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { withStyles } from '@material-ui/core/styles'; +import { IconChevronUp16, IconChevronDown16, colors, spacers } from '@dhis2/ui'; + +type Props = $ReadOnly<{| + coordinates: Array>, + classes: { + buttonContainer: string, + viewButton: string, + }, +|}>; + +const styles = { + buttonContainer: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }, + viewButton: { + background: 'none', + border: 'none', + cursor: 'pointer', + color: colors.grey800, + marginTop: spacers.dp8, + display: 'flex', + alignItems: 'center', + '&:hover': { + textDecoration: 'underline', + color: 'black', + }, + }, +}; + +const PolygonCoordinatesPlain = ({ coordinates, classes }: Props) => { + const [showMore, setShowMore] = useState(false); + return ( + <> +
+ {coordinates.slice(0, showMore ? coordinates.length : 1).map((coordinatePair, index) => ( + // eslint-disable-next-line react/no-array-index-key +
+ {`${i18n.t('lat')}: ${coordinatePair[1]}`}
+ {`${i18n.t('long')}: ${coordinatePair[0]}`} +
+ ))} +
+
+ +
+ + ); +}; + +export const PolygonCoordinates = withStyles(styles)(PolygonCoordinatesPlain); diff --git a/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/index.js b/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/index.js new file mode 100644 index 0000000000..0c85230d28 --- /dev/null +++ b/src/core_modules/capture-core/components/Coordinates/PolygonCoordinates/index.js @@ -0,0 +1,2 @@ +// @flow +export { PolygonCoordinates } from './PolygonCoordinates'; diff --git a/src/core_modules/capture-core/components/Coordinates/index.js b/src/core_modules/capture-core/components/Coordinates/index.js new file mode 100644 index 0000000000..a7549a63b6 --- /dev/null +++ b/src/core_modules/capture-core/components/Coordinates/index.js @@ -0,0 +1,3 @@ +// @flow +export { MinimalCoordinates } from './MinimalCoordinates'; +export { PolygonCoordinates } from './PolygonCoordinates'; diff --git a/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/open.epics.js b/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/open.epics.js index cfa4280b97..3244faf794 100644 --- a/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/open.epics.js +++ b/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/open.epics.js @@ -30,7 +30,7 @@ function getTrackerProgram(suggestedProgramId: string) { log.error( errorCreator('tracker program for id not found')({ suggestedProgramId, error }), ); - throw Error(i18n('Metadata error. see log for details')); + throw Error(i18n.t('Metadata error. see log for details')); } return trackerProgram; } diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.actions.js b/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.actions.js index 5a42d5c775..7e76b2b1ec 100644 --- a/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.actions.js +++ b/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.actions.js @@ -1,4 +1,5 @@ // @flow +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { actionCreator } from '../../../../actions/actions.utils'; import { effectMethods } from '../../../../trackerOffline'; @@ -25,11 +26,13 @@ export const updateEventNoteField = (value: string) => export const requestSaveEventNote = (note: string) => actionCreator(actionTypes.REQUEST_SAVE_EVENT_NOTE)({ note }); -export const startSaveEventNote = (eventId: string, serverData: Object, selections: Object, clientId: string) => +export const startSaveEventNote = (eventUid: string, serverData: Object, selections: Object, clientId: string) => actionCreator(actionTypes.START_SAVE_EVENT_NOTE)({ selections, clientId }, { offline: { effect: { - url: `events/${eventId}/note`, + url: (featureAvailable(FEATURES.newNoteEndpoint)) + ? `tracker/events/${eventUid}/note` + : `events/${eventUid}/note`, method: effectMethods.POST, data: serverData, }, diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.epics.js b/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.epics.js index 820f9a4065..2c2c78fd8b 100644 --- a/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.epics.js +++ b/src/core_modules/capture-core/components/Pages/ViewEvent/Notes/viewEventNotes.epics.js @@ -1,6 +1,7 @@ // @flow import { batchActions } from 'redux-batched-actions'; import { ofType } from 'redux-observable'; +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { map, switchMap } from 'rxjs/operators'; import uuid from 'd2-utilizr/lib/uuid'; import moment from 'moment'; @@ -21,9 +22,15 @@ import { setNotes, } from '../../../Notes/notes.actions'; - const noteKey = 'viewEvent'; +const createServerData = (eventId, note, useNewEndpoint) => { + if (useNewEndpoint) { + return { event: eventId, value: note }; + } + return { event: eventId, notes: [{ value: note }] }; +}; + export const loadNotesForViewEventEpic = (action$: InputObservable) => action$.pipe( ofType( @@ -52,8 +59,9 @@ export const addNoteForViewEventEpic = (action$: InputObservable, store: ReduxSt switchMap((action) => { const state = store.value; const payload = action.payload; - const eventId = state.viewEventPage.eventId; + const useNewEndpoint = featureAvailable(FEATURES.newNoteEndpoint); + return querySingleResource({ resource: 'me', params: { @@ -62,10 +70,7 @@ export const addNoteForViewEventEpic = (action$: InputObservable, store: ReduxSt }).then((user) => { const { userName, firstName, surname } = user; const clientId = uuid(); - const serverData = { - event: eventId, - notes: [{ value: payload.note }], - }; + const serverData = createServerData(eventId, payload.note, useNewEndpoint); const clientNote = { value: payload.note, diff --git a/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/TrackedEntityRelationshipsWrapper/TrackedEntityRelationshipsWrapper.epics.js b/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/TrackedEntityRelationshipsWrapper/TrackedEntityRelationshipsWrapper.epics.js index 488faf8e6f..c752b65d0a 100644 --- a/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/TrackedEntityRelationshipsWrapper/TrackedEntityRelationshipsWrapper.epics.js +++ b/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/TrackedEntityRelationshipsWrapper/TrackedEntityRelationshipsWrapper.epics.js @@ -30,7 +30,7 @@ function getTrackerProgram(suggestedProgramId: string) { log.error( errorCreator('tracker program for id not found')({ suggestedProgramId, error }), ); - throw Error(i18n('Metadata error. see log for details')); + throw Error(i18n.t('Metadata error. see log for details')); } return trackerProgram; } diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.actions.js b/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.actions.js index 68d632fbb8..b2a9e299e8 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.actions.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.actions.js @@ -1,4 +1,5 @@ // @flow +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { actionCreator } from '../../actions/actions.utils'; import { effectMethods } from '../../trackerOffline'; @@ -18,11 +19,13 @@ export const batchActionTypes = { export const requestAddNoteForEnrollment = (enrollmentId: string, note: string) => actionCreator(actionTypes.REQUEST_ADD_NOTE_FOR_ENROLLMENT)({ enrollmentId, note }); -export const startAddNoteForEnrollment = (enrollmentId: string, serverData: Object, selections: Object, context: Object) => +export const startAddNoteForEnrollment = (enrollmentUid: string, serverData: Object, selections: Object, context: Object) => actionCreator(actionTypes.START_ADD_NOTE_FOR_ENROLLMENT)({ selections, context }, { offline: { effect: { - url: `enrollments/${enrollmentId}/note`, + url: (featureAvailable(FEATURES.newNoteEndpoint)) + ? `tracker/enrollments/${enrollmentUid}/note` + : `enrollments/${enrollmentUid}/note`, method: effectMethods.POST, data: serverData, }, @@ -31,5 +34,5 @@ export const startAddNoteForEnrollment = (enrollmentId: string, serverData: Obje }, }); -export const addEnrollmentNote = (enrollmentId: string, note: Object) => - actionCreator(actionTypes.ADD_ENROLLMENT_NOTE)({ enrollmentId, note }); +export const addEnrollmentNote = (enrollmentUid: string, note: Object) => + actionCreator(actionTypes.ADD_ENROLLMENT_NOTE)({ enrollmentUid, note }); diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.epics.js b/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.epics.js index ef60ee39b0..5a0fb28ebb 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.epics.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentNote/WidgetEnrollmentNote.epics.js @@ -1,18 +1,27 @@ // @flow import { batchActions } from 'redux-batched-actions'; import { ofType } from 'redux-observable'; +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { switchMap } from 'rxjs/operators'; import uuid from 'd2-utilizr/lib/uuid'; import moment from 'moment'; import { actionTypes, batchActionTypes, startAddNoteForEnrollment, addEnrollmentNote } from './WidgetEnrollmentNote.actions'; +const createServerData = (note, useNewEndpoint) => { + if (useNewEndpoint) { + return { value: note }; + } + return { notes: [{ value: note }] }; +}; + export const addNoteForEnrollmentEpic = (action$: InputObservable, store: ReduxStore, { querySingleResource }: ApiUtils) => action$.pipe( ofType(actionTypes.REQUEST_ADD_NOTE_FOR_ENROLLMENT), switchMap((action) => { const state = store.value; const { enrollmentId, note } = action.payload; + const useNewEndpoint = featureAvailable(FEATURES.newNoteEndpoint); return querySingleResource({ resource: 'me', params: { @@ -22,9 +31,7 @@ export const addNoteForEnrollmentEpic = (action$: InputObservable, store: ReduxS const { firstName, surname, userName } = user; const clientId = uuid(); - const serverData = { - notes: [{ value: note }], - }; + const serverData = createServerData(note, useNewEndpoint); const clientNote = { value: note, diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.js b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.js index e7041bdd74..2d7d294dd0 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.js @@ -1,5 +1,6 @@ // @flow import React, { useMemo } from 'react'; +import i18n from '@dhis2/d2-i18n'; import type { DataElement } from '../../../metaData'; import { dataElementTypes } from '../../../metaData'; import type { Props } from './EventChangelogWrapper.types'; @@ -42,9 +43,19 @@ export const EventChangelogWrapper = ({ formFoundation, eventId, eventData, ...p return acc; }, {}); + const additionalFields = formFoundation.featureType !== 'None' ? { + geometry: { + id: 'geometry', + name: formFoundation.featureType === 'Polygon' ? i18n.t('Area') : i18n.t('Coordinate'), + type: formFoundation.featureType === 'Polygon' ? + dataElementTypes.POLYGON : dataElementTypes.COORDINATE, + }, + } : null; + return { ...fieldElementsById, ...fieldElementsContext, + ...additionalFields, }; }, [formFoundation]); diff --git a/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.actions.js b/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.actions.js index 1bced30837..c6a0309f4e 100644 --- a/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.actions.js +++ b/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.actions.js @@ -1,4 +1,5 @@ // @flow +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { actionCreator } from '../../actions/actions.utils'; import { effectMethods } from '../../trackerOffline'; @@ -17,11 +18,13 @@ export const batchActionTypes = { export const requestAddNoteForEvent = (itemId: string, dataEntryId: string, note: string) => actionCreator(actionTypes.REQUEST_ADD_NOTE_FOR_EVENT)({ itemId, dataEntryId, note }); -export const startAddNoteForEvent = (eventId: string, serverData: Object, selections: Object, context: Object) => +export const startAddNoteForEvent = (eventUid: string, serverData: Object, selections: Object, context: Object) => actionCreator(actionTypes.START_ADD_NOTE_FOR_EVENT)({ selections, context }, { offline: { effect: { - url: `events/${eventId}/note`, + url: (featureAvailable(FEATURES.newNoteEndpoint)) + ? `tracker/events/${eventUid}/note` + : `events/${eventUid}/note`, method: effectMethods.POST, data: serverData, }, diff --git a/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.epics.js b/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.epics.js index 1bcd33222e..8aae3f0f24 100644 --- a/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.epics.js +++ b/src/core_modules/capture-core/components/WidgetEventNote/WidgetEventNote.epics.js @@ -1,6 +1,7 @@ // @flow import { batchActions } from 'redux-batched-actions'; import { ofType } from 'redux-observable'; +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { map, switchMap } from 'rxjs/operators'; import uuid from 'd2-utilizr/lib/uuid'; import moment from 'moment'; @@ -18,6 +19,13 @@ import { removeNote, } from '../DataEntry/actions/dataEntry.actions'; +const createServerData = (eventId, note, useNewEndpoint) => { + if (useNewEndpoint) { + return { event: eventId, value: note }; + } + return { event: eventId, notes: [{ value: note }] }; +}; + export const addNoteForEventEpic = (action$: InputObservable, store: ReduxStore, { querySingleResource }: ApiUtils) => action$.pipe( ofType(actionTypes.REQUEST_ADD_NOTE_FOR_EVENT), @@ -25,6 +33,7 @@ export const addNoteForEventEpic = (action$: InputObservable, store: ReduxStore, const state = store.value; const payload = action.payload; const eventId = state.dataEntries[payload.dataEntryId].eventId; + const useNewEndpoint = featureAvailable(FEATURES.newNoteEndpoint); return querySingleResource({ resource: 'me', params: { @@ -34,10 +43,7 @@ export const addNoteForEventEpic = (action$: InputObservable, store: ReduxStore, const { firstName, surname, userName } = user; const clientId = uuid(); - const serverData = { - event: eventId, - notes: [{ value: payload.note }], - }; + const serverData = createServerData(eventId, payload.note, useNewEndpoint); const clientNote = { value: payload.note, diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js index e36d5f4b16..4a02ddcd75 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/StageDetail.component.js @@ -19,7 +19,7 @@ import { Tooltip, } from '@dhis2/ui'; import log from 'loglevel'; -import { sortDataFromEvent } from './hooks/sortFuntions'; +import { sortDataFromEvent } from './hooks/sortFunctions'; import { StageCreateNewButton } from '../StageCreateNewButton'; import { useComputeDataFromEvent, useComputeHeaderColumn, formatRowForView } from './hooks/useEventList'; import { DEFAULT_NUMBER_OF_ROW, SORT_DIRECTION } from './hooks/constants'; @@ -115,7 +115,6 @@ const StageDetailPlain = (props: Props) => { const headerColumns = useComputeHeaderColumn(dataElements, hideDueDate, enableUserAssignment, stage?.stageForm); const { loading, value: dataSource, error } = useComputeDataFromEvent(dataElements, events); - const [{ columnName, sortDirection }, setSortInstructions] = useState(defaultSortState); const [displayedRowNumber, setDisplayedRowNumber] = useState(DEFAULT_NUMBER_OF_ROW); diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js index 9d7f31f63f..f80831a9a7 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/helpers.js @@ -9,7 +9,6 @@ import type { StageDataElement } from '../../../../types/common.types'; import { Notes } from '../Notes.component'; import type { QuerySingleResource } from '../../../../../../utils/api/api.types'; import { isEventOverdue } from '../../../../../../utils/isEventOverdue'; -import { TooltipOrgUnit } from '../../../../../Tooltips/TooltipOrgUnit/TooltipOrgUnit.component'; const getEventStatus = (event: ApiEnrollmentEvent) => { const today = moment().startOf('day'); @@ -63,7 +62,6 @@ const convertStatusForView = (event: ApiEnrollmentEvent) => { }; }; -const convertOrgUnitForView = (event: ApiEnrollmentEvent) => ; const convertNoteForView = (event: ApiEnrollmentEvent) => ; @@ -100,7 +98,6 @@ export { isEventOverdue, getEventStatus, convertStatusForView, - convertOrgUnitForView, convertNoteForView, getValueByKeyFromEvent, groupRecordsByType, diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFuntions.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFunctions.js similarity index 91% rename from src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFuntions.js rename to src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFunctions.js index c57e42ed0e..3da3a324fa 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFuntions.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/sortFunctions.js @@ -1,6 +1,7 @@ // @flow import log from 'loglevel'; import { errorCreator } from 'capture-core-utils'; +import { getCachedOrgUnitName } from 'capture-core/metadataRetrieval/orgUnitName'; import moment from 'moment'; import { dataElementTypes } from '../../../../../../metaData'; import { SORT_DIRECTION } from './constants'; @@ -40,7 +41,7 @@ const sortText = (clientValueA: Object, clientValueB: Object, direction: string, if (!clientValueB) return -1; if (clientValueA !== clientValueB) { - return clientValueA.localeCompare(clientValueB); + return clientValueB.localeCompare(clientValueA); } return moment(eventDateB).unix() - moment(eventDateA).unix(); @@ -49,7 +50,7 @@ const sortText = (clientValueA: Object, clientValueB: Object, direction: string, if (!clientValueB) return 1; if (clientValueA !== clientValueB) { - return clientValueB.localeCompare(clientValueA); + return clientValueA.localeCompare(clientValueB); } return moment(eventDateB).unix() - moment(eventDateA).unix(); @@ -78,7 +79,12 @@ const sortTime = (clientValueA: Object, clientValueB: Object, direction: string, return 0; }; -const sortOrgUnit = (clientValueA: Object, clientValueB: Object, direction: string, options: Object) => sortText(clientValueA.name, clientValueB.name, direction, options); +const sortOrgUnit = (clientValueA: string, clientValueB: string, direction: string, options: Object) => { + const orgUnitNameA = getCachedOrgUnitName(clientValueA); + const orgUnitNameB = getCachedOrgUnitName(clientValueB); + + return sortText(orgUnitNameA, orgUnitNameB, direction, options); +}; // desc: Scheduled -> Active -> Completed -> Skipped const sortStatus = (clientValueA: Object, clientValueB: Object, direction: string, options: Object) => { @@ -113,7 +119,7 @@ const sortStatus = (clientValueA: Object, clientValueB: Object, direction: strin return 0; }; -const sortDataFromEvent = ({ dataA, dataB, type, columnName, direction }: Object) => { +export const sortDataFromEvent = ({ dataA, dataB, type, columnName, direction }: Object) => { if (!type) { log.error(errorCreator('Type is not defined')({ dataA, dataB })); } @@ -128,11 +134,6 @@ const sortDataFromEvent = ({ dataA, dataB, type, columnName, direction }: Object return sortForTypes[type](clientValueA, clientValueB, direction, options); }; -export { - sortDataFromEvent, -}; - - const sortForTypes = { [dataElementTypes.EMAIL]: sortText, [dataElementTypes.TEXT]: sortText, diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js index f160eb00e3..d6fcf10be0 100644 --- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js +++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/hooks/useEventList.js @@ -11,7 +11,6 @@ import { convertValue as convertClientToList } from '../../../../../../converter import { convertValue as convertServerToClient } from '../../../../../../converters/serverToClient'; import { convertStatusForView, - convertOrgUnitForView, convertNoteForView, getValueByKeyFromEvent, groupRecordsByType, @@ -27,7 +26,7 @@ const basedFieldTypes = [ { type: dataElementTypes.STATUS, resolveValue: convertStatusForView }, { type: dataElementTypes.DATE }, { type: 'ASSIGNEE' }, - { type: dataElementTypes.TEXT, resolveValue: convertOrgUnitForView }, + { type: dataElementTypes.ORGANISATION_UNIT }, { type: dataElementTypes.DATE }, { type: dataElementTypes.UNKNOWN, resolveValue: convertNoteForView }, ]; diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/Changelog/Changelog.types.js b/src/core_modules/capture-core/components/WidgetsChangelog/common/Changelog/Changelog.types.js index 56dccc68cd..ece01ab3a9 100644 --- a/src/core_modules/capture-core/components/WidgetsChangelog/common/Changelog/Changelog.types.js +++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/Changelog/Changelog.types.js @@ -6,6 +6,7 @@ type CreatedChange = {| type: typeof CHANGE_TYPES.CREATED, dataElement?: string, attribute?: string, + field?: string, currentValue: any, |} @@ -13,6 +14,7 @@ type UpdatedChange = {| type: typeof CHANGE_TYPES.UPDATED, dataElement?: string, attribute?: string, + field?: string, previousValue: any, currentValue: any, |} @@ -21,6 +23,7 @@ type DeletedChange = {| type: typeof CHANGE_TYPES.DELETED, dataElement?: string, attribute?: string, + field?: string, previousValue: any, |} diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogCells/ChangelogValueCell.js b/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogCells/ChangelogValueCell.js index 4d6bd41b3e..3b43a13eba 100644 --- a/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogCells/ChangelogValueCell.js +++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/ChangelogTable/ChangelogCells/ChangelogValueCell.js @@ -23,9 +23,12 @@ const styles = { display: 'flex', flexDirection: 'row', alignItems: 'center', - whiteSpace: 'normal', height: '100%', }, + buttonContainer: { + display: 'flex', + justifyContent: 'center', + }, previousValue: { color: colors.grey700, wordBreak: 'break-word', @@ -33,9 +36,10 @@ const styles = { currentValue: { color: colors.grey900, wordBreak: 'break-word', + maxWidth: '82%', }, arrow: { - margin: `0 ${spacers.dp4}`, + margin: spacers.dp4, }, }; diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.js b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.js index e94bf94a88..16dcbe87f2 100644 --- a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.js +++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.js @@ -44,7 +44,8 @@ const fetchFormattedValues = async ({ elementKey: string, change: Change, ) => { - const fieldId = change.dataElement || change.attribute; + const { dataElement, attribute, field } = change; + const fieldId = dataElement ?? attribute ?? field; if (!fieldId) { log.error('Could not find fieldId in change:', change); return { metadataElement: null, fieldId: null }; @@ -115,6 +116,7 @@ const fetchFormattedValues = async ({ reactKey: fieldId ? `${createdAt}-${fieldId}` : attributeOptionsKey, date: pipe(convertServerToClient, convertClientToList)(fromServerDate(createdAt), dataElementTypes.DATETIME), user: `${firstName} ${surname} (${username})`, + dataItemId: fieldId, changeType: type, dataItemLabel: metadataElement.name, previousValue, diff --git a/src/core_modules/capture-core/components/WidgetsRelationship/common/useRelationships/useRelationships.js b/src/core_modules/capture-core/components/WidgetsRelationship/common/useRelationships/useRelationships.js index 84f3db620e..489d83a8fd 100644 --- a/src/core_modules/capture-core/components/WidgetsRelationship/common/useRelationships/useRelationships.js +++ b/src/core_modules/capture-core/components/WidgetsRelationship/common/useRelationships/useRelationships.js @@ -1,6 +1,7 @@ // @flow import { useMemo } from 'react'; import { handleAPIResponse, REQUESTED_ENTITIES } from 'capture-core/utils/api'; +import { featureAvailable, FEATURES } from 'capture-core-utils'; import { useApiDataQuery } from '../../../../utils/reactQueryHelpers'; import type { InputRelationshipData, RelationshipTypes } from '../Types'; import { determineLinkedEntity } from '../RelationshipsWidget/useGroupedLinkedEntities'; @@ -20,14 +21,21 @@ type Props = {| type ReturnData = Array; export const useRelationships = ({ entityId, searchMode, relationshipTypes }: Props) => { - const query = useMemo(() => ({ - resource: 'tracker/relationships', - params: { - // $FlowFixMe - searchMode should be a valid key of RelationshipSearchEntities - [searchMode]: entityId, - fields: 'relationship,relationshipType,createdAt,from[trackedEntity[trackedEntity,attributes,program,orgUnit,trackedEntityType],event[event,dataValues,program,orgUnit,orgUnitName,status,createdAt]],to[trackedEntity[trackedEntity,attributes,program,orgUnit,trackedEntityType],event[event,dataValues,program,orgUnit,orgUnitName,status,createdAt]]', - }, - }), [entityId, searchMode]); + const query = useMemo(() => { + const supportForFeature = featureAvailable(FEATURES.newRelationshipQueryParam); + + return { + resource: 'tracker/relationships', + params: { + // $FlowFixMe - searchMode should be a valid key of RelationshipSearchEntities + [searchMode]: entityId, + fields: 'relationship,relationshipType,createdAt,from[trackedEntity[trackedEntity,attributes,program,orgUnit,trackedEntityType],event[event,dataValues,program,orgUnit,orgUnitName,status,createdAt]],to[trackedEntity[trackedEntity,attributes,program,orgUnit,trackedEntityType],event[event,dataValues,program,orgUnit,orgUnitName,status,createdAt]]', + ...(supportForFeature + ? { paging: false } + : { skipPaging: true }), + }, + }; + }, [entityId, searchMode]); return useApiDataQuery( ['relationships', entityId], diff --git a/src/core_modules/capture-core/converters/clientToList.js b/src/core_modules/capture-core/converters/clientToList.js index e72b837179..abbfbf6975 100644 --- a/src/core_modules/capture-core/converters/clientToList.js +++ b/src/core_modules/capture-core/converters/clientToList.js @@ -7,7 +7,7 @@ import { PreviewImage } from 'capture-ui'; import { dataElementTypes, type DataElement } from '../metaData'; import { convertMomentToDateFormatString } from '../utils/converters/date'; import { stringifyNumber } from './common/stringifyNumber'; -import { MinimalCoordinates } from '../components/MinimalCoordinates'; +import { MinimalCoordinates, PolygonCoordinates } from '../components/Coordinates'; import { TooltipOrgUnit } from '../components/Tooltips/TooltipOrgUnit'; function convertDateForListDisplay(rawValue: string): string { @@ -87,41 +87,45 @@ function convertStatusForDisplay(clientValue: Object) { ); } -function convertOrgUnitForDisplay(clientValue: string | {id: string}) { +function convertOrgUnitForDisplay(clientValue: string | { id: string }) { const orgUnitId = typeof clientValue === 'string' ? clientValue : clientValue.id; return ( ); } +function convertPolygonForDisplay(clientValue: Object) { + return ; +} const valueConvertersForType = { - [dataElementTypes.NUMBER]: stringifyNumber, - [dataElementTypes.INTEGER]: stringifyNumber, - [dataElementTypes.INTEGER_POSITIVE]: stringifyNumber, - [dataElementTypes.INTEGER_ZERO_OR_POSITIVE]: stringifyNumber, - [dataElementTypes.INTEGER_NEGATIVE]: stringifyNumber, - [dataElementTypes.INTEGER_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), - [dataElementTypes.INTEGER_POSITIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), - [dataElementTypes.INTEGER_ZERO_OR_POSITIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), - [dataElementTypes.INTEGER_NEGATIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), - [dataElementTypes.PERCENTAGE]: (value: number) => `${stringifyNumber(value)} %`, + [dataElementTypes.AGE]: convertDateForListDisplay, + [dataElementTypes.ASSIGNEE]: (rawValue: Object) => `${rawValue.name} (${rawValue.username})`, + [dataElementTypes.BOOLEAN]: (rawValue: boolean) => (rawValue ? i18n.t('Yes') : i18n.t('No')), + [dataElementTypes.COORDINATE]: MinimalCoordinates, [dataElementTypes.DATE]: convertDateForListDisplay, [dataElementTypes.DATE_RANGE]: value => convertRangeForDisplay(convertDateForListDisplay, value), [dataElementTypes.DATETIME]: convertDateTimeForListDisplay, [dataElementTypes.DATETIME_RANGE]: value => convertRangeForDisplay(convertDateTimeForListDisplay, value), - [dataElementTypes.TIME]: convertTimeForListDisplay, - [dataElementTypes.TIME_RANGE]: value => convertRangeForDisplay(convertTimeForListDisplay, value), - [dataElementTypes.TRUE_ONLY]: () => i18n.t('Yes'), - [dataElementTypes.BOOLEAN]: (rawValue: boolean) => (rawValue ? i18n.t('Yes') : i18n.t('No')), - [dataElementTypes.COORDINATE]: MinimalCoordinates, - [dataElementTypes.AGE]: convertDateForListDisplay, [dataElementTypes.FILE_RESOURCE]: convertFileForDisplay, [dataElementTypes.IMAGE]: convertImageForDisplay, - [dataElementTypes.ORGANISATION_UNIT]: convertOrgUnitForDisplay, - [dataElementTypes.ASSIGNEE]: (rawValue: Object) => `${rawValue.name} (${rawValue.username})`, + [dataElementTypes.INTEGER]: stringifyNumber, + [dataElementTypes.INTEGER_NEGATIVE]: stringifyNumber, + [dataElementTypes.INTEGER_NEGATIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), + [dataElementTypes.INTEGER_POSITIVE]: stringifyNumber, + [dataElementTypes.INTEGER_POSITIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), + [dataElementTypes.INTEGER_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), + [dataElementTypes.INTEGER_ZERO_OR_POSITIVE]: stringifyNumber, + [dataElementTypes.INTEGER_ZERO_OR_POSITIVE_RANGE]: value => convertRangeForDisplay(stringifyNumber, value), + [dataElementTypes.NUMBER]: stringifyNumber, [dataElementTypes.NUMBER_RANGE]: convertNumberRangeForDisplay, + [dataElementTypes.ORGANISATION_UNIT]: convertOrgUnitForDisplay, + [dataElementTypes.PERCENTAGE]: (value: number) => `${stringifyNumber(value)} %`, + [dataElementTypes.POLYGON]: convertPolygonForDisplay, [dataElementTypes.STATUS]: convertStatusForDisplay, + [dataElementTypes.TIME]: convertTimeForListDisplay, + [dataElementTypes.TIME_RANGE]: value => convertRangeForDisplay(convertTimeForListDisplay, value), + [dataElementTypes.TRUE_ONLY]: () => i18n.t('Yes'), }; export function convertValue(value: any, type: $Keys, dataElement?: ?DataElement) { diff --git a/src/core_modules/capture-core/converters/clientToView.js b/src/core_modules/capture-core/converters/clientToView.js index fb7728f723..826c637456 100644 --- a/src/core_modules/capture-core/converters/clientToView.js +++ b/src/core_modules/capture-core/converters/clientToView.js @@ -6,7 +6,7 @@ import { PreviewImage } from 'capture-ui'; import { dataElementTypes, type DataElement } from '../metaData'; import { convertMomentToDateFormatString } from '../utils/converters/date'; import { stringifyNumber } from './common/stringifyNumber'; -import { MinimalCoordinates } from '../components/MinimalCoordinates'; +import { MinimalCoordinates } from '../components/Coordinates'; import { TooltipOrgUnit } from '../components/Tooltips/TooltipOrgUnit'; diff --git a/src/core_modules/capture-core/converters/serverToClient.js b/src/core_modules/capture-core/converters/serverToClient.js index 7a342c3aff..456e87d6af 100644 --- a/src/core_modules/capture-core/converters/serverToClient.js +++ b/src/core_modules/capture-core/converters/serverToClient.js @@ -43,6 +43,24 @@ export function convertOptionSetValue(value: any, type: $Keys moment(d2Value).toISOString(), [dataElementTypes.TRUE_ONLY]: (d2Value: string) => ((d2Value === 'true') || null), [dataElementTypes.BOOLEAN]: (d2Value: string) => (d2Value === 'true'), - [dataElementTypes.COORDINATE]: (d2Value: string | Array) => { - const arr = typeof d2Value === 'string' ? JSON.parse(d2Value) : d2Value; - return { latitude: arr[1], longitude: arr[0] }; - }, - [dataElementTypes.POLYGON]: (d2Value: Array) => d2Value, + [dataElementTypes.COORDINATE]: (d2Value: string | Array) => convertCoordinateToClient(d2Value), + [dataElementTypes.POLYGON]: (d2Value: string | Array>) => convertPolygonToClient(d2Value), [dataElementTypes.ASSIGNEE]: convertAssignedUserToClient, }; diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js index 204c983009..21e8b84212 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/index.js @@ -3,4 +3,5 @@ export { useOrgUnitNameWithAncestors, useOrgUnitNames, getOrgUnitNames, + getCachedOrgUnitName, } from './orgUnitName'; diff --git a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js index c86c4d7c14..56d222c119 100644 --- a/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js +++ b/src/core_modules/capture-core/metadataRetrieval/orgUnitName/orgUnitName.js @@ -209,3 +209,5 @@ export const useOrgUnitNameWithAncestors = (orgUnitId: ?string): { return { error }; }; + +export const getCachedOrgUnitName = (orgUnitId: string): ?string => displayNameCache[orgUnitId]?.displayName; diff --git a/yarn.lock b/yarn.lock index 4c2c7b3910..1ac6dd9c83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3987,7 +3987,7 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.3": +"@types/eslint-scope@^3.7.7": version "3.7.7" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== @@ -4011,7 +4011,7 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.5": +"@types/estree@*": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -4021,6 +4021,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": version "4.19.5" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz#218064e321126fcf9048d1ca25dd2465da55d9c6" @@ -4702,11 +4707,6 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-import-attributes@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" - integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== - acorn-import-meta@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/acorn-import-meta/-/acorn-import-meta-1.1.0.tgz#c384423462ee7d4721d4de83231021a36cb09def" @@ -4781,7 +4781,12 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + +acorn@^8.2.4, acorn@^8.8.2, acorn@^8.9.0: version "8.12.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== @@ -5352,10 +5357,10 @@ axios@^0.25.0: dependencies: follow-redirects "^1.14.7" -axios@^1.6.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.3.tgz#a1125f2faf702bc8e8f2104ec3a76fab40257d85" - integrity sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw== +axios@^1.7.7: + version "1.7.9" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" + integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -5884,7 +5889,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.23.1, browserslist@^4.23.3: +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.4, browserslist@^4.23.1, browserslist@^4.23.3: version "4.23.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== @@ -5894,6 +5899,16 @@ browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^ node-releases "^2.0.18" update-browserslist-db "^1.1.0" +browserslist@^4.24.0: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== + dependencies: + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -6045,6 +6060,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== +caniuse-lite@^1.0.30001669: + version "1.0.30001685" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz#2d10d36c540a9a5d47ad6ab9e1ed5f61fdeadd8c" + integrity sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA== + capital-case@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" @@ -7827,6 +7847,11 @@ electron-to-chromium@^1.5.4: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz#03bfdf422bdd2c05ee2657efedde21264a1a566b" integrity sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA== +electron-to-chromium@^1.5.41: + version "1.5.67" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz#66ebd2be4a77469ac2760ef5e9e460ba9a43a845" + integrity sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ== + emittery@^0.10.2: version "0.10.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" @@ -7900,7 +7925,7 @@ enhanced-resolve@^0.9.1: memory-fs "^0.2.0" tapable "^0.1.8" -enhanced-resolve@^5.17.0: +enhanced-resolve@^5.17.1: version "5.17.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== @@ -8237,6 +8262,11 @@ escalade@^3.1.1, escalade@^3.1.2: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -11570,7 +11600,7 @@ jiti@^1.20.0, jiti@^1.21.0: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== -joi@^17.11.0: +joi@^17.13.3: version "17.13.3" resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec" integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== @@ -12985,9 +13015,9 @@ nano-time@1.0.0: big-integer "^1.6.16" nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== nanomatch@^1.2.9: version "1.2.13" @@ -13720,6 +13750,11 @@ picocolors@^1.0.0, picocolors@^1.0.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -17644,6 +17679,14 @@ update-browserslist-db@^1.1.0: escalade "^3.1.2" picocolors "^1.0.1" +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.0" + update-notifier@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-3.0.1.tgz#78ecb68b915e2fd1be9f767f6e298ce87b736250" @@ -17868,13 +17911,13 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" -wait-on@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.2.0.tgz#d76b20ed3fc1e2bebc051fae5c1ff93be7892928" - integrity sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ== +wait-on@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-8.0.1.tgz#13c8ec77115517f8fbc2d670521a444201f03f53" + integrity sha512-1wWQOyR2LVVtaqrcIL2+OM+x7bkpmzVROa0Nf6FryXkS+er5Sa1kzFGjzZRqLnHa3n1rACFLeTwUqE1ETL9Mig== dependencies: - axios "^1.6.1" - joi "^17.11.0" + axios "^1.7.7" + joi "^17.13.3" lodash "^4.17.21" minimist "^1.2.8" rxjs "^7.8.1" @@ -18012,20 +18055,19 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.41.1, webpack@^5.64.4: - version "5.93.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" - integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== + version "5.96.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.96.1.tgz#3676d1626d8312b6b10d0c18cc049fba7ac01f0c" + integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA== dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.5" + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.6" "@webassemblyjs/ast" "^1.12.1" "@webassemblyjs/wasm-edit" "^1.12.1" "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" + acorn "^8.14.0" + browserslist "^4.24.0" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0"