rubyforgood / rubyforgood/casa
Feature gaps for new case contacts table
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 381
- Forks
- 542
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 47
Description
Feature Gap Analysis: Old vs. New Case Contacts Table
Compares app/views/case_contacts/index.html.erb (old) with
app/views/case_contacts/case_contacts_new_design/index.html.erb (new).
Figma for new case contacts table
The last of the new case contacts table issues (https://github.com/rubyforgood/casa/issues/6503) has been picked up, and there is a PR for it (https://github.com/rubyforgood/casa/pull/6945). However, there are still gaps. This analysis is intended to idenfity those gaps so that I can get feedback on which of them (if any) need filling. If we need to fill any of these gaps, we can create issues for them.
Summary
The new table adds full-text search and column visibility toggling, which the old table lacks. The main gaps in the new table are:
Intentional drops (not gaps):
- Driving reimbursement filter — not in the Figma; deliberately omitted in #6502.
- Flat filter panel instead of Figma drill-down overlay — deliberate simplification in #6502; pure frontend change if revisited.
Deferred filter features (Figma shows these; not yet built):
- Multi-select for Medium, Contacted, Draft — Figma shows checkboxes; current implementation uses single-select dropdowns.
- Created By filter — Figma shows it; open question about which users to populate in the UI.
- Topics filter — Figma shows it; no backend scope exists yet.
Functional gaps vs. the old table:
- Sort control — the old table offers a named sort dropdown (date, contact type, medium, reimbursement, contact made); the new table only sorts by Date column (asc/desc toggle). Medium had a misleading sort icon that did nothing and has been removed.
- Filter persistence — old filter state is in the URL; new state is JS-only and resets on reload.
- Miles driven / reimbursement in the row — the old card shows this via the decorator subheading.
- Transition-age youth icon — the old table shows 🦋/🐛 next to the case number.
- Medium icon — the old card renders a medium-specific icon (envelope, camera, phone, etc.).
- Soft-deleted record visibility — admins can see and restore deleted contacts in the old view; the new table never shows them.
- Sidebar deep-linking by case — the volunteer sidebar links to
case_contacts_path(casa_case_id: cc.id). The new table has no equivalent route parameter support. - Empty state messaging — the old table shows contextual empty state copy; the new table falls back to DataTables' generic text.
- Thank-you modal — shown after creating a contact in the old table.
Additional gaps visible in the Figma (not in old table either):
- Case filter tabs — clickable case-number pills above the toolbar for quick per-case filtering.
- Download button — CSV/PDF export; out of scope for #6503, needs its own issue.
Filtering
| Feature | Old | New |
|---|---|---|
| Date range (start / end) | ✅ | ✅ |
| Contact type (checkboxes by group) | ✅ | ✅ |
| Contact medium (single-select) | ✅ | ✅ |
| Contact made (single-select) | ✅ | ✅ |
| Hide drafts | ✅ | ✅ |
| Want driving reimbursement | ✅ | 🚫 intentionally dropped — not in Figma (see #6502 decisions) |
| Contact medium (multi-select, as Figma shows) | ❌ | ❌ deferred — Figma shows checkboxes supporting multiple simultaneous selections; current scope accepts a single value |
| Contact made (multi-select, as Figma shows) | ❌ | ❌ deferred — same as medium |
| Draft (multi-select, as Figma shows) | ❌ | ❌ deferred — same pattern |
| Created By filter | ❌ | ❌ deferred — Figma shows it; open question about which users to list in the UI |
| Topics filter | ❌ | ❌ deferred — Figma shows it; no backend scope exists yet |
| Sort order (occurred_at, contact_type, medium, reimbursement, contact_made) | ✅ | ❌ partial — Date column sorts asc/desc; Medium sort icon removed (was present but non-functional); all other columns not sortable |
| Filter state persists in URL (bookmarkable / shareable) | ✅ (Filterrific uses query params + Turbo) | ❌ missing (filter state is JS-only; reloading resets it) |
| Filter panel remembers state across reload | ✅ (URL params) | ❌ missing |
Data Displayed per Row / Card
| Data | Old | New |
|---|---|---|
| Date of contact | ✅ (subheading) | ✅ column |
| Case number | ✅ (card heading) | ✅ column |
| Contact type / relationship | ✅ (card heading) | ✅ column |
| Contact medium | ✅ (icon + subheading) | ✅ column |
| Created By (linked by role) | ✅ | ✅ column |
| Contact made (reached / not reached) | ✅ (subheading: "No Contact Made") | ✅ column (icon) |
| Duration | ✅ (subheading) | ✅ (shown alongside contact-made icon in expanded row via JS) |
| Contact topic answers | ✅ (truncated, in-card) | ✅ (expanded row) |
| Notes | ✅ (truncated, in-card) | ✅ (expanded row) |
| Draft badge | ✅ | ✅ |
| Miles driven / reimbursement | ✅ (subheading via miles_traveled + reimbursement) |
❌ missing |
| Medium icon | ✅ | ❌ missing |
| Transition-age youth icon next to case number | ✅ (🦋 / 🐛 via transition_aged_youth_icon) |
❌ missing |
Actions
| Action | Old | New |
|---|---|---|
| Edit | ✅ | ✅ |
| Delete | ✅ (policy-gated) | ✅ (policy-gated, with confirmation dialog) |
| Set Reminder (followup) | ✅ ("Make Reminder" button, visible inline) | ✅ (in actions menu) |
| Resolve Reminder | ✅ ("Resolve Reminder" button, visible inline) | ✅ (in actions menu) |
| Restore / Undelete (soft-deleted records) | ✅ (admins see "[DELETE]" prefix + Undelete button) | ❌ missing — soft-deleted records are not shown at all |
Navigation and Linking
| Feature | Old | New |
|---|---|---|
Deep-link to contacts for a specific case (?casa_case_id=) |
✅ (sidebar links pass this param; controller filters to one case) | ❌ missing — sidebar still links to old table path |
| Pagination | ✅ (Pagy bootstrap nav) | ✅ (DataTables native — rows-per-page dropdown, record count, page links) |
| Empty state message (no contacts / no results) | ✅ | ❌ missing (DataTables shows its own generic "No data available" string) |
| Thank-you modal after creating a contact | ✅ (rendered in layout) | ❌ missing |
Search
| Feature | Old | New |
|---|---|---|
| Full-text search across creator name, email, case number, notes, contact type | ❌ not present | ✅ (DataTables search box, server-side) |
Gaps Visible in the Figma Design
Source: Figma
These items appear in the Figma but are not yet implemented in either the old or new table.
Case tabs above the toolbar
The Figma shows a row of clickable case-number pills immediately above the Filter/Columns/Download toolbar (e.g. CNA-19-1004 | CNA-08-1003 | CNA-19-1004 & CNA-09-1003). These appear to be the volunteer's assigned cases, each acting as a quick filter to show only contacts for that case. Clicking one would filter the table to a single case; clicking a combined pill (e.g. two case numbers joined with &) would show contacts shared across both. This is a more prominent and discoverable replacement for the old ?casa_case_id= deep-link pattern used by the sidebar.
Pagination controls with rows-per-page selector and record count
The Figma shows pagination controls at the bottom of the table. These are already present in the new table — DataTables renders a rows-per-page dropdown, a "Showing X to Y of Z entries" record count, and Previous/Next page links natively. The styling differs from the Figma's layout but the functionality is equivalent. Not a gap.
Download button in the toolbar
The Figma toolbar shows three controls: Filter, Columns, and Download. The Download button is not yet implemented. Its intended behavior is not specified in the Figma — likely a CSV or PDF export of the current filtered view, consistent with the export functionality available elsewhere in the app. This was explicitly called out as out of scope for #6503 and should be its own issue.
Column count badge counts all columns, not just toggleable ones
The Figma Columns button shows 9/9, which appears to count every visible data column (Date, Case, Relationship, Medium, Created By, Contacted, Topics, Draft, and possibly one more). The current implementation shows 6/6 counting only the six user-toggleable columns, excluding the fixed Date and Case columns. It is unclear whether the Figma intends all columns to be toggleable or simply counts them all in the badge. If the intent is to include Date and Case in the count, the badge label and toggle list both need updating.
Figma filter UI: two-level drill-down overlay
The Figma shows a two-level drill-down filter overlay — clicking Filter opens a category list, and clicking a category slides into a sub-panel. The #6502 implementation used a flat panel instead (simpler to build, simpler to test, no backend impact). Replacing the flat panel with the Figma drill-down is a pure frontend change with no backend work required, and can be done in a future ticket if the UX difference matters.
Possible bulk-selection checkboxes
The leftmost column in the Figma rows may include checkboxes for selecting multiple contacts, which would presumably enable a bulk action (e.g. bulk delete or bulk export). The image resolution makes this ambiguous — it may instead be the bell/reminder indicator already implemented. Worth confirming with a product owner before creating an issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the comparison between app/views/case_contacts/index.html.erb and app/views/case_contacts/case_contacts_new_design/index.html.erb, then compare the listed gaps with the linked Figma design. Confirm ambiguous product decisions, such as case tabs, column counts, bulk selection, and download behavior. Done means the remaining gaps are either accepted or split into separately scoped follow-up issues.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- jquery, rails, ruby
- Domain
- frontend
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100