Skip to content

#(feat): 6503 New case contacts table column visibility#6945

Open
cliftonmcintosh wants to merge 6 commits into
rubyforgood:mainfrom
cliftonmcintosh:feature/6503-column-visibility
Open

#(feat): 6503 New case contacts table column visibility#6945
cliftonmcintosh wants to merge 6 commits into
rubyforgood:mainfrom
cliftonmcintosh:feature/6503-column-visibility

Conversation

@cliftonmcintosh
Copy link
Copy Markdown
Collaborator

What github issue is this PR for, if any?

Resolves #6503

What changed, and why?

Adds a "Columns" button to the case contacts new design table toolbar that lets users show and hide individual columns.

  • CaseContact::TOGGLEABLE_COLUMNS — a new constant defining the 6 user-configurable columns (Relationship, Medium, Created By, Contacted, Topics, Draft). Date and Case are intentionally fixed and always visible.
  • Columns button — sits next to the Filter button in the toolbar. Shows a (X/6) badge indicating how many columns are currently visible. The badge is rendered invisible on page load and revealed once the correct count is known, preventing a layout flash.
  • Columns panel — a slide-down panel (same pattern as the Filter panel) with Bootstrap toggle switches for each of the 6 toggleable columns, plus "Update View" and "Show All" buttons. Update View applies the current toggle state; Show All restores all columns immediately.
  • Column alignment — replaced DataTables' scrollX: true with CSS overflow-x: auto on the table wrapper. scrollX caused header/body misalignment when columns were hidden; the CSS approach provides horizontal scrolling without the split-table mechanism. Also added autoWidth: false to prevent DataTables from computing oversized fixed column widths.
  • State persistence — column visibility is saved to PreferenceSet#table_state under the key case_contacts_table using DataTables' stateSave callbacks, following the same pattern as the volunteers table. State is restored on page load; initComplete syncs the toggle switches and badge after the async state load completes.

How is this tested?

Added 10 new system spec examples to spec/system/case_contacts/case_contacts_new_design_spec.rb covering:

  • Columns button is present in the toolbar
  • Badge shows the correct visible/total count
  • Panel is hidden by default
  • Panel opens and closes on button click
  • All 6 toggleable columns are listed with toggle switches, all on by default
  • Hiding a column via Update View removes it from the table
  • Showing a column again via Update View restores it
  • Badge count updates when a column is hidden
  • Show All restores all columns and closes the panel
  • Column visibility persists across page reloads

Screen Captures and Recordings

Columns button and badge
Opening and closing the Columns panel
Hiding a column and updating the badge
Restoring columns with Show All
Column visibility persists across page reloads

Design Decisions

Deviations from the Figma

The Figma design was used as a guide but not followed exactly, for reasons rooted in the existing technical approach.

Panel instead of a floating popover — The Figma shows a small floating selector card. I used a slide-down panel consistent with the Filter button already in this view. Both the Filter and Columns controls follow the same open/close pattern, which keeps the toolbar interaction model consistent.

"Update View" / "Show All" retained — The Figma's "Update View" and "Show All" buttons were kept, matching the filter panel's "Apply Filters" / "Reset" rhythm. Changes are buffered until Update View is clicked rather than applied immediately on toggle.

Date and Case are fixed columns — The Figma's columns selector shows only 6 columns (Relationship, Medium, Created By, Contacted, Topics, Draft). Date and Case are intentionally absent — they are always visible since they form the core identity of a contact row.

No horizontal scrolling via DataTables — The Figma did not account for DataTables' scrollX feature, which causes header/body misalignment when columns are hidden. I replaced it with CSS overflow-x: auto on the table wrapper, which provides equivalent scrolling behaviour without the alignment bug.

Download button not included — The Figma toolbar shows Filter, Columns, and Download. The Download button is tracked separately and is out of scope for this PR.

Table stays full-width

The table is kept at width: 100% rather than shrinking to content width when columns are hidden. When scrollX: true was removed, DataTables' default autoWidth computed oversized column widths based on content. Setting autoWidth: false keeps proportional widths without expanding beyond the card boundary. The tradeoff is that visible columns expand to fill the full card width rather than collapsing to their natural content width — this was an acceptable tradeoff because full-width table borders and a consistently positioned actions column matter more than exact content-width columns.

Search term excluded from persisted state

stateSaveParams strips the search query before saving to PreferenceSet#table_state. Column visibility and sort order are durable preferences; a keyword search is session-intent. If the search term were saved, returning users would land on a filtered subset every time — a confusing and likely unwanted default.

Filter and Columns panels can both be open simultaneously

There is no mutual-exclusion logic between the Filter and Columns panels. Each toggle button independently shows or hides its panel. Adding close-the-other behavior was considered but left out — it is a minor UX polish detail not required by the issue and adds coupling between two otherwise independent controls.

AI Disclosure

This PR was implemented collaboratively with Claude Code (Claude Sonnet 4.6). The working approach:

  • I led all design and product decisions: which columns are toggleable, the panel-vs-modal choice, whether to persist state, the deviation from the Figma layout, and the commit strategy.
  • Claude analyzed the codebase, identified existing patterns to follow (filter panel, volunteers table column visibility, PreferenceSet persistence), and produced the implementation plan.
  • Development followed a red-green TDD rhythm: for each commit, I reviewed failing tests before implementation began and reviewed passing tests and code before committing. I staged and committed all changes.
  • Several issues discovered during visual testing (header/body misalignment, table overflow, column expansion, badge flash) were debugged and fixed collaboratively before each commit was finalized.

All commits are co-authored: Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

cliftonmcintosh and others added 4 commits May 11, 2026 10:40
…ntact table

Adds the Columns toolbar button with a (6/6) badge, the slide-down
panel with Bootstrap toggle switches for the 6 user-configurable
columns, and the CaseContact::TOGGLEABLE_COLUMNS constant that drives
the panel. Date and Case columns are intentionally fixed (always
visible).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…count

Update View applies current toggle state and updates the (X/6) badge.
Show All restores all columns, resets the badge, and closes the panel.
Removes DataTables scrollX in favour of CSS overflow-x on the wrapper,
which fixes header/body misalignment when columns are hidden.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds DataTables stateSave with server-side callbacks posting to
PreferenceSet#table_state under key "case_contacts_table". The
initComplete callback syncs toggle switch state and the badge count
from the loaded state, since stateLoadCallback is async.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added 🧪 Tests Tests javascript Touches JavaScript code ruby Touches Ruby code erb Touches ERB templates labels May 11, 2026
@cliftonmcintosh cliftonmcintosh marked this pull request as ready for review May 11, 2026 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

erb Touches ERB templates javascript Touches JavaScript code ruby Touches Ruby code 🧪 Tests Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Case Contact Table: implement "columns" button

1 participant