-
Notifications
You must be signed in to change notification settings - Fork 331
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(recurrence): Added advanced recurrence settings #7585
Conversation
const meeting = await safeCreateTeamPrompt(teamId, facilitatorId, r, dataLoader, { | ||
name: `${meetingSeries.title} - ${formattedDate}`, | ||
scheduledEndTime: new Date(startTime.getTime() + ms(`${meetingSeries.duration}m`)), | ||
scheduledEndTime: nextMeetingStartDate, |
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 changed the way we calculate the next meeting start date because now, as we support multiple recurrence configurations, we can't rely on fixed meeting duration. Imagine the following scenario:
The meeting is set to recur weekly on Fridays and Saturdays. IMO it's not ideal to assume that the meeting will last only 24h, and I'd expect the meeting to last the whole period before the next one starts. this means Saturday's meeting will last almost a week and will end just before Friday's meeting starts. Friday's meeting will last only 24h and will end on Saturday (just before Saturday's meeting starts)
@jmtaber129 @enriquesanchez wdyt?
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 expect the meeting to last the whole period before the next one starts
This sounds right to me 👍
25f7536
to
cceb2f8
Compare
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
@jmtaber129 except for the timezone issue this PR is ready to be reviewed. Migration to make edit: I didn't notice you already approved it! sorry! |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
//TODO: this causes rrule to provide 'Invalid Date' for the next occurrences - see https://github.com/jakubroztocil/rrule/pull/547 | ||
tzid: timeZone |
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.
Seems like the RRule
library isn't actively maintained anymore. I propose to fork and maintain our own version of it. @mattkrick @Dschoordsch do you have any concerns or thoughts about that? this issue is the only blocker of this PR.
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 comment yesterday from what seems to be one of the maintainers, so I wouldn't consider this unmaintained. I see no issues having our own fork with this fix if we need it right now. Maintaining a date handling library long term though sounds quite frightening to me.
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, will wait a little bit longer and see what happens.
export type Day = {name: DayFullName; short: DayShortName; rruleVal: Weekday; intVal: number} | ||
export type Day = { | ||
name: DayFullName | ||
med: string |
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.
+1 The name med
is somewhat ambiguous. Maybe we call this shortName
, and rename short
to abbreviation
?
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 like that! will do.
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
@mattkrick do you mind taking a look? thanks! |
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.
all pretty minor stuff. lookin ggggreat!
const [recurrenceInterval, setRecurrenceInterval] = React.useState( | ||
recurrenceRule ? recurrenceRule.options.interval : 1 | ||
) | ||
const [recurrenceDays, setRecurrenceDays] = React.useState<Day[]>( |
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.
+1 if we're suggesting 6:00AM tomorrow down below, should we pick a default day for them here? If we only want to select a single day, perhaps we pick today's date & time & assume they'll want to run the same meeting in a week?
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.
we're suggesting 6:00 AM, not necessarily tomorrow. setting next day in code is a safeguard to not create any meeting automatically the same day user starts the meeting manually (ie. via start new meeting modal while setting up recurrence).
current recurrence behavior is the following, new meeting is started immediately after clicking, a new one will be started according to recurrence rule, but not faster than tomorrow. ie. we don't want to start a meeting today, and also automatically start a new meeting on the same day. couple of examples below
-
It's 11 PM and user starts a meeting with recurrence enabled for all days with time 6:00 AM selected - new meeting starts immediately, next one will be started automatically at 6:00 AM tomorrow (and the previous one automatically closed)
-
It's Monday, 11:00 PM and user starts a meeting with recurrence enabled for Fridays with 6:00 AM selected - new meeting starts immediately, next one will be started automatically on Friday at 6:00 AM (and the previous one closed)
@matt do you have any concerns about this behavior? isn't it clear how it works when you look at the UI for the first time? if not, how would you improve that?
? recurrenceRule.options.dtstart | ||
: dayjs() | ||
.add(1, 'day') | ||
.set('hour', 6) |
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.
+1 Please let's not encourage 6AM meetings 😅 Maybe 9AM, or whatever their current time is rounded to the nearest 30 mins? We do something similar here when we suggest adding the meeting to their calendar
const newTime = roundDateToNearestHalfHour(new Date(createdAt.getTime() + ms('7d'))) |
EDIT: ohhh i think this is when the meeting opens, not necessary when it starts! If so, could we add a little note about that? If people set it for their actual meeting start time, it'd be a shame if no one can join 15 seconds early
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, standups are meant to be async first so there's no such thing as start time
. 6AM is suggested as it's a pretty safe bet so everyone can have time to add responses. if that causes any tensions for our users, we'll improve but imo should be good as v1
const {menuProps, onClick} = props | ||
const startOfToday = new Date().setHours(0, 0, 0, 0) | ||
return ( | ||
<Menu {...menuProps} ariaLabel={'6:00 AM'}> |
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.
-1 set ariaLabel to a description
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.
done
const {menuProps, onClick} = props | ||
const startOfToday = new Date().setHours(0, 0, 0, 0) | ||
return ( | ||
<Menu {...menuProps} ariaLabel={'6:00 AM'}> |
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.
-1 can we add a defaultActiveIdx
on & scroll to the current value? For example, if the value is currently 6AM, when i open the menu that item should be highlighted & in the center so I can quickly pick 5:30 or 6:30
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.
added defaultActiveIdx
. seems like it should automatically scroll to the element using this code. but it doesn't seem to work. I played with it for a while but I can't make it work. would you mind if I handle this as a separate issue?
|
||
// TODO: now, as new meeting series could be created from a new meeting view, let's grab the first part ie. "Standup - Jan 1" will be "Standup" | ||
// TODO: this is a temporary solution, we should have a better way to handle this | ||
const [cleanMeetingName] = meetingName.includes('-') ? meetingName.split('-') : [meetingName] |
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.
+1 no need for the ternary, meetingName.split('-') works, or meetingName.slice(0, meetingName.indexOf('-'))
plays better with typescript so you don't need to add a !
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.
@@ -25,7 +26,7 @@ export const TimeLeftBadge = (props: Props) => { | |||
<TeamPromptBadge onMouseEnter={openTooltip} onMouseLeave={closeTooltip} ref={originRef}> | |||
{fromNow} left | |||
</TeamPromptBadge> | |||
{tooltipPortal(`Ends at ${meetingEndTimeDate.toLocaleString()}`)} | |||
{tooltipPortal(`Restarts at ${dayjs(meetingEndTimeDate).format('MMM D, YYYY h:mm A')}`)} |
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.
+1 Since the day immediately follows the preposition, grammatically I believe it's "restarts on" and then ideally have "at" preceding the time.
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.
@@ -25,7 +26,7 @@ export const TimeLeftBadge = (props: Props) => { | |||
<TeamPromptBadge onMouseEnter={openTooltip} onMouseLeave={closeTooltip} ref={originRef}> |
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.
+1 badges shouldn't show the caret when hovered. maybe user-select: none
or change the cursor?
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 don't see anything better than cursor help
which isn't ideal. I'd go with user-select: none
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
@mattkrick fixed all the comments, would you mind taking a look? I added |
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR will be delayed and might be rejected due to its size. |
@mattkrick everything resolved, |
Description
Fixes #6922, #7497, #7496
Changes introduced in this PR reflect technical spec discussed here.
startRecurrence
andstopRecurrence
mutationupdateRecurrenceSettings
mutation that handles both scenariosstartTeamPrompt
mutation to SDLRRule
gql scalar typeTODO:
tzid
issueduration
nullable - will be handled in separate PRDemo
https://www.loom.com/share/09082094a1e14e168e6af28fe3d1d12a
Testing scenarios
Enabling recurrence from the new meeting view
Updating recurrence from the existing meeting view
Disabling recurrence from the existing meeting view
Enable recurrence from the meeting view
Final checklist
One Review Required
if the PR introduces only minor changes, does not contain any architectural changes or does not introduce any new patterns and I think one review is sufficient'