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

Select multiple non-consecutive dates #4537

Merged
merged 22 commits into from
Feb 28, 2024

Conversation

tbowmo
Copy link
Contributor

@tbowmo tbowmo commented Feb 27, 2024

Rework of #3999 that seems to be stalled.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

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

✅ This pull request was sent to the PullRequest network.


@tbowmo you can click here to see the review status or cancel the code review job.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

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

PullRequest Breakdown

Reviewable lines of change

+ 292
- 14

58% JavaScript (tests)
42% JavaScript

Type of change

Feature - These changes are adding a new feature or improvement to existing code.

Copy link

codecov bot commented Feb 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.51%. Comparing base (8089471) to head (4cf8db1).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4537      +/-   ##
==========================================
+ Coverage   95.45%   95.51%   +0.05%     
==========================================
  Files          29       29              
  Lines        2533     2566      +33     
  Branches     1039     1053      +14     
==========================================
+ Hits         2418     2451      +33     
  Misses        115      115              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@martijnrusschen
Copy link
Member

@tbowmo Thanks for submitting this PR! Are you able to check out the missing coverage that Codecov is complaining about?

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 27, 2024

Yup will do.

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 27, 2024

@martijnrusschen Hmm.. could we bump codecov? I've updated code here and there, and would be nice to get a new status (I'm used to coverage reports running automatically)

@martijnrusschen
Copy link
Member

Running it now

@martijnrusschen
Copy link
Member

Results are updated now

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

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

Overall this looks like a clean and well tested implementation. The only thing I'd necessarily want to block on is what seems to be a minor bug in the isSelected function.

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>


Reviewed with ❤️ by PullRequest

@@ -0,0 +1,15 @@
() => {
Copy link

Choose a reason for hiding this comment

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

ISSUE: no-unused-expressions (Severity: Medium)
Expected an assignment or function call and instead saw an expression.

Remediation:
This may be a non-issue if there's an existing convention and bundler configuration that I'm unaware of, but should this not be exported?

🤖 powered by PullRequest Automation 👋 verified by Ryan Lester <@buu700>

setSelectedDates(dates);
};
return (
<DatePicker
Copy link

Choose a reason for hiding this comment

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

ISSUE: react/jsx-no-undef (Severity: Medium)
'DatePicker' is not defined.

Remediation:
Similar to my other comment, not sure if there's a missing import statement for this.

🤖 powered by PullRequest Automation 👋 verified by Ryan Lester <@buu700>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the same for all the example files, none of them import DatePicker

Copy link

Choose a reason for hiding this comment

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

👍

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

@@ -197,6 +197,23 @@ export function safeDateRangeFormat(startDate, endDate, props) {
return `${formattedStartDate} - ${formattedEndDate}`;
}

export function safeMultipleDatesFormat(dates, props) {
Copy link

Choose a reason for hiding this comment

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

Seems like a lot of care was put into defensive input handling here.

◽ Compliment

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

Copy link

Choose a reason for hiding this comment

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

Agreed - is !dates?.length a valid input state? Is "" a value that makes sense for the output of safeMultipleDatesFormat?

Image of Jacques Jacques

Copy link
Contributor Author

@tbowmo tbowmo Feb 28, 2024

Choose a reason for hiding this comment

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

If length is zero, it should return an empty string. I haven't looked that deep into the underlying code to see if null / undefined is a valid input. But I'm used to do the ?.length test in our own code, so seemed natural for me to do that.

Now that I think of it, it could probably skip a couple of if branches here, and reduce cyclic complexity a bit, by using an array join, like this

export function safeMultipleDatesFormat(dates, props) {
  if (dates?.length > 2) {
    return `${safeDateFormat(dates[0], props)} (+${dates.length - 1})`;
  }

  return (dates || []).map((date) => safeDateFormat(date, props)).join(', ')
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also seems that the rest of the safeDateFormat methods is taking care of possible null/undefined inputs

src/day.jsx Outdated
return false;
}

if (this.props.selectsMultiple) {
Copy link

Choose a reason for hiding this comment

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

This might be slightly more readable as something like:

const isSelectedDate = this.props.selectsMultiple
  ? this.props.selectedDates?.some(
      (date) => this.isSameDay(date) || this.isSameWeek(date),
    )
  : this.isSameDay(this.props.selected) || this.isSameWeek(this.props.selected);

const isPreSelectedDate =
  this.isSameDay(this.props.preSelection) ||
  this.isSameWeek(this.props.preSelection);

return !isSelectedDate && isPreSelectedDate;

You could also go further and factor out (date) => this.isSameDay(date) || this.isSameWeek(date) to a named isSameDayOrWeek function, which could be used further below in isSelected.

🔹 Code Reuse (Nice to have)

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

src/day.jsx Outdated
isSelected = () => {
if (this.props.selectsMultiple) {
return this.props.selectedDates?.some(
(date) => this.isSameDay(date) || this.isSameWeek(this.props.selected),
Copy link

Choose a reason for hiding this comment

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

This looks like a bug: this.isSameWeek(this.props.selected) -> this.isSameWeek(date).

In addition to fixing the bug, consider adding a test to cover this specific issue.

🔺 Bug (Critical)

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

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 added this.isSameWeek() as it apparently was used in "single selected" mode, and thought it was supposed to be there? (I'm fairly new to this react component, so bear with me if I'm mistaken ;))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oooh.. now I see it.. yup, that should be date and not props.selected :)

Copy link

Choose a reason for hiding this comment

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

Sorry, just to clarify, it seems to me from context that the correct argument to isSameWeek() on this line should be date rather than this.props.selected. (If I misunderstood something, feel free to disregard.)

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>


if (
!isEqual(this.props.selected, changedDate) ||
this.props.allowSameDay ||
selectsRange
selectsRange ||
selectsMultiple
) {
if (changedDate !== null) {
Copy link

Choose a reason for hiding this comment

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

This would be a pre-existing issue, but is there any scenario where changedDate might be undefined? If so, consider changing this to != null (as used in code further below).

🔹 Bug (Nice to have)

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure about this one? haven't touched this part myself..

Copy link

Choose a reason for hiding this comment

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

Ah okay, sounds good, just something that caught my attention while I was working backwards from your code to see what changedDate was. Seems out of scope of this PR either way, but may be worth someone taking a look at separately.

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>

@porlov
Copy link

porlov commented Feb 27, 2024

@tbowmo Does this PR allow to select multiple date ranges?
I think we should support them for consistency too.

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 27, 2024

@tbowmo Does this PR allow to select multiple date ranges?
I think we should support them for consistency too.

No, it does not. Date ranges is another set of properties.

I would like to keep this pr as simple as possible, and keep dateranges separated.

Also my current usecase is multiple single dates.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

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

This change looks good and is simple enough

Image of Jacques Jacques


Reviewed with ❤️ by PullRequest

return false;
}

const isSelectedDate = this.props.selectsMultiple
Copy link

Choose a reason for hiding this comment

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

Good - you can maybe even further break this ball of hair down to one or two more if statements.

🔹 Improve Readability (Nice to have)

Image of Jacques Jacques

@@ -0,0 +1,59 @@
import React from "react";
Copy link

Choose a reason for hiding this comment

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

ISSUE: no-unused-vars (Severity: Low)
'React' is defined but never used.

Remediation:
Pointing this out just in case it's not actually needed

🤖 powered by PullRequest Automation 👋 verified by Jacques

@porlov
Copy link

porlov commented Feb 27, 2024

No, it does not. Date ranges is another set of properties.

@tbowmo Will it be planned to support it in the future?
Having only multiple dates selection looks inconsistent with base functionality.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

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

Latest changes look good to me!

Image of Ryan Lester <@buu700> Ryan Lester <@buu700>


Reviewed with ❤️ by PullRequest

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 28, 2024

No, it does not. Date ranges is another set of properties.

@tbowmo Will it be planned to support it in the future? Having only multiple dates selection looks inconsistent with base functionality.

Not sure how it should be implemented at the moment (should we add yet another set of properties for multiple date ranges?).

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 28, 2024

There is one test failing, which also fails if I checkout upstream main branch?

@martijnrusschen
Copy link
Member

Yes it looks like the main branch is failing because of some end of month test that's failing.

@martijnrusschen
Copy link
Member

Here's a fix #4541 (comment)

@martijnrusschen
Copy link
Member

Try pulling in the latest main branch

@tbowmo
Copy link
Contributor Author

tbowmo commented Feb 28, 2024

Yay.. all green now.. Let me know if there are anything that needs to be done further before it's ready to merge

@martijnrusschen martijnrusschen merged commit 698e44e into Hacker0x01:main Feb 28, 2024
6 checks passed
@martijnrusschen
Copy link
Member

Good to go! Thanks for the effort and help getting this over the finish line.

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.

5 participants