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-18310] enable non-Gregorian calendars in views & lists & forms #3900

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

alaa-yahia
Copy link
Member

@alaa-yahia alaa-yahia commented Dec 5, 2024

Implements DHIS2-18310 & DHIS2-18311 & DHIS2-18309

  • Modified clientToList, clientToForm and clientToView converters to handle local format conversions (DHIS2-18310)
  • Modified FormToClient converter to handle ISO format (DHIS2-18309)
  • Ensure that all “Last updated” calculations are working when local calendar is used
  • Ensure all date pickers (form and working list) are using local calendar.
  • Enable non-Gregorian calendars in working list filters DHIS2-18311

@alaa-yahia alaa-yahia requested a review from a team as a code owner December 5, 2024 00:21
@alaa-yahia alaa-yahia force-pushed the DHIS2-18310-enable-non-gregorian-calendars-in-views-and-lists branch from 8983fd7 to 0294f8d Compare December 5, 2024 11:00
@simonadomnisoru
Copy link
Contributor

Hi @alaa-yahia,
I noticed two issues with the Age field:

  1. When selecting a date from the calendar, the year, months, and days are filled with incorrect values. (i.e. In the video below, I selected today's date from the Ethiopian calendar, so the year, months, and day should have been filled with 0).
  2. When typing a value into the days field, the calendar is filled with the gregorian value of the date.
Screen.Recording.2024-12-12.at.16.51.40.mov

In the video above I used the Ethiopian calendar. Can you have a look? Thank you!

alaa-yahia and others added 2 commits December 16, 2024 10:44
…ent date (#3905)

feat: typing the date when editing enrollment and incident date
Copy link
Member

@JoakimSM JoakimSM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good start, but some things we will have to work a bit more on.

In addition to the individual comments we should convert the "last updated" tooltips from ISO to local calendar (I saw this in both the stages and events Widget and the enrollment Widget). Had a very quick look at the stages and events Widget and for now I think you can use something like moment(fromServerDate(updatedAt)).toISOString() and put the result into the clientToView converter of type DATETIME (we should probably also use the serverToClient converter, but this will be checked and resolved in separate ticket)

Comment on lines +366 to +377
const formatDate = (dateValue) => {
if (!dateValue) return '';
const momentValue = moment(dateValue, dateFormat);
if (!momentValue.isValid()) return dateValue;
const isoDate = momentValue.format('YYYY-MM-DD');
return convertIsoToLocalCalendar(isoDate);
};

const from = value?.from;
const to = value?.to;
const fromDate = formatDate(from?.value);
const toDate = formatDate(to?.value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this will likely work, I would really prefer it if we approached this like we do elsewhere regarding the value we store in the state. Let's keep the local calendar date in the state and convert it to the client format when it is needed (in this case when we commit the value by clicking the update button). For the validations in the DateFilter where we currently use moment, it would be great to use Temporal instead.

Looked through the DateFilter code and I don't think this should be too much work. Some docs for Temporal and comparing dates: https://tc39.es/proposal-temporal/docs/plaindate.html#compare

Comment on lines 14 to +16
const momentDate = moment(rawValue);
return convertMomentToDateFormatString(momentDate);
const dateString = momentDate.format('YYYY-MM-DD');
return convertIsoToLocalCalendar(dateString);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see we can just pass on the ISO-string (rawValue in this case) to the convertIsoToLocalCalendar function without doing the conversion to moment first. There is quite few examples like this where we convert back and forth, but this should not be needed as the convertIsoToLocalCalendar function accepts an ISO-string (And I would like the function to continue accepting an ISOstring).

if (!parsedDate.isValid || !parsedDate.momentDate) {
return null;
}
const formattedDate = parsedDate.momentDate.format('YYYY-MM-DD');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comment (parsedDate.momentDate.toISOString())

@@ -15,7 +16,7 @@ export const getDateFieldConfig = (metaData: DateDataElement, options: Object, q
maxWidth: options.formHorizontal ? 150 : 350,
calendarWidth: options.formHorizontal ? 250 : 350,
popupAnchorPosition: getCalendarAnchorPosition(options.formHorizontal),
calendarMaxMoment: !metaData.allowFutureDate ? moment() : undefined,
calendarMaxMoment: !metaData.allowFutureDate ? convertDateObjectToDateFormatString(moment()) : undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the property name as it is not a moment anymore? calendarMax is probably good enough for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't put the local date into moment like we do here. We will have to use Temporal instead of moment here for the calculations. The current implementation will set invalid dates and do erroneous calculations under certain circumstances.

For example, using the Islamic calendar: If I set days to 17, at the time of writing this the calculated date will be 31-05-1446. This is an invalid date in the Islamic calendar. Secondly, when days in the month is not the same in the local calendar and the ISO calendar, the days calculation will be wrong. Thirdly, a local date might not exist in the ISO calendar and cause the calculations to be wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants