-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Datetime format #842
Datetime format #842
Conversation
@biilmann I'm missing some context here -- Why did we make the change that broke it, in the first place? |
I did a little digging, and it seems we never actually supported the https://github.com/netlify/netlify-cms/pull/162/files#r88311221 In the older Ember version, this was handled by always turning the value into a https://github.com/netlify/netlify-cms/blob/master/src/formats/yaml.js#L6 I think the approach suggested here - of simply treating dates as formatted strings - is going to be more robust in general (since most of the supported formats have no standard for dates). If keeping the existing behavior feels important, we could make sure that we always keep the entry value as a date when no |
I updated the PR to keep the current behavior when no |
I'm fine with a formatted string (even with no fallback), it just seems way simpler, like you said. I really don't see any reason why we would need an actual Date/Moment object instead of a string, unless there was a valid use case for that before. |
@Benaiah per our convo, make the updates you'll be mentioning in your review, handle any necessary rebasing, and merge as soon as you can. |
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.
I'm preparing a commit to fix the specific issues I noted in the review comments.
This changes do seem to work on save (the PR is currently broken but renaming the components correctly makes it work), but it still has a couple shortcomings (similar shortcomings are why I haven't submitted a PR for this issue yet).
The DateTime
control we're using supports passing a format setting to control visible controls and the display of the time controls (the two settings are conflated in the component, unfortunately). This would be work well, except that it splits the timeFormat
and dateFormat
for no apparent reason, forcing us to either use the default UI or expose that bad API to the user. In my attempt at fixing this issue, I used only dateFormat
(ignoring timeFormat) and tried to work around the issues caused by the date/time distinction and the conflation of multiple different settings into the
*Format` props. This proved difficult to do.
The problem with that approach was that when you had a format
that didn't save a piece of data you needed, it would immediately reset to the default value, which made the UI look very broken. In addition, the displayed date was not formatted correctly. (Passing the full format to dateFormat
resulted in the correct display in the string input
except that the time was duplicated - I couldn't set the timeFormat
to empty to fix it because that hides the time controls).
This PR does the opposite - it ignores the component's format props for purposes of control and display, choosing instead to only format on save. This has similar, but slightly different issues. Controls are similarly not hidden correctly when they are setting a value not present in the format
, but they break differently. In addition, the time shown in the string input of the date does not represent the data actually saved.
IMO the problem will be best fixed by fixing the underlying control. I'm ok with merging this without a fix to that issue, since the PR is an improvement, I just wanted to point out the issue and the underlying cause.
return value; | ||
} | ||
|
||
export default class DateTimeControl extends React.Component { |
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.
This naming is very confusing (there's two DateTimeControl
s, one of which is in DateTimeControl.js
and one of which is in DateControl.js
.
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.
Yes, it's an old oversight predating this PR, but obviously the DateControl
should just export DateControl
import React from 'react'; | ||
import DateTime from 'react-datetime'; | ||
import DateControl from './DateControl'; |
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.
DateControl.js
as written exports DateTimeControl
, not DateControl
. (This is the cause of the PR being currently broken).
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.
@Benaiah That's weird, a default export/import shouldn't break things if it's named differently. Am I mistaken there?
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.
Good catch
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.
@tech4him1 it does seem like a default export should work regardless, but changing the name in DateControl.js
fixed the broken CMS. (note: this is now fixed, even though this line hasn't actually changed).
onChange={this.handleChange} | ||
return ( | ||
<DateTime | ||
timeFormat={this.props.includeTime || false} |
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.
Using ||
with a literal false
is logically redundant. This line is exactly equivalent to timeFormat={this.props.includeTime}
.
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.
Actually I think passing undefined
or null
to the timeFormat property will trigger the default setting which is true
.
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.
@biilmann ah - I'll add !!
to coerce this to a boolean.
export default class DateControl extends React.Component { | ||
function format(format, value) { | ||
if (format) { | ||
return moment(value).format(format || moment.defaultFormat); |
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.
The default of moment
will never be reached here, since this is wrapped in if (format)
. A falsy format
will never reach this branch, so this line is exactly equivalent to return moment(value).format(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.
yeah, that's an oversight in the commit to preserve the current behavior (which I do think makes sense for serialization formats that actually handle date objects)
|
||
export default class DateControl extends React.Component { | ||
function format(format, 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.
I'm not a fan of the interface of format
and toDate
- depending on the falsiness of one argument they:
- either do something or do nothing
- either return either a specific type of value or return whatever was passed in
The name of the format
function is also very confusing, as it collides with the format
variable frequently used in this file.
I've now updated the PR with fixes to the problems I mentioned.
Added boolean coercion. |
d28ff8c
to
54a617c
Compare
@Benaiah so many people have complained about the empty date thing, figured we'd tack that on. Please give another review and merge if you have no objections. |
d6aabfb
to
14f8bc9
Compare
14f8bc9
to
4c35b66
Compare
An earlier change broke the
format
attribute for date and datetime widgets (see #529).Before this was handled by always treating the value as a
moment
object and having the YAML serializer respect that.This takes a slightly different approach and always treats the value of date and datetime widgets as a formatted string. If we take this approach we should get rid of the moment specific code for formats in the YAML serializer.
The downside of this is that some future supported formats might handle actual date/datetime objects - but it seems this is the only approach I can think of where the
format
attribute would be respected across any output format apart from that...