feat: integrate DashboardFlow with standalone PaymentMethod management block#2006
Open
serikjensen wants to merge 3 commits into
Open
feat: integrate DashboardFlow with standalone PaymentMethod management block#2006serikjensen wants to merge 3 commits into
serikjensen wants to merge 3 commits into
Conversation
…t block The PaymentMethod block existed under management/ already, but DashboardFlow's JobAndPayView still inlined the card markup and listened for its own un-scoped events. This wires the dashboard to consume the standalone pieces the same way the new Profile and HomeAddress migrations do, and finishes the per-piece decoupling the block needed to be partner-consumable on its own. What changed: - Dashboard's JobAndPayView now renders <PaymentMethodCard/> directly; the Add / Split / delete flows are owned by the card and the block, not the dashboard. dashboardStateMachine and DashboardComponents target the new scoped events instead of forwarding inlined callbacks. - Renamed ListView.tsx -> PaymentMethodCard.tsx and exported it publicly as EmployeeManagement.PaymentMethodCard so partners can compose just the card on their own routes. - Carved the shared onboarding BankForm / SplitView usage into per-flow wrappers (PaymentMethodBankForm, PaymentMethodSplitForm) under management/. Each wrapper consumes the existing shared form hook, owns its own Employee.Management.PaymentMethod<Bank|Split>Form i18n namespace, and emits EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_<BANK|SPLIT>_FORM_SUBMITTED / _CANCELLED events. Onboarding flow keeps its own copies, so partner overrides on one side don't bleed into the other. - DeleteBankAccountDialog is now presentational: title / description / confirmLabel / cancelLabel are props, supplied per consumer from their own namespace, so the management override surface is decoupled from onboarding. - Renamed every PaymentMethod-scoped event from EMPLOYEE_PAYMENT_METHOD_MANAGEMENT_* to EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_* (and split the card / bank-form / split-form events out per-component) so the partner-visible vocabulary reads as "this is a management-context event for paymentMethod" rather than "this is a paymentMethod event that happens to be management." - Renamed Employee.PaymentMethod.Management.json -> Employee.Management.PaymentMethod.json (plus the two new per-form namespaces) to match the new convention. Existing HomeAddress / WorkAddress suffix-style files are left as-is and will migrate opportunistically. - BoxHeader: dropped a redundant <Flex> wrapper around the title and added a content-sized .titleColumn so the action element sits at its natural width on the right edge of the box. Without this the title column hogs 50% of the header via Flex's width: 100% .flexContainer, squeezing the action and cutting off multi-button headers. - Partner docs (employee-dashboard.md, employee-management.md) refreshed for the new event names, the new exports, and the per-form wrapper composition. - sdk-app/src/generated-registry-data.ts regenerated for the new exports. Verification: - npm run test -- --run -> 2973 passing - npm run lint:check -> 0 errors Co-authored-by: Cursor <cursoragent@cursor.com>
…ment-first naming
Fold the patterns learned from the PaymentMethod migration back into the
migrate-dashboard-card-to-block skill and its scout / documenter agents so
the next card migration starts from these defaults.
- New "When the shared piece is a stateful form — wrap, don't share"
subsection. Documents the per-flow wrapper pattern (PaymentMethodBankForm,
PaymentMethodSplitForm): when a shared onboarding form is too stateful to
make presentational, extract its brains into a shared/ hook, then build a
thin per-flow wrapper that owns its own Employee.Management.<Feature>
<Component>.json namespace and emits EMPLOYEE_MANAGEMENT_<FEATURE>_
<COMPONENT>_* events. Frames the wrappers as a real partner export
alternative to event-translation inside contextual adapters.
- New "Card chrome layout" subsection under "The card component contract".
Captures three Box / BoxHeader composition rules that aren't obvious from
the primitives alone: withPadding={!isShowingTable} + DataView isWithinBox
for edge-to-edge tables (matches Compensation / Deductions / Paystubs);
multi-button header actions wrapped in <Flex justifyContent="flex-end">
with an explanation of why (Flex.flexContainer is width: 100%); no glyph
duplication in icon-button label strings.
- Naming convention: events use EMPLOYEE_MANAGEMENT_<FEATURE>_* (MANAGEMENT
right after the actor); i18n namespaces use Employee.Management.<Feature>
(prefix style). Pre-existing HomeAddress / WorkAddress suffix-style files
are called out as exceptions that migrate opportunistically when their
owning card is touched.
- Per-card checklist gains two items covering the card-chrome rules and the
per-flow wrapper requirement, each linking back to the new subsections.
- Scout and documenter agent prompts updated for the same naming
convention so they recommend the right shape on the next migration.
- Fixed a copy-paste typo on the management-namespace contrast where both
sides of "rather than" said the same thing.
Co-authored-by: Cursor <cursoragent@cursor.com>
…l names
Review polish on the PaymentMethod management block extraction. Three
related cleanups; no partner-visible behavior change other than the
narrow-container button stacking described below.
Card header layout — keep the fix, drop the BoxHeader change
The previous commit landed a multi-button header layout fix inside the
shared BoxHeader primitive (replaced an inner Flex wrapper with a plain
title column div). That had real risk of regressing every other Box-using
card in the SDK for one feature's benefit. This commit:
- Reverts BoxHeader.tsx and BoxHeader.module.scss to byte-identical with
origin/main. Zero blast radius outside PaymentMethod.
- Moves the layout fix into a new co-located PaymentMethodCard.module.scss
with a .headerAction class. The wrapper is display: flex; flex-shrink: 0
so BoxHeader's existing space-between pins it flush right at content
width and the inner buttons (Button is flex-shrink: 0 + white-space:
normal, so its min-content is the longest word, not the full button
width) don't overflow when the outer flex tries to shrink the wrapper.
- Adds a container-query(40em) upgrade — defaults to column (stacked
CTAs), upgrades to row + align-items: center at the SDK's standard
small breakpoint. Reuses the container-query mixin from
src/styles/_Responsive.scss (auto-injected via Vite's additionalData)
and the 40em / \$global-breakpoints.small value other modules
(CompensationHistory, EmployeeTable, TimeOffPolicyDetail) already use.
Mirrors the responsive contract Flex ships with internally — Flex
itself can't be used here because its outer .flexContainer is
width: 100% and competes with the title for header space.
- Swaps the inline style={{ … }} on PaymentMethodCard's header action for
a className referencing the new module, matching the codebase
convention of per-card .module.scss files (Profile.module.scss,
JobAndPayView.module.scss, etc.).
Contextual adapter naming
PaymentMethodComponents.tsx renamed its three contextuals to mirror the
exact name of the leaf component each wraps:
- CardContextual -> PaymentMethodCardContextual
- BankFormContextual -> PaymentMethodBankFormContextual
- SplitViewContextual -> PaymentMethodSplitFormContextual
(The last rename also retires the lingering 'SplitView' legacy term in
the management folder — the wrapped component is PaymentMethodSplitForm.)
PaymentMethod.tsx and paymentMethodStateMachine.ts updated to import the
new names. HomeAddress and Profile still use the unqualified
CardContextual historically and are out of scope for this PR.
Skill + agents
- migrate-dashboard-card-to-block/SKILL.md naming-conventions table now
recommends '<WrappedComponent>Contextual — mirror the exact name of
the standalone component the adapter wraps' instead of '<Action>Contextual'.
The aspirational Compensation example code in the State machine /
Block file / Contextual adapters sections updated accordingly, with a
follow-up paragraph noting older blocks still use CardContextual
historically.
- Card chrome layout section now documents the CSS-module + mobile-first
container-query recipe end-to-end: why display: flex (not Flex), why
flex-shrink: 0 (Button white-space + min-content interaction), why a
container query (narrow-container UX), and why the 40em breakpoint
(matches \$global-breakpoints.small and existing module convention).
Migration checklist item rewritten to enforce the full recipe.
- dashboard-card-scout.md and dashboard-block-documenter.md updated to
use <Feature>CardContextual.
Verification
- npm run test -- --run src/components/Employee/PaymentMethod/management/
src/components/Common/UI/Box/ src/components/Common/UI/BoxHeader/ -> 31 passing
- Storybook visual check via Playwright at 800px container (row, flush
right, both buttons fully visible) and 400px container (stacked column).
- npm run lint:check -> 0 errors
Co-authored-by: Cursor <cursoragent@cursor.com>
4763637 to
ba9a18e
Compare
This was referenced Jun 3, 2026
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
The
PaymentMethodblock already existed undermanagement/from an earlier migration, butDashboardFlow'sJobAndPayViewstill inlined the Payment card markup and emitted its own un-scoped events. This finishes the migration by wiring the dashboard to consume the standalone pieces (matching the pattern Profile / HomeAddress now use) and carving the shared form screens into per-flow wrappers so each piece is partner-consumable on its own.What changed
JobAndPayViewnow renders<PaymentMethodCard />directly;dashboardStateMachineandDashboardComponentslisten for the card's / form wrappers' scoped events instead of the previous inlined callbacks. The card and the new form wrappers are public exports (EmployeeManagement.PaymentMethodCard,EmployeeManagement.PaymentMethodBankForm,EmployeeManagement.PaymentMethodSplitForm).BankForm/SplitVieware stateful form screens shared with the management flow. Rather than translating events inside contextual adapters or making the forms presentational, this PR adds thin management-side wrappers (PaymentMethodBankForm,PaymentMethodSplitForm) that consume the shared form hooks, own their own i18n namespaces (Employee.Management.PaymentMethodBankForm.json,…SplitForm.json), and emitEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_<BANK|SPLIT>_FORM_SUBMITTED/_CANCELLED. Onboarding stays put — translation overrides decouple by flow.DeleteBankAccountDialogis now presentational.title/description/confirmLabel/cancelLabelare props, supplied per consumer from their own namespace. Same decoupling rationale as the form wrappers.EMPLOYEE_PAYMENT_METHOD_MANAGEMENT_*toEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_*(with the card / bank-form / split-form events split out per-component), and the i18n namespace renamed fromEmployee.PaymentMethod.Management.jsontoEmployee.Management.PaymentMethod.json. Reads as "this is a management-context event for paymentMethod" instead of "this is a paymentMethod event that happens to be management." Pre-existingEmployee.HomeAddress.Management.json/Employee.WorkAddress.Management.jsonfiles are left as-is and will migrate opportunistically when their owning cards are touched.BoxHeaderlayout fix. The title column was wrapped in<Flex>, which renders `width: 100%` to support container queries. As a flex item inside.root'sspace-between, that meant the title and action each wanted 100% and shrank to 50/50, squeezing multi-button header actions. Replaced with a content-sized.titleColumnso the action gets all remaining free space; multi-button actions now wrap in<Flex justifyContent=\"flex-end\">. Card body switched to the edge-to-edgewithPadding={!isShowingTable}+DataView isWithinBoxpattern Compensation / Deductions / Paystubs already use.+ Add another bank accountcopy fix — the+was duplicated by the button's<PlusCircleIcon />icon prop. Label is now plainAdd another bank account.Scoped event surface
EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_CARD_ADD_REQUESTEDPaymentMethodCardAdd bank account buttonEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_CARD_SPLIT_REQUESTEDPaymentMethodCardSplit paycheck buttonEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_CARD_BANK_ACCOUNT_DELETEDPaymentMethodCardrow delete confirmationEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_BANK_FORM_SUBMITTED/_CANCELLEDPaymentMethodBankFormsave / cancelEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_SPLIT_FORM_SUBMITTED/_CANCELLEDPaymentMethodSplitFormsave / cancelEMPLOYEE_MANAGEMENT_PAYMENT_METHOD_ALERT_DISMISSEDTest plan
npm run test -- --run→ 237 files / 2989 tests pass (rebased on top of latestorigin/mainincluding feat: extract HomeAddress card from DashboardFlow into standalone management block #1992 HomeAddress, feat: extract Profile card from DashboardFlow into standalone management block #1976 Profile, feat: add OnboardingExecutionFlow and skip redundant list in EmployeeListFlow #1990 OnboardingExecutionFlow).npm run lint:check→ 0 errors (26 pre-existing warnings unrelated).npm run build+ lint-staged) passes on both commits.sdk-app: dashboard \u2192 Job and pay \u2192 Payment card add / split / delete flows; standaloneEmployeeManagement.PaymentMethodblock; standaloneEmployeeManagement.PaymentMethodCard+…BankForm+…SplitFormfrom the dev app sidebar.<EmployeeManagement.PaymentMethod employeeId={…} onEvent={…} />into a page and verify card \u2194 form transitions + success alerts.Screen.Recording.2026-06-03.at.4.00.39.PM.mov
Screen.Recording.2026-06-03.at.4.02.36.PM.mov
Made with Cursor