release: Rework sharing, list copying, and the product action clusters - #161
Conversation
Changes: - Add Stage 4, which detects the run's artifacts, branches and worktrees and proposes removing them - Require AskUserQuestion before any deletion, with scratch output and triage docs asked separately - Refuse to delete a branch with unpushed commits or an open PR, even when selected - Note that a deleted reviews/ is not a broken state, since the runners recreate it A cycle left scratch folders, triage docs and a fix branch behind with nothing in the skill to clear them, so they accumulated across runs and muddied the resume detection the skill reads on every invocation. Notes: Cleanup is opt-in per run rather than automatic. A triage doc is the only record of the findings the user chose to skip, and a fix branch can hold the only copy of unpushed commits, so nothing here is safe to sweep on the agent's initiative.
Changes: - Derive isFormValid in use-watchlist-item-form by parsing the schema over the current values, and gate the submit button on it formState.isValid only refreshes when RHF runs the resolver, and seeding the prefill through reset does not run it, so the only pass was the mount one over the empty defaults. A first-time watch opened with a valid prefilled threshold but a dead Prati button, until switching watch mode triggered an unrelated validation pass and woke it up. Notes: this mirrors isEdited, which already compares values to baselines rather than trusting RHF's dirty flags. The resolver stays in place and still owns the messages under the field, so nothing is marked red before it is touched.
Changes: - Extend the prefill gotcha with the validity half: formState.isValid only refreshes when the resolver runs, a seeding reset does not run it, and a form gating an untouched prefill should parse the schema itself The dirty half of this trap was already written down; the validity half is what left a prefilled first-time watch unsavable until the mode was switched.
Changes: - Extract the list name field into shopping-list-title-field.tsx, shared by the create, edit and copy modals - Give the copy modal a react-hook-form title input, prefilled with "<naziv> (Kopija)" and submitted through the modal's form id - Shorten the prefill by code point so the suffix fits the schema's ceiling, read off the schema rather than restated - Trim the title inside shoppingListRequestSchema, so whitespace cannot pass min(3) and reach the backend blank - Key CopyListModal by list id in the entity outlet, so the lingering instance cannot carry a typed name to the next list - Grow the option row icon to size-6 and the checkbox to size-8 with a size-6 tick - Relabel the option rows to "Kopiraj sve proizvode" and "Označeno i spremljene trgovine" Copying always produced "<naziv> (Kopija)" and left renaming as a second trip through the edit modal. The name is now an input the user can change before the copy exists, and the field is the same one the create modal uses rather than a second copy of it. Notes: - The progress row's description still mentions prices while its new label does not. Deliberate, and the copy does carry the prices.
Changes: - Note in SHARING.md that the copy modal asks for a name, prefilled with the "(Kopija)" suggestion - Add the copy hook and the shared title field to the file table Keeps the sharing reference matching what the copy modal now does.
Changes: - Remove the "Kopirat će se samo naziv popisa." paragraph that appeared when no option was ticked The modal is vertically centred, so the hint appearing and disappearing shifted the whole dialog as options were toggled. The name field and the three rows already say what the copy will contain.
✅ Deploy Preview for disscount canceled.
|
|
Warning Review limit reached
Next review available in: 48 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?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 reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Summary by CodeRabbit
WalkthroughThe PR adds a reusable shopping-list title field, configurable copy names, schema-based title validation, and direct watchlist validity checks. It also adds modal remounting and documents form-prefill behavior and review-cycle cleanup rules. ChangesShopping-list form flows
Watchlist validation
Review cycle cleanup
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant CopyListModal
participant useCopyListModal
participant shoppingListRequestSchema
CopyListModal->>useCopyListModal: Submit title and copy options
useCopyListModal->>shoppingListRequestSchema: Validate ShoppingListRequest
shoppingListRequestSchema-->>useCopyListModal: Return validated data
useCopyListModal->>useCopyListModal: Call copyList(data)
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
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.
Actionable comments posted: 4
🤖 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 @.claude/skills/multi-tool-code-review/SKILL.md:
- Line 110: Update the branch-deletion safety rule in the multi-tool review
guidance to protect any branch associated with an open PR, not only branches
described as behind one. Require failed PR checks or missing upstream references
to be treated as protected states, and preserve the existing unpushed-commit
check before deletion.
- Around line 96-108: Update the review-run workflow to record exact paths and
refs for every worktree, branch, and remote branch created by the current cycle
in an ownership manifest. Use that manifest, rather than broad discovery results
from git worktree list, git branch --merged, or git ls-remote, to build cleanup
proposals; retain unknown-ownership resources and explicitly report them as
excluded.
In `@frontend/src/app/`(user)/shopping-lists/hooks/use-copy-list-modal.ts:
- Around line 42-45: Update suggestCopyTitle in
frontend/src/app/(user)/shopping-lists/hooks/use-copy-list-modal.ts:42-45 to
limit the generated prefix by JavaScript string length so prefix.length plus
COPY_SUFFIX.length does not exceed TITLE_MAX_LENGTH, while truncating only at
whole code points. The sibling reference in docs/SHARING.md:164-169 requires no
direct change; it is another affected site covered by the title-generation fix.
In `@frontend/src/app/products/hooks/use-watchlist-item-form.ts`:
- Around line 163-173: The comments around the form reset and isFormValid logic
contradict each other about whether reset refreshes validation. Update the stale
reset-validity comment near the watchlist form initialization to state that
reset updates values but does not re-run the resolver unless validation is
explicitly triggered, while preserving the existing schema safeParse validity
calculation and resolver behavior.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2d1b7a8a-1815-4ed0-a467-2a3a3f4831b3
📒 Files selected for processing (12)
.claude/skills/multi-tool-code-review/SKILL.mddocs/SHARING.mddocs/STATE-PERSISTENCE.mdfrontend/src/app/(user)/shopping-lists/components/forms/copy-list-modal.tsxfrontend/src/app/(user)/shopping-lists/components/forms/copy-option-row.tsxfrontend/src/app/(user)/shopping-lists/components/forms/shopping-list-modal.tsxfrontend/src/app/(user)/shopping-lists/components/forms/shopping-list-title-field.tsxfrontend/src/app/(user)/shopping-lists/hooks/use-copy-list-modal.tsfrontend/src/app/products/components/forms/watchlist-item-modal.tsxfrontend/src/app/products/hooks/use-watchlist-item-form.tsfrontend/src/components/custom/modal-router/entity-modal-outlet.tsxfrontend/src/lib/api/schemas/shopping-list.ts
Changes: - Build the shortened title a code point at a time, stopping on the UTF-16 length the schema measures - Correct the matching note in SHARING.md zod's max() counts UTF-16 code units, so slicing to 91 code points let an emoji title prefill at up to 182 units and open the modal on a validation error the user did not cause. Whole code points are still taken, so the cut cannot split an emoji. Notes: - Found by CodeRabbit on #161.
…alid Changes: - Parse shoppingListRequestSchema for the copy modal's validity, reading the title through useWatch - Correct the watchlist form's reset comment, which claimed reset refreshes isValid - Scope the review skill's cleanup proposal to a manifest of what the cycle created, and protect branches on either side of an open PR formState.isValid only refreshes when the resolver runs, and a seeding reset does not run it, which docs/STATE-PERSISTENCE.md already records for the watchlist form. The copy modal gated its submit button on that flag, so an untouched valid prefill would have left Kopiraj dead until the user typed. useWatch rather than form.watch, since watch() opts the hook out of the React Compiler. Notes: - The skill changes are CodeRabbit findings on #161: branch discovery matched unrelated worktrees and branches by shape alone, and "behind an open PR" missed a branch that is the PR's head.
Release of everything currently on
dev, 34 commits.Sharing
Privatno,Pregled,Kupnja,Uređivanje) rather than a toggle plus a level picker, saving on change with a toast and a live region.docs/SHARING.mdrecords why revocation was given up.Copying a list
<naziv> (Kopija), so renaming and copying are one action. The field is shared with the create and edit modals.Products and watchlist
isValid.UI and accessibility
SelectItemhas an icon slot.Bannerhonours its own size, and the layout no longer clips the last card's shadow.Notes
dev.🤖 Generated with Claude Code