-
Notifications
You must be signed in to change notification settings - Fork 642
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(milestones):add dates to milestones section #6020
feat(milestones):add dates to milestones section #6020
Conversation
Can you add some screenshots that show that the dates are the same in the Milestones vs the Timeline and This Week? The tricky part of this particular issue is to guarantee that we're using the same algorithm to calculate the dates everywhere they are shown — ideally, only calculating them once, or if done multiple times, then using the same function with the same inputs. |
I am using the same |
@@ -28,9 +30,11 @@ const Milestones = createReactClass({ | |||
const weekNumberOffset = CourseDateUtils.weeksBeforeTimeline(this.props.course); | |||
const blocks = []; | |||
|
|||
this.props.allWeeks.map((week) => { | |||
this.props.allWeeks.map((week,navIndex) => { |
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.
Where does this come from? In Timeline.jsx, it the result of some complex code in the render cycle for handling empty weeks.
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 navIndex
is generated by the map
function, which helps identify unique elements in the array. Additionally, the DateCalculator
requires the navIndex
prop for its calculations. Upon cross-checking in the Timeline page, I confirmed that the navIndex
is simply the index number generated by the map
function.
You've shown the first week, but it's important to check for how it handles empty weeks as well. |
Empty weeks can come at the beginning of a course, by including a gap between course start and timeline_start, and also in the middle of the course by using the calendar (via Edit Course Dates on the Timeline tab) to create weeks with no meeting days. |
In the Milestones section, empty weeks are not displayed Weeks 159 and 164 are empty, and they are not displayed in the Milestones section. I also tried using another course for this: University of Pennsylvania Medical Missionaries to Community Partners (Fall 2023). |
cool. this looks like it's working properly. do you see a good way to avoid repeating the date calculations so that both the timeline and the milestones component can use the same value without a risk that they will diverge with later changes to the timeline component? i think it's dangerous to have these hard-to-understand parallel implementations. |
@ragesoss Yes, but it’s only two lines of code. I hope there won’t be any divergence in the future, as I believe it’s a straightforward implementation. If we implement a new way to eliminate redundancy in the code, we would still need to pass timelineStart, timelineEnd, and navIndex, which would make the code redundant again, right?
|
@shishiro26 I think the ideal strategy would be to do whatever data manipulation and calculation is necessary in a |
…ates_to_milestones
@ragesoss I have reviewed the codebase and confirmed that the date-related data is derived from the course or stored in the Redux store. In line with your previous suggestion, I plan to create a selector that extracts the course timelines and returns the start and end dates. This approach will help prevent discrepancies in date calculations and ensure that components such as Milestones and Timeline display consistent data. Centralizing date calculations within the selector will enhance uniformity across the application. Would you suggest any additional refactoring beyond this plan? |
@shishiro26 I think it's wise to do the minimum amount of refactoring necessary to unify this particular calculation, and if you notice anything along the way that you think ought to be refactored, make a note of it. |
@ragesoss, I will ensure that I do the minimum necessary refactoring and update the commit accordingly. I will also make sure to note any important refactoring opportunities if they arise. |
@ragesoss I have updated the code. Could you please check if this aligns with what we discussed? |
@@ -4,6 +4,7 @@ import createReactClass from 'create-react-class'; | |||
import { filter } from 'lodash-es'; | |||
|
|||
import CourseDateUtils from '../../utils/course_date_utils'; | |||
import DateCalculator from '../../utils/date_calculator'; |
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.
Is this still needed?
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.
Nope,I forgot to remove the DateCalculator. I'll go ahead and remove it now, sorry about that.
@@ -388,16 +389,24 @@ const Timeline = createReactClass({ | |||
navClassName += ' is-current'; | |||
} | |||
|
|||
const dateCalc = new DateCalculator(this.props.course.timeline_start, this.props.course.timeline_end, navIndex, { zeroIndexed: 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.
If this was the only use of DateCalculator, it no longer needs to be imported in the file.
const milestoneBlocks = filter(week.blocks, block => block.kind === this.milestoneBlockType); | ||
return milestoneBlocks.map((block) => { | ||
if ( |
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.
It looks we're doing something similar in both this component and the Timeline, checking for whether to map a particular block to null
. Is this something that can become shared logic in the selector, or do they handle these cases differently?
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, the problem I encountered is that in the selector, I needed the index for the weeks to display, so I used weeks
in the const getWeeks = state => state.timeline.weeks;
function to memoize all the results. However, the issue is that the allWeekDates
being sent from getAllWeekDates(state)
contains weeks that are after the timeline end date, but the getWeeks
function doesn't include them.
To handle this, when creating the DateCalculator
instance:
const dateCalc = new DateCalculator(course.timeline_start, course.timeline_end, index, {
zeroIndexed: true
});
I found that the last indexes didn't have any dates, causing it to be empty when trying to render in the milestones and timeline. To fix this, I added a check for that in both files.
if ( | ||
!this.props.weekDates[navIndex]?.start || | ||
!this.props.weekDates[navIndex]?.end || | ||
this.props.weekDates[navIndex]?.start > this.props.weekDates[navIndex]?.end |
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 quite verbose, but it's not obvious what this if statement is for. What situation(s) for a block are being checked for here?
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 check was added to prevent any date from showing after the timeline's end date in the milestone.
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.
Hmm... I don't think that' necessary. The Timeline can handle dates that are after the end date (in which case, they get highlighted in red). I think in the Milestones component, it would be better to show dates that stretch beyond the end date, when that happens.
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.
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 don't think any special formatting is needed in the Milestones 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.
Yes, I have updated it. Could you please check it?
|
||
if ( | ||
!startDate || | ||
!endDate |
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.
Why were these checks not necessary in the current implementation?
Build is currently failing because of JS linting errors. |
I would like to do this since I have been using Docker. Could you provide me with the steps to run lint in Docker? |
You're kind of on your own with that, as we don't have up-to-date docs for docker, and I don't use it. |
I have resolved all the linting issues, @ragesoss. |
@ragesoss I came across an issue while fixing the lint errors. I saw the line lint-non-build": "eslint 'test/**/.{jsx,js}' '.js'" and I’m not sure if this is the only line responsible for linting, as I couldn't find any other run functions in the codebase. Last time, when I encountered lint issues, I fixed everything explicitly. Could you guide me on what I need to do for this? |
The failing tests seem to be related to this change. |
Looks like the one failing test is related. |
…to use allWeeksDates
I hope these new changes work now, @ragesoss! 🤞🤞 |
@@ -397,7 +398,7 @@ const Timeline = createReactClass({ | |||
if (usingCustomTitles) { | |||
let navTitle = ''; | |||
if (weekInfo.emptyWeek) { | |||
const datesStr = `${dateCalc.start()} - ${dateCalc.end()}`; | |||
const datesStr = `${weekDates[navIndex].start} - ${weekDates[navIndex].end}`; |
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 note that his branch of code is being switched to use weekDates, but another branch below uses dateCalc. Is that the intended/correct behavior?
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.
Thank you for pointing this out! I don't recall the exact branch in question, but this is the updated and correct code. The change to weekDates is intentional and reflects the latest update to the logic.
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.
What I mean is, is it intention to switch from dateCalc to weekDates in only one branch, or should it be done in both?
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.
It should be implemented in only one branch, not both.
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.
Okay. Why?
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 other branch is the older one, and I have been working on different changes there. In this branch, I’ve completely rewritten the code, while the other branch continues to focus on the previous changes or issues
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 feel a little lost here. Why can't the calls to dateCalc in the else
branch below also be switched to use weekDates?
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.
Apologies for any confusion on my end. I currently have two branches in development: one focused on resolving the current issue, and the other working on issue #651. The second branch is entirely separate, and I need to make some changes to it. As a result, I've converted that branch into a draft and have been focusing solely on the first branch for now. Are we on the same page, or is there still some misunderstanding on my part? This is why I've added the weekDates to this branch and not the other branch .
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.
Oh! Sorry, I meant logical branch of the code, as in the if/else
statement that starts at line 399. This PR changes the if
portion but does not change the else
portion, and I think it should probably change both.
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.
Thanks for the clarification! I’ve updated both the if and else parts as suggested and pushed the changes. Let me know if anything else is needed! 😅👍
@@ -27,6 +27,7 @@ import { getStudentCount, getCurrentUser, getWeeksArray } from '../../selectors' | |||
import ActivityHandler from '../activity/activity_handler'; | |||
import CourseApproval from './course_approval'; | |||
|
|||
|
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.
Please remove this.
@@ -1,11 +1,28 @@ | |||
import { createSelector } from 'reselect'; | |||
import { sortBy, difference, uniq, filter, includes, pickBy, find } from 'lodash-es'; | |||
import { |
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'd prefer not to include all these formatting changes alongside the new feature.
[getAllWeeksArray, getCourse], | ||
(weeksArray, course) => { | ||
return weeksArray.map((_, index) => { | ||
const DateCalc = new DateCalculator( |
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.
By convention, this DateCalc object should start with a lower-case letter.
I am happy with this implementation, and I'm ready to merge it after cleanup of the minor issues in my latest comments. |
@ragesoss, I have fixed all the formatting changes. This should work now! 😃😃 |
…ates_to_milestones
What this PR does
This PR addresses the issue of missing date information in the Milestones section on the Home tab. Previously, while the Milestones section displayed the week numbers derived from the Timeline data, it did not include the corresponding start and end dates for each milestone block.
Screenshots
Before:
After:
#279