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: Javascript DatePicker Implementation #667

Merged
merged 49 commits into from
Aug 21, 2024

Conversation

dgodinez-dh
Copy link
Contributor

@dgodinez-dh dgodinez-dh commented Jul 25, 2024

Closes #369
Implements JS side of DatePicker.

Copy link
Contributor

@bmingles bmingles left a comment

Choose a reason for hiding this comment

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

Code generally looks good to me. Left a few comments / questions.

bmingles
bmingles previously approved these changes Jul 25, 2024
Copy link
Contributor

@bmingles bmingles left a comment

Choose a reason for hiding this comment

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

I would still suggest using the re-exported MappedDateValue, but I don't feel strongly enough to block the PR for it. Everything looks good to me.

AkshatJawne
AkshatJawne previously approved these changes Jul 26, 2024
Copy link
Contributor

Choose a reason for hiding this comment

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

This code looks good, although after my ui.text_area PR merges, we should probably create a follow-up ticket to leverage the useDebouncedOnChange hook I created, since this logic here to handle input looks similar: https://github.com/deephaven/deephaven-plugins/blob/0f0f3ca7d8e3016182f89127ceca677d09fcb27e/plugins/ui/src/js/src/elements/hooks/useDebouncedOnChange.ts

Doesn't impact this PR merging though 👍🏼

Copy link
Contributor

Choose a reason for hiding this comment

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

@AkshatJawne that hook should probably live in DHC instead of plugins repo.

@dgodinez-dh dgodinez-dh dismissed stale reviews from AkshatJawne and bmingles via 8f86f73 July 26, 2024 14:37
@dgodinez-dh dgodinez-dh reopened this Jul 30, 2024
@dgodinez-dh dgodinez-dh marked this pull request as ready for review July 30, 2024 19:58
Comment on lines 51 to 52
zoned_date_time = to_j_zdt("1995-03-22T11:11:11.23142 UTC")
instant = to_j_instant("2022-01-01T00:00:00 ET")
Copy link
Member

Choose a reason for hiding this comment

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

Not a great example because the ZDT is UTC, which looks like the same behavior as Instant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in an update.

Copy link
Member

Choose a reason for hiding this comment

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

This interface feels like it has an incomplete integration with the existing time libraries. In particular, business calendars are not supported. Business calendars could be used to limit selected dates or times, they can be used to get a appropriate time zone, etc. Business calendars could be added as a future enhancement, but I wanted to note it here.
https://deephaven.io/core/pydoc/code/deephaven.calendar.html
https://github.com/deephaven/deephaven-core/blob/main/engine/time/src/main/java/io/deephaven/time/calendar/BusinessCalendar.java

Copy link
Member

Choose a reason for hiding this comment

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

We're looking at adding the unavailable dates afterwards: #698
Didn't want that to hold up the the rest of the date picker.

Copy link
Member

Choose a reason for hiding this comment

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

date_picker interprets date-time strings in a way that is inconsistent with all other DH time libraries. For example, it interprets any UTC string only as an Instant. All other time libraries accept the same date-time format for either an Instant or a ZonedDateTime. The inconsistency introduced by date_picker is not good and will be confusing to explain and support. I think the inconsistency can be resolved cleanly by introducing a date_type or string_format parameter that can take values of LocalDate, Instant, and ZonedDateTime. This could then be used to control how the string is parsed.

Note: I have a PR to introduce a new format string that is ZDT specific, but there has been enough arguing that I have not pushed it forward. deephaven/deephaven-core#5069

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Per discussion, we are going to default datetime strings to ZDT. Then update the documentation to clarify which value input types will produce which output types.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think the widget has a way to select a time zone via clicking. I can imagine that this would be useful. The adobe docs don't seem to mention it, so it might not be available.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the DatePicker will display a timezone but does not allow to change it.
For the current implementation, the DatePicker will display the TZ from the user settings and update if the user changes the TZ in the settings. This is for an Instant. If the user uses a ZDT, then the DatePicker is locked to the TZ provided by the ZDT.

Comment on lines +31 to +33
1. `value`
2. `default_value`
3. `placeholder_value`
Copy link
Member

Choose a reason for hiding this comment

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

Do they get an error if value and default_value are inconsistent types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried this in various permutations.
There is no error. Instead one of the types "wins" in order of value, default_value, placeholder_value
The docs discuss this as on_change being determined in that precedence.

Comment on lines 39 to 41
Recommendations for creating clear and effective date pickers:

1. Using the Date Type `Instant` will be most compatible with other Deephaven components.
Copy link
Member

Choose a reason for hiding this comment

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

This is a weird recommendation because doing everything in UTC is the least useful presentation for a user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed in an update.

ui.date_picker(description="description"),
ui.date_picker(error_message="error", validation_state="valid"),
ui.date_picker(error_message="error", validation_state="invalid"),
ui.date_picker(min_value="2024-01-01", max_value="2024-01-5"),
Copy link
Member

Choose a reason for hiding this comment

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

2024-01-5 looks like it should be an invalid ISO date.
https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in an update.


1. `value`
2. `default_value`
3. `placeholder_value`
Copy link
Member

Choose a reason for hiding this comment

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

In DESIGN.md, the default is described as Defaults to today at midnight in the user's timezone. I assume that doc should also indicate that it is a ZonedDateTime. There is an enormous amount of ambiguity in what the "user's timezone" is. Possibilities are:

  1. The local machine time zone.
  2. The Java default time zone.
  3. The time zone of the default calendar.
  4. The time zone configured for rendering in the UI.

There needs to be a discussion about which is most appropriate and for what reason. The docs then need to be very clear on the default.

Notes:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This comes from the Spectrum docs:

A placeholder date that influences the format of the placeholder shown when no value is selected. Defaults to today's date at midnight.

So it must be defaulting to the local machine time zone.

Copy link
Member

Choose a reason for hiding this comment

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

There is a question about what return values should result from string inputs. There was a very long discussion around this topic when we created the query language time and calendar library. Ultimately, we decided to make everything as java time centric as possible. As a result, almost all return types are Java time types. There are a few cases where local-date-strings can be provided as inputs and they will return local-date-strings as outputs, but I think these were only included to make it easier to work with tables using strings as date columns -- which is very common.

As a result, I think it is least confusing to always return a java time value. If there is a compelling case to do something different, we should discuss that specific case.

Having said that, it doesn't look like we have exposed the string formatting methods (e.g. https://github.com/deephaven/deephaven-core/blob/main/engine/time/src/main/java/io/deephaven/time/DateTimeUtils.java#L4273) in python. (https://deephaven.io/core/pydoc/code/deephaven.time.html). Do we need to do this?

Notes:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Per discussion, we are going to stick with Java date types. User can convert to python / strings as needed.


## Date types

There are three types that can be passed in to the props that control the date format:
Copy link
Member

Choose a reason for hiding this comment

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

Only supporting these 3 inputs types is probably excessively restrictive. Our to_j_* methods can handle far more types. For example, to_j_instant can take Instant, int, str, datetime.datetime, numpy.datetime64, and pandas.Timestamp inputs. to_local_date can take about the same inputs, so supporting all of these types would probably need the date_type parameter suggested above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Per discussion, we do support those other input types. Will need to update docs to clarify inputs and outputs.

@dgodinez-dh dgodinez-dh marked this pull request as draft August 7, 2024 19:34
@dgodinez-dh dgodinez-dh marked this pull request as ready for review August 8, 2024 12:47
Copy link
Member

@mofojed mofojed left a comment

Choose a reason for hiding this comment

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

It's still showing up as GMT-5 for me when I enter America/New_York for my time zone:
image

Shouldn't that say EST/EDT? It's weird when I switch dates and it switches from GMT-5 to GMT-4...

@mofojed
Copy link
Member

mofojed commented Aug 19, 2024

It's still showing up as GMT-5 for me when I enter America/New_York for my time zone:
Turns out this was because in Chrome I had "English (United Kingdom)" set as my preferred language in settings: It's still showing up as GMT-5 for me when I enter America/New_York for my time zone:
Not sure why that was set to me. Changing to "English (Canada)" shows "EST/EDT" correctly.

mofojed
mofojed previously approved these changes Aug 19, 2024
Comment on lines +112 to +138
## Variants

Date Pickers can have different variants to indicate their purpose.

```python
from deephaven import ui


@ui.component
def date_picker_variants():
return [
ui.date_picker(description="description"),
ui.date_picker(error_message="error", validation_state="valid"),
ui.date_picker(error_message="error", validation_state="invalid"),
ui.date_picker(min_value="2024-01-01", max_value="2024-01-05"),
ui.date_picker(value="2024-07-27T16:10:10 America/New_York", hour_cycle=24),
ui.date_picker(granularity="YEAR"),
ui.date_picker(granularity="MONTH"),
ui.date_picker(granularity="DAY"),
ui.date_picker(granularity="HOUR"),
ui.date_picker(granularity="MINUTE"),
ui.date_picker(granularity="SECOND"),
]


date_picker_variants_example = date_picker_variants()
```
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be split into timezone, validation and granulariy sections.

Docs are expected to be exhaustive and there are several concepts and sections from: https://react-spectrum.adobe.com/react-spectrum/DatePicker.html that are missing

@dgodinez-dh dgodinez-dh merged commit ff48512 into deephaven:main Aug 21, 2024
16 checks passed
@dgodinez-dh dgodinez-dh deleted the dag_DatePickerUi branch August 21, 2024 13:01
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.

ui.date_picker JS side implementation
6 participants