-
Notifications
You must be signed in to change notification settings - Fork 7
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
Router multi step forms #1966
Router multi step forms #1966
Conversation
✅ Deploy Preview for decent-interface-dev ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
I've been doing a bit of manual testing, and so far the following things would need to be "fixed" before we can consider merging:
|
|
…s, navigate to essentials from multisig if DAO name or governance type is not set
@adamgall Done, check updated implementation pls |
Thanks for the improvements @mudrila! Some more suggestions:
|
@adamgall Instead of component I just made a hook - I think "Component that returns null and calls hook" is kinda anti-pattern - if all it does is calling hook - just call damn hook in the place where you were rendering that empty component |
Haha, good point |
Hey @mudrila / @adamgall , love to see this coming down the line. So I just tested two use cases:
See video for full experience of (2) here - https://decentdao.slack.com/archives/C06QZTUTKRC/p1717419840496079?thread_ts=1717419826.480139&cid=C06QZTUTKRC This is the main issue at 0:40 seconds. When clicking 'create child safe' the URLs get mixed between the new 'essentials' and childsafe URL Note - At 0:18 and 1:00 I also got errors when navigating back to a DAO after starting the create DAO flow. This could be a seperate issue but wanted to raise it in case it was URL related. ![]() |
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.
Create DAO ✅
Create ChildDAO ❌
- Same error as @tomstuart123
Proposal Create Proposals: ✅
Proposal Templates ❌
That's probably new issue introduced after very latest changes. |
Team agreed (on standup) that first "issue" here is expected behavior and not something to fix. |
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.
Finally finished this code review, whew. I'll leave code-level approval for someone else on the dev team, but code looks good to me as of now. I'll get around to manual testing tomorrow, which I have not yet done.
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 think the code used to determine nextStep
and previousStep
could be improved.
I think that improvement starts with where the enum CreatorSteps
are being defined. That enum
doesn't actually define a "set of steps", it defines a bunch of independent steps, but there's no relationship between them.
Starting from the type definition code here, can we actually create a set of (numbered) enums, one for each type of DAO which might be created.
For example:
enum RootMultisigSteps {
ESSENTIALS,
MULTISIG_DETAILS,
}
enum ChildMultisigSteps {
ESSENTIALS,
MULTISIG_DETAILS,
FREEZE_DETAILS,
}
enum RootERC20Steps {
ESSENTIALS,
ERC20_DETAILS,
AZORIUS_DETAILS,
}
These enums all have numbers as their base type, and importantly the different "steps" within them are numbered, so it should be much easier to know which step is "prev" and which is "next", when we're in the actual step code flow.
Will something like this work? Let me know if it would be easier to talk out in person.
Bug? This url: "https://deploy-preview-1966.app.dev.decentdao.org/create/essentials/" (trailing slash) triggers a weird recursive redirect loop that ends up sth like this (note address bar content): ![]() |
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 gonna stop my code review prematurely, and talk about more structural changes I'd like to see in this PR.
Now that we've got a good framework for dynamically rendering UI, let's reorganize the structure of our routes to bring some closeness (and maybe convergence) between the different "dao creation flavors" (arrays of enum values), and the url structure.
You might see where I'm going with this.
-
new root ERC20 token dao on the first step
- /create/root/erc20/essentials
-
new root ERC20 token dao on the second step
- /create/root/erc20/erc20token
-
new root ERC20 token dao on the third step
- /create/root/erc20/azorius
-
new child multisig dao on the first steps
- /create/child/multisig/essentials
-
... etc
I expect that continued experimentation in this direction will lead to some pretty code.
Specifically, i'd like to see the URL structure uniquely identify any step in any creation flow.
const { t } = useTranslation(['daoCreate', 'common']); | ||
const { | ||
readOnly: { user }, | ||
} = useFractal(); | ||
const location = useLocation(); | ||
const paths = location.pathname.split('/'); | ||
const step = (paths[paths.length - 1] || paths[paths.length - 2]) as CreatorSteps | undefined; |
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.
Can you leave a comment in code explaining why there are two options for "current step"
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 sir
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.
btw, what was the outcome of trying to "remove trailing slashes" that was a fkn nightmare the other 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.
Oh yeah - freaking nightmare, I just gave up and made it to work with trailing slash with this "hacky" way 🤣
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've gotten through this review, and it's a lot of great work.
I just feel a kind of way about how StepController.tsx
is structured. I wonder why it can't flow more smoothly?
Early this week let's keep talking about this PR.
const { t } = useTranslation(['daoCreate', 'common']); | ||
const { | ||
readOnly: { user }, | ||
} = useFractal(); | ||
const location = useLocation(); | ||
const paths = location.pathname.split('/'); | ||
const step = (paths[paths.length - 1] || paths[paths.length - 2]) as CreatorSteps | undefined; |
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.
btw, what was the outcome of trying to "remove trailing slashes" that was a fkn nightmare the other day?
useNavigationScrollReset(); | ||
|
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.
Might be cool to pull this sub-feature, and maybe the changes to "scrollToTop" and "scrollToBottom" into a new PR.
Anything else that can be broken off of this into a new 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.
Well these changes just ~15-20 lines of code - I don't see much benefits of extracting that into separate PR, unless you think that's reasonable. They also contextually bound to this PR as initially solving the problem that scrolling is not happening while you navigating between steps of proposal builder
…describe why prevStepUrl and nextStepUrl are calculated this way in StepButtons from ProposalBuilder
setStepState(newStep); | ||
scrollToTop(); | ||
}; | ||
function StepController(props: Omit<ICreationStepProps, 'steps'>) { |
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.
Can we not omit steps
from this object, and use it in place of the const steps = useMemo()
below?
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.
Not really, coz we aren't passing steps prop here actually - this is the place where it is calculated first time and I felt like it would be right place to do so comparing to the moment of rendering
Since steps are calculated based off values.governance - this is the highest component where we can leverage useMemo, otherwise we'll be recalculating them during each rendering of StepController
So I feel like we should leave it as is
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 sorry, but no, the more I look at this StepController
the more I want to see this implemented differently.
The things I'm thinking about:
- Pass the
steps
in as a prop - I don't like how these
Route
s are being declared, conditionally like this.
I will take a stab at implementing the direction I'm thinking.
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 would we be passing steps as prop here though? This is literally StepsController component which I would expect to see this stuff
Creating some wrapper would be an overkill IMO
Conditional routes is an over-engineering, totally agree
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.
@adamgall Id rather create proper type definition
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.
Not another wrapper, no. But, at some point the user clicks some button which triggers these steps components to mount and render. At the place of that button click can't we know which set of steps the user is intending to do, add pass in the appropriate CreatorSteps
object from right there at that button click?
Very likely that I'm incorrectly assuming how things work in other parts of the codebase, because what I described above seems like the obvious way to design these changes in this PR.
This PR contains following changes:
For testing:
Closes #1914
Closes #1915
@adamgall I slightly altered the behavior comparing to what you mentioned in the ticket - instead of letting user know when he already filled in everything required - I'm immediately taking him to the first step and showing toast that certain governance type is not supported on current network. Think it is gonna be hella frustrating to input all the NFTs you have and then you get "Oopsie, not supported".