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/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/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/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/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/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,
};