fix: default destination page to match source on import#4084
Conversation
Previously the destination page always defaulted to page 1, meaning users importing a page export (e.g. page 21) would need to manually change the destination, risking accidentally overwriting the wrong page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe import flow now distinguishes source vs destination pages: state renamed to Changes
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Updates the Import/Export single-page import wizard so the destination page defaults to the original exported page number (via snapshot.oldPageNumber) instead of always defaulting to page 1, improving the “export page N, re-import page N” workflow.
Changes:
- Compute a
defaultDestinationPagefor single-page imports usingsnapshot.oldPageNumber ?? 1. - Initialize the destination page picker with that computed default (instead of always
1). - Keep existing behavior for full config imports (Buttons tab) by continuing to initialize at page 1.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0b1623e8-deae-40cd-9c62-32b47ee856b6
📒 Files selected for processing (1)
webui/src/ImportExport/Import/Page.tsx
If snapshot.oldPageNumber is out of range for the destination system, default to new page (-1) rather than an invalid page number. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| if (typeof oldPage === 'number' && Number.isInteger(oldPage) && oldPage >= 1 && oldPage <= pages.data.length) { | ||
| return oldPage | ||
| } | ||
| return -1 |
There was a problem hiding this comment.
Nice suggestion @tonypiper ! Some comments
- This will default to a new page (-1) rather than the first page (1), as was the pre-existing behavior. Is that your intention? This actually makes sense when
oldPageis beyondpages.data.length, but otherwise it should probably default to 1. useMemohere seems a bit of overkill: you're just doing a couple of logical tests and all it's doing is setting a default, so it's a no-op if any of the dependents change, anyway. Suggestion: either it should be done only on mount or just take it out of a useMemo.- Technically the
!isSinglePagetest isn't necessary, since full won't have an oldPageNumber, and really, if there is an oldPageNumber it should probably be used.
There was a problem hiding this comment.
Thank you for the quick and helpful feedback. Defaulting to a new page was intentional - original motivation was that I have important buttons on page 1 and they kept getting overwritten. It seems to me that it's safer to create a new page (and then move it manually if need be) than overwrite an existing page if we can't be sure that it's the right page to overwrite.
|
@tonypiper two general comments:
|
Address PR review feedback: - Rename importPageNumber/setImportPageNumber/changeImportPage to sourcePageNumber/setSourcePageNumber/changeSourcePage for clarity - Remove useMemo and isSinglePage guard from defaultDestinationPage - Sync destination page to follow source page changes on full imports - Default to new page (-1) when source page doesn't exist in destination Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 05f63e74-23d3-4ae5-ad7f-dd22b01f5701
📒 Files selected for processing (1)
webui/src/ImportExport/Import/Page.tsx
|
|
||
| useEffect(() => { | ||
| if (isSinglePage) return | ||
| setPageNumber(pageOrNew(sourcePageNumber)) |
There was a problem hiding this comment.
It's looking much better now, @tonypiper. One comment here: useEffect here is in inefficient since it adds a render cycle and it somewhat hides the intent, which is that it's specifically in response to a user action. Better to wrap setSourcePageNumber and changeSourcePage in useCallbacks for use by lines 136-137, which set both source and dest. (yeah, sorry my original suggestion wasn't quite right) Also, again, you don't need to protect for isSinglePage.
Another thing, which is mainly for clarity: instead of usePagePicker(pageCount, 1) online 73, determine validOldPage first and set the default page to Math.abs(validOldPage) or if that horrifies you validOldPage === -1 ? 1 : validOldPage, then you can get rid of defaultDestinationPage and just use sourcePageNumber in the second usePagePicker, which makes both of the calls clearer (to me).
Anyway, think about that second suggestion and question it, if you disagree!
|
I'm not 100% convinced by some of the behaviour here. While the auto page changing will be useful in some cases, in others it will be very frustrating. eg, if you want to import 1,2,3 to 15,16,17, then it requires jumping all the way through the list of pages after each one instead of simply hitting next on both. sometimes I pick the destination page first, before the source page too. Maybe this is solvable by having the destination page picker track that the user has changed it manually, and stop auto-adjusting when that happens? might need a way to indicate that and put it back to auto, not sure where that should go though |
Summary
snapshot.oldPageNumberif valid, otherwise defaults to "new page" (-1)importPageNumber/setImportPageNumber/changeImportPagetosourcePageNumber/setSourcePageNumber/changeSourcePagefor clarityWhy
The previous default of page 1 was almost always wrong — if you export page 21 and re-import it, you want to restore it to page 21, not overwrite page 1. Defaulting to "new page" when the source page doesn't exist in the destination is safer than silently overwriting page 1. The same logic applies to full imports where the destination should follow the source page selection.
Reviewer feedback addressed
Per @arikorn's review:
useEffectimportPageNumbervars tosourcePageNumberuseMemoand!isSinglePageguard fromdefaultDestinationPageTest plan
🤖 Generated with Claude Code