-
Notifications
You must be signed in to change notification settings - Fork 82
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: drag-and-drop schedules #1089
base: main
Are you sure you want to change the base?
Conversation
previously, the copy button would copy the selected schedule instead of the schedule it was linked to.
That is the case now because of the RDS migration. All duplicate schedule names have been mangled. Looks pretty good, and well-detailed PR description as well. I'll try to look at this soon. |
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.
Drag icon is not visible in light mode
@adcockdalton remember to review this. It's marked changes requested because I requested changes, but that has been addressed. |
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.
Firstly I must apologize for the incredible delay on reviewing this. It's a useful PR and very well done and written up; it was disrespectful of me to lose track of it.
As for the PR itself, it looks great for the most part, but I had a couple issues. I'll explain how to repro:
- On reload with unsaved changes, deleted classes are only remembered to have been deleted for what seems to be the "root" schedule.
- Add 2-3 schedules
- Add classes to each
- Save
- Delete one class from each (don't save)
- Reload and check yes to load unsaved changes
You will be redirected to the "root" schedule, for which the class will be deleted (expected behavior in agreement with the main branch). The other schedules will not have their class deleted.
To follow-up with this, it also seems appropriate (if easily implementable from where we are now, since I'd like to merge this in soon) to also remember which schedule was being viewed on reload (without saving).
- I couldn't get mobile reordering via touch-scroll to work on my end. This could just be a chrome devtools issue though--is it currently working for you?
--
I also wanted to ask about your reasoning behind the tooltips:
I'm pretty sure tooltips have to encode additional information in order to be useful for accessibility: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tooltip_role , but I could be wrong on that--I'm not very familiar with screen readers and the like.
--
LGTM: all other unsaved changes features, tabbing, light mode
The saving issue seems to be a problem on prod as well. I'll look into why and get it fixed. The main point of the tooltip is to provide the full length of the schedule name if it exceeds the display limit and is omitted with ellipses. Currently, its behavior renders a tooltip for every schedule name regardless of whether the schedule name length exceeds the display length. This behavior is consistent with prod and can be reworked, if needed, in another PR. This PR just improves the styling of the tooltip offsets. |
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.
PR looks really great, thanks for tackling this much-requested feature! Will be a really nice value add for users.
Have added a handful of (mostly) non-blocking / quick fix comments mostly regarding code standards.
For testing:
-
Schedule select popover buttons (duplicate, rename, delete) work after reordering
-
Autosave works
-
Mobile works, Keyboard controls work
-
Skeleton Mode works great (or rather, doesn't)
-
Styles look good
-
Deleting schedules correctly deletes from the appropriate schedule
@@ -143,7 +152,7 @@ class ActionTypesStore extends EventEmitter { | |||
|
|||
async loadScheduleFromLocalSave() { | |||
const unsavedActionsString = getLocalStorageUnsavedActions(); | |||
|
|||
console.log(unsavedActionsString); |
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.
chore: extraneous console log
@@ -153,18 +162,20 @@ class ActionTypesStore extends EventEmitter { | |||
const actions = parseUnsavedActionsString(unsavedActionsString); | |||
|
|||
actions.forEach((action) => { | |||
console.log(typeof action); |
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.
chore: console log
inputProps={{ | ||
maxLength: NOTE_MAX_LEN, | ||
style: { cursor: skeletonMode ? 'not-allowed' : 'text' }, | ||
}} | ||
InputProps={{ disableUnderline: true }} | ||
fullWidth | ||
multiline | ||
disabled={skeletonMode} | ||
sx={{ | ||
'& .MuiInputBase-root': { | ||
cursor: skeletonMode ? 'not-allowed' : 'text', | ||
}, | ||
}} |
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.
question (non-blocking): why are we applying the cursor styling in both inputProps
and in sx
?
<DndContext | ||
sensors={sensors} | ||
modifiers={[restrictToVerticalAxis]} | ||
onDragStart={({ active }) => { |
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.
suggestion: Generally, it's better to extract logic out into named functions rather than using inline anonymous functions. Won't ask of that in this PR, but I think the codebase would be better off as we move towards explicit handlers
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.
suggestion: If you followed any documentation / largely drew your implementation from some source(s), it would be beneficial for future maintenance to link it here in a JSDoc
}} | ||
> | ||
<DragIndicatorIcon | ||
style={{ |
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.
issue: prefer sx
disabled?: boolean; | ||
} | ||
|
||
export function DragHandle({ disabled = false }: DragHandleProps) { |
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.
question/nit (non-blocking): we should keep files (mostly) atomic -- is there a reason this isn't in another file DragHandle.tsx
?
return ( | ||
<SortableList.Item id={item.id}> | ||
<Box | ||
display="flex" |
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.
suggestion: place these props in sx
Summary
Drag-And-Drop
Bug Fixes
Misc
Note
Previously, a list of
scheduleNames
was passed down as a prop to theSelectSchedulePopover
component. For implementing reordering via a sortable dnd list, eachscheduleName
must be mapped to a unique ID because we can't assume allscheduleNames
are unique yet.To address this:
AppStore.ts
saved schedule arrayAppStore
is recalculated accordingly.Important: The local mapping is not fully recreated after every reordering action. Instead, only the swapped elements are updated. The local mapping is only recreated during a complete component re-render. If we were to fully recreate the mapping on every reorder, it would disrupt:
Test Plan
Remember Me
checked, Try various combinations of schedule actions (create new schedules, delete some, reorder some, rename some, etc), reload the page, load unsaved changes and make sure the schedule state is the samehttps://dev.api.antalmanac.com/trpc/websoc
Issues
Closes #1054