Devlog Week 13: Employee Lists, Log Views, and LogCard Refactor#
This entry focuses on the employee list + employee log viewing flows, plus a refactor of LogCard to support reuse across more contexts (and avoid invalid nested interactive elements).
What Changed#
EmployeeListimplemented using the same fetch + filter pattern asAssetList- Active/inactive filter moved server-side via
getEmployees(activeFilter) - Role filter handled client-side using
Array.filter()(backend does not support role filtering) - Dynamic filter option lists derived from loaded data using
Setfor deduplication EmployeeCardadded with existing CSS module styling and navigable card behaviorEmployeeLogListfetches employee + logs in parallel (Promise.all) and supports client-side filteringLogCardrefactored to supportshowAssetNameand improved keyboard accessibility
EmployeeList: Server-Side vs Client-Side Filtering#
The EmployeeList page follows the same core structure as AssetList:
- local state for
loading,error, and the loaded employee array - a
useEffectthat refetches when filter state changes - filter UI built from reusable
Selectcomponents
Filtering is intentionally split based on backend capability:
- active/inactive is server-side (through
getEmployees(activeFilter)), because it maps cleanly to the API and keeps payloads smaller - role filtering is client-side using
Array.filter()on the already-loaded employees, because the backend does not currently expose role filtering
For role filter options, values are derived from the loaded list via Set to avoid duplicates and keep the UI resilient to data changes.
EmployeeCard: Clickable Cards Without Double Navigation#
EmployeeCard reuses existing CSS module patterns and shows:
- name + email
- an active badge
- a role badge
The card click navigates to /employees/:id. A secondary “View performed logs” action is rendered inside the card; it uses e.stopPropagation() to prevent the card click handler from firing at the same time.
EmployeeLogList: Parallel Fetch + Derived Filters#
EmployeeLogList loads two independent datasets:
- employee summary data
- logs performed by that employee
These are fetched in parallel with Promise.all, keeping the page responsive.
Filtering is implemented client-side for:
- status
- task type
- asset name
Asset name options are derived from the loaded logs using Set for deduplication (same idea as the role filter).
LogCard Refactor: Reuse + Accessibility#
To support log lists in multiple contexts, LogCard was updated with a showAssetName prop.
Other refactor outcomes:
- collapsed view includes the key metadata; expanded view now only shows additional info (log id and links)
- asset and performer values are rendered as
<Link>elements e.stopPropagation()is applied to those links to avoid toggling the card when the link itself is clicked
Up Next#
- Add manager/admin-oriented pages (create asset/employee and domain-specific admin actions)
- Tighten UX around failures (consistent error messages and session expiry handling)