-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Default single step selection to max step; Refactor TimeSelection type so end is always set. #6364
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
Conversation
| export interface TimeSelection { | ||
| start: {step: number}; | ||
| end: {step: number} | null; | ||
| start: {step: number} | null; |
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 decision to have end be end: {step: number} | null rather than end?: {step: number} has lead to a lot of clunky code (especially in tests). I would love to see this changed and I think this may be a good time for this update. However, I recognize that this is not a small change so I'll leave it to your discretion.
rileyajones
left a comment
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 will get back to reviewing this tomorrow, I only made it ~50% of the way through today but I wanted to leave some initial comments for now.
This has clearly taken a lot of work and I do think it is an improvement so I'm not going to block the effort, however, given the number of PR/CLs that are going to be required to get his checked in please think carefully about the cost benefit of making such a large change.
- Given the existing plans to remove the global values for step and range selection along with the check boxes I'm not sure how this will actually be different from the existing experience. This is definitely an improvement while the check boxes and default values stay around though.
- The same result could likely have been achieved with only updates to the fob controller, the rangeSelectionEnabled reducer, the stepSelectionEnabled reducer, and the getCardTimeSelection selector
- At the redux level there is always both a start and end value. This value is then clipped at the container level. You could have just removed that, removed the ability for end to be null, and updated the data table and card fob controller to read the value of
getCardRangeSelectionEnabled(like they should).
| }; | ||
| } | ||
| if (!linkedTimeSelection.end) { | ||
| if (linkedTimeSelection.start === null) { |
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.
nit: While your solution is technically more correct I'm not sure the distinction between null and falsey is important here.
| if (linkedTimeSelection.start === null) { | |
| if (!linkedTimeSelection.start) { |
|
|
||
| let nextStepIndexMetaData: CardStepIndexMetaData | null = null; | ||
| if (timeSelection.end === null) { | ||
| if (timeSelection.start === null) { |
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.
nit
| if (timeSelection.start === null) { | |
| if (!timeSelection.start) { |
| if (steps.indexOf(timeSelection.start.step) !== -1) | ||
| return [timeSelection.start.step]; | ||
| // Single selection: returns end step if matching any step in the list, otherwise returns nothing. | ||
| if (timeSelection.start === null) { |
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.
nit
| if (timeSelection.start === null) { | |
| if (!timeSelection.start) { |
| @Input() timeSelection!: { | ||
| start: {step: number}; | ||
| end: {step: number} | null; | ||
| start: {step: number} | null; | ||
| end: {step: number}; | ||
| } | null; |
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 aware that you are just updating the existing code but it would be nice to actually use the type here
| @Input() timeSelection!: { | |
| start: {step: number}; | |
| end: {step: number} | null; | |
| start: {step: number} | null; | |
| end: {step: number}; | |
| } | null; | |
| @Input() timeSelection!: TimeSelection | null` |
| (step) => | ||
| step >= linkedTimeSelection.startStep && | ||
| step <= linkedTimeSelection.endStep! | ||
| step >= linkedTimeSelection.startStep! && |
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 is a rare situation where the difference between null and undefined actually matters. If you do decide to take my advice to change to using undefined rather than null you will need to this.
For reference numbers are never greater than nor less than undefined but null is treated as 0.
| ]).pipe( | ||
| map(([timeSelection, singleSelectionHeaders, rangeSelectionHeaders]) => { | ||
| if (!timeSelection || timeSelection.end === null) { | ||
| if (!timeSelection || timeSelection.start === null) { |
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.
nit
| if (!timeSelection || timeSelection.start === null) { | |
| if (!timeSelection || !timeSelection.start) { |
| return [timeSelection.start.step]; | ||
| // Single selection: returns end step if matching any step in the list, otherwise returns nothing. | ||
| if (timeSelection.start === null) { | ||
| if (steps.indexOf(timeSelection.end.step) !== -1) |
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.
Because we are not actually using the index this seems like an excellent place to use the includes function
| if (steps.indexOf(timeSelection.end.step) !== -1) | |
| if (steps.includes(timeSelection.end.step)) |
Good advice. I will close this and have a simpler change in #6372. |
Motivation for features / changes
We are changing single step selection to default to the maximum step. We think this is more useful than making the default the minimum step.
Technical description of changes
Change
TimeSelectiontype so thatstartis nullable whileendis not and adjust the code to fit.Where default value is set to "min" step, instead set it to the "max" step.
One tricky aspect: In some places we were checking that
endwas falsy or truthy to determine if it was set. There was a latent bug that ifendwas set to 0 then it would be considered unset in those cases. This was not a big problem becauseendwas rarely set to 0. Butstartis often set to 0 so those cases needed to be carefully tracked down and fixed.Another tricky aspect: The
TimeSelectionrefactor does not cleanly import into the internal repo. I have three CLs that accompagny this change.Detailed steps to verify changes work correctly (as executed by you)