-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Feat: add support for day-first and year-first date formats (DD/MM/YYYY, YYYY/MM/DD) #12333
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
base: main
Are you sure you want to change the base?
Feat: add support for day-first and year-first date formats (DD/MM/YYYY, YYYY/MM/DD) #12333
Conversation
…ashes for YEAR_FIRST format
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.
PR Summary
This PR adds international date format support to the DateTime Picker component, enabling DD/MM/YYYY and YYYY-MM-DD formats alongside the existing MM/DD/YYYY format.
- Introduced
useDateParser
hook inhooks/useDateParser.ts
to centralize date parsing logic and format handling - Added dynamic format selection through
getDateFormatString
indate-utils.ts
based on user preferences - Removed hardcoded format constants (
DateParserFormat.ts
,DateTimeParserFormat.ts
) in favor of flexible format system - Improved timezone handling by using Luxon's DateTime for consistent date/time conversions
- Updated placeholder text and input validation to reflect user's selected date format
12 file(s) reviewed, 7 comment(s)
Edit PR Review Bot Settings | Greptile
(date: any) => { | ||
return parseDateToString({ | ||
date, | ||
isDateTimeInput: isDateTimeInput === true, | ||
userTimezone, | ||
}); | ||
return parseToString(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.
style: date parameter is typed as 'any' - should be explicitly typed as Date | null
(date: any) => { | |
return parseDateToString({ | |
date, | |
isDateTimeInput: isDateTimeInput === true, | |
userTimezone, | |
}); | |
return parseToString(date); | |
(date: Date | null) => { | |
return parseToString(date); |
default: | ||
return `Type date${isDateTimeInput ? ' and time' : ' (mm/dd/yyyy)'}`; | ||
} | ||
}, [dateFormat, isDateTimeInput]); | ||
|
||
return ( | ||
<StyledInputContainer> | ||
<StyledInput | ||
type="text" | ||
ref={ref as any} |
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.
style: Type assertion to 'any' could be replaced with proper typing of the ref
...ages/twenty-front/src/modules/ui/input/components/internal/date/components/DateTimeInput.tsx
Show resolved
Hide resolved
@@ -44,42 +46,38 @@ type DateTimeInputProps = { | |||
onChange?: (date: Date | null) => void; | |||
date: Date | null; | |||
isDateTimeInput?: boolean; | |||
userTimezone?: string; | |||
onError?: (error: Error) => void; |
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.
logic: onError prop is defined but never used in the component
import { TIME_MASK } from '@/ui/input/components/internal/date/constants/TimeMask'; | ||
import { DateFormat } from '~/modules/localization/constants/DateFormat'; | ||
import { getDateMask } from './DateMask'; |
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.
style: The relative import path for DateFormat ('~/' vs '@/') is inconsistent with the other imports
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.
style: Consider keeping this file but deprecating the constant with a warning message directing users to getDateFormatString for smoother migration
userTimezone: string | undefined; | ||
dateFormat: DateFormat; |
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.
logic: userTimezone is marked as optional but the code doesn't handle undefined case, which could cause runtime errors
userTimezone: string | undefined; | |
dateFormat: DateFormat; | |
userTimezone: string; | |
dateFormat: DateFormat; |
…eParseDateToString function
…mapping object for date formats
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:21814 This environment will automatically shut down when the PR is closed or after 5 hours. |
packages/twenty-front/src/modules/ui/input/components/internal/date/utils/parseDateToString.ts
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/ui/input/components/internal/date/constants/DateTimeMask.ts
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/ui/input/components/internal/hooks/useDateParser.ts
Outdated
Show resolved
Hide resolved
...ages/twenty-front/src/modules/ui/input/components/internal/date/components/DateTimeInput.tsx
Show resolved
Hide resolved
...ages/twenty-front/src/modules/ui/input/components/internal/date/components/DateTimeInput.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/ui/input/components/internal/date/constants/DateMask.ts
Outdated
Show resolved
Hide resolved
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.
Hi @abdulrahmancodes, thank you for your nice contribution !
I left few comments and questions.
packages/twenty-front/src/modules/ui/input/components/internal/date/constants/DateMask.ts
Outdated
Show resolved
Hide resolved
…and parseToDate functions
… to streamline date parsing logic.
Hey @etiennejouan! Thanks for the review! I’ve addressed all the comments. Could you please take another look when you get a chance? |
export const DATE_MASK = 'm`/d`/Y`'; // See https://imask.js.org/guide.html#masked-date | ||
import { DateFormat } from '~/modules/localization/constants/DateFormat'; | ||
|
||
export const getDateMask = (dateFormat: DateFormat): string => { |
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.
file should have the same name as utils
@@ -212,3 +214,20 @@ export const formatToHumanReadableDateTime = (date: Date | string) => { | |||
minute: 'numeric', | |||
}).format(parsedJSDate); | |||
}; | |||
|
|||
export const getDateFormatString = ( |
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.
neat: I'm a bit confused why we have utils here and in ui/input/components/internal/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.
Looking at the code, I can see that the utilities in date-utils.ts
are actually the core date utilities used throughout the application, while the ones in ui/input/components/internal/date/utils/
are specialized utilities specifically for the date picker component that build on top of the core utilities
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.
LGTM ! thanks for updating.
@abdulrahmancodes, I let you check Charles comments.
29173d0
to
0dcc412
Compare
Closes #12152
Screen.Recording.2025-05-27.at.10.11.23.PM.mov