-
Notifications
You must be signed in to change notification settings - Fork 22
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
base: master
Are you sure you want to change the base?
feat: [DHIS2-18310] enable non-Gregorian calendars in views & lists & forms #3900
Conversation
8983fd7
to
0294f8d
Compare
src/core_modules/capture-core/components/FiltersForTypes/Date/DateFilter.component.js
Outdated
Show resolved
Hide resolved
src/core_modules/capture-core/components/FiltersForTypes/Date/DateFilter.component.js
Outdated
Show resolved
Hide resolved
src/core_modules/capture-core/components/FiltersForTypes/Date/DateFilter.component.js
Show resolved
Hide resolved
…non-gregorian-calendars-in-views-and-lists
Hi @alaa-yahia,
Screen.Recording.2024-12-12.at.16.51.40.movIn the video above I used the Ethiopian calendar. Can you have a look? Thank you! |
…ent date (#3905) feat: typing the date when editing enrollment and incident date
There was a problem hiding this 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)
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); |
There was a problem hiding this comment.
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
const momentDate = moment(rawValue); | ||
return convertMomentToDateFormatString(momentDate); | ||
const dateString = momentDate.format('YYYY-MM-DD'); | ||
return convertIsoToLocalCalendar(dateString); |
There was a problem hiding this comment.
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'); |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Implements DHIS2-18310 & DHIS2-18311 & DHIS2-18309