-
Notifications
You must be signed in to change notification settings - Fork 25
feat: keep form data in memory #1525
base: main
Are you sure you want to change the base?
feat: keep form data in memory #1525
Conversation
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.
Pull Request Overview
This PR implements form data persistence in memory to maintain user-entered data across tab switches and route navigation. The implementation includes tab mounting behavior changes and form state management for cross-route drafts.
- Added
FormPersistenceState
provider for managing in-memory form drafts across routes - Modified
Tabs
component to supportkeepMounted
prop for preserving tab content in DOM - Enhanced
FeeModal
to preselect fee rate options based on current fee rate
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
src/ui/common/state/index.tsx | Added FormPersistenceState to the state provider list |
src/ui/common/state/FormPersistenceState.tsx | New state provider for managing BTC and Baby stake form drafts |
src/ui/common/page.tsx | Enabled keepMounted prop for main tabs |
src/ui/common/components/Tabs/Tabs.tsx | Added keepMounted functionality to preserve tab content |
src/ui/common/components/Staking/FeeModal/index.tsx | Added currentFeeRate prop and preselection logic |
src/ui/common/components/Multistaking/MultistakingForm/StakingFeesSection.tsx | Removed redundant default fee rate setting and passed currentFeeRate to FeeModal |
src/ui/common/components/Multistaking/MultistakingForm/MultistakingFormContent.tsx | Added BtcFormPersistence component |
src/ui/common/components/Multistaking/MultistakingForm/BtcFormPersistence.tsx | New component for persisting BTC staking form data |
src/ui/baby/widgets/StakingForm/index.tsx | Added BabyFormPersistence component |
src/ui/baby/widgets/StakingForm/BabyFormPersistence.tsx | New component for persisting Baby staking form data |
src/ui/baby/layout.tsx | Enabled keepMounted prop for baby staking tabs |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
stakingInfo?.defaultFeeRate !== undefined && | ||
(feeRate === undefined || feeRate === "") |
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.
[nitpick] The condition feeRate === \"\"
should use a more robust check. Consider using a utility function to check for empty/falsy values consistently across the codebase, or at minimum check for both \"\"
and \"0\"
.
stakingInfo?.defaultFeeRate !== undefined && | |
(feeRate === undefined || feeRate === "") | |
(feeRate === undefined || feeRate === "" || feeRate === "0") |
Copilot uses AI. Check for mistakes.
const fee = Number(currentFeeRate); | ||
if (!fee || !Number.isFinite(fee)) { |
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 condition !fee
will be true for valid fee rate of 0, which should be allowed. Change to !Number.isFinite(fee) || fee <= 0
to properly handle zero values while rejecting invalid numbers.
const fee = Number(currentFeeRate); | |
if (!fee || !Number.isFinite(fee)) { | |
if (!Number.isFinite(fee) || fee < 0) { |
Copilot uses AI. Check for mistakes.
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.
Approved with some comments, let's wait for @jonybur and @jeremy-babylonlabs also
if (babyStakeDraft) { | ||
if (babyStakeDraft.amount !== undefined) { | ||
setValue("amount", babyStakeDraft.amount, { | ||
shouldValidate: 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.
Can we have comments on these values so it's easier to understand why, besides Hydrate once on mount
if (btcStakeDraft) { | ||
if (btcStakeDraft.finalityProviders) { | ||
setValue("finalityProviders", btcStakeDraft.finalityProviders, { | ||
shouldValidate: false, |
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.
Same here
|
||
import { createStateUtils } from "@/ui/common/utils/createStateUtils"; | ||
|
||
export type BtcStakeDraft = { |
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.
Let's add comments for these types and interfaces
} | ||
if (babyStakeDraft.feeAmount !== undefined) { | ||
setValue("feeAmount", babyStakeDraft.feeAmount, { | ||
shouldValidate: 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.
Could probably move these {shouldValidate: true, shouldDirty: false, shouldTouch: false} to a const and assign on each of these setValues. Would make the code a bit cleaner.
Actually, since we are at it, this is simply a matter of doing something like
["amount", "validatorAddress", "feeAmount"].forEach(value => {
if (babyStakeDraft[value] !== undefined) setValue(value, /*object here*/)
}
className="flex flex-col gap-2 h-[500px]" | ||
onSubmit={handlePreview} | ||
> | ||
<BabyFormPersistence /> |
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 is this a functional component? can't this be a hook instead? Since it's returning null that 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.
agree
Added
keepMounted
toTabs
Added
FormPersistenceState
provider that wraps app for cross-route in-memory draftsFeeModal
now takescurrentFeeRate
and preselects fast/medium/slow/customScreen.Recording.2025-09-02.at.16.20.15.mov
Closes: #1403