Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [DHIS2-18328] Handle log entries for occurredAt, scheduledAt and geometry #3887

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ type Props = $ReadOnly<{|

const toSixDecimal = value => (parseFloat(value) ? parseFloat(value).toFixed(6) : null);

export const MinimalCoordinates = ({ latitude, longitude }: Props) =>
(<div>
export const MinimalCoordinates = ({ latitude, longitude }: Props) => (
<div>
lat: {toSixDecimal(latitude)} <br />
long: {toSixDecimal(longitude)}
henrikmv marked this conversation as resolved.
Show resolved Hide resolved
</div>);
</div>
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// @flow
import React, { useState } from 'react';
import { withStyles } from '@material-ui/core/styles';
import { IconChevronUp16, IconChevronDown16, colors, spacers } from '@dhis2/ui';

type Props = $ReadOnly<{|
coordinates: Array<Array<number>>,
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 (
<>
<div>
{coordinates.slice(0, showMore ? coordinates.length : 1).map((coordinatePair, index) => (
// eslint-disable-next-line react/no-array-index-key
<div key={index}>
{`lat: ${coordinatePair[1]}`}<br />
{`long: ${coordinatePair[0]}`}
henrikmv marked this conversation as resolved.
Show resolved Hide resolved
</div>
))}
</div>
<div className={classes.buttonContainer}>
<button className={classes.viewButton} onClick={() => setShowMore(!showMore)}>
{showMore ? 'Show Less' : 'Show More'}
henrikmv marked this conversation as resolved.
Show resolved Hide resolved
{showMore ? <IconChevronUp16 /> : <IconChevronDown16 />}
</button>
</div>
</>
);
};

export const PolygonCoordinates = withStyles(styles)(PolygonCoordinatesPlain);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @flow
export { PolygonCoordinates } from './PolygonCoordinates';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow
export { MinimalCoordinates } from './MinimalCoordinates';
export { PolygonCoordinates } from './PolygonCoordinates';
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,19 @@ export const EventChangelogWrapper = ({ formFoundation, eventId, eventData, ...p
return acc;
}, {});

const additionalFields = formFoundation.featureType !== 'None' ? {
geometry: {
id: 'geometry',
name: formFoundation.featureType,
henrikmv marked this conversation as resolved.
Show resolved Hide resolved
type: formFoundation.featureType === 'Polygon' ?
dataElementTypes.POLYGON : dataElementTypes.COORDINATE,
},
} : null;

return {
...fieldElementsById,
...fieldElementsContext,
...additionalFields,
};
}, [formFoundation]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ type CreatedChange = {|
type: typeof CHANGE_TYPES.CREATED,
dataElement?: string,
attribute?: string,
field?: string,
currentValue: any,
|}

type UpdatedChange = {|
type: typeof CHANGE_TYPES.UPDATED,
dataElement?: string,
attribute?: string,
field?: string,
previousValue: any,
currentValue: any,
|}
Expand All @@ -21,6 +23,7 @@ type DeletedChange = {|
type: typeof CHANGE_TYPES.DELETED,
dataElement?: string,
attribute?: string,
field?: string,
previousValue: any,
|}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,23 @@ const styles = {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
whiteSpace: 'normal',
height: '100%',
},
buttonContainer: {
display: 'flex',
justifyContent: 'center',
},
previousValue: {
color: colors.grey700,
wordBreak: 'break-word',
},
currentValue: {
color: colors.grey900,
wordBreak: 'break-word',
maxWidth: '82%',
},
arrow: {
margin: `0 ${spacers.dp4}`,
margin: spacers.dp4,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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,
Expand Down
44 changes: 24 additions & 20 deletions src/core_modules/capture-core/converters/clientToList.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 (
<TooltipOrgUnit orgUnitId={orgUnitId} />
);
}

function convertPolygonForDisplay(clientValue: Object) {
return <PolygonCoordinates coordinates={clientValue} />;
}

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<typeof dataElementTypes>, dataElement?: ?DataElement) {
Expand Down
2 changes: 1 addition & 1 deletion src/core_modules/capture-core/converters/clientToView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';


Expand Down
25 changes: 20 additions & 5 deletions src/core_modules/capture-core/converters/serverToClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ export function convertOptionSetValue(value: any, type: $Keys<typeof dataElement
return optionSetConvertersForType[type] ? optionSetConvertersForType[type](value) : value;
}

function convertCoordinateToClient(value: any) {
const coordinates = typeof value === 'string' ?
value.replace(/[\(\)\[\]\s]/g, '').split(',').map(Number) : value;

return { latitude: coordinates[1], longitude: coordinates[0] };
}

function convertPolygonToClient(value: any) {
if (typeof value === 'string') {
const coordinates = value.replace(/[()]/g, '').split(',').map(Number);
const coordinatesArray = [];
for (let i = 0; i < coordinates.length; i += 2) {
coordinatesArray.push([coordinates[i], coordinates[i + 1]]);
}
return coordinatesArray;
}
return value;
}

const valueConvertersForType = {
[dataElementTypes.NUMBER]: parseNumber,
Expand All @@ -55,11 +73,8 @@ const valueConvertersForType = {
[dataElementTypes.DATETIME]: (d2Value: string) => moment(d2Value).toISOString(),
[dataElementTypes.TRUE_ONLY]: (d2Value: string) => ((d2Value === 'true') || null),
[dataElementTypes.BOOLEAN]: (d2Value: string) => (d2Value === 'true'),
[dataElementTypes.COORDINATE]: (d2Value: string | Array<string>) => {
const arr = typeof d2Value === 'string' ? JSON.parse(d2Value) : d2Value;
return { latitude: arr[1], longitude: arr[0] };
},
[dataElementTypes.POLYGON]: (d2Value: Array<number>) => d2Value,
[dataElementTypes.COORDINATE]: (d2Value: string | Array<string>) => convertCoordinateToClient(d2Value),
[dataElementTypes.POLYGON]: (d2Value: string | Array<Array<number>>) => convertPolygonToClient(d2Value),
[dataElementTypes.ASSIGNEE]: convertAssignedUserToClient,
};

Expand Down
Loading