feat: extract Paystubs card from DashboardFlow into standalone management block#2011
Draft
serikjensen wants to merge 1 commit into
Draft
feat: extract Paystubs card from DashboardFlow into standalone management block#2011serikjensen wants to merge 1 commit into
serikjensen wants to merge 1 commit into
Conversation
…ment block Moves the inline paystubs UI out of `JobAndPayView` and into a new `Employee/Paystubs/management` block following the standalone card pattern established by HomeAddress (#1992) and PaymentMethod (#2006): - `shared/usePaystubsList` — `BaseHookReady`-shaped data hook that fetches the paginated paystubs list and exposes a `downloadPayStub` action returning a PDF Blob. - `management/PaystubsCard` — self-fetching card that renders the table and owns the per-row download UX (new-tab spinner page, Blob URL navigation, scoped `EMPLOYEE_MANAGEMENT_PAYSTUBS_CARD_*` events). - `management/Paystubs` — thin block that wraps the card in `BaseBoundaries` and registers the `Employee.Management.Paystubs` i18n namespace. Paystubs is a read-only surface, so the block has no `robot3` state machine, no `Flow` orchestration, and no contextual adapter — the doc comment documents this exception so future maintainers know the shape to adopt if/when an edit state appears. `useEmployeeCompensation` no longer fetches paystubs (callers now embed `<PaystubsCard />` directly), and the `jobAndPay.paystubs.*` keys move from `Employee.Dashboard` to `Employee.Management.Paystubs`. Also fixes a regression caught during manual QA: the per-row download spinner never cleared because the payroll UUID was added to the in-flight set but never removed. A `finally` block now drops it on success, failure, or empty result; covered by a new assertion in `PaystubsCard.test.tsx`. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the inline paystubs UI out of
JobAndPayViewand into a newEmployee/Paystubsfeature folder, following the standalone-card pattern established by HomeAddress (#1992) and PaymentMethod (#2006).Four independently consumable pieces under the new
Employee/Paystubs/folder:shared/usePaystubsList—BaseHookReady-shaped data hook that fetches the paginated paystubs list and exposes adownloadPayStub(payrollId)action returning a PDFBlob. Partners can build a fully custom paystubs UI on top of this hook.management/PaystubsCard— self-fetching card that renders the paystubs table and owns the per-row download UX (new-tab spinner page → Blob URL navigation → revoke). Emits scopedEMPLOYEE_MANAGEMENT_PAYSTUBS_CARD_DOWNLOAD_REQUESTED/_DOWNLOADEDevents. Cross-fetchesusePaymentMethodListinternally for the "Payment method" column.management/Paystubs— thin block that wraps the card inBaseBoundariesand registers theEmployee.Management.Paystubsi18n namespace.Employee/exports/employeeManagement.tsand the SDK dev-app registry.State-machine exception
Paystubs is a read-only surface — the only interaction is a per-row PDF download that resolves as a side effect (opens a new tab). With zero transitions, the block has no
robot3state machine, noFloworchestration, and no contextual adapter. ThePaystubsblock doc comment explicitly documents this exception so future maintainers know which shape to adopt if/when an edit/review state is ever added.Cleanup in
Dashboard/useEmployeeCompensationno longer fetches paystubs (and its return type dropspayStubs/payStubsPagination/isPayStubsLoading). Callers embed<PaystubsCard />directly.JobAndPayViewdeletes ~160 lines of inline paystubs code (download handler, columns, DataView, loading branch) and replaces them with<PaystubsCard employeeId={employeeId} onEvent={onEvent} />.jobAndPay.paystubs.*keys move fromEmployee.Dashboard→Employee.Management.Paystubs(regenerated i18n types).Bug fix included
While QA'ing manually I noticed the per-row download spinner spun forever after a successful download — the payroll UUID was added to the in-flight set but never removed. Added a
finallyblock inhandleDownloadthat drops it on success, failure, or empty result, plus a regression assertion inPaystubsCard.test.tsx.Test plan
usePaystubsList.test.tsx— loading state, ready state, pagination,downloadPayStubsuccess returning a Blob,downloadPayStubAPI failure surfacing througherrorHandling.errorsPaystubsCard.test.tsx— title + per-row download buttons render, empty state, event emission on request + success, spinner clears after download completes (regression for the bug above)Paystubs.test.tsx— block renders the card, events propagateuseEmployeeCompensation.test.tsx— paystubs assertions removed; remaining compensation/cancel-pending-change behavior still passesnpm run test -- --run— greennpm run tsc— cleannpm run lint:check— clean (warnings only, all pre-existing)docs/workflows-overview/employee-management/employee-management.mdadditionsRefs
migrate-dashboard-card-to-blockMade with Cursor