Skip to content

feat(invoice-schedule): group the onboarding step under fieldsets - #1767

Merged
gabrielseco merged 5 commits into
feat/invoice-schedule-semi-monthly-cyclefrom
feat/invoice-schedule-fieldsets
Oct 29, 2026
Merged

gabrielseco merged 5 commits into
feat/invoice-schedule-semi-monthly-cyclefrom
feat/invoice-schedule-fieldsets

Conversation

@gabrielseco

@gabrielseco gabrielseco commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The invoice schedule step in contractor onboarding now groups its fields under the same headings the Remote platform uses: Invoicing details, Invoice items, Invoicing preferences and Summary.

Why

The platform's "Create invoice schedule" step is split into those four groups. The onboarding step here rendered one long flat list. The standalone Invoice Schedule flow should stay as it is, so the grouping has to be switchable.

What changed

Toggle details
  • The shared create-invoice-schedule schema takes a new includeFieldsets option (off by default). When on, it adds x-jsf-fieldsets with the four groups, in the same shape Tiger's schemas use. Every field of the schema belongs to exactly one group.
  • useGetCreateInvoiceScheduleSchema passes the option through. Contractor onboarding turns it on and reads the groups from the form's meta for the create_invoice_schedule step, where it used to be null.
  • The standalone InvoiceScheduleFlow does not pass the option, so it renders the same fields flat, unchanged.
  • No form code or shared component changes: the form already groups fields when it is given fieldsets.
  • No exported component, hook or prop changes. The option is internal to the shared schema builder.
  • Not changed: the platform's "Add item" repeater. Items still use the ten fixed slots revealed one by one, inside the "Invoice items" group.
  • Stacked on feat(invoice-schedule): add the semi-monthly invoicing cycle fieldset #1765; retarget to main once it merges.

Screenshots

Toggle screenshots

Contractor onboarding, create invoice schedule step, run from the example app against the review environment (PRT contractor). The semi-monthly shot shows the cycle fieldset nested inside "Invoicing preferences".

Open as a gallery (⌘-click or Ctrl-click for a new tab): click a screenshot, then use the arrow keys.

Invoicing details and items
Invoicing details and items
Preferences with semi monthly
Preferences with semi monthly
Summary and actions
Summary and actions

Related Resources

Testing

Schema tests cover no fieldsets by default, the four headings in order with the option on, and every field landing in exactly one group. ContractorOnboarding.test.tsx checks the four headings on the create invoice schedule step, and InvoiceScheduleFlow.test.tsx checks they are absent in the standalone flow.

  • Standalone flow checked against the example/ app in a browser (review environment): fields render flat
  • Onboarding step checked in the browser (example app, review environment)
  • Feature flag: N/A

🤖 Generated with Claude Code


Note

Low Risk
Presentation-only JSON Schema metadata; validation, payloads, and public APIs are unchanged.

Overview
Contractor onboarding’s create invoice schedule step now matches the Remote platform layout by grouping fields under Invoicing details, Invoice items, Invoicing preferences, and Summary.

The shared schema builder and useGetCreateInvoiceScheduleSchema gain an internal includeFieldsets flag (default off). When enabled, the schema adds x-jsf-fieldsets; onboarding turns it on and passes those fieldsets through step meta instead of rendering a flat list. The standalone InvoiceScheduleFlow still omits the flag, so behavior there is unchanged.

Tests assert default flat layout, correct headings and field coverage when fieldsets are on, onboarding shows the headings, and the standalone flow does not. README notes the onboarding vs standalone difference.

Reviewed by Cursor Bugbot for commit 904e9f7. Bugbot is set up for automated code reviews on this repo. Configure here.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Metric Current Previous Change Status
Total (gzip) 235.54 kB 235.41 kB +134 B (+0.1%) 🔴
Total (raw) 653.67 kB 653.12 kB +542 B (+0.1%) 🔴
CSS (gzip) 21.95 kB 21.95 kB 0 B (0%) 🟢
CSS (raw) 114.51 kB 114.51 kB 0 B (0%) 🟢

Size Limits

  • ✅ Total gzipped: 235.54 kB / 350 kB (67.3%)
  • ✅ Total raw: 653.67 kB / 850 kB (76.9%)
  • ✅ CSS gzipped: 21.95 kB / 25 kB (87.8%)

Largest Files (Top 5)

  1. index.esm-wIkXrqU6.js - 11.4 kB (0 B (0%))
  2. styles.css - 10.97 kB (0 B (0%))
  3. index.css - 10.97 kB (0 B (0%))
  4. internals-Cdk22Zh1.js - 6.13 kB (0 B (0%))
  5. hooks--Qy2ol9F.js - 5.76 kB (new)
View All Files (301 total)
File Size (gzip) Change
index.esm-wIkXrqU6.js 11.4 kB 0 B (0%)
styles.css 10.97 kB 0 B (0%)
index.css 10.97 kB 0 B (0%)
internals-Cdk22Zh1.js 6.13 kB 0 B (0%)
hooks--Qy2ol9F.js 5.76 kB new
sdk.gen-BRPiw4M1.js 5.58 kB 0 B (0%)
index.js 5.55 kB 0 B (0%)
flows/Onboarding/hooks.js 4.67 kB 0 B (0%)
utils-Bc1UgCXy.js 4.26 kB 0 B (0%)
FieldSetField-IPPOYf7r.js 4.11 kB 0 B (0%)

✅ Bundle size check passed

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for remote-flows ready!

Project:remote-flows
Status: ✅  Deploy successful!
Preview URL:https://remote-flows-ek5rfwz8k-remotecom.vercel.app
Latest Commit:904e9f7

Deployed with vercel-action

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for adp-cost-calculator ready!

Project:adp-cost-calculator
Status: ✅  Deploy successful!
Preview URL:https://adp-cost-calculator-nnmnl2lzk-remotecom.vercel.app
Latest Commit:904e9f7

Deployed with vercel-action

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage Report

✅ Coverage increased! 🎉

Metric Current Previous Change Status
Lines 89.93% 89.92% +0.02% 🟢
Statements 89.81% 89.79% +0.02% 🟢
Functions 88.69% 88.69% 0% ⚪
Branches 81.56% 81.54% +0.01% 🟢

Detailed Breakdown

Lines Coverage
  • Covered: 5521 / 6139
  • Coverage: 89.93%
  • Change: +0.02% (2 lines)
Statements Coverage
  • Covered: 5588 / 6222
  • Coverage: 89.81%
  • Change: +0.02% (2 statements)
Functions Coverage
  • Covered: 1459 / 1645
  • Coverage: 88.69%
  • Change: 0% (1 functions)
Branches Coverage
  • Covered: 3409 / 4180
  • Coverage: 81.56%
  • Change: +0.01% (3 branches)

✅ Coverage check passed

…ly-cycle' into feat/invoice-schedule-fieldsets

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bb5e092. Configure here.

summary: {
title: 'Summary',
propertiesByName: ['note'],
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Schedule summary omitted from fieldsets

Medium Severity

invoiceFieldsets() never lists schedule_summary, so that field is the only schema property left outside a group. When frequency is weekly, bi-weekly, or monthly, the computed schedule statement renders ungrouped between Invoicing preferences and Summary instead of under the Summary heading.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bb5e092. Configure here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

solved: 351b9d3

@gabrielseco
gabrielseco merged commit 83725a3 into feat/invoice-schedule-semi-monthly-cycle Oct 29, 2026
13 checks passed
@gabrielseco
gabrielseco deleted the feat/invoice-schedule-fieldsets branch October 29, 2026 09:59
gabrielseco added a commit that referenced this pull request Oct 29, 2026
…#1765)

* fix(invoice-schedule): label the date as start date for recurring frequencies

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(invoice-schedule): choose how a recurring schedule ends

A recurring invoice schedule now asks for an end date choice: "No end date" or
"End after a number of occurrences". The count only appears, and is only required
(at least 1), for the second option. Both are hidden for a one-off. The fields sit
right after the start date, and a saved schedule prefills the choice from its
occurrence count.

The choice is form-only: "No end date" still omits nr_occurrences from the request.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): type the end date choice on the form values

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): prefill the occurrence count with 1 when end after is picked

The platform defaults the count to 1 once "End after a number of occurrences" is selected. The schema can't express that, so a form hook sets it when the end type changes to multiple and the count is still empty. Used by the standalone flow and the contractor onboarding step.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Revert "fix(invoice-schedule): prefill the occurrence count with 1 when end after is picked"

This reverts commit f34c672. A schema-level default for revealed fields is handled separately.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(forms): apply a schema default when a conditional field is revealed

A field with a schema default that becomes visible after the form mounts is filled with that default if it is still empty. Fields visible on first render, read-only and forced-value fields are left alone. Uses it for the invoice schedule occurrence count, which now starts at 1 once "End after a number of occurrences" is picked.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(forms): don't treat fields present once the schema loads as newly revealed

The form can render with no fields while its schema loads. The empty list was recorded as the baseline, so every field that then appeared with a default was filled in. The baseline now starts at the first render that has fields.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): seed schema defaults from the loaded fields instead of a form-wide hook

The standalone flow builds its form before the schema loads, so a schema default was never read. It now runs the same initial-values helper the other flows use once its fields arrive, and fills only values that are still empty. The generic reveal-time hook is removed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): create the form inside InvoiceScheduleForm like the other flows

The form was created in InvoiceScheduleFlow before the schema loaded, so schema defaults could not feed its initial values. InvoiceScheduleForm now mounts once the fields exist and builds its values with getInitialValues, as the onboarding and termination forms do. The flow keeps the bag, the form id and a ref the preview button reads the live values from. The one-off seeding effect is removed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): use RefObject instead of the deprecated MutableRefObject

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): drop the form ref and the Contractor of Record reset

The preview button now reads the latest values from the bag, which the form reports through checkFieldUpdates, so the form no longer registers itself in a ref. The flow is keyed by employmentId, so a different contractor starts from a fresh form. The frequency reset for a Contractor of Record is removed: the schema already rejects a frequency it no longer offers, and onboarding has no such reset.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): drop the employmentId-keyed remount wrapper from InvoiceScheduleFlow

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Revert "refactor(invoice-schedule): drop the employmentId-keyed remount wrapper from InvoiceScheduleFlow"

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): build initialValues in the hook and expose them on the bag

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): drop the empty-fields guard and gate the form on isLoading like the other flows

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(invoice-schedule): prove the employmentId key by switching to an already-cached contractor

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(invoice-schedule): document mounting after isLoading and the new bag members, tidy leftovers

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): use useDeepStable for the stable defaultValues

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(invoice-schedule): add the semi-monthly invoicing cycle fieldset

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): type the readOnly field flag and the schema test access

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): derive the second semi-monthly day in the schema

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): shorten the derived second-day line

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): validate the start date against the semi-monthly cycle

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* refactor(invoice-schedule): always include the semi-monthly cycle fields

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(invoice-schedule): drop the stale custom_days client note

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): restore the saved semi-monthly cycle when editing a schedule

* test(invoice-schedule): type the saved semi-monthly schedules

* feat(invoice-schedule): group the onboarding step under fieldsets (#1767)

* feat(invoice-schedule): group the onboarding step under fieldsets

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(invoice-schedule): group the schedule summary under invoicing preferences

* test(invoice-schedule): handle optional fieldsets in the grouping test

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
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.

2 participants