Skip to content

Show checkboxes on hover instead of avatars (#46) - #49

Merged
yamcodes merged 11 commits into
mainfrom
46-checkboxes-should-show-on-hover-instead-of-profile-pictures
Apr 3, 2026
Merged

Show checkboxes on hover instead of avatars (#46)#49
yamcodes merged 11 commits into
mainfrom
46-checkboxes-should-show-on-hover-instead-of-profile-pictures

Conversation

@yamcodes

@yamcodes yamcodes commented Mar 21, 2026

Copy link
Copy Markdown
Owner

Closes #46

Summary by CodeRabbit

  • New Features

    • Added bulk selection controls with select-all/deselect-all and selection-aware UI states.
  • Style

    • Refined table layout and checkbox positioning; centralized selection colors via CSS variables.
    • Improved hover/reveal behavior for row controls and avatar/checkbox integration.
  • Documentation

    • Removed always-on SQL initialization from the setup guide.
  • Chores

    • Added CSRF header injection for dynamic requests.
    • Adjusted development run behavior to remove an automatic pre-run compose step.

@yamcodes yamcodes linked an issue Mar 21, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Mar 21, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9d28f291-2859-4ca5-8094-37b10e48a594

📥 Commits

Reviewing files that changed from the base of the PR and between ed91386 and 0675251.

📒 Files selected for processing (4)
  • .run/Docker Compose Up.run.xml
  • .run/Spring Development.run.xml
  • src/main/resources/templates/contacts/index.html
  • src/main/resources/templates/fragments/contact-list-rows.html
💤 Files with no reviewable changes (1)
  • .run/Spring Development.run.xml
🚧 Files skipped from review as they are similar to previous changes (3)
  • .run/Docker Compose Up.run.xml
  • src/main/resources/templates/fragments/contact-list-rows.html
  • src/main/resources/templates/contacts/index.html

📝 Walkthrough

Walkthrough

Updated IDE run configurations and README; refactored contacts list UI to show selection checkboxes on hover, implemented bulk-select controls and Alpine state sync, added server-rendered CSRF meta tags and an Htmx request injector, and adjusted related CSS and template markup.

Changes

Cohort / File(s) Summary
IDE Run Configs
.run/Docker Compose Up.run.xml, .run/Spring Development.run.xml
Changed Docker Compose run command from detached to --wait, removed factoryName attribute, added execution options; removed a pre-run ToolBeforeRunTask from Spring Development config.
Docs
README.md
Removed spring.sql.init.mode: always line from documented application-local.yaml.
CSS
src/main/resources/static/css/input.css
Added :root CSS variables --color-selection and --color-selection-bold; removed some column-width/.thead-selected rules; unified checkbox checked/indeterminate styling to use the new variables; adjusted table column sizing.
Contacts index template
src/main/resources/templates/contacts/index.html
Reordered HTMX/Thymeleaf attributes, expanded Alpine state to track selected and total, added selectAll/deselectAll/syncSelectAll, registered htmx:afterSwap listener, implemented select-all header UI and conditional styling tied to selection state.
Contact row fragment
src/main/resources/templates/fragments/contact-list-rows.html
Moved checkbox into avatar container, renamed Tailwind group state to group/row and updated dependent selectors, made checkbox reveal on row hover via group-hover/row interactions.
Layout / CSRF + HTMX
src/main/resources/templates/layout.html
Added server-rendered CSRF meta tags and registered an htmx:configRequest handler to inject CSRF header/value into outgoing Htmx requests.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant HTMX
    participant Server
    participant DB

    Browser->>HTMX: User clicks bulk-delete / pagination
    HTMX->>HTMX: Read CSRF meta header/token
    HTMX->>Server: XHR with CSRF header + action payload
    Server->>DB: Perform query/update (delete/list)
    DB-->>Server: Result
    Server-->>HTMX: HTML fragment or JSON response
    HTMX-->>Browser: Swap updated fragment, trigger htmx:afterSwap
    Browser->>Browser: Alpine syncSelectAll recalculates selected/total
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰
Hidden checks beneath my paw,
Hover shows them — neat and raw.
I hop, I click, selections grow,
CSRF safe, requests all go.
A rabbit cheers the contacts flow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Several changes appear tangential to the core objective: Docker Compose configuration updates, SQL initialization removal from README, CSS custom properties, and CSRF configuration are not directly related to implementing hover-based checkbox visibility. Consider separating infrastructure changes (Docker Compose, CSRF, SQL init) into separate PRs to keep this PR focused on the checkbox hover visibility feature.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Show checkboxes on hover instead of avatars (#46)' directly matches the main objective to display checkboxes on hover instead of profile pictures.
Linked Issues check ✅ Passed The code changes successfully implement the requirement from issue #46 to show checkboxes only on hover by updating Alpine.js state management, modifying template markup, and hiding checkbox visibility by default with opacity/pointer-events.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 46-checkboxes-should-show-on-hover-instead-of-profile-pictures

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

autofix-ci Bot and others added 8 commits March 21, 2026 18:07
* Add a "Select All" checkbox to the table header with Alpine.js logic for indeterminate and checked states
* Update `x-data` and `x-init` to track both `selected` and `total` contact counts
* Update table header styling and pagination controls to highlight when items are selected
* Apply consistent styling to checkboxes in the indeterminate state via CSS
* Add `selectAll` and `deselectAll` Alpine.js methods to the contact list
* Add selection dropdown with "All" and "None" options to the table header
* Refactor hardcoded selection colors into CSS variables (`--color-selection`)
* Remove unused `.thead-selected` CSS classes and simplify table header styling
* Add CSRF meta tags to layout template
* Include CSRF token in HTMX request headers via `htmx:configRequest` listener
@yamcodes
yamcodes marked this pull request as ready for review March 28, 2026 15:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.run/Spring Development.run.xml:
- Line 8: The pre-run task RunConfigurationTask (run_configuration_name "Docker
Compose Up") currently runs docker compose up -d which detaches immediately;
update the command used by that task to include the --wait flag (e.g., docker
compose up --wait -d or equivalent invocation supported by your environment) so
the pre-run step waits for services to be healthy before continuing, ensuring
Spring Boot doesn't race with dependencies.

In `@src/main/resources/templates/contacts/index.html`:
- Around line 56-58: The chevron dropdown button inside the form is currently a
plain <button> (the element with class "btn btn-ghost btn-xs px-0" and child
icon data-lucide="chevron-down") which defaults to type="submit" and can
accidentally submit the surrounding hx-delete form; change that button to an
explicit non-submitting button (set type="button") so clicks only toggle the
dropdown and do not submit the form.
- Line 47: The header checkbox currently uses `@change`="selected > 0 ?
deselectAll() : selectAll()", which treats the indeterminate state as "deselect
all"; change the condition to only deselect when everything is already selected
(e.g., selected === items.length or selected === contacts.length), otherwise
call selectAll() so clicking in the indeterminate state selects all; update the
`@change` handler to reference the collection size instead of just selected > 0
while keeping the existing deselectAll() and selectAll() calls.
- Line 35: x-init currently computes total once (selected and total variables in
the Alpine component) so total becomes stale after HTMX updates; update total
whenever the tbody is replaced by listening for HTMX swap/afterSwap (or
mutation) events on the same container and recompute total =
$el.querySelectorAll('input[name=selected_contact_slugs]').length and selected =
$el.querySelectorAll('input[name=selected_contact_slugs]:checked').length, then
call syncSelectAll() to re-evaluate the "select all" checkbox state; locate the
Alpine component initialized with x-init and the syncSelectAll() usage to add
this event handler.

In `@src/main/resources/templates/fragments/contact-list-rows.html`:
- Line 60: The fragment uses a static id="actions" inside the repeated row
(th:each), causing duplicated IDs; change it to a non-duplicated selector by
replacing id="actions" with a class (e.g., class="actions") or generate a unique
id using the th:each iteration (e.g., append ${iter.index} or the entity id) so
each row's actions element is uniquely addressable; locate the tag that
currently has id="actions" in contact-list-rows.html and update the attribute
and any JS/CSS references accordingly.
- Around line 39-49: The container that wraps the checkbox uses the "hidden"
utility which removes the input from the tab order; change the wrapper class on
the element that currently reads "absolute inset-0 hidden cursor-pointer
items-center justify-center group-hover/row:flex" to not use "hidden" but
instead use utilities that visually hide while preserving focusability (for
example "absolute inset-0 opacity-0 pointer-events-none items-center
justify-center group-hover/row:flex group-hover/row:opacity-100
group-hover/row:pointer-events-auto"), keep the `@click.stop` and `@change` handlers
and the input name "selected_contact_slugs" unchanged so keyboard users can tab
to and toggle the checkbox even when the row is not hovered.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 30eed9a6-7ce2-446e-ac6b-524872c70cd1

📥 Commits

Reviewing files that changed from the base of the PR and between c5cb112 and ed91386.

📒 Files selected for processing (7)
  • .run/Docker Compose Up.run.xml
  • .run/Spring Development.run.xml
  • README.md
  • src/main/resources/static/css/input.css
  • src/main/resources/templates/contacts/index.html
  • src/main/resources/templates/fragments/contact-list-rows.html
  • src/main/resources/templates/layout.html
💤 Files with no reviewable changes (1)
  • README.md

Comment thread .run/Spring Development.run.xml Outdated
Comment thread src/main/resources/templates/contacts/index.html Outdated
<div class="flex items-center">
<label aria-label="Select all">
<input
@change="selected > 0 ? deselectAll() : selectAll()"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Select-all toggle condition is wrong for partial selection.

At Line 47, any selected > 0 triggers deselectAll(). In indeterminate state, clicking the header checkbox should select all, not clear all.

Suggested fix
-@change="selected > 0 ? deselectAll() : selectAll()"
+@change="selected === total ? deselectAll() : selectAll()"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@change="selected > 0 ? deselectAll() : selectAll()"
`@change`="selected === total ? deselectAll() : selectAll()"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/templates/contacts/index.html` at line 47, The header
checkbox currently uses `@change`="selected > 0 ? deselectAll() : selectAll()",
which treats the indeterminate state as "deselect all"; change the condition to
only deselect when everything is already selected (e.g., selected ===
items.length or selected === contacts.length), otherwise call selectAll() so
clicking in the indeterminate state selects all; update the `@change` handler to
reference the collection size instead of just selected > 0 while keeping the
existing deselectAll() and selectAll() calls.

Comment thread src/main/resources/templates/contacts/index.html Outdated
Comment thread src/main/resources/templates/fragments/contact-list-rows.html Outdated
Comment thread src/main/resources/templates/fragments/contact-list-rows.html Outdated
yamcodes and others added 2 commits March 28, 2026 21:37
* Use `docker compose up --wait` and remove the automatic Docker trigger from the Spring run configuration
* Add `refreshCounts` to Alpine.js state and trigger it on `htmx:afterSwap` to sync counts after partial updates
* Fix "Select All" checkbox logic to toggle based on total selection rather than partial selection
* Improve checkbox visibility transitions using opacity and pointer-events instead of display toggles
* Convert the actions container from an ID to a class in contact list rows
@yamcodes
yamcodes merged commit ac02186 into main Apr 3, 2026
4 checks passed
@yamcodes
yamcodes deleted the 46-checkboxes-should-show-on-hover-instead-of-profile-pictures branch April 3, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

checkboxes should show on hover instead of profile pictures

1 participant