Fix broken new-interlinear-project#122
Conversation
|
Warning Review limit reached
More reviews will be available in 28 minutes and 7 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe "New Project" modal flow is refactored from a deferred two-step process (empty draft + later Save As) to immediate backend persistence. A new async ChangesNew Project Immediate-Persist Flow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
- Restructure createAndPersistProject to eliminate duplicate setCreateSourceIsSelect/setModal calls via a single exit path - Set isCreating during the discard-confirm createAndPersistProject path so the create modal buttons are disabled in that flow too - Update stale JSDoc: PendingReplace comment and component summary now accurately describe the immediate-persist New behavior - Split the old New-flow test into success and failure cases so resetActiveProject is asserted for the right reason in each - Add validation-failure test (parse succeeds, non-project shape) to cover lines 242-245 and restore 100% coverage - Fix no-type-assertion lint error in makeWebViewStateWithActiveProjectSpies - Update discard-confirm test to assert createProject is called after confirm Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches the openProject convention: the catch block now sends the same notification as the validation-failure path, so transport-level rejections (where the backend may not have reached its own notification send) also surface visible feedback to the user. Expanded the JSDoc to document why the pre-round-trip newDraft() call is safe: dirty=false means all draft data is committed to the active project (or the draft was empty), and dirty=true means the user has already confirmed discarding via DiscardDraftConfirm. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove papi.notifications.send from createAndPersistProject catch block; interlinearizer.createProject already sends its own notification before rethrowing, so the second call caused a duplicate toast (handleSaveAsNew follows the same convention) - createAndPersistProject now returns boolean success; callers own the modal transition so the create modal stays open on failure, preserving the user name/description/language inputs for retry - useDraftProject.ts newDraft JSDoc updated to reflect that the caller is responsible for immediately persisting to the backend Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
b5d68ee to
1178d8b
Compare
The handleConfirmReplace else branch was uncovered: the existing test used the default mock (undefined -> JSON.parse throws -> success false), leaving the if (success) close path unreached. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@alex-rawlings-yyc The behavior of the "New Interlinear Project..." route wasn't making sense to me, but this change is perhaps moving away from an intentional design choice. Could you review and/or test it out and let me know if that's the case. |
There was a problem hiding this comment.
@imnasnainaec I think what I wanted "New Interlinear Project..." to do initially was act like "New..." in a word processor, but prompting the user to add information deviated from that design and "Wipe..." does that well enough on its own. I think what you've done here is better; feel free to merge (though I imagine GitHub will want me to review again once this is no longer a draft)
@alex-rawlings-yyc reviewed 3 files and all commit messages, and made 1 comment.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on imnasnainaec).
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/__tests__/components/modals/ProjectModals.test.tsx`:
- Around line 633-640: The assertion on lines 633-640 uses expect.anything() for
all arguments, but this matcher does not match undefined values. Since the
interlinearizer.createProject signature includes undefined as argument 4, this
allows false negatives where the command could be called with undefined and the
test would still pass. Replace the expect.anything() placeholders with the
actual expected argument values or appropriate matchers (such as undefined where
the signature expects it) to ensure the assertion properly validates that the
command was not called with the expected parameters.
In `@src/components/modals/ProjectModals.tsx`:
- Around line 292-307: The handleCreateDraft function lacks a synchronous
in-flight guard, allowing rapid double-clicks to trigger createAndPersistProject
twice before the state update from setIsCreating(true) takes effect. Add a
synchronous guard at the beginning of handleCreateDraft (before the dirty check)
using a ref variable to track if a request is already in progress; return early
if a request is already in flight, and set this flag to true before calling
createAndPersistProject and to false in the finally block. Apply the same
pattern to any other similar functions mentioned in the comment (line 330-339
area).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e06d0d34-55d3-4e9e-bb3a-bfbab253709a
📒 Files selected for processing (3)
src/__tests__/components/modals/ProjectModals.test.tsxsrc/components/modals/ProjectModals.tsxsrc/hooks/useDraftProject.ts
expect.anything() does not match undefined, so not.toHaveBeenCalledWith with five expect.anything() placeholders passed even when createProject was called with undefined as arg 4. Replace with the exact expected argument values so the assertion correctly guards the not-yet-called path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Only arg 4 (undefined targetProjectId) needed to be explicit; the other arguments are non-undefined so expect.anything() is correct. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
alex-rawlings-yyc
left a comment
There was a problem hiding this comment.
@alex-rawlings-yyc reviewed 1 file and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on imnasnainaec).
Problem
Clicking "New Interlinear Project…" → "Create" did nothing — no project was created and the project list stayed empty. The New dialog was calling an internal draft-seeding function instead of persisting to the backend.
Changes
ProjectModals.tsxinterlinearizer.createProject, so the project appears in "Select Interlinear Project…" right awayisCreatingstate to disable Create/Cancel buttons during the backend round-trip (prevents double-submit)papi.notifications.sendfrom the catch block —interlinearizer.createProjectalready sends its own error notification before rethrowing (matching the convention used by Save As)useDraftProject.tsnewDraftJSDoc to reflect that the caller is responsible for immediately persisting the new project to the backendTests
Test plan
npm testpassesThis change is
Summary by CodeRabbit
Release Notes