-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
fix: switch DnD to modern context API (was legacy) #1819
Conversation
Hmmm... might still have remaining v17 compatibility issues due to DnD's use of findDOMNode (deprecated). Working on that too. |
let me know when you want to merge 👍 |
Thanks, @jquense -- the context switch was easy. The use of deprecated findDOMNode is harder (am working on that now). The original DnD addon is looking like it needs some serious love (very non-DRY, odd js idioms throughout) -- I might take a crack some rejuvenation throughout, but I also want to see it working with React 17 asap. I'll ping you when I have something useful to review! |
Hi @jquense... I just realized that the examples build on github seem to be of a different vintage than those on master? (for example, the page's dropdown is missing more recently-added examples). I've been working on finishing up the DnD refresh and thought I had introduced a regression but noticed that the examples built from master have the same probs (!). I'll dive into this but wondering if you had thoughts on why the examples page is out-of-date? (or maybe I'm missing something...) |
@ehahn9 i just always forget to deploy new docs which is why they are out of date. we should make that automatic with the version release tho |
HI @jquense - I [finally, sorry] had a chance to work on this. Many changes:
I had hoped to do a LOT more (css modules for scoped addon classnames, and major cleanup of original implementation which is difficult to maintain) -- maybe I'll get back to that at some point! I'm still a newbie, so apologies if this PR needs more work (happy to try!). |
@jquense, any chance you could review and possibly merge this PR? With DND resize broken in react 17, would be great to have it fixed. |
Hi @jquense - oh apologies - I'm new to this and I wasn't even aware that this was waiting on me. Sorry for asking for a lesson in OSS, but what's the protocol when one is reviewing their own PR? Do I just click squash + merge or should others be reviewing first/also? thx. |
@ehahn9 generally you still want someone else to review it, but i've not been prompt on that sorry! |
There is a lot of different fixes and changes here that make it a bit hard to review all at once. Generally its better to split these things into separate PR's, e.g. one for event propagation bugs, one for context changes, etc. |
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.
lots of great work, sorry i'm having a hard time following it!
@@ -55,7 +55,7 @@ class Dnd extends React.Component { | |||
|
|||
const nextEvents = events.map(existingEvent => { | |||
return existingEvent.id == event.id | |||
? { ...existingEvent, start, end } | |||
? { ...existingEvent, start, end, allDay } |
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.
doesn't the existingEvent
already have this?
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 old story's moveEvent
handler did't honor changes affecting allDay
. This change purports to make it possible to demo moving events in and out of the allDay gutter - supported by DnD but previously not supported by the story as it ignored the new value for allDay.
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 should have done this as a separate PR for sure! Newbie/learning.
this.update(event, slotMetrics.getRange(currentSlot, end, false, true)) | ||
const { duration } = eventTimes(event, accessors) | ||
let newEnd = dates.add(newSlot, duration, 'milliseconds') | ||
this.update(event, slotMetrics.getRange(newSlot, newEnd, false, 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.
I'm not sure i understand what the changes in this file are fixing? can you walk me through it?
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.
Good catch. The problem I was addressing was that the addon would sometimes fail to update the event end
on a move. This change always sets end = start + duration
where start = newSlot
(e.g. the target time slot at the end of the move).
|
||
EventContainerWrapper.propTypes = propTypes | ||
render() { | ||
return <div ref={this.ref}>{this.renderContent()}</div> |
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 spliting renderContent out as a separate function adds much? maybe just have render()
.
On the another note, I think it might more more sense to pass the ref to children
instead of adding a new DOM element
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.
Absolutely right. I was having trouble forwarding the ref and took the coward's way out. I'll try to work on this.
this.context.draggable.onBeginAction(this.props.event, 'resize', 'DOWN') | ||
} | ||
handleResizeLeft = e => { | ||
if (e.button !== 0) return | ||
e.stopPropagation() |
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 seems like removing these would create bugs, not fix them? Can you walk me through why this is necessary?
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.
Ok, this one is tricky. the Dnd addon uses rbc's selectable() mechanism to monitor mouse events before/during drags. selectable needs to see those events in order to work. The event wrapper stopped the propagation and so the selection logic was basically broken.
So first, I removed the stop propagation - that helped a lot.
But because the resize anchors are on top of the drag (move) anchor, clicking on a resize would also start a drag/move, which would abort the resize, etc.
So I added a check (see :42) to ignore this case:
// hack: because of the way the anchors are arranged in the DOM, resize
// anchor events will bubble up to the move anchor listener. Don't start
// move operations when we're on a resize anchor.
const isResizeHandle = e.target.className.includes('rbc-addons-dnd-resize')
if (!isResizeHandle)
this.context.draggable.onBeginAction(this.props.event, 'move')
Now the million dollar question is why did this ever work? My only theory is that react 17 changed where the event listeners were placed and maybe that subtle changed the event propagation?
I would love to back all of this out, but it seemed to be required both in reading the code and trying it.
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.
sounds like you got it all handled 👍
@@ -79,42 +61,34 @@ class WeekWrapper extends React.Component { | |||
this.setState({ segment }) | |||
} | |||
|
|||
handleMove = ({ x, y }, node, draggedEvent) => { | |||
handleMove = (point, bounds, draggedEvent) => { |
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 the changes in this file are hard to follow (though i'm sure correct and needed). What is is going on here, and how should test that it works?
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.
Purely idiomatic: all the other event handlers had the (point, bounds)
signature (as does the similar code in EventContainerWrapper
) so I was just conforming the idiom.
BTW, if you look closely, you'll see that WeekWrapper
and EventContainerWrapper
are in DIRE need of being DRY'ed out -- they basically do the same exact thing, with the main difference being the orientation of the event (horizontal or vertical). I spent a few days on that, but had to abandon due to 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.
... oh, and the other changes (sorry, that's probably what you were asking about) - were all about making the date handling correct during drags - which had a number of probs, some of which might have been introduce with the (required) upgrade to date-arithmetic (which was out-of-date and causing some probs).
Happy to answer in more detail about these edits although my memory is fading a bit on this.
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.
testing: I think the only way is via storybook/examples -- the code seems too intertwined IMHO for proper testing (definitely a good should a rewrite occur!)
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.
fine to defer the testing if there isn't a good way to write a unit test. I was thinking of the common-ish case where we fix one of these date bounds issues and introduce another one, partly because the calculations have no tests asserting their current behavior so easy to break stuff!
I'll wait to hear back from you (@jquense) before working further on this PR. Agreed, I really should have done this in more atomic pieces (and will next time!). Alas, I find the DnD addon to be super hard to work on (maybe even a rewrite) and so my energy was flagging during this... apologies. |
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 would rename the PR so semantic release doesn't call all of this a "fix", might be worth hand rebasing the commits into different messages and then doing a "merge" instead of a "squash" but up to you.
Thanks @jquense - just to be sure I'm doing the right thing: are you suggesting I replace this PR with smaller, more focussed ones? (I presume there's a way to cancel this PR?) I'm happy to work on that! I know there's some time pressure for this due to v17 so I hope I'm not holding things up. |
not quite, the suggestion was to rebase the commits in the current PR to something like
etc, etc, and then merging instead of squash and merge so the commits stay intact on master. That said it all involves a bunch of Git-fu, that you may or may not be comfortable with, so fine to merge as is if you want |
also upg date-arithmetic dep & some minor cleanup
Just rebased all the commits and reworded - lmk if this looks okay to you -- then I'm happy to merge (merge commit, no squash) |
very nice 👍 |
🎉 This PR is included in version 0.33.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 very nice |
@yann-combarnous - although more knowledgeable folks might disagree, I suspect the addon might be at the limits of maintainability at this point :-(. ps: I took a stab at rewriting it from scratch as a completely separate project using react-dnd, but ran into some architectural problems with resize animation. |
DnD addon was relying on legacy context api which finally broke with React 17 (couldn't resize events, etc.).
Fixes #1795. Related to #1776.