Week tab: move property between days #35
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "32-week-move-property-between-days"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a button-based day picker to the Week tab that lets users move a queued or completed property from one day to another within the current week. Tap a cell to reveal day buttons, tap a target day to move.
Changes
config/routes.rb— Addedpatch :movecollection route to weeks resourceapp/controllers/weeks_controller.rb— Addedmoveaction with uniqueness error handling; extended index to pluck item IDs for the viewapp/views/weeks/index.html.erb— Wrapped queued/completed cells in a Stimulus-controlled wrapper with day-picker buttons; added flash message renderingapp/javascript/controllers/week_move_controller.js— New Stimulus controller: toggle picker, close on outside clickapp/assets/stylesheets/application.css— Styles for day-picker, day-picker buttons (44px touch targets), flash messagesspec/requests/weeks_spec.rb— Added 5 new specs covering move success, duplicate rejection, invalid date handling, and picker renderingTest Plan
docker compose run --rm -e RAILS_ENV=test web bundle exec rspec— 39 examples, 0 failuresReview Checklist
Related Notes
None.
Related
Closes #32
QA Review
Scope: 6 files, +259/-9 lines. New
moveaction on WeeksController, Stimulus controller for day-picker UI, CSS, tests.Findings
No blocking issues found.
Minor observations (informational, not blocking):
Flash messages are view-scoped -- Flash rendering was added only to
weeks/index.html.erb. If other views later need flash support, consider moving to the layout. Fine for now since only weeks#move produces flashes.Day-picker overflow on small screens -- The picker renders 7 buttons in a row (absolute positioned, right-aligned). On a narrow mobile viewport with a property in the leftmost columns, the picker could overflow off-screen to the left. Low risk since the week grid cells are near the right side of the viewport anyway, but worth a manual check at 375px.
button_togenerates a full<form>per day button -- This means 7 forms per cell with an item. For a grid with many properties, this increases DOM size. Acceptable for a landscaping business scale (dozens of properties, not thousands).Checklist
work_queue_items_controller.rbuntouched32-week-move-property-between-daysVERDICT: APPROVE
PR #35 Review
DOMAIN REVIEW
Tech stack: Ruby on Rails 8, Hotwire (Stimulus + Turbo), vanilla CSS with design tokens, RSpec request specs.
Controller (
weeks_controller.rb- move action):ActiveRecord::RecordNotUniquerescue handles race conditions where the uniqueness validation passes but the DB constraint catches a concurrent insert.Date::Errorrescue handles malformedtarget_dateparams.find(params[:work_queue_item_id])which raisesActiveRecord::RecordNotFound(returns 404) if the item ID is tampered with. Safe for a single-user app without auth.item.updatecall will trigger model validation (validates :property_id, uniqueness: { scope: :work_date }), so theRecordNotUniquerescue is a belt-and-suspenders approach -- correct.Stimulus controller (
week_move_controller.js):connect()registers the listener,disconnect()cleans it up. No memory leaks.event.stopPropagation()intoggle()prevents the outside-click handler from immediately re-closing.move()action closes the picker but the actual navigation happens viabutton_toform submission -- the picker closure is cosmetic UX polish. Correct pattern.Route:
patch :moveon collection is appropriate -- the item ID is passed as a param rather than nested in the URL, which is fine for a single action.View:
if/elsifblock falls through to empty div). No crash risk.button_togenerates a form with CSRF token automatically. Safe against CSRF.aria-label="Move <%= property.address_line %> from <%= day.strftime('%A') %>"-- good accessibility on the toggle button.CSS:
--spacing-*,--color-*,--radius) throughout..day-picker-btnusesmin-width: 2.75rem/min-height: 2.75rem(44px) -- meets mobile touch target requirements.z-index: 50is a reasonable value for a dropdown; no z-index wars evident.Tests:
BLOCKERS
None.
NITS
Hardcoded color in
.flash-alert:background: #fef2f2is a raw hex value. The design token system has--color-success-lightfor the notice flash but no--color-danger-lighttoken. Suggest adding--color-danger-light: #fef2f2;to:rootand usingvar(--color-danger-light)for consistency.DRY opportunity in view: The day-picker markup is duplicated for both the completed and queued branches (lines ~43-59 and ~61-77 in the diff). These are identical except for the inner icon. Consider extracting a partial like
_week_cell_with_picker.html.erbthat accepts the icon content as a block or local. Non-blocking since it is two instances, not a proliferation.itemIdvalue declared but unused: The Stimulus controller declaresstatic values = { itemId: Number }but never referencesthis.itemIdValue. The item ID is embedded in thebutton_toform action URL instead. The value declaration is dead code -- remove it or use it for something.No constraint on target_date range: The
moveaction accepts any valid date, not just dates within the current week. A user could theoretically move an item to a date months away. For a single-user app this is low-risk, but a guard likeunless (@start_date..@end_date).cover?(target_date)would tighten the API.SOP COMPLIANCE
32-week-move-property-between-daysfollows{issue-number}-{kebab-case-purpose}PROCESS OBSERVATIONS
VERDICT: APPROVED