feat(dashboard): show Pending badge for future-dated compensations on job card and table#1897
Conversation
…job card and table When a job has no current (on-or-before-today) compensation — i.e., the job itself hasn't started yet — show a "Pending" status badge instead of the existing warning alert. The alert remains for jobs that have an active compensation with a scheduled future update. - Add `isNewJob: boolean` to `PendingCompensationChange` (true when baseline is null, meaning the job's only comp is future-dated) - Single-job card view (exempt or nonexempt): renders a Status / Pending badge row below start date; no alert for pending-new jobs - Multi-job table view: conditionally adds a Status column with a Pending badge for future-dated jobs; column is hidden when all jobs are current - Add i18n strings: `columns.status` and `pendingStatus` - Unit tests for `isNewJob` flag in `getPendingCompensationChanges` - Integration tests in Dashboard.test.tsx covering single-job badge, table column, no-column-when-all-current, and mixed badge+alert case Co-authored-by: Cursor <cursoragent@cursor.com>
Fresh Eyes ReviewFound 1 issue in this PR. Download findings.json — drag the file into Claude or use Please 👍🏽 👎🏽 if you found this useful. Generated by Fresh Eyes Reviewer. Get help in #ai-code-reviews |
Move duplicated Compensation/JobFixture types and helper functions (buildEmployeeWithJobs, overrideEmployee, goToJobAndPayTab) to the parent describe block so both 'Compensation pending changes' and 'Compensation pending badge' describe blocks share a single definition.
Co-authored-by: Cursor <cursoragent@cursor.com>
…f employee endpoint Co-authored-by: Cursor <cursoragent@cursor.com>
| // vs "update" (existing comp with a scheduled future change). | ||
| // New-job changes get a Pending badge on the card/table row. | ||
| // Update changes get the existing warning alert treatment. | ||
| const newJobPendingChanges = pendingChanges.filter(c => c.isNewJob) | ||
| const updatePendingChanges = pendingChanges.filter(c => !c.isNewJob) | ||
|
|
||
| const pendingNewJobUuids = new Set(newJobPendingChanges.map(c => c.jobUuid)) | ||
| const singleJobIsPendingNew = singleJob ? pendingNewJobUuids.has(singleJob.uuid) : false | ||
| const hasAnyPendingNewJobs = pendingNewJobUuids.size > 0 | ||
|
|
||
| const hasPendingUpdates = updatePendingChanges.length > 0 |
There was a problem hiding this comment.
🟡 Minor | [fresh_eyes]: logic-errors-dataflow
When a new (not-yet-started) job has stacked future compensations, only the first comp gets isNewJob: true (baseline === null). Subsequent comps get isNewJob: false and flow into updatePendingChanges. In the single-job view this means both a 'Pending' badge AND an inline 'Compensation will change' alert would render simultaneously for the same job that hasn't started yet. The badge says the job is pending, while the alert warns about a future comp change — on a job with no current comp. This is a potential UX-confusing state, but more importantly the alert's content (referencing a future change relative to a 'current' comp that doesn't exist) may produce misleading text since nextChange would contain details diffed against a baseline that is the first future comp, not an actual active comp.
Please 👍🏽 👎🏽 if you found this useful. Generated by Fresh Eyes Reviewer. Get help in #ai-code-reviews
Summary
How it works
`getPendingCompensationChanges` now carries an `isNewJob: boolean` field on each `PendingCompensationChange`. It is `true` when `baseline === null` (no current comp exists for the job), which maps to the existing `buildNewJobDetails` path. The view splits pending changes into two buckets — `newJobPendingChanges` (badge) and `updatePendingChanges` (alert) — and drives each UI surface independently.
Test plan
Made with Cursor