Skip to content

Add agents list view (#478)#556

Open
ivannissimrch wants to merge 12 commits into
developfrom
ivannissimrch/478/feat/agents-table-list-view
Open

Add agents list view (#478)#556
ivannissimrch wants to merge 12 commits into
developfrom
ivannissimrch/478/feat/agents-table-list-view

Conversation

@ivannissimrch
Copy link
Copy Markdown
Collaborator

@ivannissimrch ivannissimrch commented May 24, 2026

Description

Adds the list-view (table) variant for the agents dashboard.

Related Issues

Closes #478

Changes

  • New AgentTableList and AgentTableRow wired into AgentListController via viewMode
  • 7 agent table columns (title, type, volunteerSearch, district, activeVolunteers, numberOfOpportunities, email) with EN and DE translations.
  • District lookup via districtsList (table and card paths) fixes empty district render
  • Email rendering with temporary cast workaround (see SDK note below)
  • New shared COLUMN_WIDTH constants (XS/SM/MD/LG), both agent and volunteer tables migrated
  • New shared WrapAnywhereCell for long unbreakable text (used by agent email column)
  • Card constant globals consolidation: CARD_COLUMNS/CARD_ROWS moved to src/config/constants.ts (touches Agent, Volunteer and Opportunity controllers)
  • createAgentTypeMap moved out of icon.tsx into Agents/constants.ts
  • DE translation fix: dashboard.agents.* now uses Bezirk

SDK 0.0.91 note (relevant to email column)

Tried to bump to need4deed-sdk@0.0.91 to pick up the typed email field on ApiAgentGetList.
0.0.91 introduced Voidable<T> (= T | null | undefined) on many fields where they were previously T | undefined, which broke 10 typecheck errors across 6 unrelated files. I stayed on 0.0.90 for this PR and used a cast workaround for email (with a TODO comment explaining when to remove).

  • numberOfOpportunities column currently renders 0, but currently the BE is not sending the number of opportunities; we have activeVolunteers and numActiveVolunteers (which appear to be the same value, possibly duplicate metrics).

Screenshots / Demos

Screenshot from 2026-05-24 12-14-24

Checklist

  • WITHIN THE SCOPE OF AN ISSUE; No unnecessary files included
  • Tests added/updated
  • Documentation updated
  • CI passes

Copy link
Copy Markdown
Collaborator

@nadavosa nadavosa left a comment

Choose a reason for hiding this comment

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

Good feature, @ivannissimrch — the structure follows the volunteer table pattern cleanly, the district lookup fix is correct, and the shared COLUMN_WIDTH constants are a nice cleanup. A few things to address:


🔴 Hardcoded 0 for numberOfOpportunities — AgentTableRow.tsx

<TableCell $width={AGENT_COL_WIDTHS.numOpportunities} data-testid={`agent-opportunities-${id}`}>
  0
</TableCell>

I understand the BE doesn't send this yet, but displaying 0 for every agent is actively misleading — users will read it as "this agent has zero opportunities." Use "—" as a placeholder (same as you do for district) until the field arrives from the BE:

{activeVolunteers ?? "—"}  // how district handles it
// →
{"—"}  // for numOpportunities until BE supports it

Or remove the column entirely until the data is available.


🟡 Fragile viewMode mapping — Agents.tsx

const viewMode = Object.values(ViewMode)[selectedTabIndex];

This relies on JavaScript object key insertion order matching the tab order. If ViewMode values are ever reordered, or a tab is added/removed, this silently breaks — viewMode becomes the wrong value with no type error. Use an explicit array instead:

const VIEW_MODE_BY_TAB = [ViewMode.LIST, ViewMode.CARD, ViewMode.MAP] as const;
const viewMode = VIEW_MODE_BY_TAB[selectedTabIndex] ?? ViewMode.LIST;

🟡 districtsList not coerced to undefinedAgentListController.tsx

districtsList={apiFilterOptions?.district}

With SDK ≥ 0.0.91, district becomes Voidable<OptionItem[]> (i.e. can be null). AgentCard and AgentTableList type their prop as OptionItem[] | undefined, so passing null will be a type error after the SDK bump. Add ?? undefined here (same pattern as PR #561 does for the same field):

districtsList={apiFilterOptions?.district ?? undefined}

Nit

The TABLE_LIMIT constant was moved from the middle of constants.ts to the bottom. Not a problem, but it's a pure noise change that adds diff noise in the file. Can be skipped.


Overall this is solid work — just needs the 0"—" fix and the viewMode mapping hardened before merging.

Copy link
Copy Markdown
Collaborator

@nadavosa nadavosa left a comment

Choose a reason for hiding this comment

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

Two non-blocking issues worth addressing: misleading hardcoded '0' for opportunities column, and fragile tab→viewMode mapping. Details in the comment above.

@ivannissimrch
Copy link
Copy Markdown
Collaborator Author

ivannissimrch commented May 28, 2026

Thank you for the feedback. I have addressed all three:

  • numberOfOpportunities: em-dash placeholder
  • ViewMode mapping: explicit VIEW_MODE_BY_TAB array with LIST fallback
  • districtsList: coerced to undefined

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.

feat: agents list view

2 participants