diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 1c9be68ff..4528bebe2 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -50,7 +50,7 @@ Do not make any file changes or git operations in dry-run mode. git push -u origin chore/release- gh pr create --title "chore: release " ``` -6. Once the PR is merged, publishing happens automatically — the [Publish to NPM](https://github.com/Gusto/embedded-react-sdk/actions/workflows/publish.yaml) workflow triggers when the `chore: release` commit lands on `main` and CI passes. No manual action needed unless something goes wrong. +6. Once the PR is merged, publishing happens automatically — the [Publish to NPM](https://github.com/Gusto/embedded-react-sdk/actions/workflows/publish.yaml) workflow triggers when the `chore: release` commit lands on `main` and CI passes. The [Sync Docs Source](https://github.com/Gusto/embedded-react-sdk/actions/workflows/publish-docs.yaml) workflow then propagates the docs to `Gusto/embedded-sdk-docs` and creates or refreshes the versioned snapshot for the released minor automatically. No manual action needed unless something goes wrong. ## Changelog curation (step 4) diff --git a/.github/workflows/publish-docs.yaml b/.github/workflows/publish-docs.yaml index c14613e42..bad0139c1 100644 --- a/.github/workflows/publish-docs.yaml +++ b/.github/workflows/publish-docs.yaml @@ -1,11 +1,42 @@ name: Sync Docs Source -# Fires after a successful NPM publish on main. Runs TypeDoc to generate -# docs/api/ markdown, then pushes the Docusaurus source -# (docs/ + docs-site/ + .nvmrc, including the generated docs/api/ files) -# to the main branch of Gusto/embedded-sdk-docs. That repo's Buildkite -# pipeline runs the Docusaurus build and publishes the result to its -# gh-pages branch. +# Builds docs source on this repo and pushes it to Gusto/embedded-sdk-docs. +# The downstream repo's Buildkite pipeline then runs the Docusaurus build +# and publishes the result to its gh-pages branch. +# +# Versioning lives entirely in the downstream repo, not here. This repo +# only ever carries the live (current) docs in `docs/`. Versioned snapshots +# (`docs-site/versioned_docs/`, `versions.json`, `versioned_sidebars/`) +# accumulate in `embedded-sdk-docs` over time as releases land. +# +# Three triggers, all funnel through the same job: +# 1. workflow_run after Publish to NPM — the release path. If the released +# minor isn't in downstream's versions.json, creates a new snapshot. +# If it is, refreshes the existing snapshot's content from the freshly +# synced docs (content-only; structural changes to versioned docs are +# explicit edits in the downstream repo). +# 2. push to main on docs/** or docs-site/** — the live-content path. +# Syncs the latest docs source down so /docs/ refreshes. Does not touch +# versioned snapshots. +# 3. workflow_dispatch — manual run. Always allowed; useful for recovery, +# end-to-end testing, or bootstrapping the first snapshot on a clean +# downstream (it will create the snapshot if missing for the current +# package.json minor). +# +# Snapshot mechanics: +# New minor / bootstrap: `npx docusaurus docs:version ` runs inside the +# freshly-synced downstream working tree. Docusaurus copies the current +# docs/ into versioned_docs/version-/, captures the sidebar, and adds +# to versions.json. The conditional config in docs-site/docusaurus.config.ts +# then derives lastVersion from versions.json[0], so the unprefixed /docs/ +# automatically points at the newest snapshot — no manual config change. +# +# Patch refresh: walks versioned_docs/version-/ and refreshes the +# content of each file from the matching path in the freshly-synced docs/. +# Files in the snapshot that have no live counterpart are left as-is. +# Files in live docs/ that aren't already in the snapshot are NOT added — +# adding a doc to a released minor is an intentional change made directly +# in the downstream repo. # # Auth: a GitHub App installed on Gusto/embedded-sdk-docs with # Contents: write. Credentials live in this repo's `publish-docs` @@ -18,17 +49,22 @@ name: Sync Docs Source # DOCS_APP_ID and DOCS_APP_PRIVATE_KEY (paste the entire .pem # contents for the private key). # 3. Once a manual workflow_dispatch run is green, set repo variable -# DOCS_PUBLISH_ENABLED=true to turn on auto-publish on release. +# DOCS_PUBLISH_ENABLED=true to turn on the workflow_run + push paths. # # Manual `workflow_dispatch` triggers fire any time (the gate below only -# guards the auto-on-release path), so the pipeline can be exercised -# end-to-end before flipping the variable. +# guards the auto paths), so the pipeline can be exercised end-to-end +# before flipping the variable. on: workflow_run: workflows: [Publish to NPM] types: [completed] branches: [main] + push: + branches: [main] + paths: + - 'docs/**' + - 'docs-site/**' workflow_dispatch: concurrency: @@ -38,12 +74,15 @@ concurrency: jobs: sync: # workflow_dispatch always allowed (for manual testing). workflow_run - # only fires when DOCS_PUBLISH_ENABLED=true, so the next NPM release - # won't auto-publish docs until that variable is explicitly set. + # and push only fire when DOCS_PUBLISH_ENABLED=true, so neither an NPM + # release nor a docs push will auto-publish until that variable is + # explicitly set. if: | github.event_name == 'workflow_dispatch' || - (vars.DOCS_PUBLISH_ENABLED == 'true' && - github.event.workflow_run.conclusion == 'success') + (vars.DOCS_PUBLISH_ENABLED == 'true' && ( + github.event_name == 'push' || + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') + )) runs-on: group: gusto-ubuntu-default environment: publish-docs @@ -60,7 +99,13 @@ jobs: - name: Read SDK version id: version - run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT" + run: | + VERSION=$(node -p "require('./package.json').version") + MINOR=$(echo "$VERSION" | cut -d. -f1,2) + { + echo "version=${VERSION}" + echo "minor=${MINOR}" + } >> "$GITHUB_OUTPUT" - name: Install SDK dependencies for TypeDoc run: npm ci @@ -77,32 +122,29 @@ jobs: owner: Gusto repositories: embedded-sdk-docs - # Push docs source (markdown + Docusaurus config + Node pin) to - # embedded-sdk-docs/main. Its Buildkite pipeline then builds and - # publishes the result to gh-pages. - # - # docs/api/ contains a mix of tracked and generated files: - # docs/api/index.md — hand-authored, tracked in this repo - # docs/api/reference.md — generated by TypeDoc (step above) - # docs/api/{domain}/... — generated by TypeDoc (step above) - # All are copied and force-staged so the docs repo always has the - # full generated output regardless of its own .gitignore rules. - # - # Safety model: this workflow only touches paths it explicitly - # manages (docs/, docs-site/, .nvmrc). Everything else in the - # docs repo (.buildkite/, README.md, CODEOWNERS, CNAME, .github/, - # …) is left untouched, ever. A defense-in-depth check at the - # end fails the push if any staged change escapes the allowlist - # — so if someone later widens the cp/rm logic by accident, the - # push fails closed instead of silently wiping unrelated files. + # Sync live source to downstream, then create or refresh the versioned + # snapshot if appropriate. Versioning is owned by the downstream repo — + # this is the only place that knows about versioned_docs/ etc. # - # `concurrency: publish-docs` above prevents overlapping pushes, - # so a non-force push is safe. - - name: Push docs source to embedded-sdk-docs + # Sequencing: + # 1. Clone downstream (which may already have versioned_docs/, etc.) + # 2. Wipe the source-owned paths in downstream (docs/, .nvmrc, and + # everything in docs-site/ EXCEPT the versioned files) + # 3. Copy fresh source into downstream + # 4. Run versioning logic (create new snapshot OR refresh existing + # snapshot content), but only when the trigger calls for it + # 5. Defense-in-depth: refuse to push anything outside the managed + # allowlist (docs/, docs-site/, .nvmrc) + # 6. Commit + push + - name: Sync source and update versioned snapshot in embedded-sdk-docs env: GH_TOKEN: ${{ steps.app-token.outputs.token }} SDK_VERSION: ${{ steps.version.outputs.version }} + MINOR: ${{ steps.version.outputs.minor }} + TRIGGER: ${{ github.event_name }} run: | + set -euo pipefail + git clone --depth 50 \ "https://x-access-token:$GH_TOKEN@github.com/Gusto/embedded-sdk-docs.git" \ docs-repo @@ -110,13 +152,22 @@ jobs: git config user.name "gusto-embedded-docs[bot]" git config user.email "gusto-embedded-docs[bot]@users.noreply.github.com" - # Remove only the paths this workflow owns. Anything else in - # the docs repo (.buildkite/, README.md, etc.) stays put. - # --ignore-unmatch so first-run (no prior docs/ on the repo) - # doesn't fail. - git rm -rf --quiet --ignore-unmatch docs docs-site .nvmrc + # ---- Step 2: wipe source-owned paths, preserve versioned files ---- + # docs/ and .nvmrc are entirely source-owned. + git rm -rf --quiet --ignore-unmatch docs .nvmrc + + # docs-site/ is mostly source-owned, but versioned_docs/, + # versioned_sidebars/, versions.json belong to downstream. + # Move them aside so the wipe doesn't take them out. + mkdir -p /tmp/preserved + for v in versioned_docs versioned_sidebars versions.json; do + if [ -e "docs-site/$v" ]; then + mv "docs-site/$v" "/tmp/preserved/$v" + fi + done + git rm -rf --quiet --ignore-unmatch docs-site - # Copy fresh source in. + # ---- Step 3: copy fresh source in ---- cp -R ../docs . cp -R ../docs-site . cp ../.nvmrc . @@ -124,16 +175,75 @@ jobs: # Strip anything that shouldn't ship with source. rm -rf docs-site/node_modules docs-site/build - # Stage only the paths we manage. NOT `git add -A` — that - # could pick up unrelated tree changes if anything went sideways. + # Restore the versioned files (or initialize empty placeholders if + # downstream was bare — the snapshot step below populates them). + for v in versioned_docs versioned_sidebars versions.json; do + if [ -e "/tmp/preserved/$v" ]; then + mv "/tmp/preserved/$v" "docs-site/$v" + fi + done + + # ---- Step 4: snapshot creation or refresh ---- + # Snapshot ACTION is determined by trigger + downstream state: + # workflow_run, minor missing -> create (new minor) + # workflow_run, minor present -> refresh (patch) + # workflow_dispatch, missing -> create (bootstrap / recover) + # workflow_dispatch, present -> none + # push -> none + MINOR_IN_VERSIONS=false + if [ -f docs-site/versions.json ] \ + && jq -e --arg key "${MINOR}" 'index($key) != null' docs-site/versions.json > /dev/null 2>&1; then + MINOR_IN_VERSIONS=true + fi + + SNAPSHOT_ACTION=none + if [ "$TRIGGER" = "workflow_run" ] || [ "$TRIGGER" = "workflow_dispatch" ]; then + if [ "$MINOR_IN_VERSIONS" = "false" ]; then + SNAPSHOT_ACTION=create + elif [ "$TRIGGER" = "workflow_run" ]; then + SNAPSHOT_ACTION=refresh + fi + fi + echo "Snapshot action for SDK ${SDK_VERSION} (minor ${MINOR}, trigger ${TRIGGER}): ${SNAPSHOT_ACTION}" + + if [ "$SNAPSHOT_ACTION" = "create" ]; then + # docusaurus docs:version copies docs/ -> versioned_docs/version-/, + # captures the sidebar, prepends to versions.json. + # The conditional config picks up versions.json[0] as lastVersion automatically. + (cd docs-site && npm ci && npx docusaurus docs:version "${MINOR}") + echo "Created snapshot version-${MINOR} in downstream." + elif [ "$SNAPSHOT_ACTION" = "refresh" ]; then + VERSIONED_DIR="docs-site/versioned_docs/version-${MINOR}" + if [ ! -d "$VERSIONED_DIR" ]; then + echo "::error::${MINOR} is in versions.json but ${VERSIONED_DIR}/ is missing in downstream." + exit 1 + fi + updated=0 + orphan=0 + while IFS= read -r snap_file; do + rel="${snap_file#${VERSIONED_DIR}/}" + live="docs/${rel}" + if [ -f "$live" ]; then + cp "$live" "$snap_file" + updated=$((updated + 1)) + else + orphan=$((orphan + 1)) + fi + done < <(find "$VERSIONED_DIR" -type f) + echo "Refreshed ${updated} file(s) in version-${MINOR}; ${orphan} orphan(s) left as-is." + fi + + # ---- Step 5: stage and validate ---- + # Stage only the paths we manage. NOT `git add -A` — that could + # pick up unrelated tree changes if anything went sideways. # Force-add docs/api/ so the TypeDoc-generated files are staged # even if the docs repo's .gitignore excludes them. git add docs docs-site .nvmrc git add -f docs/api - # Defense in depth: refuse to push if any staged change - # escapes the managed allowlist. No-op when the workflow is - # correct; catches future drift. + # Defense in depth: refuse to push if any staged change escapes + # the managed allowlist. No-op when the workflow is correct; + # catches future drift. unexpected=$(git diff --cached --name-only | grep -vE '^(docs/|docs-site/|\.nvmrc$)' || true) if [[ -n "$unexpected" ]]; then echo "ERROR: refusing to push — staged changes outside managed paths:" >&2 @@ -141,8 +251,28 @@ jobs: exit 1 fi + # ---- Step 6: commit and push ---- + # Commit message records the trigger + snapshot action so the + # downstream history is traceable to whichever cause prompted it. + SHORT_SHA=$(git -C "${GITHUB_WORKSPACE}" rev-parse --short HEAD) + case "${TRIGGER}" in + workflow_run) + MSG="docs: sync source for SDK ${SDK_VERSION}" + ;; + push) + MSG="docs: sync docs source from ${SHORT_SHA} (SDK ${SDK_VERSION})" + ;; + *) + MSG="docs: sync source from ${SHORT_SHA} (SDK ${SDK_VERSION}, ${TRIGGER})" + ;; + esac + if [ "$SNAPSHOT_ACTION" = "create" ]; then + MSG="${MSG} — created version-${MINOR} snapshot" + elif [ "$SNAPSHOT_ACTION" = "refresh" ]; then + MSG="${MSG} — refreshed version-${MINOR} snapshot" + fi + # Always commit (even with no file changes) so every sync run - # leaves a release-marker in the docs repo's history, matching - # 1:1 with the NPM releases that triggered it. - git commit -q --allow-empty -m "docs: sync source for SDK $SDK_VERSION" + # leaves a marker in the docs repo's history. + git commit -q --allow-empty -m "${MSG}" git push origin main diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index e064094df..2b63055c6 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -80,3 +80,32 @@ jobs: run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Read SDK version + id: version + run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT" + + # Launch a Cursor cloud agent in the demo repo to integrate the version + # we just published. The agent runs the demo repo's update-embedded-react-sdk + # skill end to end (upgrade and open a PR; the PR notifies codeowners via + # GitHub). jq builds the JSON body so the prompt's backticks are encoded safely. + - name: Launch demo-app upgrade agent + env: + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + SDK_VERSION: ${{ steps.version.outputs.version }} + run: | + PROMPT="Use the \`update-embedded-react-sdk\` skill to upgrade @gusto/embedded-react-sdk to ${SDK_VERSION} (just published to npm). The target version is ${SDK_VERSION}. Run the skill end to end, including opening the PR." + jq -n --arg prompt "$PROMPT" '{ + prompt: { text: $prompt }, + repos: [ + { + url: "https://github.com/Gusto/embedded-react-sdk-demo-app", + startingRef: "main" + } + ], + autoCreatePR: true, + skipReviewerRequest: true + }' | curl --fail-with-body -sS https://api.cursor.com/v1/agents \ + -H "Authorization: Bearer $CURSOR_API_KEY" \ + -H "Content-Type: application/json" \ + -d @- diff --git a/.reports/embedded-react-sdk.api.md b/.reports/embedded-react-sdk.api.md index 0458558c4..e3cae5c63 100644 --- a/.reports/embedded-react-sdk.api.md +++ b/.reports/embedded-react-sdk.api.md @@ -18,12 +18,12 @@ import { BeforeRequestHook } from '@gusto/embedded-api-v-2025-11-15/hooks/types' import { ButtonHTMLAttributes } from 'react'; import { Compensation } from '@gusto/embedded-api-v-2025-11-15/models/components/compensation'; import { ComponentType } from 'react'; -import { Contractor as Contractor_2 } from '@gusto/embedded-api-v-2025-11-15/models/components/contractor'; +import { Contractor } from '@gusto/embedded-api-v-2025-11-15/models/components/contractor'; import { ContractorAddress } from '@gusto/embedded-api-v-2025-11-15/models/components/contractoraddress'; import { Control } from 'react-hook-form'; import { CustomTypeOptions } from 'i18next'; import { default as default_2 } from 'react'; -import { Employee as Employee_2 } from '@gusto/embedded-api-v-2025-11-15/models/components/employee'; +import { Employee } from '@gusto/embedded-api-v-2025-11-15/models/components/employee'; import { EmployeeAddress } from '@gusto/embedded-api-v-2025-11-15/models/components/employeeaddress'; import { EmployeeBankAccount } from '@gusto/embedded-api-v-2025-11-15/models/components/employeebankaccount'; import { EmployeeFederalTax } from '@gusto/embedded-api-v-2025-11-15/models/components/employeefederaltax'; @@ -69,29 +69,25 @@ import { UseFormReturn } from 'react-hook-form'; import { UseQueryResult } from '@tanstack/react-query'; import { z } from 'zod'; -// Warning: (ae-missing-release-tag) "ACCOUNT_TYPES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const ACCOUNT_TYPES: readonly ["Checking", "Savings"]; -// Warning: (ae-missing-release-tag) "AccountNumberFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function AccountNumberField(props: AccountNumberFieldProps): JSX; + +// @public export type AccountNumberFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "AccountNumberValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AccountNumberValidation = (typeof BankFormErrorCodes)[keyof Pick]; -// Warning: (ae-missing-release-tag) "AccountType" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AccountType = (typeof ACCOUNT_TYPES)[number]; -// Warning: (ae-missing-release-tag) "AccountTypeFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function AccountTypeField(props: AccountTypeFieldProps): JSX; + +// @public export type AccountTypeFieldProps = HookFieldProps>; // Warning: (ae-missing-release-tag) "AddEmployeesHoliday" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -166,9 +162,10 @@ export type AnchorEndOfPayPeriodFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "AnnualMaximumFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function AnnualMaximumField(props: AnnualMaximumFieldProps): JSX; + +// @public export type AnnualMaximumFieldProps = HookFieldProps>; // @public @@ -223,79 +220,49 @@ export interface BadgeProps extends Pick, 'class function BankAccount(props: BankAccountProps): JSX; // Warning: (ae-forgotten-export) The symbol "fieldValidators_8" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "BankFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type BankFormData = { [K in keyof typeof fieldValidators_8]: z.infer<(typeof fieldValidators_8)[K]>; }; -// Warning: (ae-missing-release-tag) "BankFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BankFormErrorCode = (typeof BankFormErrorCodes)[keyof typeof BankFormErrorCodes]; -// Warning: (ae-missing-release-tag) "BankFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const BankFormErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly INVALID_ROUTING_NUMBER: "INVALID_ROUTING_NUMBER"; readonly INVALID_ACCOUNT_NUMBER: "INVALID_ACCOUNT_NUMBER"; }; -// Warning: (ae-missing-release-tag) "BankFormField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BankFormField = keyof typeof fieldValidators_8; -// Warning: (ae-missing-release-tag) "BankFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface BankFormFields { - // Warning: (ae-forgotten-export) The symbol "AccountNumberField" needs to be exported by the entry point index.d.ts - // - // (undocumented) AccountNumber: typeof AccountNumberField; - // Warning: (ae-forgotten-export) The symbol "AccountTypeField" needs to be exported by the entry point index.d.ts - // - // (undocumented) AccountType: typeof AccountTypeField; - // Warning: (ae-forgotten-export) The symbol "NameField" needs to be exported by the entry point index.d.ts - // - // (undocumented) Name: typeof NameField; - // Warning: (ae-forgotten-export) The symbol "RoutingNumberField" needs to be exported by the entry point index.d.ts - // - // (undocumented) RoutingNumber: typeof RoutingNumberField; } -// Warning: (ae-missing-release-tag) "BankFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BankFormFieldsMetadata = UseBankFormReady['form']['fieldsMetadata']; // Warning: (ae-forgotten-export) The symbol "OptionalFieldsToRequire" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_7" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "BankFormOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type BankFormOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "BankFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BankFormOutputs = BankFormData; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BankFormRequiredValidation = typeof BankFormErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "BankFormSubmitOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface BankFormSubmitOptions { employeeId?: string; } @@ -414,9 +381,10 @@ export interface CardProps { menu?: ReactNode; } -// Warning: (ae-missing-release-tag) "CaseNumberFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function CaseNumberField(props: CaseNumberFieldProps): JSX; + +// @public export type CaseNumberFieldProps = HookFieldProps>; // @public @@ -460,101 +428,71 @@ export interface CheckboxProps extends SharedHorizontalFieldLayoutProps, Pick>; -// Warning: (ae-missing-release-tag) "AmountValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentAmountValidation = ChildSupportGarnishmentRequiredValidation | ChildSupportGarnishmentPercentValidation; // Warning: (ae-forgotten-export) The symbol "fieldValidators_2" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type ChildSupportGarnishmentFormData = { [K in keyof typeof fieldValidators_2]: z.infer<(typeof fieldValidators_2)[K]>; }; -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentFormErrorCode = (typeof ChildSupportGarnishmentFormErrorCodes)[keyof typeof ChildSupportGarnishmentFormErrorCodes]; -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const ChildSupportGarnishmentFormErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly NEGATIVE_AMOUNT: "NEGATIVE_AMOUNT"; readonly PERCENT_OUT_OF_RANGE: "PERCENT_OUT_OF_RANGE"; }; -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface ChildSupportGarnishmentFormFields { - // Warning: (ae-forgotten-export) The symbol "AmountField_2" needs to be exported by the entry point index.d.ts - // - // (undocumented) - Amount: typeof AmountField_2; - // Warning: (ae-forgotten-export) The symbol "CaseNumberField" needs to be exported by the entry point index.d.ts + Amount: typeof ChildSupportAmountField; CaseNumber: typeof CaseNumberField | undefined; - // Warning: (ae-forgotten-export) The symbol "FipsCodeField" needs to be exported by the entry point index.d.ts FipsCode: typeof FipsCodeField | undefined; - // Warning: (ae-forgotten-export) The symbol "OrderNumberField" needs to be exported by the entry point index.d.ts OrderNumber: typeof OrderNumberField | undefined; - // Warning: (ae-forgotten-export) The symbol "PaymentPeriodField" needs to be exported by the entry point index.d.ts - // - // (undocumented) PaymentPeriod: typeof PaymentPeriodField; - // Warning: (ae-forgotten-export) The symbol "PayPeriodMaximumField" needs to be exported by the entry point index.d.ts - // - // (undocumented) PayPeriodMaximum: typeof PayPeriodMaximumField; - // Warning: (ae-forgotten-export) The symbol "RemittanceNumberField" needs to be exported by the entry point index.d.ts RemittanceNumber: typeof RemittanceNumberField | undefined; - // Warning: (ae-forgotten-export) The symbol "StateField" needs to be exported by the entry point index.d.ts - // - // (undocumented) - State: typeof StateField; + State: typeof ChildSupportStateField; } -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentFormFieldsMetadata = UseChildSupportGarnishmentFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "ChildSupportGarnishmentFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentFormOutputs = ChildSupportGarnishmentFormData; -// Warning: (ae-missing-release-tag) "NegativeAmountValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentNegativeAmountValidation = typeof ChildSupportGarnishmentFormErrorCodes.NEGATIVE_AMOUNT; -// Warning: (ae-missing-release-tag) "PercentValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentPercentValidation = typeof ChildSupportGarnishmentFormErrorCodes.PERCENT_OUT_OF_RANGE; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentRequiredValidation = typeof ChildSupportGarnishmentFormErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "StateFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ChildSupportGarnishmentStateFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "CityFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function ChildSupportStateField(props: ChildSupportGarnishmentStateFieldProps): JSX; + +// @public +export function CityField(props: CityFieldProps): JSX; + +// @public export type CityFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "QueryWithError" needs to be exported by the entry point index.d.ts @@ -583,33 +521,11 @@ export interface ComboBoxProps extends SharedFieldLayoutProps, Pick; } +// @public +export function CompensationAdjustForMinimumWageField(props: AdjustForMinimumWageFieldProps): JSX; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "CompensationEditForm" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "CompensationAddJobForm" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "CompensationAddAnotherJobForm" @@ -707,6 +624,16 @@ interface CompensationCardProps { onEvent: OnEventType; } +// Warning: (ae-forgotten-export) The symbol "RequireAtLeastOne" needs to be exported by the entry point index.d.ts +// +// @public +type CompensationDefaultValues = RequireAtLeastOne<{ + rate?: Job['rate']; + title?: Job['title']; + paymentUnit?: (typeof PAY_PERIODS)[keyof typeof PAY_PERIODS]; + flsaStatus?: FlsaStatusType; +}>; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "CompensationCard" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "CompensationEditFormProps" @@ -725,6 +652,9 @@ interface CompensationEditFormProps extends CommonComponentInterface<'Employee.M onEvent: OnEventType; } +// @public +export function CompensationEffectiveDateField(props: CompensationEffectiveDateFieldProps): JSX; + // @public export type CompensationEffectiveDateFieldProps = HookFieldProps>; @@ -749,6 +679,9 @@ export const CompensationErrorCodes: { // @public export type CompensationFieldsMetadata = UseCompensationFormReady['form']['fieldsMetadata']; +// @public +export function CompensationFlsaStatusField(props: FlsaStatusFieldProps): JSX; + // Warning: (ae-forgotten-export) The symbol "fieldValidators_3" needs to be exported by the entry point index.d.ts // // @public @@ -758,30 +691,38 @@ export type CompensationFormData = { // @public export interface CompensationFormFields { - // Warning: (ae-forgotten-export) The symbol "AdjustForMinimumWageField" needs to be exported by the entry point index.d.ts - AdjustForMinimumWage: typeof AdjustForMinimumWageField | undefined; - // Warning: (ae-forgotten-export) The symbol "EffectiveDateField" needs to be exported by the entry point index.d.ts - EffectiveDate: typeof EffectiveDateField | undefined; - // Warning: (ae-forgotten-export) The symbol "FlsaStatusField" needs to be exported by the entry point index.d.ts - FlsaStatus: typeof FlsaStatusField | undefined; - // Warning: (ae-forgotten-export) The symbol "MinimumWageIdField" needs to be exported by the entry point index.d.ts - MinimumWageId: typeof MinimumWageIdField | undefined; - // Warning: (ae-forgotten-export) The symbol "PaymentUnitField" needs to be exported by the entry point index.d.ts - PaymentUnit: typeof PaymentUnitField | undefined; - // Warning: (ae-forgotten-export) The symbol "RateField" needs to be exported by the entry point index.d.ts - Rate: typeof RateField | undefined; - // Warning: (ae-forgotten-export) The symbol "TitleField" needs to be exported by the entry point index.d.ts - Title: typeof TitleField; + AdjustForMinimumWage: typeof CompensationAdjustForMinimumWageField | undefined; + EffectiveDate: typeof CompensationEffectiveDateField | undefined; + FlsaStatus: typeof CompensationFlsaStatusField | undefined; + MinimumWageId: typeof CompensationMinimumWageIdField | undefined; + PaymentUnit: typeof CompensationPaymentUnitField | undefined; + Rate: typeof CompensationRateField | undefined; + Title: typeof CompensationTitleField; } // @public export type CompensationFormOutputs = CompensationFormData; +// @public +export function CompensationMinimumWageIdField(props: MinimumWageIdFieldProps): JSX; + // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_2" needs to be exported by the entry point index.d.ts // // @public export type CompensationOptionalFieldsToRequire = OptionalFieldsToRequire; +// @public +export function CompensationPaymentUnitField(props: PaymentUnitFieldProps): JSX; + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" +// +// @public +interface CompensationProps extends BaseComponentInterface<'Employee.Compensation'> { + defaultValues?: CompensationDefaultValues; + employeeId: string; + startDate: string; +} + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" // // @public @@ -791,6 +732,9 @@ interface CompensationProps_2 extends CommonComponentInterface<'Employee.Managem onEvent: OnEventType; } +// @public +export function CompensationRateField(props: RateFieldProps): JSX; + // @public export type CompensationRequiredValidation = typeof CompensationErrorCodes.REQUIRED; @@ -813,6 +757,11 @@ export interface CompensationSubmitOptions { jobId?: string; } +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TitleFieldProps" +// +// @public +export function CompensationTitleField(props: CompensationTitleFieldProps): JSX; + // @public export type CompensationTitleFieldProps = HookFieldProps>; @@ -1153,6 +1102,9 @@ export function composeSubmitHandler(form [K in keyof TForms]: ComposeSubmitInput; }], onAllValid: () => Promise): ComposeSubmitHandlerResult; +// @public +export function ConfirmSignatureField(props: SignEmployeeFormConfirmSignatureFieldProps): JSX; + // Warning: (ae-missing-release-tag) "ConfirmSignatureFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1181,15 +1133,14 @@ export interface ConfirmWireDetailsProps { wireInId?: string; } -declare namespace Contractor { +// Warning: (ae-forgotten-export) The symbol "ContractorListProps" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ContractorList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +function ContractorList(props: ContractorListProps & BaseComponentInterface): JSX; + +declare namespace ContractorManagement { export { - PaymentMethod, - Address, - ContractorList, - NewHireReport, - ContractorSubmit, - ContractorProfile, - OnboardingFlow_2 as OnboardingFlow, PaymentFlow, PaymentsList, CreatePayment, @@ -1199,19 +1150,13 @@ declare namespace Contractor { } } -// Warning: (ae-forgotten-export) The symbol "ContractorListProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ContractorList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -function ContractorList(props: ContractorListProps & BaseComponentInterface): JSX; - declare namespace ContractorOnboarding { export { - OnboardingFlow_2 as OnboardingFlow, + OnboardingFlow_3 as OnboardingFlow, ContractorList, ContractorProfile, Address, - PaymentMethod, + PaymentMethod_3 as PaymentMethod, NewHireReport, ContractorSubmit } @@ -1243,24 +1188,23 @@ export const ContractorSelfOnboardingStatuses: Set<"self_onboarding_invited" | " // @public (undocumented) function ContractorSubmit(props: ContractorSubmitProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "CountyEntry" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type CountyEntry = { fipsCode: string; county: string | null; }; -// Warning: (ae-missing-release-tag) "CourtesyWithholdingFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function CourtesyWithholdingField(props: CourtesyWithholdingFieldProps): JSX; + +// @public export type CourtesyWithholdingFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "BankFormSchemaOptions" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "BuildFormSchemaResult" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createBankFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createBankFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createBankFormSchema(options?: BankFormSchemaOptions): BuildFormSchemaResult< { name: z.ZodString; routingNumber: z.ZodString; @@ -1272,9 +1216,9 @@ Savings: "Savings"; }>; // Warning: (ae-forgotten-export) The symbol "ChildSupportGarnishmentFormSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createChildSupportGarnishmentFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createChildSupportGarnishmentFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createChildSupportGarnishmentFormSchema(input?: ChildSupportGarnishmentFormSchemaOptions): BuildFormSchemaResult< { state: z.ZodString; fipsCode: z.ZodString; @@ -1318,9 +1262,9 @@ minimumWageId: z.ZodString; }>; // Warning: (ae-forgotten-export) The symbol "DeductionFormSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createDeductionFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createDeductionFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createDeductionFormSchema(options: DeductionFormSchemaOptions): BuildFormSchemaResult< { description: z.ZodString; recurring: z.ZodPipe, z.ZodBoolean>; @@ -1340,9 +1284,9 @@ readonly OtherGarnishment: "other_garnishment"; }>; // Warning: (ae-forgotten-export) The symbol "EmployeeDetailsSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createEmployeeDetailsSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createEmployeeDetailsSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createEmployeeDetailsSchema(options?: EmployeeDetailsSchemaOptions): BuildFormSchemaResult< { firstName: z.ZodString; middleInitial: z.ZodString; @@ -1360,9 +1304,9 @@ selfOnboarding: z.ZodBoolean; export function createEmployeeStateTaxesSchema(employeeStateTaxes: EmployeeStateTaxesList[], options?: EmployeeStateTaxesSchemaOptions): EmployeeStateTaxesSchemaResult; // Warning: (ae-forgotten-export) The symbol "FederalTaxesSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createFederalTaxesSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createFederalTaxesSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createFederalTaxesSchema(options?: FederalTaxesSchemaOptions): BuildFormSchemaResult< { filingStatus: z.ZodString; twoJobs: z.ZodPipe, z.ZodBoolean>; @@ -1373,9 +1317,9 @@ extraWithholding: z.ZodPipe, z.ZodNumber>; }>; // Warning: (ae-forgotten-export) The symbol "HomeAddressSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createHomeAddressSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createHomeAddressSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createHomeAddressSchema(options?: HomeAddressSchemaOptions): BuildFormSchemaResult< { street1: z.ZodString; street2: z.ZodString; @@ -1405,9 +1349,9 @@ stateWcClassCode: z.ZodString; function CreatePayment(props: CreatePaymentProps): JSX; // Warning: (ae-forgotten-export) The symbol "PaymentMethodFormSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createPaymentMethodFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createPaymentMethodFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createPaymentMethodFormSchema(options?: PaymentMethodFormSchemaOptions): BuildFormSchemaResult< { type: z.ZodEnum<{ Check: "Check"; @@ -1450,9 +1394,9 @@ confirmSignature: z.ZodBoolean; }>; // Warning: (ae-forgotten-export) The symbol "SignEmployeeFormSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createSignEmployeeFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createSignEmployeeFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createSignEmployeeFormSchema(options?: SignEmployeeFormSchemaOptions): BuildFormSchemaResult< { signature: z.ZodString; confirmSignature: z.ZodBoolean; @@ -1499,9 +1443,9 @@ preparer4Agree: z.ZodBoolean; }>; // Warning: (ae-forgotten-export) The symbol "SplitPaymentsFormSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createSplitPaymentsFormSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createSplitPaymentsFormSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createSplitPaymentsFormSchema(options?: SplitPaymentsFormSchemaOptions): BuildFormSchemaResult< { splitBy: z.ZodEnum<{ Percentage: "Percentage"; @@ -1511,32 +1455,31 @@ splitAmount: z.ZodRecord priority: z.ZodRecord; }>; -// Warning: (ae-missing-release-tag) "createStateFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createStateFields" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createStateFields(employeeStateTaxes: EmployeeStateTaxesList[], options: CreateStateFieldsOptions): StateTaxFieldsGroup[]; -// Warning: (ae-missing-release-tag) "CreateStateFieldsOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "CreateStateFieldsOptions" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export interface CreateStateFieldsOptions { // (undocumented) isAdmin: boolean; } // Warning: (ae-forgotten-export) The symbol "WorkAddressSchemaOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createWorkAddressSchema" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "createWorkAddressSchema" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function createWorkAddressSchema(options?: WorkAddressSchemaOptions): BuildFormSchemaResult< { locationUuid: z.ZodString; effectiveDate: z.ZodISODate; }>; // Warning: (ae-forgotten-export) The symbol "BaseStateTaxFieldProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "CurrencyStateTaxFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type CurrencyStateTaxFieldProps = BaseStateTaxFieldProps & { FieldComponent?: ComponentType; }; @@ -1551,6 +1494,9 @@ export type CustomNameFieldProps = HookFieldProps>; +// @internal (undocumented) +function Dashboard(input: DashboardProps & BaseComponentInterface): JSX; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" @@ -1574,9 +1520,20 @@ interface DashboardFlowProps extends BaseComponentInterface { employeeId: string; } -// Warning: (ae-missing-release-tag) "DateOfBirthFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @internal (undocumented) +interface DashboardProps extends BaseComponentInterface<'Employee.Dashboard'> { + // (undocumented) + employeeId: string; + // Warning: (ae-forgotten-export) The symbol "DashboardTab" needs to be exported by the entry point index.d.ts + // + // (undocumented) + selectedTab?: DashboardTab; +} + +// @public +export function DateOfBirthField(props: DateOfBirthFieldProps): JSX; + +// @public export type DateOfBirthFieldProps = HookFieldProps>; // Warning: (ae-internal-missing-underscore) The name "DatePickerHookField" should be prefixed with an underscore because the declaration is marked as @internal @@ -1627,9 +1584,7 @@ export interface DateRangePickerProps { value: DateRange | null; } -// Warning: (ae-missing-release-tag) "DateStateTaxFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DateStateTaxFieldProps = BaseStateTaxFieldProps & { FieldComponent?: ComponentType; }; @@ -1649,166 +1604,146 @@ export type Day2FieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "AmountFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "AmountFieldProps" // -// @public (undocumented) +// @public +export function DeductionAmountField(props: DeductionAmountFieldProps): JSX; + +// @public export type DeductionAmountFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "AmountValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormAmountValidation = DeductionFormRequiredValidation | DeductionFormNegativeAmountValidation; -// Warning: (ae-missing-release-tag) "CapValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormCapValidation = DeductionFormNegativeAmountValidation; // Warning: (ae-forgotten-export) The symbol "fieldValidators" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "DeductionFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type DeductionFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]>; }; -// Warning: (ae-missing-release-tag) "DeductionFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormErrorCode = (typeof DeductionFormErrorCodes)[keyof typeof DeductionFormErrorCodes]; -// Warning: (ae-missing-release-tag) "DeductionFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const DeductionFormErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly NEGATIVE_AMOUNT: "NEGATIVE_AMOUNT"; }; -// Warning: (ae-missing-release-tag) "DeductionFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface DeductionFormFields { - // Warning: (ae-forgotten-export) The symbol "AmountField" needs to be exported by the entry point index.d.ts - // - // (undocumented) - Amount: typeof AmountField; - // Warning: (ae-forgotten-export) The symbol "AnnualMaximumField" needs to be exported by the entry point index.d.ts + Amount: typeof DeductionAmountField; AnnualMaximum: typeof AnnualMaximumField | undefined; - // Warning: (ae-forgotten-export) The symbol "DeductAsPercentageField" needs to be exported by the entry point index.d.ts - // - // (undocumented) DeductAsPercentage: typeof DeductAsPercentageField; - // Warning: (ae-forgotten-export) The symbol "DescriptionField" needs to be exported by the entry point index.d.ts - // - // (undocumented) Description: typeof DescriptionField; - // Warning: (ae-forgotten-export) The symbol "GarnishmentTypeField" needs to be exported by the entry point index.d.ts GarnishmentType: typeof GarnishmentTypeField | undefined; - // Warning: (ae-forgotten-export) The symbol "RecurringField" needs to be exported by the entry point index.d.ts - // - // (undocumented) Recurring: typeof RecurringField; - // Warning: (ae-forgotten-export) The symbol "TotalAmountField" needs to be exported by the entry point index.d.ts TotalAmount: typeof TotalAmountField | undefined; } -// Warning: (ae-missing-release-tag) "DeductionFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormFieldsMetadata = UseDeductionFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "NegativeAmountValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormNegativeAmountValidation = typeof DeductionFormErrorCodes.NEGATIVE_AMOUNT; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "DeductionFormOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type DeductionFormOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "DeductionFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormOutputs = DeductionFormData; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type DeductionFormRequiredValidation = typeof DeductionFormErrorCodes.REQUIRED; -// Warning: (ae-forgotten-export) The symbol "DeductionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Deductions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsProps" // -// @public (undocumented) +// @public function Deductions(input: DeductionsProps): JSX; -// Warning: (ae-missing-release-tag) "Deductions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsCard" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsEditForm" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsProps" // -// @public (undocumented) +// @public function Deductions_2(input: DeductionsProps_2 & BaseComponentInterface<'Employee.Management.Deductions'>): JSX; -// Warning: (ae-missing-release-tag) "DeductionsCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsEditForm" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsCardProps" // // @public function DeductionsCard(props: DeductionsCardProps): JSX; -// Warning: (ae-missing-release-tag) "DeductionsCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsCard" // -// @public (undocumented) +// @public interface DeductionsCardProps { - // (undocumented) employeeId: string; - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsCard" onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "DeductionsEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsEditFormProps" // // @public function DeductionsEditForm(input: DeductionsEditFormProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "DeductionsEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsEditForm" // -// @public (undocumented) +// @public interface DeductionsEditFormProps extends CommonComponentInterface<'Employee.Management.Deductions'> { editingDeductionId?: string; - // (undocumented) employeeId: string; - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DeductionsEditForm" onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "DeductionsFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function DeductionsField(props: DeductionsFieldProps): JSX; + +// @public export type DeductionsFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "DeductionsProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" // -// @public (undocumented) +// @public +interface DeductionsProps extends BaseComponentInterface<'Employee.Deductions'> { + employeeId: string; +} + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" +// +// @public interface DeductionsProps_2 extends CommonComponentInterface<'Employee.Management.Deductions'> { - // (undocumented) employeeId: string; - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "DependentsAmountFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function DependentsAmountField(props: DependentsAmountFieldProps): JSX; + +// @public export type DependentsAmountFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "DescriptionFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function DescriptionField(props: DescriptionFieldProps): JSX; + +// @public export type DescriptionFieldProps = HookFieldProps>; // @public @@ -1866,20 +1801,33 @@ interface DismissalFlowProps { payrollId?: string; } +// Warning: (ae-missing-release-tag) "DismissalPayPeriodSelection" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +function DismissalPayPeriodSelection(props: DismissalPayPeriodSelectionProps): JSX; + +// Warning: (ae-missing-release-tag) "DismissalPayPeriodSelectionProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface DismissalPayPeriodSelectionProps extends BaseComponentInterface<'Payroll.Dismissal'> { + // (undocumented) + companyId: string; + // (undocumented) + employeeId?: string; + // (undocumented) + payrollId?: string; +} + // Warning: (ae-forgotten-export) The symbol "DocumentListProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "DocumentList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function DocumentList(props: DocumentListProps): JSX; -// Warning: (ae-missing-release-tag) "DocumentManager" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public +// @internal function DocumentManager(props: DocumentManagerProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "DocumentManagerProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @internal (undocumented) interface DocumentManagerProps { // (undocumented) employeeId: string; @@ -1887,31 +1835,29 @@ interface DocumentManagerProps { formId: string; } -// Warning: (ae-missing-release-tag) "Documents" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentsProps" // -// @public (undocumented) +// @public function Documents(input: DocumentsProps & BaseComponentInterface<'Employee.Management.Documents'>): JSX; -// Warning: (ae-missing-release-tag) "DocumentsCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "useDocumentsList" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentsCardProps" // // @public function DocumentsCard(props: DocumentsCardProps): JSX; -// Warning: (ae-missing-release-tag) "DocumentsCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentsCard" // -// @public (undocumented) +// @public interface DocumentsCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-forgotten-export) The symbol "DocumentSignerProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "DocumentSigner" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Form" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentSignerProps" // -// @public (undocumented) +// @public function DocumentSigner(props: DocumentSignerProps): JSX; // Warning: (ae-forgotten-export) The symbol "DocumentSignerProps_2" needs to be exported by the entry point index.d.ts @@ -1920,83 +1866,61 @@ function DocumentSigner(props: DocumentSignerProps): JSX; // @public (undocumented) function DocumentSigner_2(props: DocumentSignerProps_2): JSX; -// Warning: (ae-missing-release-tag) "DocumentsProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentSigner" // -// @public (undocumented) +// @public +interface DocumentSignerProps extends BaseComponentInterface<'Employee.DocumentSigner'> { + employeeId: string; + withEmployeeI9?: boolean; +} + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Documents" +// +// @public interface DocumentsProps extends CommonComponentInterface<'Employee.Management.Documents'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "EffectiveDateFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EditCompensationProps" // -// @public (undocumented) -export type EffectiveDateFieldProps = HookFieldProps>; +// @public +function EditCompensation(input: EditCompensationProps): JSX; -// Warning: (ae-missing-release-tag) "EmailFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EditCompensation" // -// @public (undocumented) +// @public +interface EditCompensationProps extends CommonComponentInterface<'Employee.Compensation'> { + currentJobId?: string | null; + employeeId: string; + onCancel?: () => void; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EditCompensation" + onEvent: OnEventType; + partnerDefaultValues?: CompensationDefaultValues; + startDate?: string; + submitCtaLabel: string; + title: string; +} + +// @public +export type EffectiveDateFieldProps = HookFieldProps>; + +// @public +export function EmailField(props: EmailFieldProps): JSX; + +// @public export type EmailFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "EmailValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmailValidation = (typeof EmployeeDetailsErrorCodes)['REQUIRED' | 'INVALID_EMAIL' | 'EMAIL_REQUIRED_FOR_SELF_ONBOARDING']; -declare namespace Employee { - export { - EmployeeList, - Deductions, - OnboardingSummary, - Profile, - Compensation_2 as Compensation, - FederalTaxes_2 as FederalTaxes, - FederalTaxesProps_2 as FederalTaxesProps, - StateTaxes_2 as StateTaxes, - PaymentMethod_2 as PaymentMethod, - Landing, - DocumentSigner_2 as DocumentSigner, - OnboardingFlow_3 as OnboardingFlow, - OnboardingExecutionFlow, - OnboardingExecutionFlowProps, - OnboardingExecutionInitialState, - SelfOnboardingFlow, - EmployeeDocuments, - DashboardFlow, - DashboardFlowProps, - EmployeeListFlow, - EmployeeListFlowProps, - HomeAddress, - HomeAddressProps, - EmploymentEligibility, - EmploymentEligibilityProps, - TerminateEmployee, - TerminateEmployeeProps, - TerminationSummary, - TerminationSummaryProps, - TerminationFlow, - TerminationFlowProps, - PayrollOption, - WorkAddress, - WorkAddressProps - } -} - -// Warning: (ae-missing-release-tag) "EmployeeAction" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeAction = 'edit' | 'delete' | 'cancel_self_onboarding' | 'review' | 'dismiss' | 'rehire'; -// Warning: (ae-missing-release-tag) "EmployeeDetailsErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeDetailsErrorCode = (typeof EmployeeDetailsErrorCodes)[keyof typeof EmployeeDetailsErrorCodes]; -// Warning: (ae-missing-release-tag) "EmployeeDetailsErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const EmployeeDetailsErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly INVALID_NAME: "INVALID_NAME"; @@ -2006,84 +1930,91 @@ export const EmployeeDetailsErrorCodes: { }; // Warning: (ae-forgotten-export) The symbol "fieldValidators_5" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EmployeeDetailsField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type EmployeeDetailsField = Exclude; -// Warning: (ae-missing-release-tag) "EmployeeDetailsFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export interface EmployeeDetailsFields { + DateOfBirth: typeof DateOfBirthField; + Email: typeof EmailField; + FirstName: typeof FirstNameField; + LastName: typeof LastNameField; + MiddleInitial: typeof MiddleInitialField; + SelfOnboarding: typeof SelfOnboardingField | undefined; + Ssn: typeof SsnField; +} + +// @public export type EmployeeDetailsFieldsMetadata = UseEmployeeDetailsFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "EmployeeDetailsFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeDetailsFormData = { [K in keyof typeof fieldValidators_5]: z.infer<(typeof fieldValidators_5)[K]>; }; -// Warning: (ae-missing-release-tag) "EmployeeDetailsFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeDetailsFormFields = UseEmployeeDetailsFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "EmployeeDetailsFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeDetailsFormOutputs = EmployeeDetailsFormData; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_4" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EmployeeDetailsOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type EmployeeDetailsOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeDetailsRequiredValidation = typeof EmployeeDetailsErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "EmployeeDetailsSubmitCallbacks" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface EmployeeDetailsSubmitCallbacks { - // (undocumented) - onEmployeeCreated?: (employee: Employee_2) => void; - // (undocumented) - onEmployeeUpdated?: (employee: Employee_2) => void; - // (undocumented) + onEmployeeCreated?: (employee: Employee) => void; + onEmployeeUpdated?: (employee: Employee) => void; onOnboardingStatusUpdated?: (status: unknown) => void; } -// Warning: (ae-forgotten-export) The symbol "EmployeeDocumentsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EmployeeDocuments" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public function EmployeeDocuments(props: EmployeeDocumentsProps): JSX; -// Warning: (ae-forgotten-export) The symbol "EmployeeListProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EmployeeList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeDocuments" // -// @public (undocumented) +// @public +interface EmployeeDocumentsProps extends BaseComponentInterface<'Employee.EmployeeDocuments'> { + employeeId: string; + onEvent: OnEventType; +} + +// @public function EmployeeList(input: EmployeeListProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "EmployeeListFlow" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DashboardFlow" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlow" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeListFlowProps" // -// @public (undocumented) +// @public const EmployeeListFlow: (input: EmployeeListFlowProps) => JSX; -// Warning: (ae-missing-release-tag) "EmployeeListFlowProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeListFlow" // -// @public (undocumented) +// @public interface EmployeeListFlowProps extends BaseComponentInterface { - // (undocumented) + companyId: string; +} + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeList" +// +// @public +interface EmployeeListProps extends BaseComponentInterface<'Employee.EmployeeList'> { companyId: string; } declare namespace EmployeeManagement { export { ManagementEmployeeList as EmployeeList, + ManagementEmployeeListProps, + EmployeeTab, EmployeeListFlow, EmployeeListFlowProps, Documents, @@ -2093,7 +2024,9 @@ declare namespace EmployeeManagement { DocumentsCardProps, DocumentManagerProps, DashboardFlow, + Dashboard, DashboardFlowProps, + DashboardProps, HomeAddress, HomeAddressCard, HomeAddressEditForm, @@ -2124,8 +2057,8 @@ declare namespace EmployeeManagement { ProfileProps_2 as ProfileProps, ProfileCardProps, ProfileEditFormProps, - PaymentMethod_3 as PaymentMethod, - PaymentMethodProps_3 as PaymentMethodProps, + PaymentMethod_2 as PaymentMethod, + PaymentMethodProps_2 as PaymentMethodProps, PaymentMethodCard, PaymentMethodCardProps, PaymentMethodBankForm, @@ -2151,33 +2084,52 @@ declare namespace EmployeeManagement { CompensationAddJobFormProps, CompensationAddAnotherJobFormProps, TerminateEmployee, + TerminateEmployeeProps, TerminationSummary, - TerminationFlow + TerminationSummaryProps, + TerminationFlow, + TerminationFlowProps, + PayrollOption } } declare namespace EmployeeOnboarding { export { - OnboardingFlow_3 as OnboardingFlow, + OnboardingFlow, + OnboardingFlowProps, OnboardingExecutionFlow, OnboardingExecutionFlowProps, OnboardingExecutionInitialState, + OnboardingDefaultValues, SelfOnboardingFlow, EmployeeList, + EmployeeListProps, OnboardingSummary, Landing, - DocumentSigner_2 as DocumentSigner, + DocumentSigner, + DocumentSignerProps, EmploymentEligibility, + EmploymentEligibilityProps, EmployeeDocuments, + EmployeeDocumentsProps, Profile, + ProfileProps, + ProfileDefaultValues, Compensation_2 as Compensation, - FederalTaxes_3 as FederalTaxes, - FederalTaxesProps_3 as FederalTaxesProps, - StateTaxes_3 as StateTaxes, - StateTaxesProps_3 as StateTaxesProps, + CompensationProps, + CompensationDefaultValues, + JobsList, + JobsListProps, + EditCompensation, + EditCompensationProps, + FederalTaxes, + FederalTaxesProps, + StateTaxes, + StateTaxesProps, Deductions, - PaymentMethod_2 as PaymentMethod, - PaymentMethodProps_2 as PaymentMethodProps + DeductionsProps, + PaymentMethod, + PaymentMethodProps } } @@ -2196,9 +2148,7 @@ export const EmployeeOnboardingStatus: { // @public export const EmployeeSelfOnboardingStatuses: Set<"self_onboarding_invited" | "self_onboarding_invited_started" | "self_onboarding_invited_overdue">; -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeStateTaxesErrorCode = (typeof EmployeeStateTaxesErrorCodes)[keyof typeof EmployeeStateTaxesErrorCodes]; // @public @@ -2206,33 +2156,24 @@ export const EmployeeStateTaxesErrorCodes: { readonly REQUIRED: "REQUIRED"; }; -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeStateTaxesFieldsMetadata = UseEmployeeStateTaxesFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface EmployeeStateTaxesFormData { - // (undocumented) states: Record>; } -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeStateTaxesFormFields = UseEmployeeStateTaxesFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EmployeeStateTaxesFormOutputs = EmployeeStateTaxesFormData; // Warning: (ae-forgotten-export) The symbol "FieldsMetadataConfig" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesMetadataConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "EmployeeStateTaxesMetadataConfig" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export interface EmployeeStateTaxesMetadataConfig extends FieldsMetadataConfig> { groups: Array<{ state: string; @@ -2241,9 +2182,9 @@ export interface EmployeeStateTaxesMetadataConfig extends FieldsMetadataConfig; } -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesQuestionMeta" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "EmployeeStateTaxesQuestionMeta" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export interface EmployeeStateTaxesQuestionMeta { // (undocumented) apiKey: string; @@ -2261,199 +2202,158 @@ export interface EmployeeStateTaxesQuestionMeta { variant: StateTaxQuestionVariant; } -// Warning: (ae-missing-release-tag) "EmployeeStateTaxesSchemaOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "EmployeeStateTaxesSchemaOptions" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export interface EmployeeStateTaxesSchemaOptions { // (undocumented) isAdmin?: boolean; } -// Warning: (ae-missing-release-tag) "EmployeeType" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ManagementEmployeeList" // -// @public (undocumented) +// @public +type EmployeeTab = 'active' | 'onboarding' | 'dismissed'; + +// @public export type EmployeeType = 'active' | 'onboarding' | 'terminated'; -// Warning: (ae-missing-release-tag) "EmployeeWithActions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface EmployeeWithActions extends Employee_2 { - // (undocumented) +// @public +export interface EmployeeWithActions extends Employee { allowedActions: EmployeeAction[]; - // (undocumented) primaryJob?: Job; } -// Warning: (ae-missing-release-tag) "EmploymentEligibility" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmploymentEligibilityProps" // -// @public (undocumented) +// @public function EmploymentEligibility(props: EmploymentEligibilityProps): JSX; -// Warning: (ae-missing-release-tag) "EmploymentEligibilityProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmploymentEligibility" // -// @public (undocumented) +// @public interface EmploymentEligibilityProps extends BaseComponentInterface<'Employee.EmploymentEligibility'> { - // (undocumented) employeeId: string; } // @public export type EventType = (typeof componentEvents)[keyof typeof componentEvents]; -// Warning: (ae-missing-release-tag) "ExtraWithholdingFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function ExtraWithholdingField(props: ExtraWithholdingFieldProps): JSX; + +// @public export type ExtraWithholdingFieldProps = HookFieldProps>; -// Warning: (ae-forgotten-export) The symbol "FederalTaxesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "FederalTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesProps" // -// @public (undocumented) -function FederalTaxes(props: FederalTaxesProps & BaseComponentInterface): JSX; +// @public +function FederalTaxes(input: FederalTaxesProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "FederalTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesCard" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesEditForm" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesProps" // -// @public (undocumented) +// @public function FederalTaxes_2(input: FederalTaxesProps_2 & BaseComponentInterface<'Employee.Management.FederalTaxes'>): JSX; +// Warning: (ae-forgotten-export) The symbol "FederalTaxesProps_3" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "FederalTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -function FederalTaxes_3(input: FederalTaxesProps_3 & Pick): JSX; +function FederalTaxes_3(props: FederalTaxesProps_3 & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "FederalTaxesCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public function FederalTaxesCard(props: FederalTaxesCardProps): JSX; -// Warning: (ae-missing-release-tag) "FederalTaxesCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesCard" // -// @public (undocumented) +// @public interface FederalTaxesCardProps { - // (undocumented) employeeId: string; - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesCard" onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "FederalTaxesEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesCard" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesEditFormProps" // -// @public (undocumented) +// @public function FederalTaxesEditForm(input: FederalTaxesEditFormProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "FederalTaxesEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesEditForm" // -// @public (undocumented) +// @public interface FederalTaxesEditFormProps extends CommonComponentInterface<'Employee.Management.FederalTaxes'> { - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxesEditForm" onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "FederalTaxesErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesErrorCode = (typeof FederalTaxesErrorCodes)[keyof typeof FederalTaxesErrorCodes]; -// Warning: (ae-missing-release-tag) "FederalTaxesErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const FederalTaxesErrorCodes: { readonly REQUIRED: "REQUIRED"; }; // Warning: (ae-forgotten-export) The symbol "fieldValidators_11" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "FederalTaxesField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type FederalTaxesField = keyof typeof fieldValidators_11; -// Warning: (ae-missing-release-tag) "FederalTaxesFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface FederalTaxesFields { - // Warning: (ae-forgotten-export) The symbol "DeductionsField" needs to be exported by the entry point index.d.ts - // - // (undocumented) Deductions: typeof DeductionsField; - // Warning: (ae-forgotten-export) The symbol "DependentsAmountField" needs to be exported by the entry point index.d.ts - // - // (undocumented) DependentsAmount: typeof DependentsAmountField; - // Warning: (ae-forgotten-export) The symbol "ExtraWithholdingField" needs to be exported by the entry point index.d.ts - // - // (undocumented) ExtraWithholding: typeof ExtraWithholdingField; - // Warning: (ae-forgotten-export) The symbol "FilingStatusField" needs to be exported by the entry point index.d.ts - // - // (undocumented) FilingStatus: typeof FilingStatusField; - // Warning: (ae-forgotten-export) The symbol "OtherIncomeField" needs to be exported by the entry point index.d.ts - // - // (undocumented) OtherIncome: typeof OtherIncomeField; - // Warning: (ae-forgotten-export) The symbol "TwoJobsField" needs to be exported by the entry point index.d.ts - // - // (undocumented) TwoJobs: typeof TwoJobsField; } -// Warning: (ae-missing-release-tag) "FederalTaxesFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesFieldsMetadata = UseFederalTaxesFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "FederalTaxesFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesFormData = { [K in keyof typeof fieldValidators_11]: z.infer<(typeof fieldValidators_11)[K]>; }; -// Warning: (ae-missing-release-tag) "FederalTaxesFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesFormFields = UseFederalTaxesFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "FederalTaxesFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesFormOutputs = FederalTaxesFormData; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_10" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "FederalTaxesOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type FederalTaxesOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "FederalTaxesProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" // -// @public (undocumented) -interface FederalTaxesProps_2 extends CommonComponentInterface<'Employee.Management.FederalTaxes'> { - // (undocumented) +// @public +interface FederalTaxesProps extends CommonComponentInterface<'Employee.FederalTaxes'> { + defaultValues?: Partial; employeeId: string; - // (undocumented) - onEvent: OnEventType; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" + onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "FederalTaxesProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" // -// @public (undocumented) -interface FederalTaxesProps_3 extends CommonComponentInterface<'Employee.FederalTaxes'> { - // (undocumented) - defaultValues?: Partial; - // (undocumented) +// @public +interface FederalTaxesProps_2 extends CommonComponentInterface<'Employee.Management.FederalTaxes'> { employeeId: string; - // (undocumented) - onEvent: BaseComponentInterface['onEvent']; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" + onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FederalTaxesRequiredValidation = typeof FederalTaxesErrorCodes.REQUIRED; // @public @@ -2493,29 +2393,28 @@ export interface FileInputProps extends Omit>; -// Warning: (ae-missing-release-tag) "FilingStatusValue" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FilingStatusValue = (typeof FILING_STATUS_VALUES)[number]; -// Warning: (ae-missing-release-tag) "FipsCodeFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function FipsCodeField(props: FipsCodeFieldProps): JSX; + +// @public export type FipsCodeFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "FirstNameFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function FirstNameField(props: FirstNameFieldProps): JSX; + +// @public export type FirstNameFieldProps = HookFieldProps>; // @public @@ -2556,9 +2455,10 @@ export type FormHookResult = { // @public (undocumented) export type FrequencyFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "GarnishmentTypeFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function GarnishmentTypeField(props: GarnishmentTypeFieldProps): JSX; + +// @public export type GarnishmentTypeFieldProps = HookFieldProps>; // Warning: (ae-internal-missing-underscore) The name "getQuestionVariant" should be prefixed with an underscore because the declaration is marked as @internal @@ -2566,9 +2466,9 @@ export type GarnishmentTypeFieldProps = HookFieldProps; // @public @@ -2578,9 +2478,6 @@ export interface GustoApiProps extends Omit { queryClient?: QueryClient; } -// @public @deprecated -export const GustoApiProvider: default_2.FC; - // @public export const GustoProvider: default_2.FC; @@ -2692,6 +2589,9 @@ export interface HeadingProps extends Pick, ' textAlign?: 'start' | 'center' | 'end'; } +// @public +export function HireDateField(props: HireDateFieldProps): JSX; + // @public export type HireDateFieldProps = HookFieldProps>; @@ -2757,114 +2657,106 @@ interface HolidaySelectionFormProps extends BaseComponentInterface { mode?: 'create' | 'edit'; } -// Warning: (ae-missing-release-tag) "HomeAddress" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" // -// @public (undocumented) +// @public function HomeAddress(input: HomeAddressProps & BaseComponentInterface<'Employee.Management.HomeAddress'>): JSX; -// Warning: (ae-missing-release-tag) "HomeAddressCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public function HomeAddressCard(props: HomeAddressCardProps): JSX; -// Warning: (ae-missing-release-tag) "HomeAddressCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "HomeAddressCard" // -// @public (undocumented) +// @public interface HomeAddressCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "HomeAddressEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" // -// @public (undocumented) +// @public function HomeAddressEditForm(input: HomeAddressEditFormProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "HomeAddressEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "HomeAddressEditForm" // -// @public (undocumented) +// @public interface HomeAddressEditFormProps extends CommonComponentInterface<'Employee.Management.HomeAddress'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "EffectiveDateFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function HomeAddressEffectiveDateField(props: HomeAddressEffectiveDateFieldProps): JSX; + +// @public export type HomeAddressEffectiveDateFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "HomeAddressErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type HomeAddressErrorCode = (typeof HomeAddressErrorCodes)[keyof typeof HomeAddressErrorCodes]; -// Warning: (ae-missing-release-tag) "HomeAddressErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const HomeAddressErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly INVALID_ZIP: "INVALID_ZIP"; }; // Warning: (ae-forgotten-export) The symbol "fieldValidators_7" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "HomeAddressField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type HomeAddressField = keyof typeof fieldValidators_7; -// Warning: (ae-missing-release-tag) "HomeAddressFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export interface HomeAddressFields { + City: typeof CityField; + CourtesyWithholding: typeof CourtesyWithholdingField; + EffectiveDate: typeof HomeAddressEffectiveDateField | undefined; + State: typeof HomeAddressStateField; + Street1: typeof Street1Field; + Street2: typeof Street2Field; + Zip: typeof ZipField; +} + +// @public export type HomeAddressFieldsMetadata = UseHomeAddressFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "HomeAddressFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type HomeAddressFormData = { [K in keyof typeof fieldValidators_7]: z.infer<(typeof fieldValidators_7)[K]>; }; -// Warning: (ae-missing-release-tag) "HomeAddressFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type HomeAddressFormFields = UseHomeAddressFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "HomeAddressFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type HomeAddressFormOutputs = HomeAddressFormData; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_6" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "HomeAddressOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type HomeAddressOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "HomeAddressProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "HomeAddress" // -// @public (undocumented) +// @public interface HomeAddressProps extends CommonComponentInterface<'Employee.Management.HomeAddress'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type HomeAddressRequiredValidation = typeof HomeAddressErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "HomeAddressSubmitOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function HomeAddressStateField(props: StateFieldProps): JSX; + +// @public export interface HomeAddressSubmitOptions { effectiveDate?: string; - // (undocumented) employeeId?: string; } @@ -2966,15 +2858,10 @@ export type JobFormData = { // @public export interface JobFormFields { - // Warning: (ae-forgotten-export) The symbol "HireDateField" needs to be exported by the entry point index.d.ts HireDate: typeof HireDateField | undefined; - // Warning: (ae-forgotten-export) The symbol "StateWcClassCodeField" needs to be exported by the entry point index.d.ts StateWcClassCode: typeof StateWcClassCodeField | undefined; - // Warning: (ae-forgotten-export) The symbol "StateWcCoveredField" needs to be exported by the entry point index.d.ts StateWcCovered: typeof StateWcCoveredField | undefined; - // Warning: (ae-forgotten-export) The symbol "JobTitleField" needs to be exported by the entry point index.d.ts Title: typeof JobTitleField | undefined; - // Warning: (ae-forgotten-export) The symbol "TwoPercentShareholderField" needs to be exported by the entry point index.d.ts TwoPercentShareholder: typeof TwoPercentShareholderField | undefined; } @@ -2989,24 +2876,35 @@ export type JobOptionalFieldsToRequire = OptionalFieldsToRequire { + employeeId: string; +} + // @public export interface JobSubmitOptions { employeeId?: string; hireDate?: string; } +// @public +export function JobTitleField(props: JobTitleFieldProps): JSX; + // @public export type JobTitleFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "SummaryProps_2" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Landing" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public function Landing(props: SummaryProps_2 & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "LastNameFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function LastNameField(props: LastNameFieldProps): JSX; + +// @public export type LastNameFieldProps = HookFieldProps>; // @public @@ -3068,9 +2966,7 @@ export interface LoadingSpinnerProps extends Pick style?: 'inline' | 'block'; } -// Warning: (ae-missing-release-tag) "LocationFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type LocationFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "LocationFormProps" needs to be exported by the entry point index.d.ts @@ -3085,15 +2981,19 @@ function LocationForm(input: LocationFormProps & BaseComponentInterface): JSX; // @public (undocumented) function Locations(input: LocationsProps): JSX; -// Warning: (ae-forgotten-export) The symbol "ManagementEmployeeListProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ManagementEmployeeList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public function ManagementEmployeeList(input: ManagementEmployeeListProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "MAX_PREPARERS" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ManagementEmployeeList" // -// @public (undocumented) +// @public +interface ManagementEmployeeListProps extends CommonComponentInterface<'Employee.ManagementEmployeeList'> { + companyId: string; + initialTab?: EmployeeTab; + onEvent: BaseComponentInterface['onEvent']; +} + +// @public export const MAX_PREPARERS = 4; // Warning: (ae-forgotten-export) The symbol "DataAttributes" needs to be exported by the entry point index.d.ts @@ -3118,9 +3018,10 @@ export interface MenuProps extends DataAttributes { triggerRef?: RefObject; } -// Warning: (ae-missing-release-tag) "MiddleInitialFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function MiddleInitialField(props: MiddleInitialFieldProps): JSX; + +// @public export type MiddleInitialFieldProps = HookFieldProps>; // @public @@ -3162,14 +3063,13 @@ export interface MultiSelectComboBoxProps extends SharedFieldLayoutProps, Pick>; -// Warning: (ae-missing-release-tag) "NameValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type NameValidation = (typeof EmployeeDetailsErrorCodes)['REQUIRED' | 'INVALID_NAME']; // Warning: (ae-forgotten-export) The symbol "NewHireReportProps" needs to be exported by the entry point index.d.ts @@ -3216,9 +3116,7 @@ export interface NumberInputProps extends SharedFieldLayoutProps, Pick; }; @@ -3405,47 +3303,63 @@ interface OffCycleReasonSelectionProps extends BaseComponentInterface<'Payroll.O companyId: string; } -// Warning: (ae-missing-release-tag) "OnboardingExecutionFlow" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" // -// @public (undocumented) +// @public +type OnboardingDefaultValues = RequireAtLeastOne<{ + profile?: ProfileDefaultValues; + compensation?: CompensationDefaultValues; +}>; + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingFlow" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "SelfOnboardingFlow" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethod" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeDocuments" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingSummary" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingExecutionFlowProps" +// +// @public function OnboardingExecutionFlow(input: OnboardingExecutionFlowProps): JSX; -// Warning: (ae-missing-release-tag) "OnboardingExecutionFlowProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingExecutionFlow" // -// @public (undocumented) +// @public interface OnboardingExecutionFlowProps { - // (undocumented) companyId: string; - // Warning: (ae-forgotten-export) The symbol "OnboardingDefaultValues" needs to be exported by the entry point index.d.ts - // - // (undocumented) defaultValues?: OnboardingDefaultValues; - // (undocumented) initialEmployeeId?: string; - // (undocumented) initialOnboardingStatus?: (typeof EmployeeOnboardingStatus)[keyof typeof EmployeeOnboardingStatus]; - // (undocumented) initialState?: OnboardingExecutionInitialState; - // (undocumented) isAdmin?: boolean; - // (undocumented) isSelfOnboardingEnabled?: boolean; - // (undocumented) onEvent: OnEventType; - // (undocumented) withEmployeeI9?: boolean; } // Warning: (ae-forgotten-export) The symbol "INITIAL_COMPONENT_MAP" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "OnboardingExecutionInitialState" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingExecutionFlow" // -// @public (undocumented) +// @public type OnboardingExecutionInitialState = keyof typeof INITIAL_COMPONENT_MAP; -// Warning: (ae-forgotten-export) The symbol "OnboardingFlowProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "OnboardingFlow" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeList" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Compensation" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethod" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Deductions" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeDocuments" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingSummary" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingFlowProps" // -// @public (undocumented) +// @public const OnboardingFlow: (input: OnboardingFlowProps) => JSX; // Warning: (ae-forgotten-export) The symbol "OnboardingFlowProps_2" needs to be exported by the entry point index.d.ts @@ -3460,6 +3374,16 @@ const OnboardingFlow_2: (input: OnboardingFlowProps_2) => JSX; // @public (undocumented) const OnboardingFlow_3: (input: OnboardingFlowProps_3) => JSX; +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingFlow" +// +// @public +interface OnboardingFlowProps extends BaseComponentInterface { + companyId: string; + defaultValues?: RequireAtLeastOne; + isSelfOnboardingEnabled?: boolean; + withEmployeeI9?: boolean; +} + // Warning: (ae-forgotten-export) The symbol "OnboardingOverviewProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "OnboardingOverview" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -3467,9 +3391,8 @@ const OnboardingFlow_3: (input: OnboardingFlowProps_3) => JSX; function OnboardingOverview(props: OnboardingOverviewProps & BaseComponentInterface): JSX; // Warning: (ae-forgotten-export) The symbol "SummaryProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "OnboardingSummary" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public function OnboardingSummary(props: SummaryProps & BaseComponentInterface): JSX; // Warning: (ae-forgotten-export) The symbol "BaseListProps" needs to be exported by the entry point index.d.ts @@ -3477,14 +3400,16 @@ function OnboardingSummary(props: SummaryProps & BaseComponentInterface): JSX; // @public export type OrderedListProps = BaseListProps; -// Warning: (ae-missing-release-tag) "OrderNumberFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function OrderNumberField(props: OrderNumberFieldProps): JSX; + +// @public export type OrderNumberFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "OtherIncomeFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function OtherIncomeField(props: OtherIncomeFieldProps): JSX; + +// @public export type OtherIncomeFieldProps = HookFieldProps>; // @public @@ -3504,9 +3429,16 @@ export type PaginationControlProps = { // @public (undocumented) export type PaginationItemsPerPage = 5 | 10 | 25 | 50; -// Warning: (ae-missing-release-tag) "PAYMENT_METHOD_TYPES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export const PAY_PERIODS: { + readonly HOUR: "Hour"; + readonly WEEK: "Week"; + readonly MONTH: "Month"; + readonly YEAR: "Year"; + readonly PAYCHECK: "Paycheck"; +}; + +// @public export const PAYMENT_METHOD_TYPES: readonly ["Direct Deposit", "Check"]; // Warning: (ae-forgotten-export) The symbol "PaymentFlowProps" needs to be exported by the entry point index.d.ts @@ -3521,164 +3453,133 @@ const PaymentFlow: (input: PaymentFlowProps) => JSX; // @public (undocumented) function PaymentHistory(props: PaymentHistoryProps): JSX; -// Warning: (ae-forgotten-export) The symbol "PaymentMethodProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PaymentMethod" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodProps" // -// @public (undocumented) -function PaymentMethod(props: PaymentMethodProps): JSX; +// @public +function PaymentMethod(input: PaymentMethodProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "PaymentMethod" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodCard" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodBankForm" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodSplitForm" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodProps" // -// @public (undocumented) -function PaymentMethod_2(input: PaymentMethodProps_2 & BaseComponentInterface): JSX; +// @public +function PaymentMethod_2(input: PaymentMethodProps_2 & BaseComponentInterface<'Employee.Management.PaymentMethod'>): JSX; +// Warning: (ae-forgotten-export) The symbol "PaymentMethodProps_3" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "PaymentMethod" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -function PaymentMethod_3(input: PaymentMethodProps_3 & BaseComponentInterface<'Employee.Management.PaymentMethod'>): JSX; +function PaymentMethod_3(props: PaymentMethodProps_3): JSX; -// Warning: (ae-missing-release-tag) "PaymentMethodBankForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "BankFormBody" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodBankFormProps" // // @public function PaymentMethodBankForm(input: PaymentMethodBankFormProps): JSX; -// Warning: (ae-missing-release-tag) "PaymentMethodBankFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodBankForm" // -// @public (undocumented) +// @public interface PaymentMethodBankFormProps extends Omit { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "PaymentMethodCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "usePaymentMethodList" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodCardProps" // // @public function PaymentMethodCard(props: PaymentMethodCardProps): JSX; -// Warning: (ae-missing-release-tag) "PaymentMethodCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodCard" // -// @public (undocumented) +// @public interface PaymentMethodCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } // Warning: (ae-forgotten-export) The symbol "fieldValidators_9" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PaymentMethodFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type PaymentMethodFormData = { [K in keyof typeof fieldValidators_9]: z.infer<(typeof fieldValidators_9)[K]>; }; -// Warning: (ae-missing-release-tag) "PaymentMethodFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodFormErrorCode = (typeof PaymentMethodFormErrorCodes)[keyof typeof PaymentMethodFormErrorCodes]; -// Warning: (ae-missing-release-tag) "PaymentMethodFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const PaymentMethodFormErrorCodes: { readonly REQUIRED: "REQUIRED"; }; -// Warning: (ae-missing-release-tag) "PaymentMethodFormField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodFormField = keyof typeof fieldValidators_9; -// Warning: (ae-missing-release-tag) "PaymentMethodFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface PaymentMethodFormFields { - // Warning: (ae-forgotten-export) The symbol "TypeField" needs to be exported by the entry point index.d.ts - // - // (undocumented) - Type: typeof TypeField; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TypeField" + Type: typeof PaymentMethodTypeField; } -// Warning: (ae-missing-release-tag) "PaymentMethodFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodFormFieldsMetadata = UsePaymentMethodFormReady['form']['fieldsMetadata']; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_8" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PaymentMethodFormOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type PaymentMethodFormOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "PaymentMethodFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodFormOutputs = PaymentMethodFormData; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodFormRequiredValidation = typeof PaymentMethodFormErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "PaymentMethodProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethod" // -// @public (undocumented) -interface PaymentMethodProps_2 extends CommonComponentInterface<'Employee.PaymentMethod'> { - // (undocumented) +// @public +interface PaymentMethodProps extends CommonComponentInterface<'Employee.PaymentMethod'> { defaultValues?: never; - // (undocumented) employeeId: string; - // (undocumented) isAdmin?: boolean; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "PaymentMethodProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethod" // -// @public (undocumented) -interface PaymentMethodProps_3 extends CommonComponentInterface<'Employee.Management.PaymentMethod'> { - // (undocumented) +// @public +interface PaymentMethodProps_2 extends CommonComponentInterface<'Employee.Management.PaymentMethod'> { defaultValues?: never; - // (undocumented) employeeId: string; - // (undocumented) initialState?: 'list' | 'add' | 'split'; - // (undocumented) isAdmin?: boolean; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "PaymentMethodSplitForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "SplitPaymentsFormBody" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodSplitFormProps" // // @public function PaymentMethodSplitForm(input: PaymentMethodSplitFormProps): JSX; -// Warning: (ae-missing-release-tag) "PaymentMethodSplitFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethodSplitForm" // -// @public (undocumented) +// @public interface PaymentMethodSplitFormProps extends Omit { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "PaymentMethodType" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PaymentMethodType = (typeof PAYMENT_METHOD_TYPES)[number]; -// Warning: (ae-missing-release-tag) "PaymentPeriodFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function PaymentMethodTypeField(props: TypeFieldProps): JSX; + +// @public +export function PaymentPeriodField(props: PaymentPeriodFieldProps): JSX; + +// @public export type PaymentPeriodFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "PaymentsListProps" needs to be exported by the entry point index.d.ts @@ -3702,14 +3603,13 @@ const PaymentSummary: (input: PaymentSummaryProps) => JSX | null; // @public export type PaymentUnitFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "PayPeriodMaximumFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function PayPeriodMaximumField(props: PayPeriodMaximumFieldProps): JSX; + +// @public export type PayPeriodMaximumFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "PayPeriodMaximumValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PayPeriodMaximumValidation = ChildSupportGarnishmentRequiredValidation | ChildSupportGarnishmentNegativeAmountValidation; declare namespace Payroll { @@ -3750,6 +3650,8 @@ declare namespace Payroll { DismissalFlow, DismissalFlowProps, DismissalFlowContextInterface, + DismissalPayPeriodSelection, + DismissalPayPeriodSelectionProps, TransitionFlow, TransitionFlowContextInterface, TransitionFlowProps, @@ -3843,9 +3745,9 @@ export interface PayrollLoadingProps { title: ReactNode; } -// Warning: (ae-missing-release-tag) "PayrollOption" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlow" // -// @public (undocumented) +// @public type PayrollOption = 'dismissalPayroll' | 'regularPayroll' | 'anotherWay'; // Warning: (ae-forgotten-export) The symbol "PayrollOverviewProps" needs to be exported by the entry point index.d.ts @@ -3924,19 +3826,16 @@ export type PayScheduleOptionalFieldsToRequire = OptionalFieldsToRequire; } @@ -3981,6 +3880,11 @@ interface PolicyListProps extends BaseComponentInterface<'Company.TimeOff.TimeOf companyId: string; } +// Warning: (ae-missing-release-tag) "PolicySettings" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +function PolicySettings(props: PolicySettingsProps): JSX; + // Warning: (ae-missing-release-tag) "PolicySettingsDisplay" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -4026,6 +3930,16 @@ interface PolicySettingsPresentationProps { onContinue: (data: PolicySettingsFormData) => void; } +// Warning: (ae-missing-release-tag) "PolicySettingsProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface PolicySettingsProps extends BaseComponentInterface { + // (undocumented) + mode?: 'create' | 'edit'; + // (undocumented) + policyId: string; +} + // Warning: (ae-missing-release-tag) "PolicyTypeSelector" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -4043,90 +3957,117 @@ interface PolicyTypeSelectorProps extends BaseComponentInterface<'Company.TimeOf defaultPolicyType?: PolicyType; } -// Warning: (ae-missing-release-tag) "PREPARER_FIELDS_BY_INDEX" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const PREPARER_FIELDS_BY_INDEX: SignEmployeeFormField[][]; -// Warning: (ae-missing-release-tag) "PreparerCheckboxFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PreparerCheckboxFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "preparer1Fields" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PreparerFieldGroup" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type PreparerFieldGroup = typeof preparer1Fields; -// Warning: (ae-missing-release-tag) "preparerFieldName" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-internal-missing-underscore) The name "preparerFieldName" should be prefixed with an underscore because the declaration is marked as @internal // -// @public (undocumented) +// @internal (undocumented) export function preparerFieldName(index: PreparerIndex, field: PreparerFieldSuffix): string; -// Warning: (ae-missing-release-tag) "PreparerFieldSuffix" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PreparerFieldSuffix = 'FirstName' | 'LastName' | 'Street1' | 'Street2' | 'City' | 'State' | 'Zip' | 'Signature' | 'Agree'; -// Warning: (ae-missing-release-tag) "PreparerIndex" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PreparerIndex = 1 | 2 | 3 | 4; -// Warning: (ae-missing-release-tag) "PreparerTextFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type PreparerSelectFieldProps = HookFieldProps>; + +// @public export type PreparerTextFieldProps = HookFieldProps>; -// Warning: (ae-forgotten-export) The symbol "ProfileProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Profile" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Employee" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Employee" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Employee" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileProps" // -// @public (undocumented) +// @public function Profile(input: ProfileProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "Profile" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Employee" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileProps" // -// @public (undocumented) +// @public function Profile_2(input: ProfileProps_2 & BaseComponentInterface<'Employee.Management.Profile'>): JSX; -// Warning: (ae-missing-release-tag) "ProfileCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileCardProps" // // @public function ProfileCard(props: ProfileCardProps): JSX; -// Warning: (ae-missing-release-tag) "ProfileCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileCard" // -// @public (undocumented) +// @public interface ProfileCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "ProfileEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" // -// @public (undocumented) +// @public +type ProfileDefaultValues = RequireAtLeastOne<{ + employee?: RequireAtLeastOne<{ + firstName?: string; + middleInitial?: string; + lastName?: string; + email?: string; + dateOfBirth?: string; + }>; + homeAddress?: RequireAtLeastOne<{ + street1?: string; + street2?: string; + city?: string; + state?: string; + zip?: string; + }>; + inviteEmployeeDefault?: boolean; +}>; + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Employee" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileEditFormProps" +// +// @public function ProfileEditForm(input: ProfileEditFormProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "ProfileEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "ProfileEditForm" // -// @public (undocumented) +// @public interface ProfileEditFormProps extends CommonComponentInterface<'Employee.Management.Profile'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "ProfileProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" // -// @public (undocumented) +// @public +interface ProfileProps extends CommonComponentInterface<'Employee.Profile'> { + companyId: string; + defaultValues?: ProfileDefaultValues; + employeeId?: string; + isAdmin?: boolean; + isSelfOnboardingEnabled?: boolean; + onEvent: BaseComponentInterface['onEvent']; +} + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" +// +// @public interface ProfileProps_2 extends CommonComponentInterface<'Employee.Management.Profile'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } @@ -4181,9 +4122,7 @@ export interface RadioProps extends SharedHorizontalFieldLayoutProps, Pick; }; @@ -4200,24 +4139,25 @@ export type RateValidation = (typeof CompensationErrorCodes)['REQUIRED' | 'RATE_ // @public (undocumented) function RecoveryCases(input: RecoveryCasesInternalProps): JSX; -// Warning: (ae-missing-release-tag) "RecurringFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function RecurringField(props: RecurringFieldProps): JSX; + +// @public export type RecurringFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "RemittanceNumberFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function RemittanceNumberField(props: RemittanceNumberFieldProps): JSX; + +// @public export type RemittanceNumberFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "RoutingNumberFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function RoutingNumberField(props: RoutingNumberFieldProps): JSX; + +// @public export type RoutingNumberFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "RoutingNumberValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type RoutingNumberValidation = (typeof BankFormErrorCodes)[keyof Pick]; // @public @@ -4321,23 +4261,30 @@ interface SelectReasonPayload { reason: OffCycleReason; } -// Warning: (ae-missing-release-tag) "SelectStateTaxFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SelectStateTaxFieldProps = BaseStateTaxFieldProps & { placeholder?: string; FieldComponent?: ComponentType; }; -// Warning: (ae-missing-release-tag) "SelfOnboardingFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function SelfOnboardingField(props: SelfOnboardingFieldProps): JSX; + +// @public export type SelfOnboardingFieldProps = HookFieldProps; // Warning: (ae-forgotten-export) The symbol "SelfOnboardingFlowProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SelfOnboardingFlow" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Landing" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "Profile" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "FederalTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxes" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PaymentMethod" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "DocumentSigner" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmploymentEligibility" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "OnboardingSummary" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "SelfOnboardingFlowProps" // -// @public (undocumented) +// @public const SelfOnboardingFlow: (input: SelfOnboardingFlowProps) => JSX; // @public @@ -4352,6 +4299,9 @@ export interface SharedFieldLayoutProps extends DataAttributes { // @public export type SharedHorizontalFieldLayoutProps = SharedFieldLayoutProps; +// @public +export function SignatureField(props: SignEmployeeFormSignatureFieldProps): JSX; + // Warning: (ae-missing-release-tag) "SignatureFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -4423,160 +4373,96 @@ export type SignCompanyFormOutputs = SignCompanyFormData; // @public (undocumented) export type SignCompanyFormRequiredValidation = typeof SignCompanyFormErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "ConfirmSignatureFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormConfirmSignatureFieldProps = HookFieldProps>; // Warning: (ae-forgotten-export) The symbol "fieldValidators_12" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SignEmployeeFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type SignEmployeeFormData = { [K in keyof typeof fieldValidators_12]: z.infer<(typeof fieldValidators_12)[K]>; }; -// Warning: (ae-missing-release-tag) "SignEmployeeFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormErrorCode = (typeof SignEmployeeFormErrorCodes)[keyof typeof SignEmployeeFormErrorCodes]; -// Warning: (ae-missing-release-tag) "SignEmployeeFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const SignEmployeeFormErrorCodes: { readonly REQUIRED: "REQUIRED"; }; -// Warning: (ae-missing-release-tag) "SignEmployeeFormField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormField = keyof typeof fieldValidators_12; -// Warning: (ae-missing-release-tag) "SignEmployeeFormFieldComponents" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface SignEmployeeFormFieldComponents { - // Warning: (ae-forgotten-export) The symbol "ConfirmSignatureField" needs to be exported by the entry point index.d.ts - // - // (undocumented) ConfirmSignature: typeof ConfirmSignatureField; - // (undocumented) Preparer1: PreparerFieldGroup | undefined; - // (undocumented) Preparer2: PreparerFieldGroup | undefined; - // (undocumented) Preparer3: PreparerFieldGroup | undefined; - // (undocumented) Preparer4: PreparerFieldGroup | undefined; - // Warning: (ae-forgotten-export) The symbol "SignatureField" needs to be exported by the entry point index.d.ts - // - // (undocumented) Signature: typeof SignatureField; - // Warning: (ae-forgotten-export) The symbol "UsedPreparerField" needs to be exported by the entry point index.d.ts - // - // (undocumented) UsedPreparer: typeof UsedPreparerField | undefined; } -// Warning: (ae-missing-release-tag) "SignEmployeeFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormFields = UseSignEmployeeFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "SignEmployeeFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormFieldsMetadata = UseSignEmployeeFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "SignEmployeeFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormOutputs = SignEmployeeFormData; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormRequiredValidation = typeof SignEmployeeFormErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "SignatureFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SignEmployeeFormSignatureFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "SPLIT_BY_VALUES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const SPLIT_BY_VALUES: readonly ["Percentage", "Amount"]; -// Warning: (ae-missing-release-tag) "SplitByFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitByFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "SplitByValue" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitByValue = (typeof SPLIT_BY_VALUES)[number]; -// Warning: (ae-missing-release-tag) "SplitFieldEntry" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface SplitFieldEntry { - // (undocumented) Field: ComponentType; - // (undocumented) hiddenAccountNumber: string | null; - // (undocumented) name: string | null; - // (undocumented) uuid: string; } -// Warning: (ae-missing-release-tag) "SplitFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface SplitFieldProps { - // (undocumented) description?: ReactNode; - // (undocumented) FieldComponent?: ComponentType; - // (undocumented) formHookResult?: FormHookResult; - // (undocumented) label: string; - // (undocumented) max?: NumberInputProps['max']; - // (undocumented) min?: NumberInputProps['min']; - // (undocumented) placeholder?: NumberInputProps['placeholder']; - // (undocumented) validationMessages?: ValidationMessages; } -// Warning: (ae-missing-release-tag) "SplitFieldValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SplitFieldValidation = typeof SplitPaymentsFormErrorCodes.REQUIRED | typeof SplitPaymentsFormErrorCodes.INVALID_AMOUNT | typeof SplitPaymentsFormErrorCodes.INVALID_PERCENTAGE; -// Warning: (ae-missing-release-tag) "SplitPaymentsFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitPaymentsFormData = { splitBy: SplitByValue; splitAmount: Record; priority: Record; }; -// Warning: (ae-missing-release-tag) "SplitPaymentsFormErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitPaymentsFormErrorCode = (typeof SplitPaymentsFormErrorCodes)[keyof typeof SplitPaymentsFormErrorCodes]; -// Warning: (ae-missing-release-tag) "SplitPaymentsFormErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const SplitPaymentsFormErrorCodes: { readonly REQUIRED: "REQUIRED"; readonly INVALID_PERCENTAGE: "INVALID_PERCENTAGE"; @@ -4586,106 +4472,85 @@ export const SplitPaymentsFormErrorCodes: { }; // Warning: (ae-forgotten-export) The symbol "fieldValidators_10" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SplitPaymentsFormField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type SplitPaymentsFormField = keyof typeof fieldValidators_10; -// Warning: (ae-missing-release-tag) "SplitPaymentsFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface SplitPaymentsFormFields { - // (undocumented) + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "SplitByField" SplitBy: ComponentType; - // (undocumented) splits: SplitFieldEntry[]; } -// Warning: (ae-missing-release-tag) "SplitPaymentsFormFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitPaymentsFormFieldsMetadata = UseSplitPaymentsFormReady['form']['fieldsMetadata']; // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_9" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SplitPaymentsFormOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type SplitPaymentsFormOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "SplitPaymentsFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitPaymentsFormOutputs = SplitPaymentsFormData; -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SplitPaymentsFormRequiredValidation = typeof SplitPaymentsFormErrorCodes.REQUIRED; -// Warning: (ae-forgotten-export) The symbol "SsnRequiredValidation" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SsnFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function SsnField(props: SsnFieldProps): JSX; + +// @public export type SsnFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "SsnValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type SsnRequiredValidation = typeof EmployeeDetailsErrorCodes.REQUIRED; + +// @public export type SsnValidation = typeof EmployeeDetailsErrorCodes.INVALID_SSN; -// Warning: (ae-missing-release-tag) "StateFieldEntry" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type StateFieldEntry = { state: string; name: string; manualPaymentRequired?: boolean; }; -// Warning: (ae-missing-release-tag) "StateFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type StateFieldProps = HookFieldProps>; -// Warning: (ae-forgotten-export) The symbol "StateTaxesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "StateTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -function StateTaxes(input: StateTaxesProps): JSX; +// @public +function StateTaxes(input: StateTaxesProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "StateTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxesCard" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxesEditForm" // -// @public (undocumented) +// @public function StateTaxes_2(input: StateTaxesProps_2 & BaseComponentInterface<'Employee.Management.StateTaxes'>): JSX; +// Warning: (ae-forgotten-export) The symbol "StateTaxesProps_3" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "StateTaxes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -function StateTaxes_3(input: StateTaxesProps_3 & Pick): JSX; +function StateTaxes_3(input: StateTaxesProps_3): JSX; -// Warning: (ae-missing-release-tag) "StateTaxesCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public function StateTaxesCard(props: StateTaxesCardProps): JSX; -// Warning: (ae-missing-release-tag) "StateTaxesCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxesCard" // -// @public (undocumented) +// @public interface StateTaxesCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "StateTaxesEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public function StateTaxesEditForm(input: StateTaxesEditFormProps & Pick): JSX; -// Warning: (ae-missing-release-tag) "StateTaxesEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxesEditForm" // -// @public (undocumented) +// @public type StateTaxesEditFormProps = Omit, 'children'> & { employeeId: string; onEvent: BaseComponentInterface['onEvent']; @@ -4703,39 +4568,32 @@ function StateTaxesForm(props: StateTaxesFormProps & BaseComponentInterface): JS // @public (undocumented) function StateTaxesList(props: StateTaxesListProps): JSX; -// Warning: (ae-missing-release-tag) "StateTaxesProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -interface StateTaxesProps_2 extends CommonComponentInterface<'Employee.Management.StateTaxes'> { - // (undocumented) - employeeId: string; - // (undocumented) - onEvent: OnEventType; -} - -// Warning: (ae-missing-release-tag) "StateTaxesProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxes" // -// @public (undocumented) -type StateTaxesProps_3 = Omit, 'children'> & { +// @public +type StateTaxesProps = Omit, 'children'> & { employeeId: string; isAdmin?: boolean; onEvent: BaseComponentInterface['onEvent']; }; -// Warning: (ae-missing-release-tag) "StateTaxFieldsGroup" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "StateTaxes" // -// @public (undocumented) +// @public +interface StateTaxesProps_2 extends CommonComponentInterface<'Employee.Management.StateTaxes'> { + employeeId: string; + onEvent: OnEventType; +} + +// @public export interface StateTaxFieldsGroup { - // (undocumented) questions: StateTaxQuestionFieldEntry[]; - // (undocumented) state: string; } // Warning: (ae-forgotten-export) The symbol "SharedQuestionMetadata" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "StateTaxQuestionFieldEntry" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type StateTaxQuestionFieldEntry = ({ type: 'select'; Field: ComponentType; @@ -4759,27 +4617,33 @@ export type StateTaxQuestionFieldEntry = ({ // @public export type StateTaxQuestionVariant = 'select' | 'radio' | 'text' | 'number' | 'currency' | 'date'; -// Warning: (ae-missing-release-tag) "StateTaxValue" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type StateTaxValue = string | number | boolean | Date | null | undefined; +// @public +export function StateWcClassCodeField(props: StateWcClassCodeFieldProps): JSX; + // Warning: (ae-forgotten-export) The symbol "WARiskClassCode" needs to be exported by the entry point index.d.ts // // @public export type StateWcClassCodeFieldProps = HookFieldProps>; +// @public +export function StateWcCoveredField(props: StateWcCoveredFieldProps): JSX; + // @public export type StateWcCoveredFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "Street1FieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function Street1Field(props: Street1FieldProps): JSX; + +// @public export type Street1FieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "Street2FieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function Street2Field(props: Street2FieldProps): JSX; + +// @public export type Street2FieldProps = HookFieldProps>; // @public @@ -4788,14 +4652,10 @@ export type SubmitStateForErrorHandling = { setSubmitError: (error: SDKError | null) => void; }; -// Warning: (ae-missing-release-tag) "SUPPORTED_REQUIRED_ATTR_KEYS" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const SUPPORTED_REQUIRED_ATTR_KEYS: readonly ["case_number", "order_number", "remittance_number"]; -// Warning: (ae-missing-release-tag) "SupportedRequiredAttrKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SupportedRequiredAttrKey = (typeof SUPPORTED_REQUIRED_ATTR_KEYS)[number]; // Warning: (ae-internal-missing-underscore) The name "SwitchHookField" should be prefixed with an underscore because the declaration is marked as @internal @@ -4856,52 +4716,48 @@ export interface TabsProps { tabs: TabProps[]; } -// Warning: (ae-missing-release-tag) "TerminateEmployee" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlow" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminateEmployeeProps" // -// @public (undocumented) +// @public function TerminateEmployee(props: TerminateEmployeeProps): JSX; -// Warning: (ae-missing-release-tag) "TerminateEmployeeProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminateEmployee" // -// @public (undocumented) +// @public interface TerminateEmployeeProps extends BaseComponentInterface<'Employee.Terminations.TerminateEmployee'> { - // (undocumented) companyId: string; - // (undocumented) employeeId: string; } -// Warning: (ae-missing-release-tag) "TerminationFlow" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlowAlert" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "PayrollOption" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlowProps" // -// @public (undocumented) +// @public const TerminationFlow: (input: TerminationFlowProps) => JSX; -// Warning: (ae-missing-release-tag) "TerminationFlowProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlow" // -// @public (undocumented) +// @public interface TerminationFlowProps extends BaseComponentInterface { - // (undocumented) companyId: string; - // (undocumented) employeeId: string; } -// Warning: (ae-missing-release-tag) "TerminationSummary" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationFlowAlert" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationSummaryProps" // -// @public (undocumented) +// @public function TerminationSummary(props: TerminationSummaryProps): JSX; -// Warning: (ae-missing-release-tag) "TerminationSummaryProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "TerminationSummary" // -// @public (undocumented) +// @public interface TerminationSummaryProps extends BaseComponentInterface<'Employee.Terminations.TerminationSummary'> { - // (undocumented) companyId: string; - // (undocumented) employeeId: string; - // (undocumented) payrollOption?: PayrollOption; - // (undocumented) payrollUuid?: string; } @@ -4953,9 +4809,7 @@ export interface TextProps extends Pick, 'c weight?: 'regular' | 'medium' | 'semibold' | 'bold'; } -// Warning: (ae-missing-release-tag) "TextStateTaxFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type TextStateTaxFieldProps = BaseStateTaxFieldProps & { placeholder?: string; FieldComponent?: ComponentType; @@ -4969,8 +4823,10 @@ declare namespace TimeOff { PolicyTypeSelectorProps, PolicyConfigurationForm, PolicyConfigurationFormProps, - PolicySettingsPresentation as PolicySettings, - PolicySettingsPresentationProps as PolicySettingsProps, + PolicySettings, + PolicySettingsProps, + PolicySettingsPresentation, + PolicySettingsPresentationProps, AddEmployeesToPolicy, AddEmployeesToPolicyProps, HolidaySelectionForm, @@ -4985,6 +4841,8 @@ declare namespace TimeOff { ViewHolidayScheduleProps, HolidayPolicyDetailPresentationProps, HolidayPolicyDetailEmployee, + TimeOffPolicyDetail, + TimeOffPolicyDetailProps, TimeOffPolicyDetailPresentation, TimeOffPolicyDetailPresentationProps, TimeOffPolicyDetailEmployee, @@ -5008,6 +4866,11 @@ interface TimeOffFlowProps extends BaseComponentInterface { companyId: string; } +// Warning: (ae-missing-release-tag) "TimeOffPolicyDetail" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +function TimeOffPolicyDetail(props: TimeOffPolicyDetailProps): JSX; + // Warning: (ae-missing-release-tag) "TimeOffPolicyDetailEmployee" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -5037,9 +4900,18 @@ type TimeOffPolicyDetailPresentationProps = TimeOffPolicyDetailPresentationBaseP onChangeSettings?: () => void; }); -// Warning: (ae-missing-release-tag) "TotalAmountFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TimeOffPolicyDetailProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) +interface TimeOffPolicyDetailProps extends BaseComponentInterface { + // (undocumented) + policyId: string; +} + +// @public +export function TotalAmountField(props: TotalAmountFieldProps): JSX; + +// @public export type TotalAmountFieldProps = HookFieldProps>; // Warning: (ae-missing-release-tag) "TransitionCreation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -5110,99 +4982,73 @@ interface TransitionFlowProps { startDate: string; } -// Warning: (ae-missing-release-tag) "TwoJobsFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function TwoJobsField(props: TwoJobsFieldProps): JSX; + +// @public export type TwoJobsFieldProps = HookFieldProps>; +// @public +export function TwoPercentShareholderField(props: TwoPercentShareholderFieldProps): JSX; + // @public export type TwoPercentShareholderFieldProps = HookFieldProps; -// Warning: (ae-missing-release-tag) "TypeFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type TypeFieldProps = HookFieldProps>; // @public export type UnorderedListProps = BaseListProps; -// Warning: (ae-missing-release-tag) "useBankForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useBankForm(input: UseBankFormProps): HookLoadingResult | UseBankFormReady; -// Warning: (ae-missing-release-tag) "UseBankFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseBankFormProps { - // (undocumented) defaultValues?: Partial; employeeId?: string; - // (undocumented) optionalFieldsToRequire?: BankFormOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UseBankFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseBankFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: (options?: BankFormSubmitOptions) => Promise | undefined>; }; - // (undocumented) data: Record; - // (undocumented) status: { isPending: boolean; mode: 'create'; }; } -// Warning: (ae-missing-release-tag) "UseBankFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseBankFormResult = HookLoadingResult | UseBankFormReady; -// Warning: (ae-missing-release-tag) "useChildSupportGarnishmentForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useChildSupportGarnishmentForm(input: UseChildSupportGarnishmentFormProps): UseChildSupportGarnishmentFormResult; -// Warning: (ae-missing-release-tag) "UseChildSupportGarnishmentFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseChildSupportGarnishmentFormProps { - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; garnishmentId?: string; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UseChildSupportGarnishmentFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseChildSupportGarnishmentFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; }; - // (undocumented) data: { agencies: StateFieldEntry[]; counties: CountyEntry[]; deduction: Garnishment | null; }; - // (undocumented) status: { isPending: boolean; mode: 'create' | 'update'; @@ -5212,9 +5058,7 @@ export interface UseChildSupportGarnishmentFormReady extends BaseFormHookReady; -// Warning: (ae-missing-release-tag) "useCurrentWorkAddressForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useCurrentWorkAddressForm(props: UseCurrentWorkAddressFormProps): UseWorkAddressFormResult; -// Warning: (ae-missing-release-tag) "UseCurrentWorkAddressFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseCurrentWorkAddressFormProps = Omit; -// Warning: (ae-missing-release-tag) "useDeductionForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useDeductionForm(input: UseDeductionFormProps): UseDeductionFormResult; -// Warning: (ae-missing-release-tag) "UseDeductionFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseDeductionFormProps { courtOrdered: boolean; - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; garnishmentId?: string; - // (undocumented) optionalFieldsToRequire?: DeductionFormOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UseDeductionFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseDeductionFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; }; - // (undocumented) data: { deduction: Garnishment | null; }; - // (undocumented) status: { isPending: boolean; mode: 'create' | 'update'; @@ -5321,9 +5143,7 @@ export interface UseDeductionFormReady extends BaseFormHookReady, TFormData extends FieldValues = FieldValues>(metadataConfig: FieldsMetadataConfig, control: Control): Record; -// Warning: (ae-missing-release-tag) "UsedPreparerFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function UsedPreparerField(props: UsedPreparerFieldProps): JSX; + +// @public export type UsedPreparerFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "useEmployeeDetailsForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useEmployeeDetailsForm(input: UseEmployeeDetailsFormProps): HookLoadingResult | UseEmployeeDetailsFormReady; -// Warning: (ae-forgotten-export) The symbol "UseEmployeeDetailsFormSharedProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "UseEmployeeDetailsFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseEmployeeDetailsFormProps = (UseEmployeeDetailsFormSharedProps & { companyId: string; employeeId?: never; @@ -5353,159 +5169,117 @@ export type UseEmployeeDetailsFormProps = (UseEmployeeDetailsFormSharedProps & { companyId?: string; }); -// Warning: (ae-forgotten-export) The symbol "EmployeeDetailsFields" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "UseEmployeeDetailsFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseEmployeeDetailsFormReady extends BaseFormHookReady { - // (undocumented) actions: { - onSubmit: (callbacks?: EmployeeDetailsSubmitCallbacks) => Promise | undefined>; + onSubmit: (callbacks?: EmployeeDetailsSubmitCallbacks) => Promise | undefined>; }; - // (undocumented) data: { - employee: Employee_2 | null; + employee: Employee | null; }; - // (undocumented) status: { isPending: boolean; mode: 'create' | 'update'; }; } -// Warning: (ae-missing-release-tag) "UseEmployeeDetailsFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseEmployeeDetailsFormResult = HookLoadingResult | UseEmployeeDetailsFormReady; -// Warning: (ae-missing-release-tag) "useEmployeeList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type UseEmployeeDetailsFormSharedProps = { + withSelfOnboardingField?: boolean; + optionalFieldsToRequire?: EmployeeDetailsOptionalFieldsToRequire; + defaultValues?: Partial; + validationMode?: UseFormProps['mode']; + shouldFocusError?: boolean; +}; + +// @public export function useEmployeeList(input: UseEmployeeListProps): UseEmployeeListResult; -// Warning: (ae-missing-release-tag) "UseEmployeeListProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseEmployeeListProps { - // (undocumented) companyId: string; - // (undocumented) employeeType?: EmployeeType; } -// Warning: (ae-missing-release-tag) "UseEmployeeListReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseEmployeeListReady extends BaseHookReady<{ employees: EmployeeWithActions[]; }, { isFetching: boolean; isPending: boolean; }> { - // (undocumented) actions: { onDelete: (employeeId: string) => Promise; onReview: (employeeId: string) => Promise; onCancelSelfOnboarding: (employeeId: string) => Promise; }; - // (undocumented) pagination: PaginationControlProps; } -// Warning: (ae-missing-release-tag) "UseEmployeeListResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseEmployeeListResult = HookLoadingResult | UseEmployeeListReady; -// Warning: (ae-missing-release-tag) "useEmployeeStateTaxesForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useEmployeeStateTaxesForm(input: UseEmployeeStateTaxesFormProps): UseEmployeeStateTaxesFormResult; -// Warning: (ae-missing-release-tag) "UseEmployeeStateTaxesFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseEmployeeStateTaxesFormProps { - // (undocumented) employeeId: string; isAdmin?: boolean; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UseEmployeeStateTaxesFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; }; - // (undocumented) data: { employeeStateTaxes: EmployeeStateTaxesList[]; }; - // (undocumented) form: BaseFormHookReady['form'] & { Fields: StateTaxFieldsGroup[]; }; - // (undocumented) status: { isPending: boolean; mode: 'update'; }; } -// Warning: (ae-missing-release-tag) "UseEmployeeStateTaxesFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseEmployeeStateTaxesFormResult = HookLoadingResult | UseEmployeeStateTaxesFormReady; -// Warning: (ae-missing-release-tag) "useFederalTaxesForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useFederalTaxesForm(input: UseFederalTaxesFormProps): HookLoadingResult | UseFederalTaxesFormReady; -// Warning: (ae-missing-release-tag) "UseFederalTaxesFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseFederalTaxesFormProps { - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; - // (undocumented) optionalFieldsToRequire?: FederalTaxesOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UseFederalTaxesFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseFederalTaxesFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; }; - // (undocumented) data: { employeeFederalTax: EmployeeFederalTax; }; - // (undocumented) status: { isPending: boolean; mode: 'update'; }; } -// Warning: (ae-missing-release-tag) "UseFederalTaxesFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseFederalTaxesFormResult = HookLoadingResult | UseFederalTaxesFormReady; // Warning: (ae-internal-missing-underscore) The name "useFieldErrorMessage" should be prefixed with an underscore because the declaration is marked as @internal @@ -5513,54 +5287,36 @@ export type UseFederalTaxesFormResult = HookLoadingResult | UseFederalTaxesFormR // @internal export function useFieldErrorMessage(fieldName: string, validationMessages?: ValidationMessages): string | undefined; -// Warning: (ae-missing-release-tag) "useHomeAddressForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useHomeAddressForm(input: UseHomeAddressFormProps): HookLoadingResult | UseHomeAddressFormReady; -// Warning: (ae-missing-release-tag) "UseHomeAddressFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseHomeAddressFormProps { - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; homeAddressUuid?: string; initialAddress?: EmployeeAddress; - // (undocumented) optionalFieldsToRequire?: HomeAddressOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; - // (undocumented) withEffectiveDateField?: boolean; } -// Warning: (ae-forgotten-export) The symbol "HomeAddressFields" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "UseHomeAddressFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseHomeAddressFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: (options?: HomeAddressSubmitOptions) => Promise | undefined>; }; - // (undocumented) data: { homeAddress: EmployeeAddress | null; }; - // (undocumented) status: { isPending: boolean; mode: 'create' | 'update'; }; } -// Warning: (ae-missing-release-tag) "UseHomeAddressFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseHomeAddressFormResult = HookLoadingResult | UseHomeAddressFormReady; // @public @@ -5586,7 +5342,7 @@ export interface UseJobFormReady extends BaseFormHookReady ObservabilityContextValue; -// Warning: (ae-missing-release-tag) "usePaymentMethodForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function usePaymentMethodForm(input: UsePaymentMethodFormProps): HookLoadingResult | UsePaymentMethodFormReady; -// Warning: (ae-missing-release-tag) "UsePaymentMethodFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UsePaymentMethodFormProps { - // (undocumented) defaultValues?: Partial; - // (undocumented) employeeId: string; - // (undocumented) optionalFieldsToRequire?: PaymentMethodFormOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; } -// Warning: (ae-missing-release-tag) "UsePaymentMethodFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UsePaymentMethodFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; }; - // (undocumented) data: { paymentMethod: EmployeePaymentMethod; }; - // (undocumented) status: { isPending: boolean; mode: 'update'; }; } -// Warning: (ae-missing-release-tag) "UsePaymentMethodFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UsePaymentMethodFormResult = HookLoadingResult | UsePaymentMethodFormReady; // Warning: (ae-missing-release-tag) "usePayScheduleForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -5747,37 +5487,26 @@ export interface UseSignCompanyFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; addPreparer?: () => void; removePreparer?: () => void; }; - // (undocumented) data: { form: Form; pdfUrl: string | null | undefined; }; - // (undocumented) form: BaseFormHookReady['form'] & { preparers?: { count: number; @@ -5785,54 +5514,38 @@ export interface UseSignEmployeeFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: () => Promise | undefined>; reorderSplits: (orderedUuids: string[]) => void; }; - // (undocumented) data: { paymentMethod: EmployeePaymentMethod; bankAccounts: EmployeeBankAccount[]; splits: WorkingSplit[]; remainderId: string; }; - // (undocumented) status: { isPending: boolean; mode: 'update'; @@ -5842,64 +5555,44 @@ export interface UseSplitPaymentsFormReady extends BaseFormHookReady; - // (undocumented) employeeId: string; initialAddress?: EmployeeWorkAddress; - // (undocumented) optionalFieldsToRequire?: WorkAddressOptionalFieldsToRequire; - // (undocumented) shouldFocusError?: boolean; - // (undocumented) validationMode?: UseFormProps['mode']; - // (undocumented) withEffectiveDateField?: boolean; workAddressUuid?: string; } -// Warning: (ae-forgotten-export) The symbol "WorkAddressFields" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "UseWorkAddressFormReady" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface UseWorkAddressFormReady extends BaseFormHookReady { - // (undocumented) actions: { onSubmit: (callbacks?: WorkAddressSubmitCallbacks, options?: WorkAddressSubmitOptions) => Promise | undefined>; }; - // (undocumented) data: { workAddress: EmployeeWorkAddress | null; companyLocations: Location_2[] | undefined; }; - // (undocumented) status: { isPending: boolean; mode: 'create' | 'update'; }; } -// Warning: (ae-missing-release-tag) "UseWorkAddressFormResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UseWorkAddressFormResult = HookLoadingResult | UseWorkAddressFormReady; // @public @@ -5954,146 +5647,122 @@ export function withOptions(base: FieldMetadata, options: Arra value: string; }>, entries?: readonly TEntry[]): FieldMetadataWithOptions; -// Warning: (ae-missing-release-tag) "WorkAddress" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" // -// @public (undocumented) +// @public function WorkAddress(input: WorkAddressProps & BaseComponentInterface<'Employee.Management.WorkAddress'>): JSX; -// Warning: (ae-missing-release-tag) "WorkAddressCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public function WorkAddressCard(props: WorkAddressCardProps): JSX; -// Warning: (ae-missing-release-tag) "WorkAddressCardProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "WorkAddressCard" // -// @public (undocumented) +// @public interface WorkAddressCardProps { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "WorkAddressEditForm" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "EmployeeWorkAddress" // -// @public (undocumented) +// @public function WorkAddressEditForm(input: WorkAddressEditFormProps & BaseComponentInterface): JSX; -// Warning: (ae-missing-release-tag) "WorkAddressEditFormProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "WorkAddressEditForm" // -// @public (undocumented) +// @public interface WorkAddressEditFormProps extends CommonComponentInterface<'Employee.Management.WorkAddress'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: BaseComponentInterface['onEvent']; } -// Warning: (ae-missing-release-tag) "WorkAddressErrorCode" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function WorkAddressEffectiveDateField(props: EffectiveDateFieldProps): JSX; + +// @public export type WorkAddressErrorCode = (typeof WorkAddressErrorCodes)[keyof typeof WorkAddressErrorCodes]; -// Warning: (ae-missing-release-tag) "WorkAddressErrorCodes" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const WorkAddressErrorCodes: { readonly REQUIRED: "REQUIRED"; }; // Warning: (ae-forgotten-export) The symbol "fieldValidators_6" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "WorkAddressField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type WorkAddressField = keyof typeof fieldValidators_6; -// Warning: (ae-missing-release-tag) "WorkAddressFieldsMetadata" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export interface WorkAddressFields { + EffectiveDate: typeof WorkAddressEffectiveDateField | undefined; + Location: typeof WorkAddressLocationField; +} + +// @public export type WorkAddressFieldsMetadata = UseWorkAddressFormReady['form']['fieldsMetadata']; -// Warning: (ae-missing-release-tag) "WorkAddressFormData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type WorkAddressFormData = { [K in keyof typeof fieldValidators_6]: z.infer<(typeof fieldValidators_6)[K]>; }; -// Warning: (ae-missing-release-tag) "WorkAddressFormFields" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type WorkAddressFormFields = UseWorkAddressFormReady['form']['Fields']; -// Warning: (ae-missing-release-tag) "WorkAddressFormOutputs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type WorkAddressFormOutputs = WorkAddressFormData; +// @public +export function WorkAddressLocationField(props: LocationFieldProps): JSX; + // Warning: (ae-forgotten-export) The symbol "requiredFieldsConfig_5" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "WorkAddressOptionalFieldsToRequire" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export type WorkAddressOptionalFieldsToRequire = OptionalFieldsToRequire; -// Warning: (ae-missing-release-tag) "WorkAddressProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@gusto/embedded-react-sdk" does not have an export "WorkAddress" // -// @public (undocumented) +// @public interface WorkAddressProps extends CommonComponentInterface<'Employee.Management.WorkAddress'> { - // (undocumented) employeeId: string; - // (undocumented) onEvent: OnEventType; } -// Warning: (ae-missing-release-tag) "RequiredValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type WorkAddressRequiredValidation = typeof WorkAddressErrorCodes.REQUIRED; -// Warning: (ae-missing-release-tag) "WorkAddressSubmitCallbacks" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface WorkAddressSubmitCallbacks { - // (undocumented) onWorkAddressCreated?: (workAddress: EmployeeWorkAddress) => void; - // (undocumented) onWorkAddressUpdated?: (workAddress: EmployeeWorkAddress) => void; } -// Warning: (ae-missing-release-tag) "WorkAddressSubmitOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface WorkAddressSubmitOptions { - // (undocumented) effectiveDate?: string; - // (undocumented) employeeId?: string; } -// Warning: (ae-missing-release-tag) "WorkingSplit" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface WorkingSplit { - // (undocumented) hiddenAccountNumber: string | null; - // (undocumented) name: string | null; - // (undocumented) priority: number; - // (undocumented) splitAmount: number | null; - // (undocumented) uuid: string; } -// Warning: (ae-missing-release-tag) "ZipFieldProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export function ZipField(props: ZipFieldProps): JSX; + +// @public export type ZipFieldProps = HookFieldProps>; -// Warning: (ae-missing-release-tag) "ZipValidation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ZipValidation = (typeof HomeAddressErrorCodes)['REQUIRED' | 'INVALID_ZIP']; // Warnings were encountered during analysis: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f39a1b0fa..a80452a31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -337,6 +337,48 @@ gh pr create --title "chore: release " Trigger the [Prepare Release](https://github.com/Gusto/embedded-react-sdk/actions/workflows/prepare-release.yaml) workflow from the Actions UI (`Run workflow`). It accepts an optional version override; if left blank it auto-detects from commits. The workflow creates the branch, commits the changes, and opens a PR automatically. +### Documentation versioning + +The published docs site uses Docusaurus versioning so partners on older SDK versions can read the docs that match their installed version. **All versioned content lives in `Gusto/embedded-sdk-docs`, not this repo.** This repo only ever carries the live (current) docs in `docs/`; versioned snapshots (`versioned_docs/version-X.Y/`, `versions.json`, `versioned_sidebars/`) accumulate in the downstream repo as releases land. + +Snapshots are **keyed by minor**, not by patch. A new minor creates a new snapshot in downstream; patch releases refresh the existing minor's snapshot content. The dropdown stays clean (`0.47`, `0.48`, …). + +#### What happens automatically + +The [Sync Docs Source](https://github.com/Gusto/embedded-react-sdk/actions/workflows/publish-docs.yaml) workflow does all the work: + +- **After Publish to NPM completes** (release): if the released minor isn't in downstream's `versions.json` yet, the workflow runs `npx docusaurus docs:version ` inside the freshly-synced downstream working tree — copying the new `docs/` into `versioned_docs/version-/`, capturing the sidebar, and prepending the minor to `versions.json`. If the minor is already there (patch release), the workflow refreshes the existing snapshot's file contents from the synced `docs/`. +- **On any push to `docs/**`or`docs-site/**`** on `main`: source is synced to downstream so the live (`current`) docs refresh. Versioned snapshots are not touched. +- **On manual workflow_dispatch**: same as push by default. If downstream's `versions.json` is missing the current `package.json` minor (e.g., bootstrapping a clean downstream), the snapshot is created. + +`docs-site/docusaurus.config.ts` is the same file in both places. It reads `versions.json` at config-load time: if absent (this repo), versioning is disabled and the build serves only the live docs; if present (downstream), versioning is active, `lastVersion` is derived from `versions.json[0]`, and the navbar dropdown appears. + +#### Editing docs in a released version + +To change content for a partner on an older minor: + +- For a typo / clarification that should propagate on the **next patch release** of that minor: edit `docs/` here. The next patch refresh will copy the change into the versioned snapshot in downstream. +- To add, remove, or rename a doc in an already-released minor: edit `versioned_docs/version-X.Y/` directly in [Gusto/embedded-sdk-docs](https://github.com/Gusto/embedded-sdk-docs). The patch refresh is content-only — it won't add new files or remove orphaned ones from a versioned snapshot. +- After any such manual edit downstream, also update `versioned_sidebars/version-X.Y-sidebars.json` there if the change affects navigation. Patch refresh does not regenerate the versioned sidebar. + +#### When does the variable matter + +When the repo variable `DOCS_PUBLISH_ENABLED=true` is set (the current default), the `workflow_run` and `push` triggers above fire automatically. If unset, only manual `workflow_dispatch` runs publish docs. `workflow_dispatch` is allowed any time, so the pipeline can be exercised end-to-end before flipping the variable. + +#### Markdown links + +Inside `docs/`, use relative links between files (e.g. `[link](../getting-started/index.md)`), not `/docs/...` absolute links. Absolute links don't resolve correctly when the same file is served at a versioned URL like `/docs/0.47/...`. + +```md + + +See the [Getting Started guide](../getting-started/index.md). + + + +See the [Getting Started guide](/docs/getting-started/index.md). +``` + ### After the PR is merged Publishing happens automatically. When a `chore: release` commit lands on `main` and all CI checks pass, the [Publish to NPM](https://github.com/Gusto/embedded-react-sdk/actions/workflows/publish.yaml) workflow runs automatically and publishes to NPM. diff --git a/docs-site/docusaurus.config.ts b/docs-site/docusaurus.config.ts index 50b78ac07..4101788de 100644 --- a/docs-site/docusaurus.config.ts +++ b/docs-site/docusaurus.config.ts @@ -1,7 +1,29 @@ +import { existsSync, readFileSync } from 'node:fs' +import { resolve } from 'node:path' import type { Config } from '@docusaurus/types' import type * as Preset from '@docusaurus/preset-classic' import { themes as prismThemes } from 'prism-react-renderer' +// Versioning is owned by Gusto/embedded-sdk-docs, not this repo. When this +// config builds there, `versions.json` exists and lists the cut minors; when it +// builds locally on embedded-react-sdk it doesn't, and Docusaurus falls back to +// a single-version site. The same config file works in both places — no fork. +const versionsPath = resolve(__dirname, 'versions.json') + +function isStringArray(val: unknown): val is string[] { + return Array.isArray(val) && val.every(v => typeof v === 'string') +} + +const rawVersions: unknown = existsSync(versionsPath) + ? JSON.parse(readFileSync(versionsPath, 'utf8')) + : [] +if (!isStringArray(rawVersions)) { + throw new Error('docs-site/versions.json must be a string[]') +} +const versions: string[] = rawVersions +const lastVersion = versions[0] +const hasVersions = lastVersion !== undefined + const config: Config = { title: 'Gusto Embedded', tagline: 'Embedded Payroll React SDK Documentation', @@ -54,6 +76,13 @@ const config: Config = { sidebarPath: './sidebars.ts', breadcrumbs: true, exclude: ['test-fests/**'], + ...(hasVersions && { + lastVersion, + includeCurrentVersion: false, + versions: Object.fromEntries( + versions.map(version => [version, { banner: 'none' as const, badge: false }]), + ), + }), }, blog: false, theme: { @@ -95,6 +124,15 @@ const config: Config = { position: 'left', label: 'Docs', }, + ...(hasVersions + ? [ + { + type: 'docsVersionDropdown' as const, + position: 'right' as const, + dropdownActiveClassDisabled: true, + }, + ] + : []), { href: 'https://github.com/Gusto/embedded-react-sdk', label: 'GitHub', diff --git a/docs-site/package-lock.json b/docs-site/package-lock.json index 4182b65fd..6a5cf3d7c 100644 --- a/docs-site/package-lock.json +++ b/docs-site/package-lock.json @@ -25,7 +25,7 @@ "typedoc": "^0.28.19", "typedoc-plugin-markdown": "^4.12.0", "typescript": "~5.8.0", - "vite": "^6.4.3", + "vite": "^8.0.16", "vitest": "^4.1.8" }, "engines": { @@ -1983,6 +1983,16 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@csstools/cascade-layer-name-parser": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", @@ -4223,591 +4233,180 @@ "entities": "^7.0.1" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", "license": "MIT", "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", "license": "MIT", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "license": "MIT", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">=18" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, "engines": { - "node": ">=18" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "license": "Apache-2.0", "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@gerrit0/mini-shiki": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", - "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/engine-oniguruma": "^3.23.0", - "@shikijs/langs": "^3.23.0", - "@shikijs/themes": "^3.23.0", - "@shikijs/types": "^3.23.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/buffers": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", - "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/@jsonjoy.com/codegen": { @@ -5187,105 +4786,341 @@ "tslib": "2" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "license": "MIT" + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@node-rs/jieba": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba/-/jieba-1.10.4.tgz", + "integrity": "sha512-GvDgi8MnBiyWd6tksojej8anIx18244NmIOc1ovEw8WKNUejcccLfyu8vj66LWSuoZuKILVtNsOy4jvg3aoxIw==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/jieba-android-arm-eabi": "1.10.4", + "@node-rs/jieba-android-arm64": "1.10.4", + "@node-rs/jieba-darwin-arm64": "1.10.4", + "@node-rs/jieba-darwin-x64": "1.10.4", + "@node-rs/jieba-freebsd-x64": "1.10.4", + "@node-rs/jieba-linux-arm-gnueabihf": "1.10.4", + "@node-rs/jieba-linux-arm64-gnu": "1.10.4", + "@node-rs/jieba-linux-arm64-musl": "1.10.4", + "@node-rs/jieba-linux-x64-gnu": "1.10.4", + "@node-rs/jieba-linux-x64-musl": "1.10.4", + "@node-rs/jieba-wasm32-wasi": "1.10.4", + "@node-rs/jieba-win32-arm64-msvc": "1.10.4", + "@node-rs/jieba-win32-ia32-msvc": "1.10.4", + "@node-rs/jieba-win32-x64-msvc": "1.10.4" + } + }, + "node_modules/@node-rs/jieba-android-arm-eabi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm-eabi/-/jieba-android-arm-eabi-1.10.4.tgz", + "integrity": "sha512-MhyvW5N3Fwcp385d0rxbCWH42kqDBatQTyP8XbnYbju2+0BO/eTeCCLYj7Agws4pwxn2LtdldXRSKavT7WdzNA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-android-arm64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm64/-/jieba-android-arm64-1.10.4.tgz", + "integrity": "sha512-XyDwq5+rQ+Tk55A+FGi6PtJbzf974oqnpyCcCPzwU3QVXJCa2Rr4Lci+fx8oOpU4plT3GuD+chXMYLsXipMgJA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-darwin-arm64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-arm64/-/jieba-darwin-arm64-1.10.4.tgz", + "integrity": "sha512-G++RYEJ2jo0rxF9626KUy90wp06TRUjAsvY/BrIzEOX/ingQYV/HjwQzNPRR1P1o32a6/U8RGo7zEBhfdybL6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-darwin-x64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-x64/-/jieba-darwin-x64-1.10.4.tgz", + "integrity": "sha512-MmDNeOb2TXIZCPyWCi2upQnZpPjAxw5ZGEj6R8kNsPXVFALHIKMa6ZZ15LCOkSTsKXVC17j2t4h+hSuyYb6qfQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-freebsd-x64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-freebsd-x64/-/jieba-freebsd-x64-1.10.4.tgz", + "integrity": "sha512-/x7aVQ8nqUWhpXU92RZqd333cq639i/olNpd9Z5hdlyyV5/B65LLy+Je2B2bfs62PVVm5QXRpeBcZqaHelp/bg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm-gnueabihf": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm-gnueabihf/-/jieba-linux-arm-gnueabihf-1.10.4.tgz", + "integrity": "sha512-crd2M35oJBRLkoESs0O6QO3BBbhpv+tqXuKsqhIG94B1d02RVxtRIvSDwO33QurxqSdvN9IeSnVpHbDGkuXm3g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm64-gnu": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-gnu/-/jieba-linux-arm64-gnu-1.10.4.tgz", + "integrity": "sha512-omIzNX1psUzPcsdnUhGU6oHeOaTCuCjUgOA/v/DGkvWC1jLcnfXe4vdYbtXMh4XOCuIgS1UCcvZEc8vQLXFbXQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm64-musl": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-musl/-/jieba-linux-arm64-musl-1.10.4.tgz", + "integrity": "sha512-Y/tiJ1+HeS5nnmLbZOE+66LbsPOHZ/PUckAYVeLlQfpygLEpLYdlh0aPpS5uiaWMjAXYZYdFkpZHhxDmSLpwpw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-x64-gnu": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-gnu/-/jieba-linux-x64-gnu-1.10.4.tgz", + "integrity": "sha512-WZO8ykRJpWGE9MHuZpy1lu3nJluPoeB+fIJJn5CWZ9YTVhNDWoCF4i/7nxz1ntulINYGQ8VVuCU9LD86Mek97g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-x64-musl": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-musl/-/jieba-linux-x64-musl-1.10.4.tgz", + "integrity": "sha512-uBBD4S1rGKcgCyAk6VCKatEVQb6EDD5I40v/DxODi5CuZVCANi9m5oee/MQbAoaX7RydA2f0OSCE9/tcwXEwUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", - "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "node_modules/@node-rs/jieba-wasm32-wasi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-wasm32-wasi/-/jieba-wasm32-wasi-1.10.4.tgz", + "integrity": "sha512-Y2umiKHjuIJy0uulNDz9SDYHdfq5Hmy7jY5nORO99B4pySKkcrMjpeVrmWXJLIsEKLJwcCXHxz8tjwU5/uhz0A==", + "cpu": [ + "wasm32" + ], "license": "MIT", + "optional": true, "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "acorn": "^8.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" + "@napi-rs/wasm-runtime": "^0.2.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@mdx-js/react": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", - "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "node_modules/@node-rs/jieba-win32-arm64-msvc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-arm64-msvc/-/jieba-win32-arm64-msvc-1.10.4.tgz", + "integrity": "sha512-nwMtViFm4hjqhz1it/juQnxpXgqlGltCuWJ02bw70YUDMDlbyTy3grCJPpQQpueeETcALUnTxda8pZuVrLRcBA==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "node_modules/@node-rs/jieba-win32-ia32-msvc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-ia32-msvc/-/jieba-win32-ia32-msvc-1.10.4.tgz", + "integrity": "sha512-DCAvLx7Z+W4z5oKS+7vUowAJr0uw9JBw8x1Y23Xs/xMA4Em+OOSiaF5/tCJqZUCJ8uC4QeImmgDFiBqGNwxlyA==", + "cpu": [ + "ia32" + ], "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">= 10" } }, - "node_modules/@node-rs/jieba": { + "node_modules/@node-rs/jieba-win32-x64-msvc": { "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@node-rs/jieba/-/jieba-1.10.4.tgz", - "integrity": "sha512-GvDgi8MnBiyWd6tksojej8anIx18244NmIOc1ovEw8WKNUejcccLfyu8vj66LWSuoZuKILVtNsOy4jvg3aoxIw==", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-x64-msvc/-/jieba-win32-x64-msvc-1.10.4.tgz", + "integrity": "sha512-+sqemSfS1jjb+Tt7InNbNzrRh1Ua3vProVvC4BZRPg010/leCbGFFiQHpzcPRfpxAXZrzG5Y0YBTsPzN/I4yHQ==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@node-rs/jieba-android-arm-eabi": "1.10.4", - "@node-rs/jieba-android-arm64": "1.10.4", - "@node-rs/jieba-darwin-arm64": "1.10.4", - "@node-rs/jieba-darwin-x64": "1.10.4", - "@node-rs/jieba-freebsd-x64": "1.10.4", - "@node-rs/jieba-linux-arm-gnueabihf": "1.10.4", - "@node-rs/jieba-linux-arm64-gnu": "1.10.4", - "@node-rs/jieba-linux-arm64-musl": "1.10.4", - "@node-rs/jieba-linux-x64-gnu": "1.10.4", - "@node-rs/jieba-linux-x64-musl": "1.10.4", - "@node-rs/jieba-wasm32-wasi": "1.10.4", - "@node-rs/jieba-win32-arm64-msvc": "1.10.4", - "@node-rs/jieba-win32-ia32-msvc": "1.10.4", - "@node-rs/jieba-win32-x64-msvc": "1.10.4" } }, "node_modules/@nodelib/fs.scandir": { @@ -5323,6 +5158,16 @@ "node": ">= 8" } }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@peculiar/asn1-cms": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.7.0.tgz", @@ -5527,24 +5372,10 @@ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", "cpu": [ "arm64" ], @@ -5553,12 +5384,15 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", "cpu": [ "arm64" ], @@ -5567,12 +5401,15 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", "cpu": [ "x64" ], @@ -5581,26 +5418,15 @@ "optional": true, "os": [ "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", "cpu": [ "x64" ], @@ -5609,26 +5435,15 @@ "optional": true, "os": [ "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", - "cpu": [ - "arm" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", "cpu": [ "arm" ], @@ -5637,26 +5452,15 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", "cpu": [ "arm64" ], @@ -5665,54 +5469,32 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", - "cpu": [ - "loong64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", "cpu": [ - "loong64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", - "cpu": [ - "ppc64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", "cpu": [ "ppc64" ], @@ -5721,152 +5503,172 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", "cpu": [ - "riscv64" + "s390x" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ - "riscv64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", "cpu": [ - "s390x" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", "cpu": [ - "x64" + "wasm32" ], "dev": true, "license": "MIT", "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", - "cpu": [ - "x64" - ], + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "openbsd" - ] + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", - "cpu": [ - "arm64" - ], + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "openharmony" - ] + "dependencies": { + "tslib": "^2.4.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", - "cpu": [ - "arm64" - ], + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "tslib": "^2.4.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", - "cpu": [ - "ia32" - ], + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@tybys/wasm-util": "^0.10.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", "cpu": [ "x64" ], @@ -5875,7 +5677,17 @@ "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" }, "node_modules/@shikijs/engine-oniguruma": { "version": "3.23.0", @@ -6252,6 +6064,16 @@ "node": ">=14.16" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -9015,6 +8837,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -9391,48 +9223,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -11657,13 +11447,13 @@ } }, "node_modules/launch-editor": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", - "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", "license": "MIT", "dependencies": { "picocolors": "^1.1.1", - "shell-quote": "^1.8.3" + "shell-quote": "^1.8.4" } }, "node_modules/leven": { @@ -11675,6 +11465,267 @@ "node": ">=6" } }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -17454,49 +17505,38 @@ "node": ">=0.10.0" } }, - "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.9" + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" } }, "node_modules/rtlcss": { @@ -19466,24 +19506,23 @@ } }, "node_modules/vite": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", - "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -19492,14 +19531,15 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -19508,13 +19548,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { "optional": true }, - "lightningcss": { + "jiti": { + "optional": true + }, + "less": { "optional": true }, "sass": { @@ -19540,24 +19583,6 @@ } } }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/vite/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", diff --git a/docs-site/package.json b/docs-site/package.json index eff23f6cc..e36c31270 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -11,7 +11,8 @@ "clear": "docusaurus clear", "serve": "docusaurus serve", "typedoc": "typedoc --options typedoc.config.ts", - "test": "vitest run" + "test": "vitest run", + "docs:version": "docusaurus docs:version" }, "dependencies": { "@docusaurus/core": "^3.7.0", @@ -31,7 +32,7 @@ "typedoc": "^0.28.19", "typedoc-plugin-markdown": "^4.12.0", "typescript": "~5.8.0", - "vite": "^6.4.3", + "vite": "^8.0.16", "vitest": "^4.1.8" }, "browserslist": { diff --git a/docs-site/plugins/sdk-router.ts b/docs-site/plugins/sdk-router.ts index 91784c9cc..0c7dd6918 100644 --- a/docs-site/plugins/sdk-router.ts +++ b/docs-site/plugins/sdk-router.ts @@ -368,28 +368,88 @@ function isDomainHub(model: DeclarationReflection): boolean { return model.comment?.blockTags.some(tag => tag.tag === '@domainHub') ?? false } +/** + * Return the summary text for a reflection. Function summaries live on the + * first SignatureReflection, not the DeclarationReflection, so we check there + * first before falling back to the declaration's own comment. + */ +function getReflectionDescription( + reflection: DeclarationReflection, + context: SDKThemeContext, +): string { + const comment = reflection.signatures?.[0]?.comment ?? reflection.comment + if (!comment) return '' + return context.helpers.getDescriptionForComment(comment) ?? '' +} + function renderDomainHub(context: SDKThemeContext, model: DeclarationReflection): string { const parts: string[] = [`# ${model.name}`, ''] - const namespaces = (model.children ?? []).filter(c => c.kind === ReflectionKind.Namespace) + const namespaces = (model.children ?? []).filter( + (c): c is DeclarationReflection => + c instanceof DeclarationReflection && c.kind === ReflectionKind.Namespace, + ) - if (namespaces.length > 0) { - parts.push('## Namespaces', '') - parts.push('| Namespace | Description |') - parts.push('| --------- | ----------- |') + for (const ns of namespaces) { + const nsUrl = context.urlTo(ns) + const nsLabel = ns.isDeprecated() ? `~~${ns.name}~~` : ns.name + parts.push(`## [${nsLabel}](${nsUrl})`, '') + + const nsDescription = ns.comment + ? (context.helpers.getDescriptionForComment(ns.comment) ?? '') + : '' + if (nsDescription) parts.push(nsDescription, '') + + // isComponent filters out interfaces (props types), hooks, and other non-component exports. + const componentChildren = (ns.children ?? []).filter( + (c): c is DeclarationReflection => c instanceof DeclarationReflection && isComponent(c), + ) + const flows = componentChildren.filter(c => c.name.endsWith('Flow')) + const blocks = componentChildren.filter(c => !c.name.endsWith('Flow')) + + if (flows.length > 0) { + parts.push('### Flow Components', '') + parts.push('| Component | Description |') + parts.push('| --------- | ----------- |') + for (const flow of flows) { + const url = context.urlTo(flow) + const description = getReflectionDescription(flow, context) + parts.push(`| [${flow.name}](${url}) | ${description} |`) + } + parts.push('') + } - for (const ns of namespaces) { - const url = context.urlTo(ns) - const label = ns.isDeprecated() ? `~~${ns.name}~~` : ns.name - const description = ns.comment - ? (context.helpers.getDescriptionForComment(ns.comment) ?? '') - : '' - parts.push(`| [${label}](${url}) | ${description} |`) + if (blocks.length > 0) { + parts.push('### Block Components', '') + parts.push('| Component | Description |') + parts.push('| --------- | ----------- |') + for (const block of blocks) { + const url = context.urlTo(block) + const description = getReflectionDescription(block, context) + parts.push(`| [${block.name}](${url}) | ${description} |`) + } + parts.push('') } - parts.push('') } - parts.push('## Hooks', '', `See [${model.name} Hooks](./hooks).`) + const hooksNs = (context.router as SDKRouter).hooksNsByDomain.get(model.name) + const hookGroups = (hooksNs?.groups ?? []).filter(g => /^use[A-Z]/.test(g.title)) + + if (hookGroups.length > 0) { + parts.push('## Hooks', '') + parts.push('| Hook | Description |') + parts.push('| ---- | ----------- |') + for (const group of hookGroups) { + // groupSyntheticMembers sorts the primary hook function to the top of each group. + const primaryHook = group.children[0] as DeclarationReflection | undefined + if (!primaryHook) continue + const url = context.urlTo(primaryHook) + const description = getReflectionDescription(primaryHook, context) + parts.push(`| [${group.title}](${url}) | ${description} |`) + } + } else { + parts.push('## Hooks', '', `See [${model.name} Hooks](./hooks).`) + } return parts.join('\n') } @@ -619,6 +679,9 @@ export class SDKRouter extends MemberRouter { // domain hooks page and must be skipped when buildChildPages encounters them. private readonly handledHooks = new Set() + // Keyed by domain name; populated in buildPages so renderDomainHub can list hooks. + readonly hooksNsByDomain = new Map() + /** * Pre-scan for domain hooks and consolidate them into one synthetic namespace * page per domain (e.g. Employee/hooks.md), then delegate everything else to @@ -677,6 +740,7 @@ export class SDKRouter extends MemberRouter { hooksNs.children = hooks hooksNs.groups = groupSyntheticMembers(hooks, hooksNs, hookGroupMap) this.buildSyntheticPage(`${domain}/hooks`, hooksNs, hooks, pages) + this.hooksNsByDomain.set(domain, hooksNs) } for (const [domain, nsNames] of Object.entries(DOMAIN_HUBS)) { diff --git a/docs-site/src/theme/SearchBar/index.tsx b/docs-site/src/theme/SearchBar/index.tsx index 08ea6f6f1..cdfb3ee38 100644 --- a/docs-site/src/theme/SearchBar/index.tsx +++ b/docs-site/src/theme/SearchBar/index.tsx @@ -143,6 +143,24 @@ export default function SearchBar(): ReactNode { } }, [isOpen]) + // The underlying autocomplete library closes and empties its dropdown on + // input blur. When the OS moves focus to another app (e.g. Terminal), the + // input blurs and the results vanish. Block the blur event from reaching the + // library's handler whenever the document itself is losing focus — the user + // blur (clicking elsewhere in the page) still closes as expected. + useEffect(() => { + if (!isOpen) return + const blockBlurOnWindowSwitch = (event: FocusEvent) => { + const target = event.target as HTMLElement | null + if (!target?.matches('input.navbar__search-input')) return + if (document.hasFocus()) return + event.stopImmediatePropagation() + event.stopPropagation() + } + document.addEventListener('blur', blockBlurOnWindowSwitch, true) + return () => document.removeEventListener('blur', blockBlurOnWindowSwitch, true) + }, [isOpen]) + return ( <> diff --git a/docs-site/src/theme/SearchBar/styles.module.css b/docs-site/src/theme/SearchBar/styles.module.css index baa776402..60cb0e77a 100644 --- a/docs-site/src/theme/SearchBar/styles.module.css +++ b/docs-site/src/theme/SearchBar/styles.module.css @@ -106,9 +106,9 @@ -webkit-backdrop-filter: blur(4px); z-index: 1000; display: flex; - align-items: flex-start; + align-items: center; justify-content: center; - padding: 12vh 1rem 1rem; + padding: 1rem; animation: searchBackdropFadeIn 0.15s ease; } @@ -131,12 +131,17 @@ .searchModal { width: 100%; max-width: 640px; + max-height: 100%; + min-height: 0; padding: 1.25rem 1.25rem 0; background-color: #ffffff; border: 1px solid rgba(27, 27, 29, 0.08); border-radius: 14px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.18); animation: searchModalScaleIn 0.18s ease; + display: flex; + flex-direction: column; + overflow: hidden; --search-local-modal-width: 100%; --search-local-modal-width-sm: 100%; @@ -169,6 +174,10 @@ .searchInputArea { position: relative; margin: -1.25rem -1.25rem 0; + display: flex; + flex-direction: column; + flex: 1 1 auto; + min-height: 0; } .searchInputIcon { @@ -182,10 +191,13 @@ } .searchModal :global(.navbar__search) { - display: block; + display: flex; + flex-direction: column; margin: 0; width: 100%; position: relative; + flex: 1 1 auto; + min-height: 0; } .searchModal :global(.navbar__search-input) { @@ -198,6 +210,7 @@ border: none; border-bottom: 1px solid var(--ifm-hr-background-color); border-radius: 0; + flex-shrink: 0; } .searchEscChip { @@ -260,8 +273,11 @@ } .searchModal :global([class*='searchBar_']) { - display: block !important; + display: flex !important; + flex-direction: column; width: 100% !important; + flex: 1 1 auto; + min-height: 0; } .searchModal :global([class*='dropdownMenu_']) { @@ -271,6 +287,9 @@ padding: 1.5rem 1.5rem; background: transparent; box-shadow: none; + flex: 1 1 auto; + min-height: 0; + overflow-y: auto; } .searchModal :global([class*='suggestion_']) { diff --git a/docs/build-methods/hooks.md b/docs/build-methods/hooks.md index b817ef492..d1aa2ba16 100644 --- a/docs/build-methods/hooks.md +++ b/docs/build-methods/hooks.md @@ -10,8 +10,6 @@ Hooks are the headless layer of the SDK. They handle data fetching, validation, Hooks are the deepest level of control the SDK exposes. Reach for them when [sub-components](./sub-components.md) don't give you enough say over layout or copy, when you need to slot fields into an existing form shell, or when you're building a screen that doesn't map cleanly onto a single sub-component. -> Hooks are an experimental feature. APIs may change between minor versions during 0.x.x releases. - ## Two kinds of hooks - **Form hooks** return pre-bound Field components, form actions, and metadata. You arrange the fields, label them, and decide when to call submit. Validation, submission, and error handling are wired up for you. diff --git a/docs/build-methods/sub-components.md b/docs/build-methods/sub-components.md index badfdae88..b5c5838c8 100644 --- a/docs/build-methods/sub-components.md +++ b/docs/build-methods/sub-components.md @@ -22,11 +22,11 @@ Sub-components sit between [workflows](./workflows.md) and [hooks](./hooks.md): Render the Profile step in isolation: ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function EditProfilePage({ companyId, employeeId }) { return ( - Hooks are an experimental feature. APIs may change between minor versions during 0.x.x releases. - ## Available Form Hooks | Hook | Description | diff --git a/docs/reference/endpoint-inventory.json b/docs/reference/endpoint-inventory.json index 33debae93..d84e6ff88 100644 --- a/docs/reference/endpoint-inventory.json +++ b/docs/reference/endpoint-inventory.json @@ -1,954 +1,5 @@ { "blocks": { - "Company.Industry": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/industry_selection" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyId/industry_selection" - } - ], - "variables": [ - "companyId" - ] - }, - "Company.AssignSignatory": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "POST", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyUuid/signatories/:signatoryUuid" - }, - { - "method": "DELETE", - "path": "/v1/companies/:companyUuid/signatories/:signatoryUuid" - }, - { - "method": "POST", - "path": "/v1/companies/:companyUuid/signatories/invite" - } - ], - "variables": [ - "companyUuid", - "signatoryUuid" - ] - }, - "Company.CreateSignatory": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "POST", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyUuid/signatories/:signatoryUuid" - }, - { - "method": "DELETE", - "path": "/v1/companies/:companyUuid/signatories/:signatoryUuid" - } - ], - "variables": [ - "companyUuid", - "signatoryUuid" - ] - }, - "Company.InviteSignatory": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "DELETE", - "path": "/v1/companies/:companyUuid/signatories/:signatoryUuid" - }, - { - "method": "POST", - "path": "/v1/companies/:companyUuid/signatories/invite" - } - ], - "variables": [ - "companyUuid", - "signatoryUuid" - ] - }, - "Company.DocumentList": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/forms" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/signatories" - } - ], - "variables": [ - "companyId", - "companyUuid" - ] - }, - "Company.DocumentSigner": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/forms" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/signatories" - }, - { - "method": "GET", - "path": "/v1/forms/:formId" - }, - { - "method": "GET", - "path": "/v1/forms/:formId/pdf" - }, - { - "method": "PUT", - "path": "/v1/forms/:formId/sign" - } - ], - "variables": [ - "companyId", - "companyUuid", - "formId" - ] - }, - "Company.OnboardingOverview": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/onboarding_status" - } - ], - "variables": [ - "companyUuid" - ] - }, - "Company.Locations": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/locations" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/locations" - }, - { - "method": "GET", - "path": "/v1/locations/:locationId" - }, - { - "method": "PUT", - "path": "/v1/locations/:locationId" - } - ], - "variables": [ - "companyId", - "locationId" - ] - }, - "Company.LocationForm": { - "endpoints": [ - { - "method": "POST", - "path": "/v1/companies/:companyId/locations" - }, - { - "method": "GET", - "path": "/v1/locations/:locationId" - }, - { - "method": "PUT", - "path": "/v1/locations/:locationId" - } - ], - "variables": [ - "companyId", - "locationId" - ] - }, - "Company.PaySchedule": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/pay_schedules" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/pay_schedules" - }, - { - "method": "GET", - "path": "/v1/companies/:companyId/pay_schedules/:payScheduleId" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyId/pay_schedules/:payScheduleId" - }, - { - "method": "GET", - "path": "/v1/companies/:companyId/pay_schedules/preview" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/payment_configs" - } - ], - "variables": [ - "companyId", - "companyUuid", - "payScheduleId" - ] - }, - "Company.FederalTaxes": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/federal_tax_details" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyId/federal_tax_details" - } - ], - "variables": [ - "companyId" - ] - }, - "Company.BankAccount": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/bank_accounts" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/bank_accounts" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyId/bank_accounts/:bankAccountUuid/verify" - } - ], - "variables": [ - "bankAccountUuid", - "companyId" - ] - }, - "Company.StateTaxesList": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/tax_requirements" - } - ], - "variables": [ - "companyUuid" - ] - }, - "Company.StateTaxesForm": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/tax_requirements/:state" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyUuid/tax_requirements/:state" - } - ], - "variables": [ - "companyUuid", - "state" - ] - }, - "Company.StateTaxes": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/tax_requirements" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/tax_requirements/:state" - }, - { - "method": "PUT", - "path": "/v1/companies/:companyUuid/tax_requirements/:state" - } - ], - "variables": [ - "companyUuid", - "state" - ] - }, - "Contractor.PaymentMethod": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid/bank_accounts" - }, - { - "method": "POST", - "path": "/v1/contractors/:contractorUuid/bank_accounts" - }, - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid/payment_method" - }, - { - "method": "PUT", - "path": "/v1/contractors/:contractorUuid/payment_method" - } - ], - "variables": [ - "contractorUuid" - ] - }, - "Contractor.Address": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid" - }, - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid/address" - }, - { - "method": "PUT", - "path": "/v1/contractors/:contractorUuid/address" - } - ], - "variables": [ - "contractorUuid" - ] - }, - "Contractor.ContractorList": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "DELETE", - "path": "/v1/contractors/:contractorUuid" - } - ], - "variables": [ - "companyUuid", - "contractorUuid" - ] - }, - "Contractor.NewHireReport": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid" - }, - { - "method": "PUT", - "path": "/v1/contractors/:contractorUuid" - } - ], - "variables": [ - "contractorUuid" - ] - }, - "Contractor.ContractorSubmit": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid" - }, - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid/onboarding_status" - }, - { - "method": "PUT", - "path": "/v1/contractors/:contractorUuid/onboarding_status" - } - ], - "variables": [ - "contractorUuid" - ] - }, - "Contractor.ContractorProfile": { - "endpoints": [ - { - "method": "POST", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "GET", - "path": "/v1/contractors/:contractorUuid" - }, - { - "method": "PUT", - "path": "/v1/contractors/:contractorUuid" - } - ], - "variables": [ - "companyUuid", - "contractorUuid" - ] - }, - "Contractor.PaymentsList": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/contractor_payment_groups" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/information_requests" - } - ], - "variables": [ - "companyId", - "companyUuid" - ] - }, - "Contractor.CreatePayment": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/bank_accounts" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/contractor_payment_groups" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/contractor_payment_groups/preview" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/payment_configs" - } - ], - "variables": [ - "companyId", - "companyUuid" - ] - }, - "Contractor.PaymentHistory": { - "endpoints": [ - { - "method": "DELETE", - "path": "/v1/companies/:companyId/contractor_payments/:contractorPaymentId" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "GET", - "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" - } - ], - "variables": [ - "companyId", - "companyUuid", - "contractorPaymentGroupUuid", - "contractorPaymentId" - ] - }, - "Contractor.PaymentSummary": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/bank_accounts" - }, - { - "method": "GET", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "GET", - "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" - } - ], - "variables": [ - "companyId", - "companyUuid", - "contractorPaymentGroupUuid" - ] - }, - "Contractor.PaymentStatement": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyUuid/contractors" - }, - { - "method": "GET", - "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" - }, - { - "method": "GET", - "path": "/v1/contractor_payments/:contractorPaymentUuid/receipt" - } - ], - "variables": [ - "companyUuid", - "contractorPaymentGroupUuid", - "contractorPaymentUuid" - ] - }, - "Employee.EmployeeList": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/employees" - }, - { - "method": "DELETE", - "path": "/v1/employees/:employeeId" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/onboarding_status" - } - ], - "variables": [ - "companyId", - "employeeId" - ] - }, - "Employee.Deductions": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId/garnishments" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/garnishments" - }, - { - "method": "PUT", - "path": "/v1/garnishments/:garnishmentId" - }, - { - "method": "GET", - "path": "/v1/garnishments/child_support" - } - ], - "variables": [ - "employeeId", - "garnishmentId" - ] - }, - "Employee.OnboardingSummary": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/onboarding_status" - } - ], - "variables": [ - "employeeId" - ] - }, - "Employee.Profile": { - "endpoints": [ - { - "method": "POST", - "path": "/v1/companies/:companyId/employees" - }, - { - "method": "GET", - "path": "/v1/companies/:companyId/locations" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/home_addresses" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/home_addresses" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/onboarding_status" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/work_addresses" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/work_addresses" - }, - { - "method": "GET", - "path": "/v1/home_addresses/:homeAddressUuid" - }, - { - "method": "PUT", - "path": "/v1/home_addresses/:homeAddressUuid" - }, - { - "method": "GET", - "path": "/v1/work_addresses/:workAddressUuid" - }, - { - "method": "PUT", - "path": "/v1/work_addresses/:workAddressUuid" - } - ], - "variables": [ - "companyId", - "employeeId", - "homeAddressUuid", - "workAddressUuid" - ] - }, - "Employee.Compensation": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/federal_tax_details" - }, - { - "method": "PUT", - "path": "/v1/compensations/:compensationId" - }, - { - "method": "DELETE", - "path": "/v1/compensations/:compensationId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/jobs" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/jobs" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/work_addresses" - }, - { - "method": "PUT", - "path": "/v1/jobs/:jobId" - }, - { - "method": "DELETE", - "path": "/v1/jobs/:jobId" - }, - { - "method": "POST", - "path": "/v1/jobs/:jobId/compensations" - }, - { - "method": "GET", - "path": "/v1/locations/:locationUuid/minimum_wages" - } - ], - "variables": [ - "companyId", - "compensationId", - "employeeId", - "jobId", - "locationUuid" - ] - }, - "Employee.FederalTaxes": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeUuid/federal_taxes" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeUuid/federal_taxes" - } - ], - "variables": [ - "employeeUuid" - ] - }, - "Employee.StateTaxes": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeUuid/state_taxes" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeUuid/state_taxes" - } - ], - "variables": [ - "employeeUuid" - ] - }, - "Employee.PaymentMethod": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId/bank_accounts" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/bank_accounts" - }, - { - "method": "DELETE", - "path": "/v1/employees/:employeeId/bank_accounts/:bankAccountUuid" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/payment_method" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/payment_method" - } - ], - "variables": [ - "bankAccountUuid", - "employeeId" - ] - }, - "Employee.Landing": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId" - } - ], - "variables": [ - "companyId", - "employeeId" - ] - }, - "Employee.DocumentSigner": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/forms" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/forms/:formId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/forms/:formId/pdf" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/forms/:formId/sign" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/i9_authorization" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/i9_authorization" - } - ], - "variables": [ - "employeeId", - "formId" - ] - }, - "Employee.EmployeeDocuments": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/onboarding_documents_config" - } - ], - "variables": [ - "employeeId" - ] - }, - "Employee.DashboardFlow": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - } - ], - "variables": [ - "employeeId" - ] - }, - "Employee.HomeAddress": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/home_addresses" - }, - { - "method": "DELETE", - "path": "/v1/home_addresses/:homeAddressUuid" - } - ], - "variables": [ - "employeeId", - "homeAddressUuid" - ] - }, - "Employee.EmploymentEligibility": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId/i9_authorization" - }, - { - "method": "PUT", - "path": "/v1/employees/:employeeId/i9_authorization" - } - ], - "variables": [ - "employeeId" - ] - }, - "Employee.TerminateEmployee": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/pay_periods/unprocessed_termination_pay_periods" - }, - { - "method": "GET", - "path": "/v1/companies/:companyId/payrolls" - }, - { - "method": "POST", - "path": "/v1/companies/:companyId/payrolls" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/terminations" - }, - { - "method": "POST", - "path": "/v1/employees/:employeeId/terminations" - }, - { - "method": "PUT", - "path": "/v1/terminations/:employeeId" - } - ], - "variables": [ - "companyId", - "employeeId" - ] - }, - "Employee.TerminationSummary": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/companies/:companyId/employees" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/terminations" - }, - { - "method": "DELETE", - "path": "/v1/employees/:employeeId/terminations" - } - ], - "variables": [ - "companyId", - "employeeId" - ] - }, - "Employee.WorkAddress": { - "endpoints": [ - { - "method": "GET", - "path": "/v1/employees/:employeeId" - }, - { - "method": "GET", - "path": "/v1/employees/:employeeId/work_addresses" - }, - { - "method": "DELETE", - "path": "/v1/work_addresses/:workAddressUuid" - } - ], - "variables": [ - "employeeId", - "workAddressUuid" - ] - }, "InformationRequests.InformationRequestsFlow": { "endpoints": [ { @@ -1338,6 +389,26 @@ "payrollId" ] }, + "Payroll.DismissalPayPeriodSelection": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyId/pay_periods/unprocessed_termination_pay_periods" + }, + { + "method": "POST", + "path": "/v1/companies/:companyId/payrolls" + }, + { + "method": "GET", + "path": "/v1/companies/:companyId/payrolls/:payrollId" + } + ], + "variables": [ + "companyId", + "payrollId" + ] + }, "Payroll.TransitionFlow": { "endpoints": [ { @@ -1445,6 +516,21 @@ "timeOffPolicyUuid" ] }, + "TimeOff.PolicySettingsPresentation": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/time_off_policies/:timeOffPolicyUuid" + }, + { + "method": "PUT", + "path": "/v1/time_off_policies/:timeOffPolicyUuid" + } + ], + "variables": [ + "timeOffPolicyUuid" + ] + }, "TimeOff.AddEmployeesToPolicy": { "endpoints": [ { @@ -1568,6 +654,30 @@ "companyUuid" ] }, + "TimeOff.TimeOffPolicyDetail": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyId/employees" + }, + { + "method": "GET", + "path": "/v1/time_off_policies/:timeOffPolicyUuid" + }, + { + "method": "PUT", + "path": "/v1/time_off_policies/:timeOffPolicyUuid/balance" + }, + { + "method": "PUT", + "path": "/v1/time_off_policies/:timeOffPolicyUuid/remove_employees" + } + ], + "variables": [ + "companyId", + "timeOffPolicyUuid" + ] + }, "TimeOff.TimeOffPolicyDetailPresentation": { "endpoints": [ { @@ -1799,31 +909,77 @@ }, { "method": "GET", - "path": "/v1/employees/:employeeId/work_addresses" + "path": "/v1/employees/:employeeId/work_addresses" + }, + { + "method": "PUT", + "path": "/v1/jobs/:jobId" + }, + { + "method": "DELETE", + "path": "/v1/jobs/:jobId" + }, + { + "method": "POST", + "path": "/v1/jobs/:jobId/compensations" + }, + { + "method": "GET", + "path": "/v1/locations/:locationUuid/minimum_wages" + } + ], + "variables": [ + "companyId", + "compensationId", + "employeeId", + "jobId", + "locationUuid" + ] + }, + "EmployeeOnboarding.JobsList": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeId/jobs" + }, + { + "method": "DELETE", + "path": "/v1/jobs/:jobId" + } + ], + "variables": [ + "employeeId", + "jobId" + ] + }, + "EmployeeOnboarding.FederalTaxes": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeUuid/federal_taxes" }, { "method": "PUT", - "path": "/v1/jobs/:jobId" - }, - { - "method": "DELETE", - "path": "/v1/jobs/:jobId" - }, + "path": "/v1/employees/:employeeUuid/federal_taxes" + } + ], + "variables": [ + "employeeUuid" + ] + }, + "EmployeeOnboarding.StateTaxes": { + "endpoints": [ { - "method": "POST", - "path": "/v1/jobs/:jobId/compensations" + "method": "GET", + "path": "/v1/employees/:employeeUuid/state_taxes" }, { - "method": "GET", - "path": "/v1/locations/:locationUuid/minimum_wages" + "method": "PUT", + "path": "/v1/employees/:employeeUuid/state_taxes" } ], "variables": [ - "companyId", - "compensationId", - "employeeId", - "jobId", - "locationUuid" + "employeeUuid" ] }, "EmployeeOnboarding.Deductions": { @@ -1850,6 +1006,34 @@ "garnishmentId" ] }, + "EmployeeOnboarding.PaymentMethod": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeId/bank_accounts" + }, + { + "method": "POST", + "path": "/v1/employees/:employeeId/bank_accounts" + }, + { + "method": "DELETE", + "path": "/v1/employees/:employeeId/bank_accounts/:bankAccountUuid" + }, + { + "method": "GET", + "path": "/v1/employees/:employeeId/payment_method" + }, + { + "method": "PUT", + "path": "/v1/employees/:employeeId/payment_method" + } + ], + "variables": [ + "bankAccountUuid", + "employeeId" + ] + }, "EmployeeManagement.EmployeeList": { "endpoints": [ { @@ -1941,6 +1125,36 @@ "workAddressUuid" ] }, + "EmployeeManagement.FederalTaxes": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeUuid/federal_taxes" + }, + { + "method": "PUT", + "path": "/v1/employees/:employeeUuid/federal_taxes" + } + ], + "variables": [ + "employeeUuid" + ] + }, + "EmployeeManagement.StateTaxes": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeUuid/state_taxes" + }, + { + "method": "PUT", + "path": "/v1/employees/:employeeUuid/state_taxes" + } + ], + "variables": [ + "employeeUuid" + ] + }, "EmployeeManagement.Profile": { "endpoints": [ { @@ -1965,6 +1179,34 @@ "employeeId" ] }, + "EmployeeManagement.PaymentMethod": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/employees/:employeeId/bank_accounts" + }, + { + "method": "POST", + "path": "/v1/employees/:employeeId/bank_accounts" + }, + { + "method": "DELETE", + "path": "/v1/employees/:employeeId/bank_accounts/:bankAccountUuid" + }, + { + "method": "GET", + "path": "/v1/employees/:employeeId/payment_method" + }, + { + "method": "PUT", + "path": "/v1/employees/:employeeId/payment_method" + } + ], + "variables": [ + "bankAccountUuid", + "employeeId" + ] + }, "EmployeeManagement.PaystubsCard": { "endpoints": [ { @@ -2470,22 +1712,117 @@ "variables": [ "contractorUuid" ] + }, + "ContractorManagement.PaymentsList": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyId/contractor_payment_groups" + }, + { + "method": "GET", + "path": "/v1/companies/:companyUuid/information_requests" + } + ], + "variables": [ + "companyId", + "companyUuid" + ] + }, + "ContractorManagement.CreatePayment": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyId/bank_accounts" + }, + { + "method": "POST", + "path": "/v1/companies/:companyId/contractor_payment_groups" + }, + { + "method": "POST", + "path": "/v1/companies/:companyId/contractor_payment_groups/preview" + }, + { + "method": "GET", + "path": "/v1/companies/:companyUuid/contractors" + }, + { + "method": "GET", + "path": "/v1/companies/:companyUuid/payment_configs" + } + ], + "variables": [ + "companyId", + "companyUuid" + ] + }, + "ContractorManagement.PaymentHistory": { + "endpoints": [ + { + "method": "DELETE", + "path": "/v1/companies/:companyId/contractor_payments/:contractorPaymentId" + }, + { + "method": "GET", + "path": "/v1/companies/:companyUuid/contractors" + }, + { + "method": "GET", + "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" + } + ], + "variables": [ + "companyId", + "companyUuid", + "contractorPaymentGroupUuid", + "contractorPaymentId" + ] + }, + "ContractorManagement.PaymentSummary": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyId/bank_accounts" + }, + { + "method": "GET", + "path": "/v1/companies/:companyUuid/contractors" + }, + { + "method": "GET", + "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" + } + ], + "variables": [ + "companyId", + "companyUuid", + "contractorPaymentGroupUuid" + ] + }, + "ContractorManagement.PaymentStatement": { + "endpoints": [ + { + "method": "GET", + "path": "/v1/companies/:companyUuid/contractors" + }, + { + "method": "GET", + "path": "/v1/contractor_payment_groups/:contractorPaymentGroupUuid" + }, + { + "method": "GET", + "path": "/v1/contractor_payments/:contractorPaymentUuid/receipt" + } + ], + "variables": [ + "companyUuid", + "contractorPaymentGroupUuid", + "contractorPaymentUuid" + ] } }, "flows": { - "Company.OnboardingFlow": { - "blocks": [ - "Company.BankAccount", - "Company.DocumentSigner", - "Company.FederalTaxes", - "Company.Industry", - "Company.Locations", - "Company.OnboardingOverview", - "Company.PaySchedule", - "Company.StateTaxes", - "EmployeeOnboarding.OnboardingFlow" - ] - }, "CompanyOnboarding.OnboardingFlow": { "blocks": [ "CompanyOnboarding.BankAccount", @@ -2499,23 +1836,13 @@ "EmployeeOnboarding.OnboardingFlow" ] }, - "Contractor.OnboardingFlow": { - "blocks": [ - "Contractor.Address", - "Contractor.ContractorList", - "Contractor.ContractorProfile", - "Contractor.ContractorSubmit", - "Contractor.NewHireReport", - "Contractor.PaymentMethod" - ] - }, - "Contractor.PaymentFlow": { + "ContractorManagement.PaymentFlow": { "blocks": [ - "Contractor.CreatePayment", - "Contractor.PaymentHistory", - "Contractor.PaymentStatement", - "Contractor.PaymentSummary", - "Contractor.PaymentsList", + "ContractorManagement.CreatePayment", + "ContractorManagement.PaymentHistory", + "ContractorManagement.PaymentStatement", + "ContractorManagement.PaymentSummary", + "ContractorManagement.PaymentsList", "InformationRequests.InformationRequestsFlow" ] }, @@ -2529,65 +1856,6 @@ "ContractorOnboarding.PaymentMethod" ] }, - "Employee.DashboardFlow": { - "blocks": [ - "Employee.HomeAddress", - "Employee.WorkAddress", - "EmployeeManagement.Compensation", - "EmployeeManagement.Deductions", - "EmployeeManagement.Documents", - "EmployeeManagement.FederalTaxes", - "EmployeeManagement.PaymentMethod", - "EmployeeManagement.PaystubsCard", - "EmployeeManagement.Profile", - "EmployeeManagement.StateTaxes" - ] - }, - "Employee.EmployeeListFlow": { - "blocks": [ - "Employee.DashboardFlow", - "Employee.OnboardingExecutionFlow", - "Employee.TerminationFlow", - "EmployeeManagement.EmployeeList" - ] - }, - "Employee.OnboardingExecutionFlow": { - "blocks": [ - "Employee.Compensation", - "Employee.Deductions", - "Employee.EmployeeDocuments", - "Employee.OnboardingSummary", - "Employee.PaymentMethod", - "Employee.Profile", - "EmployeeOnboarding.FederalTaxes", - "EmployeeOnboarding.StateTaxes" - ] - }, - "Employee.OnboardingFlow": { - "blocks": [ - "Employee.EmployeeList", - "Employee.OnboardingExecutionFlow" - ] - }, - "Employee.SelfOnboardingFlow": { - "blocks": [ - "Employee.DocumentSigner", - "Employee.Landing", - "Employee.OnboardingSummary", - "Employee.PaymentMethod", - "Employee.Profile", - "EmployeeOnboarding.FederalTaxes", - "EmployeeOnboarding.StateTaxes" - ] - }, - "Employee.TerminationFlow": { - "blocks": [ - "Employee.TerminateEmployee", - "Employee.TerminationSummary", - "Payroll.DismissalFlow", - "Payroll.PayrollLanding" - ] - }, "EmployeeManagement.DashboardFlow": { "blocks": [ "EmployeeManagement.Compensation", @@ -2620,7 +1888,6 @@ }, "EmployeeOnboarding.OnboardingExecutionFlow": { "blocks": [ - "Employee.PaymentMethod", "EmployeeOnboarding.Compensation", "EmployeeOnboarding.Deductions", "EmployeeOnboarding.EmployeeDocuments", @@ -2638,7 +1905,6 @@ }, "EmployeeOnboarding.SelfOnboardingFlow": { "blocks": [ - "Employee.PaymentMethod", "EmployeeOnboarding.DocumentSigner", "EmployeeOnboarding.FederalTaxes", "EmployeeOnboarding.Landing", @@ -2655,6 +1921,7 @@ }, "Payroll.DismissalFlow": { "blocks": [ + "Payroll.DismissalPayPeriodSelection", "Payroll.PayrollExecutionFlow" ] }, @@ -2697,7 +1964,7 @@ "TimeOff.PolicyList", "TimeOff.PolicySettings", "TimeOff.PolicyTypeSelector", - "TimeOff.TimeOffPolicyDetailPresentation", + "TimeOff.TimeOffPolicyDetail", "TimeOff.ViewHolidayEmployees", "TimeOff.ViewHolidaySchedule" ] diff --git a/docs/reference/endpoint-reference.md b/docs/reference/endpoint-reference.md index bc8bf0a89..d1eb4d48d 100644 --- a/docs/reference/endpoint-reference.md +++ b/docs/reference/endpoint-reference.md @@ -15,173 +15,6 @@ Paths use named parameters (`:companyId`, `:employeeId`, etc.) that correspond t import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' ``` -## Company components - -| Component | Method | Path | -| --- | --- | --- | -| **Company.Industry** | GET | `/v1/companies/:companyId/industry_selection` | -| | PUT | `/v1/companies/:companyId/industry_selection` | -| **Company.AssignSignatory** | GET | `/v1/companies/:companyUuid/signatories` | -| | POST | `/v1/companies/:companyUuid/signatories` | -| | PUT | `/v1/companies/:companyUuid/signatories/:signatoryUuid` | -| | DELETE | `/v1/companies/:companyUuid/signatories/:signatoryUuid` | -| | POST | `/v1/companies/:companyUuid/signatories/invite` | -| **Company.CreateSignatory** | GET | `/v1/companies/:companyUuid/signatories` | -| | POST | `/v1/companies/:companyUuid/signatories` | -| | PUT | `/v1/companies/:companyUuid/signatories/:signatoryUuid` | -| | DELETE | `/v1/companies/:companyUuid/signatories/:signatoryUuid` | -| **Company.InviteSignatory** | GET | `/v1/companies/:companyUuid/signatories` | -| | DELETE | `/v1/companies/:companyUuid/signatories/:signatoryUuid` | -| | POST | `/v1/companies/:companyUuid/signatories/invite` | -| **Company.DocumentList** | GET | `/v1/companies/:companyId/forms` | -| | GET | `/v1/companies/:companyUuid/signatories` | -| **Company.DocumentSigner** | GET | `/v1/companies/:companyId/forms` | -| | GET | `/v1/companies/:companyUuid/signatories` | -| | GET | `/v1/forms/:formId` | -| | GET | `/v1/forms/:formId/pdf` | -| | PUT | `/v1/forms/:formId/sign` | -| **Company.OnboardingOverview** | GET | `/v1/companies/:companyUuid/onboarding_status` | -| **Company.Locations** | GET | `/v1/companies/:companyId/locations` | -| | POST | `/v1/companies/:companyId/locations` | -| | GET | `/v1/locations/:locationId` | -| | PUT | `/v1/locations/:locationId` | -| **Company.LocationForm** | POST | `/v1/companies/:companyId/locations` | -| | GET | `/v1/locations/:locationId` | -| | PUT | `/v1/locations/:locationId` | -| **Company.PaySchedule** | GET | `/v1/companies/:companyId/pay_schedules` | -| | POST | `/v1/companies/:companyId/pay_schedules` | -| | GET | `/v1/companies/:companyId/pay_schedules/:payScheduleId` | -| | PUT | `/v1/companies/:companyId/pay_schedules/:payScheduleId` | -| | GET | `/v1/companies/:companyId/pay_schedules/preview` | -| | GET | `/v1/companies/:companyUuid/payment_configs` | -| **Company.FederalTaxes** | GET | `/v1/companies/:companyId/federal_tax_details` | -| | PUT | `/v1/companies/:companyId/federal_tax_details` | -| **Company.BankAccount** | GET | `/v1/companies/:companyId/bank_accounts` | -| | POST | `/v1/companies/:companyId/bank_accounts` | -| | PUT | `/v1/companies/:companyId/bank_accounts/:bankAccountUuid/verify` | -| **Company.StateTaxesList** | GET | `/v1/companies/:companyUuid/tax_requirements` | -| **Company.StateTaxesForm** | GET | `/v1/companies/:companyUuid/tax_requirements/:state` | -| | PUT | `/v1/companies/:companyUuid/tax_requirements/:state` | -| **Company.StateTaxes** | GET | `/v1/companies/:companyUuid/tax_requirements` | -| | GET | `/v1/companies/:companyUuid/tax_requirements/:state` | -| | PUT | `/v1/companies/:companyUuid/tax_requirements/:state` | - -## Contractor components - -| Component | Method | Path | -| --- | --- | --- | -| **Contractor.PaymentMethod** | GET | `/v1/contractors/:contractorUuid/bank_accounts` | -| | POST | `/v1/contractors/:contractorUuid/bank_accounts` | -| | GET | `/v1/contractors/:contractorUuid/payment_method` | -| | PUT | `/v1/contractors/:contractorUuid/payment_method` | -| **Contractor.Address** | GET | `/v1/contractors/:contractorUuid` | -| | GET | `/v1/contractors/:contractorUuid/address` | -| | PUT | `/v1/contractors/:contractorUuid/address` | -| **Contractor.ContractorList** | GET | `/v1/companies/:companyUuid/contractors` | -| | DELETE | `/v1/contractors/:contractorUuid` | -| **Contractor.NewHireReport** | GET | `/v1/contractors/:contractorUuid` | -| | PUT | `/v1/contractors/:contractorUuid` | -| **Contractor.ContractorSubmit** | GET | `/v1/contractors/:contractorUuid` | -| | GET | `/v1/contractors/:contractorUuid/onboarding_status` | -| | PUT | `/v1/contractors/:contractorUuid/onboarding_status` | -| **Contractor.ContractorProfile** | POST | `/v1/companies/:companyUuid/contractors` | -| | GET | `/v1/contractors/:contractorUuid` | -| | PUT | `/v1/contractors/:contractorUuid` | -| **Contractor.PaymentsList** | GET | `/v1/companies/:companyId/contractor_payment_groups` | -| | GET | `/v1/companies/:companyUuid/information_requests` | -| **Contractor.CreatePayment** | GET | `/v1/companies/:companyId/bank_accounts` | -| | POST | `/v1/companies/:companyId/contractor_payment_groups` | -| | POST | `/v1/companies/:companyId/contractor_payment_groups/preview` | -| | GET | `/v1/companies/:companyUuid/contractors` | -| | GET | `/v1/companies/:companyUuid/payment_configs` | -| **Contractor.PaymentHistory** | DELETE | `/v1/companies/:companyId/contractor_payments/:contractorPaymentId` | -| | GET | `/v1/companies/:companyUuid/contractors` | -| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | -| **Contractor.PaymentSummary** | GET | `/v1/companies/:companyId/bank_accounts` | -| | GET | `/v1/companies/:companyUuid/contractors` | -| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | -| **Contractor.PaymentStatement** | GET | `/v1/companies/:companyUuid/contractors` | -| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | -| | GET | `/v1/contractor_payments/:contractorPaymentUuid/receipt` | - -## Employee components - -| Component | Method | Path | -| --- | --- | --- | -| **Employee.EmployeeList** | GET | `/v1/companies/:companyId/employees` | -| | DELETE | `/v1/employees/:employeeId` | -| | PUT | `/v1/employees/:employeeId/onboarding_status` | -| **Employee.Deductions** | GET | `/v1/employees/:employeeId/garnishments` | -| | POST | `/v1/employees/:employeeId/garnishments` | -| | PUT | `/v1/garnishments/:garnishmentId` | -| | GET | `/v1/garnishments/child_support` | -| **Employee.OnboardingSummary** | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/onboarding_status` | -| **Employee.Profile** | POST | `/v1/companies/:companyId/employees` | -| | GET | `/v1/companies/:companyId/locations` | -| | GET | `/v1/employees/:employeeId` | -| | PUT | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/home_addresses` | -| | POST | `/v1/employees/:employeeId/home_addresses` | -| | PUT | `/v1/employees/:employeeId/onboarding_status` | -| | GET | `/v1/employees/:employeeId/work_addresses` | -| | POST | `/v1/employees/:employeeId/work_addresses` | -| | GET | `/v1/home_addresses/:homeAddressUuid` | -| | PUT | `/v1/home_addresses/:homeAddressUuid` | -| | GET | `/v1/work_addresses/:workAddressUuid` | -| | PUT | `/v1/work_addresses/:workAddressUuid` | -| **Employee.Compensation** | GET | `/v1/companies/:companyId/federal_tax_details` | -| | PUT | `/v1/compensations/:compensationId` | -| | DELETE | `/v1/compensations/:compensationId` | -| | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/jobs` | -| | POST | `/v1/employees/:employeeId/jobs` | -| | GET | `/v1/employees/:employeeId/work_addresses` | -| | PUT | `/v1/jobs/:jobId` | -| | DELETE | `/v1/jobs/:jobId` | -| | POST | `/v1/jobs/:jobId/compensations` | -| | GET | `/v1/locations/:locationUuid/minimum_wages` | -| **Employee.FederalTaxes** | GET | `/v1/employees/:employeeUuid/federal_taxes` | -| | PUT | `/v1/employees/:employeeUuid/federal_taxes` | -| **Employee.StateTaxes** | GET | `/v1/employees/:employeeUuid/state_taxes` | -| | PUT | `/v1/employees/:employeeUuid/state_taxes` | -| **Employee.PaymentMethod** | GET | `/v1/employees/:employeeId/bank_accounts` | -| | POST | `/v1/employees/:employeeId/bank_accounts` | -| | DELETE | `/v1/employees/:employeeId/bank_accounts/:bankAccountUuid` | -| | GET | `/v1/employees/:employeeId/payment_method` | -| | PUT | `/v1/employees/:employeeId/payment_method` | -| **Employee.Landing** | GET | `/v1/companies/:companyId` | -| | GET | `/v1/employees/:employeeId` | -| **Employee.DocumentSigner** | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/forms` | -| | GET | `/v1/employees/:employeeId/forms/:formId` | -| | GET | `/v1/employees/:employeeId/forms/:formId/pdf` | -| | PUT | `/v1/employees/:employeeId/forms/:formId/sign` | -| | GET | `/v1/employees/:employeeId/i9_authorization` | -| | PUT | `/v1/employees/:employeeId/i9_authorization` | -| **Employee.EmployeeDocuments** | GET | `/v1/employees/:employeeId` | -| | PUT | `/v1/employees/:employeeId/onboarding_documents_config` | -| **Employee.DashboardFlow** | GET | `/v1/employees/:employeeId` | -| **Employee.HomeAddress** | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/home_addresses` | -| | DELETE | `/v1/home_addresses/:homeAddressUuid` | -| **Employee.EmploymentEligibility** | GET | `/v1/employees/:employeeId/i9_authorization` | -| | PUT | `/v1/employees/:employeeId/i9_authorization` | -| **Employee.TerminateEmployee** | GET | `/v1/companies/:companyId/pay_periods/unprocessed_termination_pay_periods` | -| | GET | `/v1/companies/:companyId/payrolls` | -| | POST | `/v1/companies/:companyId/payrolls` | -| | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/terminations` | -| | POST | `/v1/employees/:employeeId/terminations` | -| | PUT | `/v1/terminations/:employeeId` | -| **Employee.TerminationSummary** | GET | `/v1/companies/:companyId/employees` | -| | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/terminations` | -| | DELETE | `/v1/employees/:employeeId/terminations` | -| **Employee.WorkAddress** | GET | `/v1/employees/:employeeId` | -| | GET | `/v1/employees/:employeeId/work_addresses` | -| | DELETE | `/v1/work_addresses/:workAddressUuid` | - ## InformationRequests components | Component | Method | Path | @@ -252,6 +85,9 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | **Payroll.DismissalFlow** | GET | `/v1/companies/:companyId/pay_periods/unprocessed_termination_pay_periods` | | | POST | `/v1/companies/:companyId/payrolls` | | | GET | `/v1/companies/:companyId/payrolls/:payrollId` | +| **Payroll.DismissalPayPeriodSelection** | GET | `/v1/companies/:companyId/pay_periods/unprocessed_termination_pay_periods` | +| | POST | `/v1/companies/:companyId/payrolls` | +| | GET | `/v1/companies/:companyId/payrolls/:payrollId` | | **Payroll.TransitionFlow** | GET | `/v1/companies/:companyId/payrolls/:payrollId` | | **Payroll.TransitionCreation** | GET | `/v1/companies/:companyId/pay_schedules` | | | POST | `/v1/companies/:companyId/payrolls` | @@ -272,6 +108,8 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | | PUT | `/v1/time_off_policies/:timeOffPolicyUuid` | | **TimeOff.PolicySettings** | GET | `/v1/time_off_policies/:timeOffPolicyUuid` | | | PUT | `/v1/time_off_policies/:timeOffPolicyUuid` | +| **TimeOff.PolicySettingsPresentation** | GET | `/v1/time_off_policies/:timeOffPolicyUuid` | +| | PUT | `/v1/time_off_policies/:timeOffPolicyUuid` | | **TimeOff.AddEmployeesToPolicy** | GET | `/v1/companies/:companyId/employees` | | | GET | `/v1/time_off_policies/:timeOffPolicyUuid` | | | PUT | `/v1/time_off_policies/:timeOffPolicyUuid` | @@ -291,6 +129,10 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | **TimeOff.ViewHolidaySchedule** | GET | `/v1/companies/:companyId/employees` | | | GET | `/v1/companies/:companyUuid/holiday_pay_policy` | | | PUT | `/v1/companies/:companyUuid/holiday_pay_policy/remove` | +| **TimeOff.TimeOffPolicyDetail** | GET | `/v1/companies/:companyId/employees` | +| | GET | `/v1/time_off_policies/:timeOffPolicyUuid` | +| | PUT | `/v1/time_off_policies/:timeOffPolicyUuid/balance` | +| | PUT | `/v1/time_off_policies/:timeOffPolicyUuid/remove_employees` | | **TimeOff.TimeOffPolicyDetailPresentation** | GET | `/v1/companies/:companyId/employees` | | | GET | `/v1/time_off_policies/:timeOffPolicyUuid` | | | PUT | `/v1/time_off_policies/:timeOffPolicyUuid/balance` | @@ -342,10 +184,21 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | | DELETE | `/v1/jobs/:jobId` | | | POST | `/v1/jobs/:jobId/compensations` | | | GET | `/v1/locations/:locationUuid/minimum_wages` | +| **EmployeeOnboarding.JobsList** | GET | `/v1/employees/:employeeId/jobs` | +| | DELETE | `/v1/jobs/:jobId` | +| **EmployeeOnboarding.FederalTaxes** | GET | `/v1/employees/:employeeUuid/federal_taxes` | +| | PUT | `/v1/employees/:employeeUuid/federal_taxes` | +| **EmployeeOnboarding.StateTaxes** | GET | `/v1/employees/:employeeUuid/state_taxes` | +| | PUT | `/v1/employees/:employeeUuid/state_taxes` | | **EmployeeOnboarding.Deductions** | GET | `/v1/employees/:employeeId/garnishments` | | | POST | `/v1/employees/:employeeId/garnishments` | | | PUT | `/v1/garnishments/:garnishmentId` | | | GET | `/v1/garnishments/child_support` | +| **EmployeeOnboarding.PaymentMethod** | GET | `/v1/employees/:employeeId/bank_accounts` | +| | POST | `/v1/employees/:employeeId/bank_accounts` | +| | DELETE | `/v1/employees/:employeeId/bank_accounts/:bankAccountUuid` | +| | GET | `/v1/employees/:employeeId/payment_method` | +| | PUT | `/v1/employees/:employeeId/payment_method` | ## EmployeeManagement components @@ -364,10 +217,19 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | **EmployeeManagement.WorkAddress** | GET | `/v1/employees/:employeeId` | | | GET | `/v1/employees/:employeeId/work_addresses` | | | DELETE | `/v1/work_addresses/:workAddressUuid` | +| **EmployeeManagement.FederalTaxes** | GET | `/v1/employees/:employeeUuid/federal_taxes` | +| | PUT | `/v1/employees/:employeeUuid/federal_taxes` | +| **EmployeeManagement.StateTaxes** | GET | `/v1/employees/:employeeUuid/state_taxes` | +| | PUT | `/v1/employees/:employeeUuid/state_taxes` | | **EmployeeManagement.Profile** | POST | `/v1/companies/:companyId/employees` | | | GET | `/v1/employees/:employeeId` | | | PUT | `/v1/employees/:employeeId` | | | PUT | `/v1/employees/:employeeId/onboarding_status` | +| **EmployeeManagement.PaymentMethod** | GET | `/v1/employees/:employeeId/bank_accounts` | +| | POST | `/v1/employees/:employeeId/bank_accounts` | +| | DELETE | `/v1/employees/:employeeId/bank_accounts/:bankAccountUuid` | +| | GET | `/v1/employees/:employeeId/payment_method` | +| | PUT | `/v1/employees/:employeeId/payment_method` | | **EmployeeManagement.PaystubsCard** | GET | `/v1/employees/:employeeId/pay_stubs` | | | GET | `/v1/payrolls/:payrollId/employees/:employeeId/pay_stub` | | **EmployeeManagement.Compensation** | GET | `/v1/employees/:employeeId/jobs` | @@ -457,33 +319,46 @@ import inventory from '@gusto/embedded-react-sdk/endpoint-inventory.json' | | GET | `/v1/contractors/:contractorUuid/onboarding_status` | | | PUT | `/v1/contractors/:contractorUuid/onboarding_status` | +## ContractorManagement components + +| Component | Method | Path | +| --- | --- | --- | +| **ContractorManagement.PaymentsList** | GET | `/v1/companies/:companyId/contractor_payment_groups` | +| | GET | `/v1/companies/:companyUuid/information_requests` | +| **ContractorManagement.CreatePayment** | GET | `/v1/companies/:companyId/bank_accounts` | +| | POST | `/v1/companies/:companyId/contractor_payment_groups` | +| | POST | `/v1/companies/:companyId/contractor_payment_groups/preview` | +| | GET | `/v1/companies/:companyUuid/contractors` | +| | GET | `/v1/companies/:companyUuid/payment_configs` | +| **ContractorManagement.PaymentHistory** | DELETE | `/v1/companies/:companyId/contractor_payments/:contractorPaymentId` | +| | GET | `/v1/companies/:companyUuid/contractors` | +| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | +| **ContractorManagement.PaymentSummary** | GET | `/v1/companies/:companyId/bank_accounts` | +| | GET | `/v1/companies/:companyUuid/contractors` | +| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | +| **ContractorManagement.PaymentStatement** | GET | `/v1/companies/:companyUuid/contractors` | +| | GET | `/v1/contractor_payment_groups/:contractorPaymentGroupUuid` | +| | GET | `/v1/contractor_payments/:contractorPaymentUuid/receipt` | + ## Flows Flows compose multiple blocks into a single workflow. The endpoint list for a flow is the union of all its block endpoints. | Flow | Blocks included | | --- | --- | -| **Company.OnboardingFlow** | Company.BankAccount, Company.DocumentSigner, Company.FederalTaxes, Company.Industry, Company.Locations, Company.OnboardingOverview, Company.PaySchedule, Company.StateTaxes, EmployeeOnboarding.OnboardingFlow | | **CompanyOnboarding.OnboardingFlow** | CompanyOnboarding.BankAccount, CompanyOnboarding.DocumentSigner, CompanyOnboarding.FederalTaxes, CompanyOnboarding.Industry, CompanyOnboarding.Locations, CompanyOnboarding.OnboardingOverview, CompanyOnboarding.PaySchedule, CompanyOnboarding.StateTaxes, EmployeeOnboarding.OnboardingFlow | -| **Contractor.OnboardingFlow** | Contractor.Address, Contractor.ContractorList, Contractor.ContractorProfile, Contractor.ContractorSubmit, Contractor.NewHireReport, Contractor.PaymentMethod | -| **Contractor.PaymentFlow** | Contractor.CreatePayment, Contractor.PaymentHistory, Contractor.PaymentStatement, Contractor.PaymentSummary, Contractor.PaymentsList, InformationRequests.InformationRequestsFlow | +| **ContractorManagement.PaymentFlow** | ContractorManagement.CreatePayment, ContractorManagement.PaymentHistory, ContractorManagement.PaymentStatement, ContractorManagement.PaymentSummary, ContractorManagement.PaymentsList, InformationRequests.InformationRequestsFlow | | **ContractorOnboarding.OnboardingFlow** | ContractorOnboarding.Address, ContractorOnboarding.ContractorList, ContractorOnboarding.ContractorProfile, ContractorOnboarding.ContractorSubmit, ContractorOnboarding.NewHireReport, ContractorOnboarding.PaymentMethod | -| **Employee.DashboardFlow** | Employee.HomeAddress, Employee.WorkAddress, EmployeeManagement.Compensation, EmployeeManagement.Deductions, EmployeeManagement.Documents, EmployeeManagement.FederalTaxes, EmployeeManagement.PaymentMethod, EmployeeManagement.PaystubsCard, EmployeeManagement.Profile, EmployeeManagement.StateTaxes | -| **Employee.EmployeeListFlow** | Employee.DashboardFlow, Employee.OnboardingExecutionFlow, Employee.TerminationFlow, EmployeeManagement.EmployeeList | -| **Employee.OnboardingExecutionFlow** | Employee.Compensation, Employee.Deductions, Employee.EmployeeDocuments, Employee.OnboardingSummary, Employee.PaymentMethod, Employee.Profile, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.StateTaxes | -| **Employee.OnboardingFlow** | Employee.EmployeeList, Employee.OnboardingExecutionFlow | -| **Employee.SelfOnboardingFlow** | Employee.DocumentSigner, Employee.Landing, Employee.OnboardingSummary, Employee.PaymentMethod, Employee.Profile, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.StateTaxes | -| **Employee.TerminationFlow** | Employee.TerminateEmployee, Employee.TerminationSummary, Payroll.DismissalFlow, Payroll.PayrollLanding | | **EmployeeManagement.DashboardFlow** | EmployeeManagement.Compensation, EmployeeManagement.Deductions, EmployeeManagement.Documents, EmployeeManagement.FederalTaxes, EmployeeManagement.HomeAddress, EmployeeManagement.PaymentMethod, EmployeeManagement.PaystubsCard, EmployeeManagement.Profile, EmployeeManagement.StateTaxes, EmployeeManagement.WorkAddress | | **EmployeeManagement.EmployeeListFlow** | EmployeeManagement.DashboardFlow, EmployeeManagement.EmployeeList, EmployeeManagement.TerminationFlow, EmployeeOnboarding.OnboardingExecutionFlow | | **EmployeeManagement.TerminationFlow** | EmployeeManagement.TerminateEmployee, EmployeeManagement.TerminationSummary, Payroll.DismissalFlow, Payroll.PayrollLanding | -| **EmployeeOnboarding.OnboardingExecutionFlow** | Employee.PaymentMethod, EmployeeOnboarding.Compensation, EmployeeOnboarding.Deductions, EmployeeOnboarding.EmployeeDocuments, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.OnboardingSummary, EmployeeOnboarding.Profile, EmployeeOnboarding.StateTaxes | +| **EmployeeOnboarding.OnboardingExecutionFlow** | EmployeeOnboarding.Compensation, EmployeeOnboarding.Deductions, EmployeeOnboarding.EmployeeDocuments, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.OnboardingSummary, EmployeeOnboarding.Profile, EmployeeOnboarding.StateTaxes | | **EmployeeOnboarding.OnboardingFlow** | EmployeeOnboarding.EmployeeList, EmployeeOnboarding.OnboardingExecutionFlow | -| **EmployeeOnboarding.SelfOnboardingFlow** | Employee.PaymentMethod, EmployeeOnboarding.DocumentSigner, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.Landing, EmployeeOnboarding.OnboardingSummary, EmployeeOnboarding.Profile, EmployeeOnboarding.StateTaxes | +| **EmployeeOnboarding.SelfOnboardingFlow** | EmployeeOnboarding.DocumentSigner, EmployeeOnboarding.FederalTaxes, EmployeeOnboarding.Landing, EmployeeOnboarding.OnboardingSummary, EmployeeOnboarding.Profile, EmployeeOnboarding.StateTaxes | | **InformationRequests.InformationRequestsFlow** | InformationRequests.InformationRequestForm, InformationRequests.InformationRequestList | -| **Payroll.DismissalFlow** | Payroll.PayrollExecutionFlow | +| **Payroll.DismissalFlow** | Payroll.DismissalPayPeriodSelection, Payroll.PayrollExecutionFlow | | **Payroll.OffCycleFlow** | Payroll.OffCycleCreation, Payroll.PayrollExecutionFlow | | **Payroll.PayrollExecutionFlow** | Payroll.PayrollFlow | | **Payroll.PayrollFlow** | Payroll.OffCycleFlow, Payroll.PayrollBlockerList, Payroll.PayrollConfiguration, Payroll.PayrollEditEmployee, Payroll.PayrollExecutionFlow, Payroll.PayrollLanding, Payroll.PayrollOverview, Payroll.PayrollReceipts, Payroll.TransitionFlow | | **Payroll.TransitionFlow** | Payroll.PayrollExecutionFlow, Payroll.TransitionCreation | -| **TimeOff.TimeOffFlow** | TimeOff.AddEmployeesHoliday, TimeOff.AddEmployeesToPolicy, TimeOff.HolidaySelectionForm, TimeOff.PolicyConfigurationForm, TimeOff.PolicyList, TimeOff.PolicySettings, TimeOff.PolicyTypeSelector, TimeOff.TimeOffPolicyDetailPresentation, TimeOff.ViewHolidayEmployees, TimeOff.ViewHolidaySchedule | +| **TimeOff.TimeOffFlow** | TimeOff.AddEmployeesHoliday, TimeOff.AddEmployeesToPolicy, TimeOff.HolidaySelectionForm, TimeOff.PolicyConfigurationForm, TimeOff.PolicyList, TimeOff.PolicySettings, TimeOff.PolicyTypeSelector, TimeOff.TimeOffPolicyDetail, TimeOff.ViewHolidayEmployees, TimeOff.ViewHolidaySchedule | diff --git a/docs/surfaces/company-onboarding/sub-components.md b/docs/surfaces/company-onboarding/sub-components.md index 92e1beda9..e29af5a7b 100644 --- a/docs/surfaces/company-onboarding/sub-components.md +++ b/docs/surfaces/company-onboarding/sub-components.md @@ -14,14 +14,14 @@ Company onboarding components can be used to compose your own workflow, or can b A component allowing users to choose between creating a new signatory with full details or inviting someone else to become the signatory. -For more granular control, you can use `Company.CreateSignatory` or `Company.InviteSignatory` directly. +For more granular control, you can use `CompanyOnboarding.CreateSignatory` or `CompanyOnboarding.InviteSignatory` directly. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -52,11 +52,11 @@ function MyComponent() { A standalone form for creating a new signatory with full personal details including name, contact information, SSN, and home address. Use this component when you want to provide only the create signatory flow without the invite option. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -85,11 +85,11 @@ function MyComponent() { A standalone form for inviting someone else to become the company signatory. The invited person will receive an email to complete their signatory information. Use this component when you want to provide only the invite signatory flow without the create option. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -116,10 +116,10 @@ function MyComponent() { A component for selecting and saving the company's industry classification (NAICS code). The selector presents a searchable list of industry options for the company. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -143,11 +143,11 @@ function MyComponent() { Provides an interface for company representatives to read and sign required company documents. The component handles document listing, signatory management, and document signing workflow. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -180,14 +180,14 @@ function MyComponent() { ## Documents list -A standalone component that displays the list of company documents to be signed and lets the user manage signatories. This is the lower-level building block used internally by `Company.DocumentSigner` for its list view. Use this component directly when you need full control over navigation between the document list and the signature form. +A standalone component that displays the list of company documents to be signed and lets the user manage signatories. This is the lower-level building block used internally by `CompanyOnboarding.DocumentSigner` for its list view. Use this component directly when you need full control over navigation between the document list and the signature form. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -212,14 +212,14 @@ function MyComponent() { ## Sign a document -A standalone form for signing an individual company document. This is the lower-level building block used internally by `Company.DocumentSigner` for its signing view. Use this component directly when you need full control over navigation between the document list and the signature form (e.g. you are routing the user yourself after they select a form from `Company.DocumentList`). +A standalone form for signing an individual company document. This is the lower-level building block used internally by `CompanyOnboarding.DocumentSigner` for its signing view. Use this component directly when you need full control over navigation between the document list and the signature form (e.g. you are routing the user yourself after they select a form from `CompanyOnboarding.DocumentList`). ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -251,11 +251,11 @@ function MyComponent() { A component for adding company federal tax information including EIN, tax payer type, filing form, and legal name. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -282,10 +282,10 @@ function MyComponent() { A component for managing company pay schedules, including creating, editing, and viewing pay schedules with preview functionality. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -308,13 +308,13 @@ function MyComponent() { ## Locations -An orchestrated component for managing company addresses, including mailing and filing address. Internally uses a state machine to switch between a list view and a create/edit form. For more granular control, you can use `Company.LocationForm` directly. +An orchestrated component for managing company addresses, including mailing and filing address. Internally uses a state machine to switch between a list view and a create/edit form. For more granular control, you can use `CompanyOnboarding.LocationForm` directly. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -340,16 +340,16 @@ function MyComponent() { ## Location form -A standalone form component for creating a new company location or editing an existing one. This is the lower-level building block used internally by `Company.Locations` for its create/edit views. Use this component directly when you need full control over navigation between the list and form views. +A standalone form component for creating a new company location or editing an existing one. This is the lower-level building block used internally by `CompanyOnboarding.Locations` for its create/edit views. Use this component directly when you need full control over navigation between the list and form views. Pass a `locationId` to edit an existing location; omit it to create a new location. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -381,10 +381,10 @@ function MyComponent() { A component for managing company bank account ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -413,10 +413,10 @@ function MyComponent() { An orchestrated component for managing company state taxes setup. Internally uses a state machine to switch between a list view and an edit form. For more granular control, you can use `CompanyOnboarding.StateTaxesList` or `CompanyOnboarding.StateTaxesForm` directly. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -439,14 +439,14 @@ function MyComponent() { ## State taxes form -A standalone form component for editing state tax requirements for a specific state. This is the lower-level building block used internally by `Company.StateTaxes` for its edit view. Use this component directly when you need full control over navigation between the list and form views. +A standalone form component for editing state tax requirements for a specific state. This is the lower-level building block used internally by `CompanyOnboarding.StateTaxes` for its edit view. Use this component directly when you need full control over navigation between the list and form views. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -474,14 +474,14 @@ function MyComponent() { ## State taxes list -A standalone component that displays the list of state tax requirements for a company. This is the lower-level building block used internally by `Company.StateTaxes` for its list view. Use this component directly when you need full control over navigation between the list and form views. +A standalone component that displays the list of state tax requirements for a company. This is the lower-level building block used internally by `CompanyOnboarding.StateTaxes` for its list view. Use this component directly when you need full control over navigation between the list and form views. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -507,11 +507,11 @@ function MyComponent() { Displays the company's overall onboarding status. Shows completed steps and remaining requirements, providing a high-level summary of where the company is in the onboarding process. Used as the landing/summary screen of the onboarding flow. ```jsx title="MyComponent.tsx" -import { Company } from '@gusto/embedded-react-sdk' +import { CompanyOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> diff --git a/docs/surfaces/contractor-onboarding/sub-components.md b/docs/surfaces/contractor-onboarding/sub-components.md index 8ee270055..a7fe4ee0a 100644 --- a/docs/surfaces/contractor-onboarding/sub-components.md +++ b/docs/surfaces/contractor-onboarding/sub-components.md @@ -8,7 +8,6 @@ order: 2 Contractor onboarding components can be used to compose your own workflow, or can be rendered in isolation. For guidance on creating a custom workflow, see [docs on composition](../../integration-guide/composition.md). -> Legacy imports via `Contractor.*` (e.g. `Contractor.OnboardingFlow`) continue to work. --- @@ -17,11 +16,11 @@ Contractor onboarding components can be used to compose your own workflow, or ca Displays a list of contractors for a company, allowing users to add new contractors, edit existing ones, delete contractors, and continue the onboarding process. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> @@ -53,11 +52,11 @@ function MyComponent() { A comprehensive form for creating and editing contractor profiles. Supports both individual and business contractor types, with different field sets for each. Includes options for wage type, self-onboarding invitations, and start date. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> @@ -89,10 +88,10 @@ function MyComponent() { A form for collecting and updating a contractor's mailing address. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -118,10 +117,10 @@ function MyComponent() { Manages the contractor's payment method, including adding a bank account for direct deposit or selecting check as the payment method. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -147,10 +146,10 @@ function MyComponent() { Handles new hire reporting requirements for the contractor. Behavior varies based on whether the contractor is going through admin onboarding or self-onboarding. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -176,10 +175,10 @@ function MyComponent() { Finalizes the contractor onboarding process. Updates the onboarding status and, in the self-onboarding flow, can trigger an invitation to the contractor. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` diff --git a/docs/surfaces/contractor-payments/sub-components.md b/docs/surfaces/contractor-payments/sub-components.md index ab9e20c69..97eca5ca9 100644 --- a/docs/surfaces/contractor-payments/sub-components.md +++ b/docs/surfaces/contractor-payments/sub-components.md @@ -15,11 +15,11 @@ Contractor payment components can be used to compose your own workflow, or can b Displays a list of contractor payment groups for a company, allowing users to view payment history, create new payments, and filter by date range. Includes alerts for pending information requests and wire transfer requirements. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorManagement } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -47,11 +47,11 @@ function MyComponent() { A comprehensive form for creating contractor payment groups. Allows selecting payment date, editing individual contractor payments with hours, wages, bonuses, and reimbursements. Supports preview before submission and handles submission blockers like Fast ACH thresholds. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorManagement } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -90,10 +90,10 @@ function MyComponent() { Displays detailed information about a specific contractor payment group, including all individual contractor payments. Allows viewing individual payment details and canceling payments when permitted. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorManagement } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -125,11 +125,11 @@ function MyComponent() { Displays a summary of a created payment group, including payment details, contractor information, and wire transfer requirements if applicable. Used as a confirmation screen after payment creation. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorManagement } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -166,10 +166,10 @@ function MyComponent() { Displays an individual contractor payment statement with detailed payment information and breakdown. ```jsx -import { Contractor } from '@gusto/embedded-react-sdk' +import { ContractorManagement } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` diff --git a/docs/surfaces/employee-dashboard.md b/docs/surfaces/employee-dashboard.md index f388249f8..88845a141 100644 --- a/docs/surfaces/employee-dashboard.md +++ b/docs/surfaces/employee-dashboard.md @@ -16,8 +16,6 @@ function MyApp() { } ``` -> Legacy import via `Employee.DashboardFlow` continues to work. - ### Props | Name | Type | Description | @@ -52,26 +50,24 @@ The Dashboard workflow can be used through the wrapping flow component or render ### Available Subcomponents - [EmployeeManagement.DashboardFlow](#employeemanagementdashboardflow) -- [Employee.Dashboard](#employeedashboard) +- [EmployeeManagement.Dashboard](#employeemanagementdashboard) - [EmployeeManagement.EmployeeList](#employeemanagementemployeelist) - [EmployeeManagement.WorkAddress](#employeemanagementworkaddress) - [EmployeeManagement.StateTaxes](#employeemanagementstatetaxes) -> Legacy import via `Employee.DashboardFlow` continues to work. - ### EmployeeManagement.DashboardFlow The main entry point for the Employee Dashboard workflow. Wraps the dashboard with error boundaries, suspense, and provides a consistent loading/error experience. See the [Implementation](#implementation) section above for full props and events. -### Employee.Dashboard +### EmployeeManagement.Dashboard The Dashboard component renders the tabbed interface directly without the flow wrapper. Use this when you want to embed the dashboard into a custom layout that already provides its own error boundaries. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeManagement } from '@gusto/embedded-react-sdk' function MyComponent() { - return {}} /> + return {}} /> } ``` @@ -85,7 +81,7 @@ function MyComponent() { #### Events -`Employee.Dashboard` emits the same events as `EmployeeManagement.DashboardFlow`. See the events table at the top of this page. +`EmployeeManagement.Dashboard` emits the same events as `EmployeeManagement.DashboardFlow`. See the events table at the top of this page. ### EmployeeManagement.EmployeeList @@ -326,7 +322,7 @@ The Dashboard component is wrapped with `BaseBoundaries` which provides: To provide a custom error fallback: ```jsx - {}} FallbackComponent={MyCustomErrorComponent} @@ -368,7 +364,7 @@ function MyDashboard() { The Dashboard supports custom translations through the `dictionary` prop. Default translations are in English. To override: ```jsx - {}} dictionary={{ @@ -396,7 +392,7 @@ import { GustoProvider } from '@gusto/embedded-react-sdk' // ... other component overrides }} > - + ``` diff --git a/docs/surfaces/employee-management/employee-management.md b/docs/surfaces/employee-management/employee-management.md index b129c0b34..89ba164e8 100644 --- a/docs/surfaces/employee-management/employee-management.md +++ b/docs/surfaces/employee-management/employee-management.md @@ -21,8 +21,6 @@ function MyApp() { } ``` -> Legacy imports via `Employee.*` (e.g. `Employee.DashboardFlow`) continue to work. - ## Using Employee Management Subcomponents Employee management components can be used to compose your own workflow, or can be rendered in isolation. Each section of the dashboard is also exported as a self-contained block (e.g. `EmployeeManagement.Profile`) that wraps its read-only card surface, its edit form, and the transitions between them — drop it into any page and it works the same way that section works inside `DashboardFlow`. For guidance on creating a custom workflow, see [docs on composition](../../integration-guide/composition.md). diff --git a/docs/surfaces/employee-onboarding/sub-components.md b/docs/surfaces/employee-onboarding/sub-components.md index f364cffdd..840d9d1b8 100644 --- a/docs/surfaces/employee-onboarding/sub-components.md +++ b/docs/surfaces/employee-onboarding/sub-components.md @@ -59,11 +59,11 @@ Used to collect basic information about the employee: This component also provides the option to invite the employee to enter some of their details themself. If selected, they can be sent an invitation to complete the form. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -150,7 +150,7 @@ function MyComponent() { Provides required form inputs for employee federal tax configuration. The component ships in two journey-scoped variants that share the same form rendering but differ in CTAs and emitted events; pick the variant that matches your screen instead of toggling a prop. - **`EmployeeOnboarding.FederalTaxes`** renders a single **Continue** submit button and emits `EMPLOYEE_FEDERAL_TAXES_DONE` after a successful save so the parent onboarding flow can advance. -- **`EmployeeManagement.FederalTaxes`** (also exported as `Employee.FederalTaxes` for backwards compatibility) renders **Cancel** + **Save**. Cancel emits `CANCEL` so the parent can navigate away; Save submits the form, surfaces a dismissible success alert, and keeps the user on the screen. +- **`EmployeeManagement.FederalTaxes`** renders **Cancel** + **Save**. Cancel emits `CANCEL` so the parent can navigate away; Save submits the form, surfaces a dismissible success alert, and keeps the user on the screen. ```jsx // Onboarding journey @@ -251,11 +251,11 @@ function ManagementEditScreen() { Used for configuring employee bank account(s). Bank accounts created with this component will be used to pay the employee when payroll is run. Payments can be split across multiple accounts. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -284,11 +284,11 @@ function MyComponent() { Used for configuring additional withholdings from employee pay. Deductions can be set by percentage or fixed amount, and can be either recurring or one-time. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> + {}} /> ) } ``` @@ -319,11 +319,11 @@ Used during admin onboarding to configure which documents are included in the em This component is conditionally shown in the `EmployeeOnboardingFlow` when `withEmployeeI9` is set to `true`. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} /> @@ -352,11 +352,11 @@ function MyComponent() { Displays the current state of employee onboarding. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} isAdmin // Set to true for admin onboarding diff --git a/docs/surfaces/employee-self-onboarding/sub-components.md b/docs/surfaces/employee-self-onboarding/sub-components.md index efddcdba1..2b49aeec2 100644 --- a/docs/surfaces/employee-self-onboarding/sub-components.md +++ b/docs/surfaces/employee-self-onboarding/sub-components.md @@ -8,7 +8,6 @@ order: 2 Like the admin-driven employee onboarding, self-onboarding components can be used to compose your own workflow or be rendered in isolation. Many of these components are the same as the ones used for general employee onboarding; some fields are hidden or shown based on the current user type. For guidance on creating a custom workflow, see [docs on composition](../../integration-guide/composition.md). -> Legacy imports via `Employee.*` (e.g. `Employee.Landing`) continue to work. --- diff --git a/docs/surfaces/employee-termination.md b/docs/surfaces/employee-termination.md index 32ba3446d..14e957f39 100644 --- a/docs/surfaces/employee-termination.md +++ b/docs/surfaces/employee-termination.md @@ -24,8 +24,6 @@ function MyApp() { } ``` -> Legacy import via `Employee.TerminationFlow` continues to work. - ### Props | Name | Type | Description | @@ -80,19 +78,19 @@ Employee termination components can be used to compose your own workflow, or can ### Available Subcomponents -- [Employee.TerminateEmployee](#employeeterminateemployee) -- [Employee.TerminationSummary](#employeeterminationsummary) +- [EmployeeManagement.TerminateEmployee](#employeemanagementterminateemployee) +- [EmployeeManagement.TerminationSummary](#employeemanagementterminationsummary) -### Employee.TerminateEmployee +### EmployeeManagement.TerminateEmployee The main termination form where users specify the last day of work and select how to process the final payroll. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeManagement } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - {}} @@ -131,16 +129,16 @@ function MyComponent() { - Include in their regular payroll - I'll handle it another way -### Employee.TerminationSummary +### EmployeeManagement.TerminationSummary Displays termination details and provides actions for managing the termination (edit, cancel, run payroll). Also includes an offboarding checklist for post-termination tasks. ```jsx -import { Employee } from '@gusto/embedded-react-sdk' +import { EmployeeManagement } from '@gusto/embedded-react-sdk' function MyComponent() { return ( - + {}} /> + + ) +} +``` + +See [Getting Started](./getting-started/getting-started.md) to install and configure the SDK for your application. diff --git a/eslint.config.ts b/eslint.config.ts index 2fa7204db..362bf76c3 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -194,13 +194,7 @@ export default [ 'src/components/Common/UI/**/*.{ts,tsx}', 'src/components/Common/PaginationControl/**', 'src/components/Common/PayrollLoading/**', - 'src/components/Employee/Compensation/management/CompensationAddAnotherJobForm/**/*.{ts,tsx}', - 'src/components/Employee/Compensation/management/CompensationAddJobForm/**/*.{ts,tsx}', - 'src/components/Employee/Compensation/management/CompensationCard/**/*.{ts,tsx}', - 'src/components/Employee/Compensation/management/CompensationEditForm/**/*.{ts,tsx}', - 'src/components/Employee/Dashboard/**/*.{ts,tsx}', - 'src/components/Employee/Compensation/shared/useCompensationForm/**/*.{ts,tsx}', - 'src/components/Employee/Compensation/shared/useJobForm/**/*.{ts,tsx}', + 'src/components/Employee/**/*.{ts,tsx}', 'src/components/Flow/**/*.{ts,tsx}', 'src/contexts/ApiProvider/**/*.{ts,tsx}', 'src/contexts/ComponentAdapter/**/*.{ts,tsx}', diff --git a/package-lock.json b/package-lock.json index eb734691e..7cc1427b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,12 +16,12 @@ "@internationalized/number": "^3.6.7", "classnames": "^2.5.1", "deepmerge": "^4.3.1", - "dompurify": "^3.4.9", + "dompurify": "^3.4.10", "i18next": "^26.3.1", "react-aria": "^3.47.0", "react-aria-components": "1.16.0", "react-error-boundary": "^6.1.2", - "react-hook-form": "^7.78.0", + "react-hook-form": "^7.79.0", "react-i18next": "^17.0.8", "react-robot": "^1.2.1", "robot3": "^1.2.0", @@ -31,13 +31,13 @@ "@commitlint/cli": "^21.0.2", "@commitlint/config-conventional": "^21.0.2", "@eslint/js": "^9.39.2", - "@microsoft/api-extractor": "^7.58.8", + "@microsoft/api-extractor": "^7.58.9", "@playwright/test": "^1.60.0", "@release-it/conventional-changelog": "^11.0.1", "@storybook/addon-a11y": "^10.4.4", "@storybook/addon-docs": "^10.4.4", "@storybook/addon-onboarding": "^10.4.4", - "@storybook/react-vite": "^10.4.3", + "@storybook/react-vite": "^10.4.4", "@storybook/test-runner": "^0.24.4", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", @@ -3648,9 +3648,9 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.58.8", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.8.tgz", - "integrity": "sha512-Y45rdEvZodD1WBAK9w8Wvqj7k/6z21YOEP8aVNWv1vemEzanjThvCowc3Eyt/bmJJyqI4gj0BQr9nLC51fsDiQ==", + "version": "7.58.9", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.9.tgz", + "integrity": "sha512-S2UF4yza5GoxCmf7hJQNxJNZN9ltOVuOQv8Dy+Z21aol5ERoBNMdWcQHm4MJMPPItW4H/4rZD906iaf4mUojJA==", "dev": true, "license": "MIT", "dependencies": { @@ -3660,7 +3660,7 @@ "@rushstack/node-core-library": "5.23.1", "@rushstack/rig-package": "0.7.3", "@rushstack/terminal": "0.24.0", - "@rushstack/ts-command-line": "5.3.9", + "@rushstack/ts-command-line": "5.3.10", "diff": "~8.0.2", "minimatch": "10.2.3", "resolve": "~1.22.1", @@ -7409,9 +7409,9 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.9.tgz", - "integrity": "sha512-GIHqU+sRGQ3LGWAZu1O+9Yh++qwtyNIIGuNbcWHJjBTm2qRez0cwINUHZ+pQLR8UuzZDcMajrDaNbUYoaL/XtQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.10.tgz", + "integrity": "sha512-fwI076HYknC0IrMXdY6UmjDv+PH7NHhNJX3/pY2UblSE5XrXgndXZPiOe/6ZtuFpn6DvVDVNhtkIzQ+Qu/MhVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7598,67 +7598,6 @@ } } }, - "node_modules/@storybook/addon-docs/node_modules/@storybook/csf-plugin": { - "version": "10.4.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.4.tgz", - "integrity": "sha512-1mzZyAwVUmAcw4WEUsJDVdSupkJf+Kf/f5uNAs4RzlBXA75P8YRkDKAb2EoMwsB5URiXFi9XoeAN/vWke0G6+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "unplugin": "^2.3.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "esbuild": "*", - "rollup": "*", - "storybook": "^10.4.4", - "vite": "*", - "webpack": "*" - }, - "peerDependenciesMeta": { - "esbuild": { - "optional": true - }, - "rollup": { - "optional": true - }, - "vite": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-docs/node_modules/@storybook/react-dom-shim": { - "version": "10.4.4", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.4.tgz", - "integrity": "sha512-y6SObmoW78AydE6VfKQSUmCkuqiaMPy9LgMpMdMEyWfJ/pSxBDMIKycr9dlRMJP1cvNgByaJgrusWtA46ndSQw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.4" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@storybook/addon-onboarding": { "version": "10.4.4", "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-10.4.4.tgz", @@ -7674,13 +7613,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.3.tgz", - "integrity": "sha512-gvXVJvcsqFuSO5PLhS5+BdoYbQDxbkVVrW2cHrf4g089bXVTImZrOSzTO7SEOTs4I9acJqv4nK22WEeJpY+VZw==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.4.tgz", + "integrity": "sha512-VyuZ4mEvhhVXjJa1qXMWKH8ohnas0rgEuJDf6u4aJ54XeENFebPUEAHde1Qo2PflJ4rUdVdXieOZzKbYwP5RAQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "10.4.3", + "@storybook/csf-plugin": "10.4.4", "ts-dedent": "^2.0.0" }, "funding": { @@ -7688,14 +7627,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.4.3", + "storybook": "^10.4.4", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.3.tgz", - "integrity": "sha512-D+XF5CVhZmIOI0uhfTKxlQr+gR1z8X9djPy9phiA1USLPAOHagBAucp/PhLwlFVUxrKzEIf8yImrvkCv50IcDg==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.4.tgz", + "integrity": "sha512-1mzZyAwVUmAcw4WEUsJDVdSupkJf+Kf/f5uNAs4RzlBXA75P8YRkDKAb2EoMwsB5URiXFi9XoeAN/vWke0G6+w==", "dev": true, "license": "MIT", "dependencies": { @@ -7708,7 +7647,7 @@ "peerDependencies": { "esbuild": "*", "rollup": "*", - "storybook": "^10.4.3", + "storybook": "^10.4.4", "vite": "*", "webpack": "*" }, @@ -7746,14 +7685,14 @@ } }, "node_modules/@storybook/react": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.4.3.tgz", - "integrity": "sha512-Td+Zoi8ylJTPC1jg5vHw8OK7U2kJgqc5kuAn92UvD4IbAkcpMTBRPHDziK1piv6q7r8yNLVah+ku6IKHpTLeXA==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.4.4.tgz", + "integrity": "sha512-6K5/uHrvjswrueyVpUt6IWGuSgYCMtMOYyVs86XJZYqKBV3Pv7nGsGNH7YSMLAVQBZW4CQqm2etd5Op0GHY9Kg==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/react-dom-shim": "10.4.3", + "@storybook/react-dom-shim": "10.4.4", "react-docgen": "^8.0.2", "react-docgen-typescript": "^2.2.2" }, @@ -7766,7 +7705,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3", + "storybook": "^10.4.4", "typescript": ">= 4.9.x" }, "peerDependenciesMeta": { @@ -7782,9 +7721,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.3.tgz", - "integrity": "sha512-aPZ+Afd+zdoSygISOVCJIYdiqWJM6uRZFw0zhsONwNcn3kU1TNce6iAoBCY8cpEhDAu61M1QjeIHM3LPy/ieog==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.4.tgz", + "integrity": "sha512-y6SObmoW78AydE6VfKQSUmCkuqiaMPy9LgMpMdMEyWfJ/pSxBDMIKycr9dlRMJP1cvNgByaJgrusWtA46ndSQw==", "dev": true, "license": "MIT", "funding": { @@ -7796,7 +7735,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3" + "storybook": "^10.4.4" }, "peerDependenciesMeta": { "@types/react": { @@ -7808,16 +7747,16 @@ } }, "node_modules/@storybook/react-vite": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.4.3.tgz", - "integrity": "sha512-Pk/hi10JFuwJ5sj/HAapWrgaa9Z83oT4MJPbHqeKzMt3A3jkIru4L9ibnt82bzV3crOaiErprvOlAFDsjxhrrQ==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.4.4.tgz", + "integrity": "sha512-hXw1c9Jq2eFzwmJ3u9phmszbHoPjwPLYjcR1Grd6Xbe2g3bReGH35urm/fTZ0HNdjXAgQlUaXp2bWw6vz0BHQw==", "dev": true, "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "10.4.3", - "@storybook/react": "10.4.3", + "@storybook/builder-vite": "10.4.4", + "@storybook/react": "10.4.4", "empathic": "^2.0.0", "magic-string": "^0.30.0", "react-docgen": "^8.0.0", @@ -7831,7 +7770,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3", + "storybook": "^10.4.4", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, @@ -12661,9 +12600,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.9.tgz", - "integrity": "sha512-4dPSRMRDqHvs0V4YDFCsaIZo4if5u0xM+llyxiM2fwuZFdKArUBAF3VtI2+n8NKg9P870WMdYk0UhqQNoWXbfQ==", + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.10.tgz", + "integrity": "sha512-0xzNv0e7oYC6yyuOGZIABPM4qtg3QxLFniDNPP4ZP90wR8Yq3zgwpRbrNiT4N3IKqDbbYFEJLV+JWEs19aZ//w==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -14478,17 +14417,17 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -15189,9 +15128,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -21897,9 +21836,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.78.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.78.0.tgz", - "integrity": "sha512-EEZqc+N23moyzTlz61Pj+JvcXo76ICkpfOZo8JZw+sM4+wLQGh6nI2Ms+PdMOYNluFu0ghlM7B8mCzhRYtJCnA==", + "version": "7.79.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.79.0.tgz", + "integrity": "sha512-mhYp/MTmXvzYX6AJcJVko0rktoIhhmRnEouObj4wF5i/tCttgJvnp1+9wRkpITZjDTqpo4IOSJqu0dBlPlV/Lw==", "license": "MIT", "engines": { "node": ">=18.0.0" diff --git a/package.json b/package.json index a6023c453..c5f2782ef 100644 --- a/package.json +++ b/package.json @@ -93,13 +93,13 @@ "@commitlint/cli": "^21.0.2", "@commitlint/config-conventional": "^21.0.2", "@eslint/js": "^9.39.2", - "@microsoft/api-extractor": "^7.58.8", + "@microsoft/api-extractor": "^7.58.9", "@playwright/test": "^1.60.0", "@release-it/conventional-changelog": "^11.0.1", "@storybook/addon-a11y": "^10.4.4", "@storybook/addon-docs": "^10.4.4", "@storybook/addon-onboarding": "^10.4.4", - "@storybook/react-vite": "^10.4.3", + "@storybook/react-vite": "^10.4.4", "@storybook/test-runner": "^0.24.4", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", @@ -174,12 +174,12 @@ "@internationalized/number": "^3.6.7", "classnames": "^2.5.1", "deepmerge": "^4.3.1", - "dompurify": "^3.4.9", + "dompurify": "^3.4.10", "i18next": "^26.3.1", "react-aria": "^3.47.0", "react-aria-components": "1.16.0", "react-error-boundary": "^6.1.2", - "react-hook-form": "^7.78.0", + "react-hook-form": "^7.79.0", "react-i18next": "^17.0.8", "react-robot": "^1.2.1", "robot3": "^1.2.0", diff --git a/rfc/2026-06-12--docs-site-infrastructure.md b/rfc/2026-06-12--docs-site-infrastructure.md new file mode 100644 index 000000000..5b8b0cfee --- /dev/null +++ b/rfc/2026-06-12--docs-site-infrastructure.md @@ -0,0 +1,59 @@ +# Docs Site Infrastructure + +**Status:** Approved | **Author:** Jeff Johnson | **Date:** 2026-06-12 + +--- + +## Context + +[SDK-758](https://gustohq.atlassian.net/browse/SDK-758) ("Modernize SDK Documentation") replaces the SDK's ReadMe-hosted documentation with a Docusaurus site we control. Phase 1a ([SDK-759](https://gustohq.atlassian.net/browse/SDK-759)) is the up-front infrastructure decisions: where the site lives, where it deploys to, what domain it serves at, what triggers a publish, and how search is implemented. These are foundational choices — getting them right unblocks the rest of the epic, and reversing them later carries real cost (DNS, CI rewiring, vendor onboarding). + +The decisions below have been made and shipped. This document records what was chosen and why so future contributors don't have to reconstruct the rationale from commit history. + +The companion RFC [`2026-05-26--autogenerated-api-docs.md`](./2026-05-26--autogenerated-api-docs.md) covers the content pipeline that produces API reference Markdown for the site; this document is purely about the site itself. + +--- + +## Decisions + +### 1. Same repo, `docs-site/` directory + +The Docusaurus project lives in `docs-site/` inside this repo, not in a dedicated repo. + +The docs site reads from sibling directories — `../docs/` for hand-authored guides, `../docs/api/` for TypeDoc-generated reference. Co-locating source and docs in one tree means a single PR can change an API and its documentation atomically, with no cross-repo coordination, no version-skew window, and no second GitHub App / CI configuration to maintain. The cost — a slightly larger repo and CI surface — is small at SDK scale. + +The directory was originally stood up as `website/` (`a659e82f`) and renamed to `docs-site/` on 2026-05-26 (`f90ace0a`) to make its purpose obvious at the top level. + +### 2. GitHub Pages, via a publish-source repo (`Gusto/embedded-sdk-docs`) + +The built site is published to GitHub Pages. The publishing pipeline is two-stage: + +1. `.github/workflows/publish-docs.yaml` in this repo runs TypeDoc to refresh `docs/api/`, then pushes `docs/`, `docs-site/`, and `.nvmrc` to `main` on `Gusto/embedded-sdk-docs`. +2. That repo's Buildkite pipeline builds Docusaurus and publishes the output to its own `gh-pages` branch, which GitHub Pages serves. + +Splitting the build artifact lifecycle into a separate repo keeps `gh-pages` history and Pages configuration out of `embedded-react-sdk`, while leaving the source of truth (and all PR review) here. GitHub Pages is free, native to the GitHub flow, and sufficient for static-content needs — there is no behavioral requirement (preview deploys per PR, edge functions, A/B tests) that would justify a paid vendor like Vercel or Netlify today. + +### 3. Domain: `https://sdk.gusto.com` + +The production domain is `https://sdk.gusto.com`, configured in `docs-site/docusaurus.config.ts` as `url: 'https://sdk.gusto.com'` and `baseUrl: '/'`. The site serves at the root of the subdomain, not a path prefix, so canonical links, sitemap entries, and OG tags resolve cleanly. + +### 4. Publishing trigger: on NPM release (+ manual dispatch) + +`publish-docs.yaml` triggers on successful completion of the `Publish to NPM` workflow on `main`, plus `workflow_dispatch` for manual republishes. It is gated behind a `DOCS_PUBLISH_ENABLED` repo variable so the pipeline can be paused without removing the workflow. + +Tying docs publishes to NPM releases — rather than every merge to `main` — guarantees that the live docs always describe a version partners can actually install. Mid-release-cycle merges that document upcoming APIs don't reach `sdk.gusto.com` until those APIs are part of a published version. `workflow_dispatch` covers the out-of-band case (typo fix, broken link) where republishing without a version bump is the right answer. + +### 5. Search: `@easyops-cn/docusaurus-search-local` + +Search is provided by the `@easyops-cn/docusaurus-search-local` Docusaurus theme, configured in `docs-site/docusaurus.config.ts`. The index is built at compile time and shipped as a static asset, so search has no runtime dependency on any external service. + +This avoids the operational footprint of Algolia DocSearch (a vendor application, account, and crawler config we'd have to maintain, plus a free-tier SLA we don't control). The SDK's documentation corpus is small enough that local search is fast and accurate; reach for Algolia if and when search quality on a larger corpus becomes a real complaint. + +--- + +## Out of scope + +Two items explicitly excluded from Phase 1 to keep the rollout focused: + +- **OpenAPI-derived API reference docs** (~1400 generated files for the full API surface) — not part of the initial site. The autogenerated reference content from SDK-758's content pipeline covers the SDK's hooks, components, and types; the broader OAS-driven API reference is a separate later effort. +- **Formal cutover from ReadMe** — the existing ReadMe-hosted docs remain in place until the Docusaurus site reaches feature parity. There is no hard switchover deadline tied to Phase 1a. diff --git a/sdk-app/src/DemoSettingsPanel.module.scss b/sdk-app/src/DemoSettingsPanel.module.scss index 2e803037a..0069b3581 100644 --- a/sdk-app/src/DemoSettingsPanel.module.scss +++ b/sdk-app/src/DemoSettingsPanel.module.scss @@ -306,12 +306,42 @@ background: var(--color-hover-bg); } +.optionPrimaryRow { + display: flex; + align-items: center; + gap: 0.375rem; + min-width: 0; +} + .optionPrimary { font-size: 0.8125rem; color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + flex: 1 1 auto; + min-width: 0; +} + +.optionBadge { + flex: 0 0 auto; + font-size: 0.625rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03125rem; + padding: 0.125rem 0.375rem; + border-radius: 0.625rem; + line-height: 1; +} + +.optionBadgeProcessed { + background: var(--color-badge-build-bg); + color: var(--color-badge-build-text); +} + +.optionBadgeUnprocessed { + background: var(--color-badge-demo-bg); + color: var(--color-badge-demo-text); } .optionSecondary { diff --git a/sdk-app/src/DemoSettingsPanel.tsx b/sdk-app/src/DemoSettingsPanel.tsx index b60acc1ea..d882abddb 100644 --- a/sdk-app/src/DemoSettingsPanel.tsx +++ b/sdk-app/src/DemoSettingsPanel.tsx @@ -331,7 +331,20 @@ function EntityCombobox({ handleSelect(option) }} > - {option.primary} + + {option.primary} + {option.badge && ( + + {option.badge.label} + + )} + {option.secondary} diff --git a/sdk-app/src/entityFormatters.ts b/sdk-app/src/entityFormatters.ts index db4b9c014..ab8e6d8ba 100644 --- a/sdk-app/src/entityFormatters.ts +++ b/sdk-app/src/entityFormatters.ts @@ -17,12 +17,14 @@ export interface RawPayroll { payroll_uuid?: string check_date?: string pay_period?: { start_date?: string; end_date?: string } + processed?: boolean } export interface EntityOption { value: string primary: string secondary: string + badge?: { label: string; tone: 'processed' | 'unprocessed' } } export function formatPayPeriod(payroll: RawPayroll): string { diff --git a/sdk-app/src/useEntityCatalog.ts b/sdk-app/src/useEntityCatalog.ts index 22eb03c5a..2bc408d25 100644 --- a/sdk-app/src/useEntityCatalog.ts +++ b/sdk-app/src/useEntityCatalog.ts @@ -51,10 +51,22 @@ export function useEntityCatalog(companyId: string): EntityCatalog { const load = async () => { const base = `/api/v1/companies/${companyId}` + const today = new Date() + const startDate = new Date(today) + startDate.setMonth(startDate.getMonth() - 6) + const endDate = new Date(today) + endDate.setMonth(endDate.getMonth() + 3) + const toIso = (d: Date) => d.toISOString().slice(0, 10) + const payrollsQuery = new URLSearchParams({ + processing_statuses: 'processed,unprocessed', + start_date: toIso(startDate), + end_date: toIso(endDate), + per: '100', + }) const [employees, contractors, payrolls] = await Promise.all([ fetchList(`${base}/employees`, controller.signal), fetchList(`${base}/contractors`, controller.signal), - fetchList(`${base}/payrolls`, controller.signal), + fetchList(`${base}/payrolls?${payrollsQuery.toString()}`, controller.signal), ]) if (controller.signal.aborted) return @@ -78,10 +90,15 @@ export function useEntityCatalog(companyId: string): EntityCatalog { .filter(p => !!(p.payroll_uuid || p.uuid)) .map(p => { const id = (p.payroll_uuid || p.uuid) as string + const isProcessed = p.processed === true return { value: id, primary: formatPayPeriod(p), secondary: id, + badge: { + label: isProcessed ? 'Processed' : 'Unprocessed', + tone: isProcessed ? ('processed' as const) : ('unprocessed' as const), + }, } }), isLoading: false, diff --git a/src/components/Company/PaySchedule/PaySchedule.test.tsx b/src/components/Company/PaySchedule/PaySchedule.test.tsx index ba49f0822..2a5d54bbb 100644 --- a/src/components/Company/PaySchedule/PaySchedule.test.tsx +++ b/src/components/Company/PaySchedule/PaySchedule.test.tsx @@ -12,7 +12,7 @@ import { getPaySchedules, updatePaySchedule, } from '@/test/mocks/apis/payschedule' -import { GustoApiProvider } from '@/contexts' +import { GustoProvider } from '@/contexts' import { API_BASE_URL } from '@/test/constants' const paymentConfigsMock = http.get( @@ -48,9 +48,9 @@ describe('PaySchedule', () => { ) render( - + {}} /> - , + , ) await waitFor(() => { @@ -76,9 +76,9 @@ describe('PaySchedule', () => { server.use(getPaySchedules, getPaySchedulePreview, createPaySchedule, updatePaySchedule) render( - + {}} /> - , + , ) await waitFor(() => { @@ -103,9 +103,9 @@ describe('PaySchedule', () => { it('starts in LIST_PAY_SCHEDULES mode with correct components', async () => { render( - + {}} /> - , + , ) await waitFor(() => { @@ -129,9 +129,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -162,9 +162,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -195,9 +195,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -229,9 +229,9 @@ describe('PaySchedule', () => { describe('when viewing pay schedules', () => { it('renders existing pay schedules in list mode', async () => { render( - + {}} /> - , + , ) await waitFor(() => { @@ -247,9 +247,9 @@ describe('PaySchedule', () => { const onEvent = vi.fn() render( - + - , + , ) await waitFor(() => { @@ -285,9 +285,9 @@ describe('PaySchedule', () => { const onEvent = vi.fn() render( - + - , + , ) await waitFor(() => { @@ -336,9 +336,9 @@ describe('PaySchedule', () => { } render( - + {}} defaultValues={defaultValues} /> - , + , ) await waitFor(() => { @@ -373,9 +373,9 @@ describe('PaySchedule', () => { const onEvent = vi.fn() render( - + - , + , ) await waitFor(() => { @@ -392,9 +392,9 @@ describe('PaySchedule', () => { const onEvent = vi.fn() render( - + - , + , ) await waitFor(() => { @@ -423,9 +423,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -452,9 +452,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -477,9 +477,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -510,9 +510,9 @@ describe('PaySchedule', () => { ) render( - + {}} /> - , + , ) await waitFor(() => { @@ -535,9 +535,9 @@ describe('PaySchedule', () => { server.use(getPaySchedules, getPaySchedulePreview, createPaySchedule, updatePaySchedule) render( - + {}} /> - , + , ) await waitFor(() => { @@ -574,9 +574,9 @@ describe('PaySchedule', () => { ) render( - + {}} /> - , + , ) await waitFor(() => { @@ -598,9 +598,9 @@ describe('PaySchedule', () => { server.use(getPaySchedules, getPaySchedulePreview, createPaySchedule, updatePaySchedule) render( - + - , + , ) await waitFor(() => { @@ -645,9 +645,9 @@ describe('PaySchedule', () => { server.use(getPaySchedules, getPaySchedulePreview, createPaySchedule, updatePaySchedule) render( - + - , + , ) await waitFor(() => { @@ -686,9 +686,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -722,9 +722,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -747,9 +747,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { @@ -782,9 +782,9 @@ describe('PaySchedule', () => { const user = userEvent.setup() render( - + {}} /> - , + , ) await waitFor(() => { diff --git a/src/components/Contractor/exports/contractorManagement.ts b/src/components/Contractor/exports/contractorManagement.ts new file mode 100644 index 000000000..f6bdb2009 --- /dev/null +++ b/src/components/Contractor/exports/contractorManagement.ts @@ -0,0 +1,6 @@ +export { PaymentFlow } from '../Payments/PaymentFlow' +export { PaymentsList } from '../Payments/PaymentsList/PaymentsList' +export { CreatePayment } from '../Payments/CreatePayment/CreatePayment' +export { PaymentHistory } from '../Payments/PaymentHistory/PaymentHistory' +export { PaymentSummary } from '../Payments/PaymentSummary' +export { PaymentStatement } from '../Payments/PaymentStatement/PaymentStatement' diff --git a/src/components/Employee/Compensation/management/CompensationCard/index.ts b/src/components/Employee/Compensation/management/CompensationCard/index.ts index 09a5bf9d0..ea1fa14aa 100644 --- a/src/components/Employee/Compensation/management/CompensationCard/index.ts +++ b/src/components/Employee/Compensation/management/CompensationCard/index.ts @@ -1,2 +1 @@ export { CompensationCard } from './CompensationCard' -export type { CompensationCardProps } from './CompensationCard' diff --git a/src/components/Employee/Compensation/management/CompensationComponents.tsx b/src/components/Employee/Compensation/management/CompensationComponents.tsx index 6303f412e..b36c55a2c 100644 --- a/src/components/Employee/Compensation/management/CompensationComponents.tsx +++ b/src/components/Employee/Compensation/management/CompensationComponents.tsx @@ -9,8 +9,9 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { ensureRequired } from '@/helpers/ensureRequired' import { componentEvents } from '@/shared/constants' -export type CompensationSuccessAlertCode = 'jobAdded' +type CompensationSuccessAlertCode = 'jobAdded' +/** @internal */ export interface CompensationContextInterface extends FlowContextInterface { employeeId?: string /** Set when transitioning to `editCompensation` via the card EDIT event; @@ -19,6 +20,7 @@ export interface CompensationContextInterface extends FlowContextInterface { successAlert?: CompensationSuccessAlertCode | null } +/** @internal */ export function CompensationCardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.Compensation') @@ -39,6 +41,7 @@ export function CompensationCardContextual() { ) } +/** @internal */ export function CompensationEditFormContextual() { const { employeeId, currentJobId, onEvent } = useFlow() return ( @@ -50,11 +53,13 @@ export function CompensationEditFormContextual() { ) } +/** @internal */ export function CompensationAddJobFormContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function CompensationAddAnotherJobFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/Compensation/management/CompensationEditJobForm/CompensationEditJobForm.tsx b/src/components/Employee/Compensation/management/CompensationEditJobForm/CompensationEditJobForm.tsx index e033752b1..f74565849 100644 --- a/src/components/Employee/Compensation/management/CompensationEditJobForm/CompensationEditJobForm.tsx +++ b/src/components/Employee/Compensation/management/CompensationEditJobForm/CompensationEditJobForm.tsx @@ -13,8 +13,15 @@ import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import { composeSubmitHandler } from '@/partner-hook-utils/form/composeSubmitHandler' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Props for {@link CompensationEditJobForm}. + * + * @public + */ export interface CompensationEditJobFormProps extends CommonComponentInterface<'Employee.Management.Compensation'> { + /** The associated employee identifier. */ employeeId: string + /** The job whose compensation is being edited. */ jobId: string /** Fires `EMPLOYEE_MANAGEMENT_COMPENSATION_EDIT_FORM_SUBMITTED` (with the saved * `Compensation`) on a successful save, and @@ -22,6 +29,11 @@ export interface CompensationEditJobFormProps extends CommonComponentInterface<' onEvent: OnEventType } +/** + * Schedules a future-dated compensation change for a job that's already in effect. + * + * @public + */ export function CompensationEditJobForm({ dictionary, ...props }: CompensationEditJobFormProps) { useComponentDictionary('Employee.Management.Compensation', dictionary) return ( diff --git a/src/components/Employee/Compensation/management/CompensationEditJobForm/index.ts b/src/components/Employee/Compensation/management/CompensationEditJobForm/index.ts deleted file mode 100644 index 5dc6ef903..000000000 --- a/src/components/Employee/Compensation/management/CompensationEditJobForm/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { CompensationEditJobForm } from './CompensationEditJobForm' -export type { CompensationEditJobFormProps } from './CompensationEditJobForm' diff --git a/src/components/Employee/Compensation/management/CompensationEditPendingJobForm/CompensationEditPendingJobForm.tsx b/src/components/Employee/Compensation/management/CompensationEditPendingJobForm/CompensationEditPendingJobForm.tsx index a25e4e6a5..85474216d 100644 --- a/src/components/Employee/Compensation/management/CompensationEditPendingJobForm/CompensationEditPendingJobForm.tsx +++ b/src/components/Employee/Compensation/management/CompensationEditPendingJobForm/CompensationEditPendingJobForm.tsx @@ -12,8 +12,15 @@ import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import { composeSubmitHandler } from '@/partner-hook-utils/form/composeSubmitHandler' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Props for {@link CompensationEditPendingJobForm}. + * + * @public + */ export interface CompensationEditPendingJobFormProps extends CommonComponentInterface<'Employee.Management.Compensation'> { + /** The associated employee identifier. */ employeeId: string + /** The job whose pending compensation is being edited. */ jobId: string /** The UUID of the pending (future-dated) compensation to update. Always required — this * component only operates in update mode. */ @@ -34,6 +41,11 @@ export interface CompensationEditPendingJobFormProps extends CommonComponentInte onEvent: OnEventType } +/** + * Edits a pending (future-dated) compensation in place. + * + * @public + */ export function CompensationEditPendingJobForm({ dictionary, ...props diff --git a/src/components/Employee/Compensation/management/ManagementCompensationFormBody.tsx b/src/components/Employee/Compensation/management/ManagementCompensationFormBody.tsx index 96bb42756..8aeabdd2f 100644 --- a/src/components/Employee/Compensation/management/ManagementCompensationFormBody.tsx +++ b/src/components/Employee/Compensation/management/ManagementCompensationFormBody.tsx @@ -9,6 +9,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { FLSA_OVERTIME_SALARY_LIMIT } from '@/shared/constants' import useNumberFormatter from '@/hooks/useNumberFormatter' +/** @internal */ export interface ManagementCompensationFormBodyProps { jobForm: UseJobFormReady compensationForm: UseCompensationFormReady @@ -24,6 +25,8 @@ export interface ManagementCompensationFormBodyProps { * Field visibility is driven entirely by hook configuration — the hooks expose `undefined` * for fields that should not render — so this component renders the correct subset for each * use case without extra conditional props. + * + * @internal */ export function ManagementCompensationFormBody({ jobForm, diff --git a/src/components/Employee/Compensation/management/compensationStateMachine.ts b/src/components/Employee/Compensation/management/compensationStateMachine.ts index b238e7773..6397465fe 100644 --- a/src/components/Employee/Compensation/management/compensationStateMachine.ts +++ b/src/components/Employee/Compensation/management/compensationStateMachine.ts @@ -36,6 +36,7 @@ const returnToCardWithAlert = (alert: CompensationContextInterface['successAlert }), ) +/** @internal */ export const compensationStateMachine = { card: state( transition( diff --git a/src/components/Employee/Compensation/management/useManagementCompensationDictionary.ts b/src/components/Employee/Compensation/management/useManagementCompensationDictionary.ts index eb61405bd..588637634 100644 --- a/src/components/Employee/Compensation/management/useManagementCompensationDictionary.ts +++ b/src/components/Employee/Compensation/management/useManagementCompensationDictionary.ts @@ -10,6 +10,8 @@ import type { AddCompensationFormDictionary } from '../shared/AddCompensationFor * `Employee.Management.Compensation` flow through here into the rendered form. * Interpolated strings keep their `{{limit}}` placeholder intact so the form * body interpolates the live value at render. + * + * @internal */ export function useManagementCompensationDictionary(): AddCompensationFormDictionary { const { t } = useTranslation('Employee.Management.Compensation') diff --git a/src/components/Employee/Compensation/onboarding/Compensation.tsx b/src/components/Employee/Compensation/onboarding/Compensation.tsx index bd4d8c8fa..bc7b78716 100644 --- a/src/components/Employee/Compensation/onboarding/Compensation.tsx +++ b/src/components/Employee/Compensation/onboarding/Compensation.tsx @@ -55,19 +55,79 @@ function deriveInitialFlowConfig(employeeJobs: Job[]): InitialFlowConfig { return { initialState: 'viewJobs', currentJobId: null } } +/** + * Default values for the compensation form fields. + * + * @remarks + * At least one of the fields must be provided. If employee data is available + * via the API, these values are overwritten. + * + * @public + */ export type CompensationDefaultValues = RequireAtLeastOne<{ + /** The compensation rate (an amount in dollars). */ rate?: Job['rate'] + /** The job title. */ title?: Job['title'] + /** The pay period — one of `Hour`, `Week`, `Month`, `Year`, `Paycheck`. */ paymentUnit?: (typeof PAY_PERIODS)[keyof typeof PAY_PERIODS] + /** The FLSA classification — drives whether the role is treated as exempt, nonexempt, etc. */ flsaStatus?: FlsaStatusType }> +/** + * Props for {@link Compensation}. + * + * @public + */ export interface CompensationProps extends BaseComponentInterface<'Employee.Compensation'> { + /** The associated employee identifier. */ employeeId: string + /** The date the employee will start work. */ startDate: string + /** Default values for the compensation form fields. If employee data is available via the API, these values are overwritten. */ defaultValues?: CompensationDefaultValues } +/** + * Onboarding step for collecting an employee's role and compensation details. + * + * @remarks + * Collects the job title, employee type (hourly, salary), compensation + * amount, and pay period. For hourly employees, allows configuring multiple + * roles. Automatically routes between editing the only job (when an employee + * has zero or one non-Nonexempt job) and a jobs-list view (when multiple + * roles need to be managed) on first mount; on subsequent refetches the user + * stays on their current step. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/job/created` | Fired after a job is successfully created | {@link Job} | + * | `employee/job/updated` | Fired after a job is successfully updated | {@link Job} | + * | `employee/job/deleted` | Fired after a job is successfully deleted | — | + * | `employee/compensation/updated` | Fired after compensation details are updated | {@link Compensation} | + * | `employee/compensation/done` | Fired when compensation setup is complete and the parent flow can advance | — | + * + * @param props - See {@link CompensationProps}. + * @returns The compensation onboarding step. + * @public + * @group Block Components + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function Compensation(props: CompensationProps) { return ( @@ -127,6 +187,7 @@ function CompensationFlow({ return } +/** @internal */ export const CompensationContextual = () => { const { employeeId, onEvent, startDate, defaultValues } = useFlow() const { t } = useTranslation('common') diff --git a/src/components/Employee/Compensation/onboarding/CompensationFlowComponents.tsx b/src/components/Employee/Compensation/onboarding/CompensationFlowComponents.tsx index 6efd1e6e4..f0b5af526 100644 --- a/src/components/Employee/Compensation/onboarding/CompensationFlowComponents.tsx +++ b/src/components/Employee/Compensation/onboarding/CompensationFlowComponents.tsx @@ -10,6 +10,7 @@ import { useI18n } from '@/i18n' import { componentEvents, FlsaStatus, type EventType } from '@/shared/constants' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export type EventPayloads = { [componentEvents.EMPLOYEE_JOB_ADD]: undefined [componentEvents.EMPLOYEE_JOB_EDIT]: { uuid: string } @@ -22,6 +23,7 @@ export type EventPayloads = { [componentEvents.EMPLOYEE_COMPENSATION_DONE]: undefined } +/** @internal */ export interface CompensationFlowContextInterface extends FlowContextInterface { employeeId: string startDate: string @@ -29,11 +31,13 @@ export interface CompensationFlowContextInterface extends FlowContextInterface { partnerDefaultValues?: CompensationDefaultValues } +/** @internal */ export function JobsListContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function InitialEditCompensationContextual() { const { employeeId, startDate, currentJobId, partnerDefaultValues, onEvent } = useFlow() @@ -65,6 +69,7 @@ export function InitialEditCompensationContextual() { ) } +/** @internal */ export function EditCompensationContextual() { const { employeeId, startDate, currentJobId, partnerDefaultValues, onEvent } = useFlow() diff --git a/src/components/Employee/Compensation/onboarding/EditCompensation/EditCompensation.tsx b/src/components/Employee/Compensation/onboarding/EditCompensation/EditCompensation.tsx index e1b2cc0ea..eeedde2dd 100644 --- a/src/components/Employee/Compensation/onboarding/EditCompensation/EditCompensation.tsx +++ b/src/components/Employee/Compensation/onboarding/EditCompensation/EditCompensation.tsx @@ -13,28 +13,51 @@ import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import { composeSubmitHandler } from '@/partner-hook-utils/form/composeSubmitHandler' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Props for {@link EditCompensation}. + * + * @public + */ export interface EditCompensationProps extends CommonComponentInterface<'Employee.Compensation'> { + /** The associated employee identifier. */ employeeId: string /** - * When provided, the hire date is pre-filled from this value and the hire - * date field is hidden. When absent (add-job from empty state), the hire - * date field is rendered so the user can set it explicitly. + * When provided, the hire date is pre-filled from this value and the hire date field is hidden. + * When absent, the hire date field is rendered so it can be set explicitly. */ startDate?: string + /** Existing job to edit. When omitted, a new job is created on submit. */ currentJobId?: string | null + /** Heading text shown above the form. */ title: string + /** Label for the primary submit button. */ submitCtaLabel: string + /** Optional handler invoked when the secondary cancel button is clicked. */ onCancel?: () => void + /** Initial values for the job title and compensation fields. */ partnerDefaultValues?: CompensationDefaultValues - /** - * Receives the broadcast events: `EMPLOYEE_JOB_CREATED` / `EMPLOYEE_JOB_UPDATED` - * (with the saved `Job`), then `EMPLOYEE_COMPENSATION_UPDATED` (with the saved - * `Compensation`) on a successful submit chain. Use `EMPLOYEE_COMPENSATION_UPDATED` - * for "save complete" branching. - */ + /** Event handler fired on flow state changes. See the events table on {@link EditCompensation}. */ onEvent: OnEventType } +/** + * Renders a form for creating or editing one of an employee's jobs together with its compensation. + * + * @remarks + * The submit chain saves the job first, then the compensation. The `employee/job_created` or + * `employee/job_updated` event fires once the job is saved; `employee/compensation_updated` + * fires once the compensation is saved and signals the full save is complete. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/job_created` | Fired when a new job is saved. | The saved {@link https://docs.gusto.com/embedded-payroll/reference/get-v1-jobs-job_id | Job}. | + * | `employee/job_updated` | Fired when an existing job is saved. | The saved {@link https://docs.gusto.com/embedded-payroll/reference/get-v1-jobs-job_id | Job}. | + * | `employee/compensation_updated` | Fired when the compensation is saved. Treat as the "save complete" signal. | The saved {@link https://docs.gusto.com/embedded-payroll/reference/get-v1-compensations-compensation_id | Compensation}. | + * + * @param props - See {@link EditCompensationProps}. + * @returns The rendered edit-compensation form. + * @public + */ export function EditCompensation({ dictionary, ...props }: EditCompensationProps) { useComponentDictionary('Employee.Compensation', dictionary) return ( diff --git a/src/components/Employee/Compensation/onboarding/EditCompensation/index.ts b/src/components/Employee/Compensation/onboarding/EditCompensation/index.ts index 78defccf0..e61f1d671 100644 --- a/src/components/Employee/Compensation/onboarding/EditCompensation/index.ts +++ b/src/components/Employee/Compensation/onboarding/EditCompensation/index.ts @@ -1,2 +1 @@ -export { EditCompensation } from './EditCompensation' -export type { EditCompensationProps } from './EditCompensation' +export { EditCompensation, type EditCompensationProps } from './EditCompensation' diff --git a/src/components/Employee/Compensation/onboarding/JobsList/JobsList.tsx b/src/components/Employee/Compensation/onboarding/JobsList/JobsList.tsx index 85229beb6..d58eb4ffe 100644 --- a/src/components/Employee/Compensation/onboarding/JobsList/JobsList.tsx +++ b/src/components/Employee/Compensation/onboarding/JobsList/JobsList.tsx @@ -12,10 +12,13 @@ import { import { useComponentDictionary, useI18n } from '@/i18n' import { componentEvents } from '@/shared/constants' +/** @public */ export interface JobsListProps extends CommonComponentInterface<'Employee.Compensation'> { + /** The associated employee identifier. */ employeeId: string } +/** @public */ export function JobsList(props: JobsListProps & BaseComponentInterface) { useComponentDictionary('Employee.Compensation', props.dictionary) return ( diff --git a/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx b/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx index 0dd726cb8..82800474a 100644 --- a/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx +++ b/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx @@ -8,16 +8,25 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useI18n } from '@/i18n' import { FlsaStatus } from '@/shared/constants' +/** @internal */ export interface JobsListPresentationProps { + /** @internal */ jobs: Job[] + /** @internal */ primaryFlsaStatus: string | undefined + /** @internal */ isPending: boolean + /** @internal */ onAdd: () => void + /** @internal */ onEdit: (jobId: string) => void + /** @internal */ onDelete: (jobId: string) => void + /** @internal */ onContinue: () => void } +/** @internal */ export function JobsListPresentation({ jobs, primaryFlsaStatus, diff --git a/src/components/Employee/Compensation/onboarding/JobsList/index.ts b/src/components/Employee/Compensation/onboarding/JobsList/index.ts index a807767ef..3a165613d 100644 --- a/src/components/Employee/Compensation/onboarding/JobsList/index.ts +++ b/src/components/Employee/Compensation/onboarding/JobsList/index.ts @@ -1,4 +1 @@ -export { JobsList } from './JobsList' -export type { JobsListProps } from './JobsList' -export { JobsListPresentation } from './JobsListPresentation' -export type { JobsListPresentationProps } from './JobsListPresentation' +export { JobsList, type JobsListProps } from './JobsList' diff --git a/src/components/Employee/Compensation/onboarding/compensationStateMachine.ts b/src/components/Employee/Compensation/onboarding/compensationStateMachine.ts index bcdd2365d..1919965a2 100644 --- a/src/components/Employee/Compensation/onboarding/compensationStateMachine.ts +++ b/src/components/Employee/Compensation/onboarding/compensationStateMachine.ts @@ -8,6 +8,7 @@ import { import { componentEvents } from '@/shared/constants' import type { MachineEventType, MachineTransition } from '@/types/Helpers' +/** @internal */ export const compensationStateMachine = { initialEditJob: state( transition(componentEvents.EMPLOYEE_COMPENSATION_DONE, 'done'), diff --git a/src/components/Employee/Compensation/shared/AddCompensationFormBody.tsx b/src/components/Employee/Compensation/shared/AddCompensationFormBody.tsx index cdc40fb1c..bd6482919 100644 --- a/src/components/Employee/Compensation/shared/AddCompensationFormBody.tsx +++ b/src/components/Employee/Compensation/shared/AddCompensationFormBody.tsx @@ -17,9 +17,12 @@ import type { ResourceDictionary } from '@/types/Helpers' * default; management surfaces resolve this dictionary from * `Employee.Management.Compensation` and pass it in so management copy renders * while the two surfaces stay isolated. + * + * @internal */ export type AddCompensationFormDictionary = ResourceDictionary<'Employee.Compensation'> +/** @internal */ export interface AddCompensationFormBodyProps { jobForm: UseJobFormReady compensationForm: UseCompensationFormReady @@ -41,6 +44,8 @@ export interface AddCompensationFormBodyProps { * Copy resolves from the onboarding `Employee.Compensation` namespace by default; management * consumers inject a `dictionary` mapped from `Employee.Management.Compensation` to keep * onboarding and management strings independently overridable. + * + * @internal */ export function AddCompensationFormBody({ jobForm, diff --git a/src/components/Employee/Compensation/shared/PendingChangesReviewModal.tsx b/src/components/Employee/Compensation/shared/PendingChangesReviewModal.tsx index d2301a3f5..0c8ea8724 100644 --- a/src/components/Employee/Compensation/shared/PendingChangesReviewModal.tsx +++ b/src/components/Employee/Compensation/shared/PendingChangesReviewModal.tsx @@ -5,6 +5,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { Flex } from '@/components/Common/Flex/Flex' import { formatDateLongWithYear } from '@/helpers/dateFormatting' +/** @internal */ export interface PendingChangesReviewModalProps { isOpen: boolean pendingChanges: PendingCompensationChange[] @@ -14,6 +15,7 @@ export interface PendingChangesReviewModalProps { onCancelChange: (pendingChange: PendingCompensationChange) => void } +/** @internal */ export function PendingChangesReviewModal({ isOpen, pendingChanges, diff --git a/src/components/Employee/Compensation/shared/derivePrimaryFlsaStatus.ts b/src/components/Employee/Compensation/shared/derivePrimaryFlsaStatus.ts index e2c95e730..55b28aeb5 100644 --- a/src/components/Employee/Compensation/shared/derivePrimaryFlsaStatus.ts +++ b/src/components/Employee/Compensation/shared/derivePrimaryFlsaStatus.ts @@ -6,6 +6,8 @@ import type { Job } from '@gusto/embedded-api-v-2025-11-15/models/components/job * * The primary job is the one with `primary === true`; "current compensation" is the * entry in `job.compensations` whose `uuid` matches `job.currentCompensationUuid`. + * + * @internal */ export function derivePrimaryFlsaStatus(jobs: Job[] | undefined): string | undefined { return (jobs ?? []).reduce((acc, job) => { diff --git a/src/components/Employee/Compensation/shared/getPendingCompensationChanges.ts b/src/components/Employee/Compensation/shared/getPendingCompensationChanges.ts index f514b540c..91869baee 100644 --- a/src/components/Employee/Compensation/shared/getPendingCompensationChanges.ts +++ b/src/components/Employee/Compensation/shared/getPendingCompensationChanges.ts @@ -3,6 +3,7 @@ import type { FlsaStatusType } from '@gusto/embedded-api-v-2025-11-15/models/com import type { Job } from '@gusto/embedded-api-v-2025-11-15/models/components/job' import { normalizeToDate } from '@/helpers/dateFormatting' +/** @internal */ export type PendingChangeDetail = | { kind: 'titleChange'; title: string } | { kind: 'payChange'; rate: number; paymentUnit: string } @@ -17,6 +18,7 @@ export type PendingChangeDetail = paymentUnit: string | null } +/** @internal */ export interface PendingCompensationChange { compensationUuid: string jobUuid: string @@ -126,6 +128,8 @@ function buildNewJobDetails(future: Compensation): PendingChangeDetail[] { * The helper returns structured deltas (a discriminated union per detail) so * the consuming UI is responsible for formatting them via i18n / pay-rate * helpers. This keeps the helper pure and trivially unit-testable. + * + * @internal */ export function getPendingCompensationChanges( jobs: Job[] | undefined, diff --git a/src/components/Employee/Compensation/shared/useCompensationForm/index.ts b/src/components/Employee/Compensation/shared/useCompensationForm/index.ts index e65a73517..9dcb2d011 100644 --- a/src/components/Employee/Compensation/shared/useCompensationForm/index.ts +++ b/src/components/Employee/Compensation/shared/useCompensationForm/index.ts @@ -16,6 +16,15 @@ export { type CompensationFormOutputs, type CompensationSchemaOptions, } from './compensationSchema' +export { + TitleField, + FlsaStatusField, + RateField, + PaymentUnitField, + AdjustForMinimumWageField, + MinimumWageIdField, + EffectiveDateField, +} from './fields' export type { RequiredValidation, RateValidation, diff --git a/src/components/Employee/Compensation/shared/useCompensationManagement/index.ts b/src/components/Employee/Compensation/shared/useCompensationManagement/index.ts index 4c750a06c..e8028c0d0 100644 --- a/src/components/Employee/Compensation/shared/useCompensationManagement/index.ts +++ b/src/components/Employee/Compensation/shared/useCompensationManagement/index.ts @@ -1,6 +1,2 @@ export { useCompensationManagement } from './useCompensationManagement' -export type { - UseCompensationManagementProps, - UseCompensationManagementReady, - UseCompensationManagementResult, -} from './useCompensationManagement' +export type { UseCompensationManagementReady } from './useCompensationManagement' diff --git a/src/components/Employee/Compensation/shared/useCompensationManagement/useCompensationManagement.tsx b/src/components/Employee/Compensation/shared/useCompensationManagement/useCompensationManagement.tsx index 190876d32..5db78e65b 100644 --- a/src/components/Employee/Compensation/shared/useCompensationManagement/useCompensationManagement.tsx +++ b/src/components/Employee/Compensation/shared/useCompensationManagement/useCompensationManagement.tsx @@ -13,10 +13,21 @@ import { useBaseSubmit } from '@/components/Base/useBaseSubmit' import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult, HookSubmitResult } from '@/partner-hook-utils/types' +/** + * Props for {@link useCompensationManagement}. + * + * @public + */ export interface UseCompensationManagementProps { + /** The associated employee identifier. */ employeeId: string } +/** + * Ready state of {@link useCompensationManagement}. + * + * @public + */ export interface UseCompensationManagementReady extends BaseHookReady< { jobs: Job[] @@ -34,6 +45,7 @@ export interface UseCompensationManagementReady extends BaseHookReady< cancellingCompensationUuid: string | null } > { + /** Actions available when the hook has loaded. */ actions: { cancelPendingChange: ( pendingChange: PendingCompensationChange, @@ -41,12 +53,19 @@ export interface UseCompensationManagementReady extends BaseHookReady< } } +/** + * Return type of {@link useCompensationManagement}. + * + * @public + */ export type UseCompensationManagementResult = HookLoadingResult | UseCompensationManagementReady /** * Non-Suspense queries powering the standalone Compensation management card. * Returns jobs + pending-changes + the employee's first name (for cosmetic * alert copy) along with a cancel-pending-change action. + * + * @public */ export function useCompensationManagement({ employeeId, diff --git a/src/components/Employee/Compensation/shared/useJobForm/index.ts b/src/components/Employee/Compensation/shared/useJobForm/index.ts index 048b597d3..5b4114b76 100644 --- a/src/components/Employee/Compensation/shared/useJobForm/index.ts +++ b/src/components/Employee/Compensation/shared/useJobForm/index.ts @@ -15,6 +15,13 @@ export { type JobFormData, type JobFormOutputs, } from './jobSchema' +export { + JobTitleField, + HireDateField, + TwoPercentShareholderField, + StateWcCoveredField, + StateWcClassCodeField, +} from './fields' export type { JobRequiredValidation, JobTitleFieldProps, diff --git a/src/components/Employee/Compensation/shared/usePendingChangeDetailRenderer.tsx b/src/components/Employee/Compensation/shared/usePendingChangeDetailRenderer.tsx index 3da20cdda..b9d742999 100644 --- a/src/components/Employee/Compensation/shared/usePendingChangeDetailRenderer.tsx +++ b/src/components/Employee/Compensation/shared/usePendingChangeDetailRenderer.tsx @@ -8,6 +8,8 @@ import { useFormatCompensationRate } from '@/helpers/formattedStrings' * labels and formats pay/min-wage rates with the shared `useFormatCompensationRate` * helper so the copy matches the form. All copy resolves from the * `Employee.Management.Compensation` namespace. + * + * @internal */ export function usePendingChangeDetailRenderer(employeeFirstName: string | null | undefined) { const { t } = useTranslation('Employee.Management.Compensation') diff --git a/src/components/Employee/Dashboard/DashboardComponents.tsx b/src/components/Employee/Dashboard/DashboardComponents.tsx index 9d7bfcb6b..89a5cf977 100644 --- a/src/components/Employee/Dashboard/DashboardComponents.tsx +++ b/src/components/Employee/Dashboard/DashboardComponents.tsx @@ -19,7 +19,7 @@ import { useI18n } from '@/i18n' import { componentEvents } from '@/shared/constants' /** @internal */ -export type DashboardSuccessAlert = +type DashboardSuccessAlert = | 'bankAccountAdded' | 'bankAccountDeleted' | 'splitUpdated' diff --git a/src/components/Employee/Dashboard/index.ts b/src/components/Employee/Dashboard/index.ts index fdb27708b..2054daf69 100644 --- a/src/components/Employee/Dashboard/index.ts +++ b/src/components/Employee/Dashboard/index.ts @@ -2,9 +2,3 @@ export { DashboardFlow } from './DashboardFlow' export type { DashboardFlowProps } from './DashboardFlow' export { Dashboard } from './Dashboard' export type { DashboardProps } from './Dashboard' -export { BasicDetailsView } from './BasicDetailsView' -export type { BasicDetailsViewProps } from './BasicDetailsView' -export { JobAndPayView } from './JobAndPayView' -export type { JobAndPayViewProps } from './JobAndPayView' -export { TaxesView } from './TaxesView' -export type { TaxesViewProps } from './TaxesView' diff --git a/src/components/Employee/Deductions/management/Deductions.tsx b/src/components/Employee/Deductions/management/Deductions.tsx index 5129af4ee..c2aafcff7 100644 --- a/src/components/Employee/Deductions/management/Deductions.tsx +++ b/src/components/Employee/Deductions/management/Deductions.tsx @@ -13,8 +13,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link Deductions}. + * + * @public + */ export interface DeductionsProps extends CommonComponentInterface<'Employee.Management.Deductions'> { + /** The associated employee identifier. */ employeeId: string + /** Callback invoked when the block emits an event. See the events table on {@link Deductions} for the available event types and payloads. */ onEvent: OnEventType } @@ -35,6 +42,29 @@ function DeductionsFlow({ employeeId, onEvent }: DeductionsProps) { return } +/** + * Self-contained block for viewing and managing an employee's post-tax deductions — the same experience the dashboard surfaces, but as a drop-in component that doesn't require the surrounding dashboard chrome. + * + * @remarks + * Renders a card listing the employee's active deductions with affordances to add a new deduction, edit an existing one, or delete one via a confirm dialog. Choosing to add or edit swaps the card for the deduction form; a successful save returns to the card and emits the corresponding event, and cancelling returns without saving. Wraps everything in error and suspense boundaries. + * + * The card and form surfaces ({@link DeductionsCard}, {@link DeductionsEditForm}) are also exported individually for cases where that orchestration is the wrong fit — for example, when the form needs to render in a modal or drawer, or when the swap is driven by a router. Using them directly means owning the swap, the alert, and any cross-component state yourself. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/deductions/card/addRequested` | Fired when the "Add deduction" CTA is clicked from the card; the block opens the edit form in add mode | `{ employeeId: string }` | + * | `employee/management/deductions/card/editRequested` | Fired when an "Edit" CTA is clicked for a deduction; the block opens the edit form pre-populated with that deduction | The matching `Garnishment` | + * | `employee/management/deductions/card/deleted` | Fired after a deduction is deleted via the confirm dialog; the block stays on the card | The deleted `Garnishment` | + * | `employee/management/deductions/editForm/created` | Fired after a new deduction is saved from the edit form; the block returns to the card view | The created `Garnishment` | + * | `employee/management/deductions/editForm/updated` | Fired after an existing deduction is updated from the edit form; the block returns to the card view | The updated `Garnishment` | + * | `employee/management/deductions/editForm/cancelled` | Fired when the user cancels the edit form; the block returns to the card view | — | + * | `employee/management/deductions/alertDismissed` | Fired when the user dismisses a success alert above the card | `null` | + * + * @param props - See {@link DeductionsProps}. + * @returns The rendered deductions block. + * @public + * @group Block Components + */ export function Deductions({ dictionary, FallbackComponent, diff --git a/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx b/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx index c41eec700..2796503e4 100644 --- a/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx +++ b/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx @@ -16,20 +16,33 @@ import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' import TrashCanSvg from '@/assets/icons/trashcan.svg?react' import PencilSvg from '@/assets/icons/pencil.svg?react' +/** + * Props for {@link DeductionsCard}. + * + * @public + */ export interface DeductionsCardProps { + /** The associated employee identifier. */ employeeId: string + /** Callback invoked when the card emits an event. See the events table on {@link DeductionsCard} for the available event types and payloads. */ onEvent: OnEventType } /** - * Standalone "Deductions" management card. Owns its own data fetch via - * `useDeductionsList`, plus the delete confirm dialog, and emits - * `EMPLOYEE_MANAGEMENT_DEDUCTIONS_CARD_ADD_REQUESTED` / - * `EMPLOYEE_MANAGEMENT_DEDUCTIONS_CARD_EDIT_REQUESTED` / - * `EMPLOYEE_MANAGEMENT_DEDUCTIONS_CARD_DELETED` events. The card has no - * alert API — alert rendering is the orchestrator's responsibility (block's - * `DeductionsCardContextual` for standalone consumption, dashboard chrome - * for dashboard consumption). + * Standalone read-only card listing an employee's active deductions, with affordances to add, edit, or delete a deduction. + * + * @remarks + * Fetches its own data and owns the delete confirm dialog. Has no alert API — alert rendering is the consumer's responsibility. Add and edit affordances do not open a form themselves; emit-then-route is the contract, so the consumer listens for the `addRequested` / `editRequested` events and renders {@link DeductionsEditForm} (or its own equivalent) accordingly. For an orchestrated card-plus-form flow, use {@link Deductions} instead. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/deductions/card/addRequested` | Fired when the "Add deduction" CTA is clicked | `{ employeeId: string }` | + * | `employee/management/deductions/card/editRequested` | Fired when an "Edit" CTA is clicked for a deduction | The matching `Garnishment` | + * | `employee/management/deductions/card/deleted` | Fired after a deduction is deleted via the confirm dialog | The deleted `Garnishment` | + * + * @param props - See {@link DeductionsCardProps}. + * @returns The rendered deductions card. + * @public */ export function DeductionsCard(props: DeductionsCardProps) { return ( diff --git a/src/components/Employee/Deductions/management/DeductionsComponents.tsx b/src/components/Employee/Deductions/management/DeductionsComponents.tsx index b88f7171b..96e071e24 100644 --- a/src/components/Employee/Deductions/management/DeductionsComponents.tsx +++ b/src/components/Employee/Deductions/management/DeductionsComponents.tsx @@ -7,8 +7,9 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { ensureRequired } from '@/helpers/ensureRequired' import { componentEvents } from '@/shared/constants' -export type DeductionsSuccessAlertCode = 'deductionAdded' | 'deductionUpdated' | 'deductionDeleted' +type DeductionsSuccessAlertCode = 'deductionAdded' | 'deductionUpdated' | 'deductionDeleted' +/** @internal */ export interface DeductionsContextInterface extends FlowContextInterface { employeeId?: string /** Set when transitioning to `editDeduction` via the EDIT event; consumed @@ -18,6 +19,7 @@ export interface DeductionsContextInterface extends FlowContextInterface { successAlert?: DeductionsSuccessAlertCode | null } +/** @internal */ export function DeductionsCardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.Deductions') @@ -38,6 +40,7 @@ export function DeductionsCardContextual() { ) } +/** @internal */ export function DeductionsEditFormContextual() { const { employeeId, editingDeductionId, onEvent } = useFlow() return ( diff --git a/src/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.tsx b/src/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.tsx index e6a16715c..659c9dbc4 100644 --- a/src/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.tsx +++ b/src/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.tsx @@ -10,22 +10,36 @@ import { import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' +/** + * Props for {@link DeductionsEditForm}. + * + * @public + */ export interface DeductionsEditFormProps extends CommonComponentInterface<'Employee.Management.Deductions'> { + /** The associated employee identifier. */ employeeId: string /** When provided, the form opens in edit mode pre-populated with the * matching active deduction. Omit to open in add mode. */ editingDeductionId?: string + /** Callback invoked when the form emits an event. See the events table on {@link DeductionsEditForm} for the available event types and payloads. */ onEvent: BaseComponentInterface['onEvent'] } /** - * Standalone add/edit surface for a single deduction. Renders the shared - * `DeductionsForm` with management's own translation dictionary so partner - * overrides on `Employee.Management.Deductions` flow into the form text. - * Looks up the row to edit by id and translates the form's `onSaved` / - * `onCancel` callbacks into the management block's scoped events - * (`EMPLOYEE_MANAGEMENT_DEDUCTIONS_EDIT_FORM_CREATED` / `_UPDATED` / - * `_CANCELLED`). + * Standalone add/edit surface for a single employee deduction. + * + * @remarks + * Renders the inline form for a post-tax custom deduction or court-ordered garnishment. Looks up the row to edit by `editingDeductionId`; omit it to open in add mode. Resolves its text against the `Employee.Management.Deductions` translation namespace so partner overrides on that namespace flow into the form. For an orchestrated card-plus-form flow, use {@link Deductions}. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/deductions/editForm/created` | Fired after a new deduction is saved | The created `Garnishment` | + * | `employee/management/deductions/editForm/updated` | Fired after an existing deduction is updated | The updated `Garnishment` | + * | `employee/management/deductions/editForm/cancelled` | Fired when the user cancels the form | — | + * + * @param input - See {@link DeductionsEditFormProps}, plus a `FallbackComponent` override for the error boundary. + * @returns The rendered add/edit form. + * @public */ export function DeductionsEditForm({ FallbackComponent, diff --git a/src/components/Employee/Deductions/management/DeductionsEditForm/useFormDictionary.ts b/src/components/Employee/Deductions/management/DeductionsEditForm/useFormDictionary.ts index 30a535d5a..ea0d08399 100644 --- a/src/components/Employee/Deductions/management/DeductionsEditForm/useFormDictionary.ts +++ b/src/components/Employee/Deductions/management/DeductionsEditForm/useFormDictionary.ts @@ -8,6 +8,8 @@ import type { DeductionsFormDictionary } from '../../shared/DeductionsForm' * management's translation file under the nested `form.*` shape, so partner * overrides on `Employee.Management.Deductions` flow into the form text via * `t(...)` resolution at render time. + * + * @internal */ export function useManagementDeductionsFormDictionary(): DeductionsFormDictionary { const { t } = useTranslation('Employee.Management.Deductions') diff --git a/src/components/Employee/Deductions/management/deductionsStateMachine.ts b/src/components/Employee/Deductions/management/deductionsStateMachine.ts index 841210b79..238ab0c82 100644 --- a/src/components/Employee/Deductions/management/deductionsStateMachine.ts +++ b/src/components/Employee/Deductions/management/deductionsStateMachine.ts @@ -29,6 +29,7 @@ const returnToCardWithAlert = (alert: DeductionsContextInterface['successAlert'] }), ) +/** @internal */ export const deductionsStateMachine = { card: state( transition( diff --git a/src/components/Employee/Deductions/onboarding/Deductions.tsx b/src/components/Employee/Deductions/onboarding/Deductions.tsx index 1b257a7fc..bcc682259 100644 --- a/src/components/Employee/Deductions/onboarding/Deductions.tsx +++ b/src/components/Employee/Deductions/onboarding/Deductions.tsx @@ -11,10 +11,55 @@ import { Flow } from '@/components/Flow/Flow' import { BaseBoundaries, type BaseComponentInterface } from '@/components/Base/Base' import { useComponentDictionary, useI18n } from '@/i18n' +/** + * Props for {@link Deductions}. + * + * @public + */ export interface DeductionsProps extends BaseComponentInterface<'Employee.Deductions'> { + /** The associated employee identifier. */ employeeId: string } +/** + * Onboarding step for collecting an employee's post-tax deductions and court-ordered garnishments. + * + * @remarks + * On first mount, routes between an "include deductions?" prompt (when the employee has no active deductions) and a list view of existing deductions. From there, users add or edit deductions inline — post-tax custom deductions or court-ordered garnishments — and can complete the step with or without any active deductions. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/deductions/include/yes` | Fired when the user chooses to add deductions from the include prompt | — | + * | `employee/deductions/include/no` | Fired when the user chooses to skip deductions from the include prompt | — | + * | `employee/deductions/add` | Fired when the user opens the form to add a new deduction | — | + * | `employee/deductions/edit` | Fired when the user opens the form to edit an existing deduction | The matching `Garnishment` | + * | `employee/deductions/created` | Fired after a new deduction is saved | The created `Garnishment` | + * | `employee/deductions/updated` | Fired after an existing deduction is updated | The updated `Garnishment` | + * | `employee/deductions/deleted` | Fired after a deduction is deleted and others remain | The deleted `Garnishment` | + * | `employee/deductions/deletedEmpty` | Fired after the last deduction is deleted, leaving none | — | + * | `employee/deductions/cancel` | Fired when the user cancels the form while other deductions exist | — | + * | `employee/deductions/cancelEmpty` | Fired when the user cancels the form and no deductions remain | — | + * | `employee/deductions/done` | Fired when the step is complete and the parent flow can advance | — | + * + * @param props - See {@link DeductionsProps}. + * @returns The deductions onboarding step. + * @public + * @group Block Components + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function Deductions({ employeeId, dictionary, onEvent }: DeductionsProps) { return ( diff --git a/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx b/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx index 1b5c42ddd..b850df0ed 100644 --- a/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx +++ b/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx @@ -13,6 +13,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useI18n } from '@/i18n' import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' +/** @internal */ export interface DeductionsListProps { className?: string deductionsList: UseDeductionsListReady @@ -22,6 +23,7 @@ export interface DeductionsListProps { onContinue: () => void } +/** @internal */ export function DeductionsList({ className, deductionsList, diff --git a/src/components/Employee/Deductions/onboarding/IncludeDeductions/IncludeDeductions.tsx b/src/components/Employee/Deductions/onboarding/IncludeDeductions/IncludeDeductions.tsx index 3e7f14c4d..1bdaff9b7 100644 --- a/src/components/Employee/Deductions/onboarding/IncludeDeductions/IncludeDeductions.tsx +++ b/src/components/Employee/Deductions/onboarding/IncludeDeductions/IncludeDeductions.tsx @@ -8,12 +8,14 @@ import { useI18n } from '@/i18n' import CoinsHandsIcon from '@/assets/icons/coins-hand.svg?react' import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' +/** @internal */ export interface IncludeDeductionsProps { className?: string onAdd: () => void onContinue: () => void } +/** @internal */ export function IncludeDeductions({ className, onAdd, onContinue }: IncludeDeductionsProps) { useI18n('Employee.Deductions') const { t } = useTranslation('Employee.Deductions') diff --git a/src/components/Employee/Deductions/onboarding/deductionsContextualComponents.tsx b/src/components/Employee/Deductions/onboarding/deductionsContextualComponents.tsx index 77c0420c6..3146f7dec 100644 --- a/src/components/Employee/Deductions/onboarding/deductionsContextualComponents.tsx +++ b/src/components/Employee/Deductions/onboarding/deductionsContextualComponents.tsx @@ -9,6 +9,7 @@ import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import { componentEvents } from '@/shared/constants' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export type EventPayloads = { [componentEvents.EMPLOYEE_DEDUCTION_INCLUDE_YES]: undefined [componentEvents.EMPLOYEE_DEDUCTION_INCLUDE_NO]: undefined @@ -23,12 +24,14 @@ export type EventPayloads = { [componentEvents.EMPLOYEE_DEDUCTION_DONE]: undefined } +/** @internal */ export interface DeductionsContextInterface extends FlowContextInterface { employeeId: string /** Set by the EDIT transition; consumed by the form-mode contextual. */ editingDeductionId?: string } +/** @internal */ export function IncludeDeductionsContextual() { const { onEvent } = useFlow() @@ -53,6 +56,7 @@ export function IncludeDeductionsContextual() { ) } +/** @internal */ export function DeductionsListContextual() { const { employeeId, onEvent } = useFlow() const list = useDeductionsList({ employeeId: ensureRequired(employeeId) }) @@ -95,6 +99,7 @@ export function DeductionsListContextual() { ) } +/** @internal */ export function DeductionsFormContextual() { const { employeeId, editingDeductionId, onEvent } = useFlow() // The same list query the form hooks use internally — React Query dedupes diff --git a/src/components/Employee/Deductions/onboarding/stateMachine.ts b/src/components/Employee/Deductions/onboarding/stateMachine.ts index d4bdb546c..f9589bf32 100644 --- a/src/components/Employee/Deductions/onboarding/stateMachine.ts +++ b/src/components/Employee/Deductions/onboarding/stateMachine.ts @@ -8,6 +8,7 @@ import { import { componentEvents } from '@/shared/constants' import type { MachineEventType, MachineTransition } from '@/types/Helpers' +/** @internal */ export const deductionsMachine = { include: state( transition( diff --git a/src/components/Employee/Deductions/onboarding/useFormDictionary.ts b/src/components/Employee/Deductions/onboarding/useFormDictionary.ts index b606e1e32..19b50f3b3 100644 --- a/src/components/Employee/Deductions/onboarding/useFormDictionary.ts +++ b/src/components/Employee/Deductions/onboarding/useFormDictionary.ts @@ -12,6 +12,8 @@ import type { DeductionsFormDictionary } from '../shared/DeductionsForm' * `childSupport.agencyLabel`, `childSupport.paymentPeriodLabel`, …). Keeping * the source keys unchanged preserves backward compatibility for partners * overriding them through the onboarding block's `dictionary` prop. + * + * @internal */ export function useOnboardingDeductionsFormDictionary(): DeductionsFormDictionary { const { t } = useTranslation('Employee.Deductions') diff --git a/src/components/Employee/Deductions/shared/DeductionsForm/ChildSupportFormView.tsx b/src/components/Employee/Deductions/shared/DeductionsForm/ChildSupportFormView.tsx index 3222c8122..3533ec115 100644 --- a/src/components/Employee/Deductions/shared/DeductionsForm/ChildSupportFormView.tsx +++ b/src/components/Employee/Deductions/shared/DeductionsForm/ChildSupportFormView.tsx @@ -17,6 +17,7 @@ interface ChildSupportFormViewProps { onCancel: () => void } +/** @internal */ export function ChildSupportFormView({ employeeId, deduction, diff --git a/src/components/Employee/Deductions/shared/DeductionsForm/DeductionsForm.tsx b/src/components/Employee/Deductions/shared/DeductionsForm/DeductionsForm.tsx index cefe070a9..68b1b04da 100644 --- a/src/components/Employee/Deductions/shared/DeductionsForm/DeductionsForm.tsx +++ b/src/components/Employee/Deductions/shared/DeductionsForm/DeductionsForm.tsx @@ -12,6 +12,7 @@ import { Flex } from '@/components/Common/Flex/Flex' import { useComponentDictionary, useI18n } from '@/i18n' import type { ResourceDictionary } from '@/types/Helpers' +/** @internal */ export type DeductionsFormDictionary = ResourceDictionary<'Employee.DeductionsForm'> // Garnishment types the form supports (mirrors the legacy SUPPORTED_GARNISHMENT_TYPES). @@ -36,8 +37,11 @@ function deductionToVariant(deduction: Garnishment): Variant { } } +/** @internal */ export interface DeductionsFormProps { + /** Optional CSS class for the root section. */ className?: string + /** The associated employee identifier. */ employeeId: string /** When provided, the form is in edit mode and the deduction's existing * garnishment type selects the inline form variant. Omit for add mode. */ @@ -48,10 +52,13 @@ export interface DeductionsFormProps { * overrides on that namespace flow into the form text. */ dictionary?: DeductionsFormDictionary + /** Called after a successful save with the saved row and whether it was a create or update. */ onSaved: (deduction: Garnishment, mode: 'create' | 'update') => void + /** Called when the user cancels the form. */ onCancel: () => void } +/** @internal */ export function DeductionsForm({ className, employeeId, diff --git a/src/components/Employee/Deductions/shared/DeductionsForm/StandardDeductionForm.tsx b/src/components/Employee/Deductions/shared/DeductionsForm/StandardDeductionForm.tsx index fec977883..ba83ee92c 100644 --- a/src/components/Employee/Deductions/shared/DeductionsForm/StandardDeductionForm.tsx +++ b/src/components/Employee/Deductions/shared/DeductionsForm/StandardDeductionForm.tsx @@ -30,6 +30,7 @@ interface StandardDeductionFormProps { onCancel: () => void } +/** @internal */ export function StandardDeductionForm({ employeeId, deduction, diff --git a/src/components/Employee/Deductions/shared/DeductionsForm/index.ts b/src/components/Employee/Deductions/shared/DeductionsForm/index.ts index f8a845d58..c6258b125 100644 --- a/src/components/Employee/Deductions/shared/DeductionsForm/index.ts +++ b/src/components/Employee/Deductions/shared/DeductionsForm/index.ts @@ -1,5 +1 @@ -export { - DeductionsForm, - type DeductionsFormProps, - type DeductionsFormDictionary, -} from './DeductionsForm' +export { DeductionsForm, type DeductionsFormDictionary } from './DeductionsForm' diff --git a/src/components/Employee/Deductions/shared/DeleteDeductionDialog.tsx b/src/components/Employee/Deductions/shared/DeleteDeductionDialog.tsx index b25fe57db..74059c9cc 100644 --- a/src/components/Employee/Deductions/shared/DeleteDeductionDialog.tsx +++ b/src/components/Employee/Deductions/shared/DeleteDeductionDialog.tsx @@ -6,6 +6,8 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon * Presentational confirm dialog for deleting a deduction. All copy is * passed in by the caller so each consumer owns its own translation strings * — partner overrides on one flow's namespace won't leak into another. + * + * @internal */ export function DeleteDeductionDialog({ pendingDeleteDeduction, diff --git a/src/components/Employee/Deductions/shared/formatDeductionAmount.ts b/src/components/Employee/Deductions/shared/formatDeductionAmount.ts index 38eff21de..6f8470c93 100644 --- a/src/components/Employee/Deductions/shared/formatDeductionAmount.ts +++ b/src/components/Employee/Deductions/shared/formatDeductionAmount.ts @@ -1,11 +1,13 @@ import type { Garnishment } from '@gusto/embedded-api-v-2025-11-15/models/components/garnishment' +/** @internal */ export interface DeductionAmountFormatters { formatCurrency: (value: number) => string formatPercent: (value: number) => string formatPerPaycheck: (value: string) => string } +/** @internal */ export function formatDeductionAmount( deduction: Pick, { formatCurrency, formatPercent, formatPerPaycheck }: DeductionAmountFormatters, diff --git a/src/components/Employee/Deductions/shared/index.ts b/src/components/Employee/Deductions/shared/index.ts deleted file mode 100644 index 529df71e5..000000000 --- a/src/components/Employee/Deductions/shared/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -export { - useDeductionsList, - type UseDeductionsListProps, - type UseDeductionsListResult, - type UseDeductionsListReady, - type DeductionsListDeleteResult, -} from './useDeductionsList' -export { useDeleteDeduction } from './useDeleteDeduction' -export { DeleteDeductionDialog } from './DeleteDeductionDialog' -export { formatDeductionAmount, type DeductionAmountFormatters } from './formatDeductionAmount' -export * from './useDeductionForm' -export * from './useChildSupportGarnishmentForm' -export { - DeductionsForm, - type DeductionsFormProps, - type DeductionsFormDictionary, -} from './DeductionsForm' diff --git a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.ts b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.ts index 7d4cc43b1..7da74b657 100644 --- a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.ts +++ b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.ts @@ -9,21 +9,37 @@ import { coerceNaN } from '@/partner-hook-utils/form/preprocessors' // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the child support garnishment form schema. + * Map these codes to localized copy in `validationMessages` when composing the + * hook. + * + * @public + */ export const ChildSupportGarnishmentFormErrorCodes = { REQUIRED: 'REQUIRED', NEGATIVE_AMOUNT: 'NEGATIVE_AMOUNT', PERCENT_OUT_OF_RANGE: 'PERCENT_OUT_OF_RANGE', } as const +/** + * Union of validation error code strings emitted by the child support + * garnishment form schema. + * + * @public + */ export type ChildSupportGarnishmentFormErrorCode = (typeof ChildSupportGarnishmentFormErrorCodes)[keyof typeof ChildSupportGarnishmentFormErrorCodes] // ── Required-attribute keys recognized from the API ──────────────────── /** - * Agencies declare which child-support attributes they need via - * `required_attributes[].key`. The legacy form only mapped three keys; - * unknown keys are ignored both there and here. + * Child support attribute keys that the form recognizes. Each state agency + * declares which of these keys it requires; the hook exposes the resolved + * subset via `requiredAttrKeys` so callers can drive their own UI on which + * `caseNumber` / `orderNumber` / `remittanceNumber` fields are required. + * + * @public */ export const SUPPORTED_REQUIRED_ATTR_KEYS = [ 'case_number', @@ -31,15 +47,14 @@ export const SUPPORTED_REQUIRED_ATTR_KEYS = [ 'remittance_number', ] as const +/** + * Union of child support attribute key strings recognized by the form. + * + * @public + */ export type SupportedRequiredAttrKey = (typeof SUPPORTED_REQUIRED_ATTR_KEYS)[number] -// Field name on the form for each required-attribute key. -export const REQUIRED_ATTR_FIELD_NAME: Record = { - case_number: 'caseNumber', - order_number: 'orderNumber', - remittance_number: 'remittanceNumber', -} - +/** @internal */ export function getRequiredAttrKeys(agency?: Agencies | null): Set { const keys = new Set() if (!agency?.requiredAttributes) return keys @@ -83,12 +98,21 @@ const fieldValidators = { paymentPeriod: z.enum(PaymentPeriod), } -export type ChildSupportGarnishmentFormField = keyof typeof fieldValidators - +/** + * Shape of the values managed by the child support garnishment form. + * + * @public + */ export type ChildSupportGarnishmentFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the child support garnishment + * form on submit. + * + * @public + */ export type ChildSupportGarnishmentFormOutputs = ChildSupportGarnishmentFormData // ── Required fields config ───────────────────────────────────────────── @@ -98,6 +122,7 @@ export type ChildSupportGarnishmentFormOutputs = ChildSupportGarnishmentFormData // based on the currently selected agency — see `createChildSupportGarnishmentFormSchema` // which assigns 'always' / 'never' per call. +/** @internal */ interface ChildSupportGarnishmentFormSchemaOptions { mode?: 'create' | 'update' /** @@ -118,6 +143,7 @@ interface ChildSupportGarnishmentFormSchemaOptions { agencyList?: readonly Agencies[] } +/** @internal */ export function createChildSupportGarnishmentFormSchema({ mode = 'create', selectedAgency, diff --git a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.tsx b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.tsx index f37dca1a7..1bd1530d7 100644 --- a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.tsx +++ b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/fields.tsx @@ -10,11 +10,61 @@ import { } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * The required-field error code produced by {@link useChildSupportGarnishmentForm} fields that only emit `REQUIRED`. + * + * @remarks + * Used as the `validationMessages` key for the state, county (fips code), case + * number, order number, remittance number, and payment-period fields. See + * {@link ChildSupportGarnishmentFormErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof ChildSupportGarnishmentFormErrorCodes.REQUIRED + +/** + * The negative-amount error code produced by {@link useChildSupportGarnishmentForm}'s currency fields. + * + * @remarks + * Used as a `validationMessages` key on `Fields.PayPeriodMaximum`. See + * {@link ChildSupportGarnishmentFormErrorCodes}. + * + * @public + */ export type NegativeAmountValidation = typeof ChildSupportGarnishmentFormErrorCodes.NEGATIVE_AMOUNT + +/** + * The percent-out-of-range error code produced by {@link useChildSupportGarnishmentForm}'s percentage field. + * + * @remarks + * Used as a `validationMessages` key on `Fields.Amount` (the percent-of-paycheck input). + * See {@link ChildSupportGarnishmentFormErrorCodes}. + * + * @public + */ export type PercentValidation = typeof ChildSupportGarnishmentFormErrorCodes.PERCENT_OUT_OF_RANGE +/** + * Validation error codes emitted by the `payPeriodMaximum` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.PayPeriodMaximum`. See + * {@link ChildSupportGarnishmentFormErrorCodes} for the full description of each code. + * + * @public + */ export type PayPeriodMaximumValidation = RequiredValidation | NegativeAmountValidation + +/** + * Validation error codes emitted by the `amount` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.Amount`. The field + * accepts a percentage of paycheck (0–100). See + * {@link ChildSupportGarnishmentFormErrorCodes} for the full description of each code. + * + * @public + */ export type AmountValidation = RequiredValidation | PercentValidation // ── State (agency) ───────────────────────────────────────────────────── @@ -23,79 +73,239 @@ export type AmountValidation = RequiredValidation | PercentValidation // supply `getOptionLabel` to translate the agency name into a localized // label (the SDK's option-label fallback is the agency state code). +/** + * Raw agency entry exposed on {@link useChildSupportGarnishmentForm}'s `data.agencies` and as the `entries` shape for the `State` select. + * + * @remarks + * Supply `getOptionLabel` on `Fields.State` to translate the agency name into a + * localized label — the SDK's option-label fallback is the agency state code. + * + * @public + */ export type StateFieldEntry = { + /** The agency's state code (e.g. `AK`). */ state: string + /** The agency name as returned by the Gusto API. */ name: string + /** True when the agency requires payments to be remitted manually rather than through Gusto. */ manualPaymentRequired?: boolean } +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.State` component. + * + * @public + */ export type StateFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Select bound to the `state` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.State`. Always rendered. The + * selected agency drives which subsequent fields are required and visible + * (`FipsCode`, `CaseNumber`, `OrderNumber`, `RemittanceNumber`). + * + * @param props - {@link StateFieldProps} — accepts the standard hook field props plus `getOptionLabel` for agency display. + * @returns The rendered select bound to `state`. + * @public + */ export function StateField(props: StateFieldProps) { return } // ── FipsCode (county) ────────────────────────────────────────────────── +/** + * Raw county entry exposed on {@link useChildSupportGarnishmentForm}'s `data.counties` and as the `entries` shape for the `FipsCode` select. + * + * @remarks + * `county` is `null` for "all counties" entries — the agency's single county + * record represents the whole state. Supply `getOptionLabel` on + * `Fields.FipsCode` to translate the county name into a localized label. + * + * @public + */ export type CountyEntry = { + /** The FIPS code for the county. */ fipsCode: string + /** The county name, or `null` for an "all counties" entry covering the whole state. */ county: string | null } +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.FipsCode` component. + * + * @public + */ export type FipsCodeFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Select bound to the `fipsCode` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.FipsCode` only when the selected + * agency offers multiple counties. When the agency has a single "all counties" + * code, the hook auto-fills the value and exposes the field as `undefined` — + * always null-check before rendering. Options are dynamically populated from + * the FIPS codes the selected agency declares. + * + * @param props - {@link FipsCodeFieldProps} — accepts the standard hook field props plus `getOptionLabel` for county display. + * @returns The rendered select bound to `fipsCode`. + * @public + */ export function FipsCodeField(props: FipsCodeFieldProps) { return } // ── Required agency-attribute text inputs ────────────────────────────── +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.CaseNumber` component. + * + * @public + */ export type CaseNumberFieldProps = HookFieldProps> +/** + * Text input bound to the `caseNumber` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.CaseNumber` only when the + * selected agency requires a case number (`status.requiredAttrKeys.has('case_number')`). + * Always null-check before rendering. + * + * @param props - {@link CaseNumberFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `caseNumber`. + * @public + */ export function CaseNumberField(props: CaseNumberFieldProps) { return } +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.OrderNumber` component. + * + * @public + */ export type OrderNumberFieldProps = HookFieldProps> +/** + * Text input bound to the `orderNumber` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.OrderNumber` only when the + * selected agency requires an order number (`status.requiredAttrKeys.has('order_number')`). + * Always null-check before rendering. + * + * @param props - {@link OrderNumberFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `orderNumber`. + * @public + */ export function OrderNumberField(props: OrderNumberFieldProps) { return } +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.RemittanceNumber` component. + * + * @public + */ export type RemittanceNumberFieldProps = HookFieldProps> +/** + * Text input bound to the `remittanceNumber` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.RemittanceNumber` only when the + * selected agency requires a remittance number (`status.requiredAttrKeys.has('remittance_number')`). + * Always null-check before rendering. + * + * @param props - {@link RemittanceNumberFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `remittanceNumber`. + * @public + */ export function RemittanceNumberField(props: RemittanceNumberFieldProps) { return } // ── Pay-period maximum (currency) ────────────────────────────────────── +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.PayPeriodMaximum` component. + * + * @public + */ export type PayPeriodMaximumFieldProps = HookFieldProps< NumberInputHookFieldProps > +/** + * Number input bound to the `payPeriodMaximum` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.PayPeriodMaximum`. Always + * rendered. Carries the per-pay-period currency cap for the garnishment. + * + * @param props - {@link PayPeriodMaximumFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered number input bound to `payPeriodMaximum`. + * @public + */ export function PayPeriodMaximumField(props: PayPeriodMaximumFieldProps) { return } // ── Amount (percent of paycheck, 0-100) ──────────────────────────────── +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.Amount` component. + * + * @public + */ export type AmountFieldProps = HookFieldProps> +/** + * Number input bound to the `amount` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Amount`. Always rendered. + * Accepts a percentage of paycheck in the range 0–100 — the API stores + * child-support amounts as percentages rather than fixed currency values. + * + * @param props - {@link AmountFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered number input bound to `amount`. + * @public + */ export function AmountField(props: AmountFieldProps) { return } // ── Payment period (select) ──────────────────────────────────────────── +/** + * Props accepted by {@link useChildSupportGarnishmentForm}'s `Fields.PaymentPeriod` component. + * + * @public + */ export type PaymentPeriodFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Select bound to the `paymentPeriod` field of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Available on the hook result as `form.Fields.PaymentPeriod`. Always rendered. + * Options: `Every week`, `Every other week`, `Twice per month`, `Monthly`. + * + * @param props - {@link PaymentPeriodFieldProps} — accepts the standard hook field props plus `getOptionLabel` for payment-period display. + * @returns The rendered select bound to `paymentPeriod`. + * @public + */ export function PaymentPeriodField(props: PaymentPeriodFieldProps) { return } diff --git a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/index.ts b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/index.ts index d29fb706a..3547d970c 100644 --- a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/index.ts +++ b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/index.ts @@ -5,7 +5,6 @@ export { type UseChildSupportGarnishmentFormReady, type ChildSupportGarnishmentFormFields, type ChildSupportGarnishmentFormFieldsMetadata, - type ChildSupportGarnishmentFormFieldsType, } from './useChildSupportGarnishmentForm' export { createChildSupportGarnishmentFormSchema, @@ -13,12 +12,20 @@ export { type ChildSupportGarnishmentFormErrorCode, type ChildSupportGarnishmentFormData, type ChildSupportGarnishmentFormOutputs, - type ChildSupportGarnishmentFormField, type SupportedRequiredAttrKey, getRequiredAttrKeys, - REQUIRED_ATTR_FIELD_NAME, SUPPORTED_REQUIRED_ATTR_KEYS, } from './childSupportGarnishmentFormSchema' +export { + StateField, + FipsCodeField, + CaseNumberField, + OrderNumberField, + RemittanceNumberField, + PayPeriodMaximumField, + AmountField, + PaymentPeriodField, +} from './fields' export type { RequiredValidation as ChildSupportGarnishmentRequiredValidation, NegativeAmountValidation as ChildSupportGarnishmentNegativeAmountValidation, diff --git a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.tsx b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.tsx index 145d9c812..6601cdf26 100644 --- a/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.tsx +++ b/src/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/useChildSupportGarnishmentForm.tsx @@ -59,19 +59,44 @@ const PAYMENT_PERIOD_ENTRIES = [ PaymentPeriod.Monthly, ] as const +/** + * Configuration options for {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Presence or absence of `garnishmentId` selects the API verb — see the + * `garnishmentId` field description. + * + * @public + */ export interface UseChildSupportGarnishmentFormProps { + /** UUID of the employee whose child-support garnishment is being created or edited. */ employeeId: string /** - * When set, loads that garnishment via the list query and updates it (PUT). - * When omitted, the form is in create mode (POST). + * When set, loads that garnishment and updates it (PUT). When omitted, the + * form is in create mode (POST). */ garnishmentId?: string + /** Pre-fill form values. Server data takes precedence on update. */ defaultValues?: Partial + /** Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler` so submit-time focus is coordinated across multiple forms. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Pre-bound field components exposed on `useChildSupportGarnishmentForm().form.Fields`. + * + * @remarks + * Each property is either the field component or `undefined`. A field is + * `undefined` when conditions for rendering it aren't met — see each member + * for its visibility rule. Always null-check conditional fields (e.g. + * `{Fields.FipsCode && }`) before rendering. + * + * @public + */ export interface ChildSupportGarnishmentFormFields { + /** Agency (state) select. Always available. */ State: typeof StateField /** Only available when the selected agency has more than one fips code, or the * sole code is county-scoped (not an "all counties" auto-pick). */ @@ -82,16 +107,31 @@ export interface ChildSupportGarnishmentFormFields { OrderNumber: typeof OrderNumberField | undefined /** Only available when the selected agency requires `remittance_number`. */ RemittanceNumber: typeof RemittanceNumberField | undefined + /** Per-pay-period currency cap input. Always available. */ PayPeriodMaximum: typeof PayPeriodMaximumField + /** Percent-of-paycheck input (0–100). Always available. */ Amount: typeof AmountField + /** Payment period select. Always available. */ PaymentPeriod: typeof PaymentPeriodField } +/** + * Ready-state shape returned by {@link useChildSupportGarnishmentForm} once data has loaded. + * + * @remarks + * Discriminated by `isLoading: false`. Extends {@link BaseFormHookReady} with + * the child-support-specific `data`, `status`, `actions`, and `form.Fields` + * shape. Static, entity-derived values live under `data.*`; reactive values + * that flip with form input live under `status.*`. + * + * @public + */ export interface UseChildSupportGarnishmentFormReady extends BaseFormHookReady< FieldsMetadata, ChildSupportGarnishmentFormData, ChildSupportGarnishmentFormFields > { + /** Child-support-specific data payload: the available agencies, counties for the selected state, and the loaded garnishment for update mode. */ data: { /** Agencies offered as `State` options; raw entries the consumer can use * with `getOptionLabel` for translated names. */ @@ -102,8 +142,11 @@ export interface UseChildSupportGarnishmentFormReady extends BaseFormHookReady< /** The garnishment loaded for update; `null` in create mode. */ deduction: Garnishment | null } + /** Submission state and reactive flags derived from current form input. */ status: { + /** `true` while a create or update mutation is in flight. */ isPending: boolean + /** Reflects whether the next submit will POST a new garnishment or PUT an existing one. */ mode: 'create' | 'update' /** The agency record matching the currently selected `state`. */ selectedAgency: Agencies | null @@ -113,15 +156,88 @@ export interface UseChildSupportGarnishmentFormReady extends BaseFormHookReady< /** Which `required_attributes` keys the selected agency declares. */ requiredAttrKeys: ReadonlySet } + /** Submission action. */ actions: { + /** Submits the form. Returns the saved garnishment + mode on success, or `undefined` when validation fails or the request errored. */ onSubmit: () => Promise | undefined> } } +/** + * Return value of {@link useChildSupportGarnishmentForm}. + * + * @remarks + * Discriminated union: {@link HookLoadingResult} while the agency catalog (and, + * in update mode, the existing garnishment) is loading; + * {@link UseChildSupportGarnishmentFormReady} once data is ready. + * + * @public + */ export type UseChildSupportGarnishmentFormResult = | HookLoadingResult | UseChildSupportGarnishmentFormReady +/** + * Headless hook for creating or updating a child-support garnishment. + * + * @remarks + * Unlike standard garnishments, child support requires agency-specific + * attributes (case number, order number, remittance number) that vary by + * state, plus an optional county selection when the state has multiple + * counties. The hook loads the agency catalog from the Gusto API, derives + * which attributes the selected state requires, and exposes the right Fields + * conditionally. + * + * Presence or absence of `garnishmentId` selects the API verb: omit it to + * POST a new garnishment, supply it to PUT updates against the existing row. + * For non-child-support deductions (court-ordered garnishments and post-tax + * custom), use {@link useDeductionForm} instead. + * + * @param input - See {@link UseChildSupportGarnishmentFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseChildSupportGarnishmentFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { useChildSupportGarnishmentForm, SDKFormProvider } from '@gusto/embedded-react-sdk' + * + * function ChildSupportPage({ employeeId, garnishmentId }: { employeeId: string; garnishmentId?: string }) { + * const form = useChildSupportGarnishmentForm({ employeeId, garnishmentId }) + * + * if (form.isLoading) return

Loading…

+ * + * const { Fields } = form.form + * + * return ( + * + *
{ + * e.preventDefault() + * void form.actions.onSubmit() + * }} + * > + * entry.name} + * validationMessages={{ REQUIRED: 'Required' }} + * /> + * {Fields.CaseNumber && ( + * + * )} + * + * + * + *
+ * ) + * } + * ``` + */ export function useChildSupportGarnishmentForm({ employeeId, garnishmentId, @@ -433,7 +549,16 @@ export function useChildSupportGarnishmentForm({ } } +/** + * Per-field metadata returned by {@link useChildSupportGarnishmentForm} as `form.fieldsMetadata`. + * + * @remarks + * Carries per-field `isRequired`, `isDisabled`, label, description, and option + * entries derived from the schema and form state. Use these to drive UI such + * as disabled state or option lists when not relying on the pre-bound + * {@link ChildSupportGarnishmentFormFields} components. + * + * @public + */ export type ChildSupportGarnishmentFormFieldsMetadata = UseChildSupportGarnishmentFormReady['form']['fieldsMetadata'] -export type ChildSupportGarnishmentFormFieldsType = - UseChildSupportGarnishmentFormReady['form']['Fields'] diff --git a/src/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.ts b/src/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.ts index 77e05c27a..073e15685 100644 --- a/src/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.ts +++ b/src/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.ts @@ -9,11 +9,22 @@ import { coerceNaN, coerceStringBoolean } from '@/partner-hook-utils/form/prepro // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the deduction form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const DeductionFormErrorCodes = { REQUIRED: 'REQUIRED', NEGATIVE_AMOUNT: 'NEGATIVE_AMOUNT', } as const +/** + * Union of validation error code strings emitted by the deduction form schema. + * + * @public + */ export type DeductionFormErrorCode = (typeof DeductionFormErrorCodes)[keyof typeof DeductionFormErrorCodes] @@ -47,12 +58,20 @@ const fieldValidators = { garnishmentType: z.enum(GarnishmentType), } -export type DeductionFormField = keyof typeof fieldValidators - +/** + * Shape of the values managed by the deduction form. + * + * @public + */ export type DeductionFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the deduction form on submit. + * + * @public + */ export type DeductionFormOutputs = DeductionFormData // ── Required fields config ───────────────────────────────────────────── @@ -67,10 +86,17 @@ const requiredFieldsConfig = { annualMaximum: 'never', } satisfies RequiredFieldConfig +/** + * Keys of optional deduction fields that can be promoted to required via the + * hook's `optionalFieldsToRequire` option. + * + * @public + */ export type DeductionFormOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface DeductionFormSchemaOptions { mode?: 'create' | 'update' /** @@ -83,6 +109,7 @@ interface DeductionFormSchemaOptions { optionalFieldsToRequire?: DeductionFormOptionalFieldsToRequire } +/** @internal */ export function createDeductionFormSchema(options: DeductionFormSchemaOptions) { const { mode = 'create', courtOrdered, optionalFieldsToRequire } = options diff --git a/src/components/Employee/Deductions/shared/useDeductionForm/fields.tsx b/src/components/Employee/Deductions/shared/useDeductionForm/fields.tsx index 79949f5fe..f9fe06b3e 100644 --- a/src/components/Employee/Deductions/shared/useDeductionForm/fields.tsx +++ b/src/components/Employee/Deductions/shared/useDeductionForm/fields.tsx @@ -12,70 +12,230 @@ import { } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * The required-field error code produced by {@link useDeductionForm} fields that only emit `REQUIRED`. + * + * @remarks + * Used as the `validationMessages` key for the description, recurring, + * deduct-as-percentage, and garnishment-type fields. See + * {@link DeductionFormErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof DeductionFormErrorCodes.REQUIRED + +/** + * The negative-amount error code produced by {@link useDeductionForm}'s currency fields. + * + * @remarks + * Used as a `validationMessages` key on `Fields.Amount`, `Fields.TotalAmount`, + * and `Fields.AnnualMaximum`. See {@link DeductionFormErrorCodes}. + * + * @public + */ export type NegativeAmountValidation = typeof DeductionFormErrorCodes.NEGATIVE_AMOUNT +/** + * Validation error codes emitted by the `amount` field of {@link useDeductionForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.Amount`. See + * {@link DeductionFormErrorCodes} for the full description of each code. + * + * @public + */ export type AmountValidation = RequiredValidation | NegativeAmountValidation + +/** + * Validation error codes emitted by the cap fields of {@link useDeductionForm} (`totalAmount`, `annualMaximum`). + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.TotalAmount` and + * `Fields.AnnualMaximum`. See {@link DeductionFormErrorCodes} for the full + * description of each code. + * + * @public + */ export type CapValidation = NegativeAmountValidation // ── Description ──────────────────────────────────────────────────────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.Description` component. + * + * @public + */ export type DescriptionFieldProps = HookFieldProps> +/** + * Text input bound to the `description` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Description`. Always rendered. + * + * @param props - {@link DescriptionFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `description`. + * @public + */ export function DescriptionField(props: DescriptionFieldProps) { return } // ── Recurring (radio: boolean) ───────────────────────────────────────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.Recurring` component. + * + * @public + */ export type RecurringFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `recurring` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Recurring`. Always rendered. + * Picks between a recurring deduction (taken every paycheck) and a one-time + * deduction. The cap fields (`Fields.TotalAmount` and `Fields.AnnualMaximum`) + * are exposed only when this is set to recurring. + * + * @param props - {@link RecurringFieldProps} — accepts the standard hook field props plus `getOptionLabel` for boolean display. + * @returns The rendered radio group bound to `recurring`. + * @public + */ export function RecurringField(props: RecurringFieldProps) { return } // ── DeductAsPercentage (radio: boolean) ──────────────────────────────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.DeductAsPercentage` component. + * + * @public + */ export type DeductAsPercentageFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `deductAsPercentage` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.DeductAsPercentage`. Always + * rendered. Toggles how `Fields.Amount` is interpreted — as a fixed currency + * amount when `false`, or as a percentage of paycheck when `true`. + * + * @param props - {@link DeductAsPercentageFieldProps} — accepts the standard hook field props plus `getOptionLabel` for boolean display. + * @returns The rendered radio group bound to `deductAsPercentage`. + * @public + */ export function DeductAsPercentageField(props: DeductAsPercentageFieldProps) { return } // ── Amount (currency or percent depending on deductAsPercentage) ─────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.Amount` component. + * + * @public + */ export type AmountFieldProps = HookFieldProps> +/** + * Number input bound to the `amount` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Amount`. Always rendered. + * Interpreted as a currency amount when `Fields.DeductAsPercentage` is set to + * a fixed amount, or as a percentage of paycheck when it's set to percentage. + * + * @param props - {@link AmountFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered number input bound to `amount`. + * @public + */ export function AmountField(props: AmountFieldProps) { return } // ── TotalAmount (optional cap — only meaningful when recurring) ──────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.TotalAmount` component. + * + * @public + */ export type TotalAmountFieldProps = HookFieldProps> +/** + * Number input bound to the `totalAmount` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.TotalAmount` only when + * `status.isRecurring` is `true`. A zero value means "no cap" — the hook + * drops it on the wire. Always null-check before rendering. + * + * @param props - {@link TotalAmountFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered number input bound to `totalAmount`. + * @public + */ export function TotalAmountField(props: TotalAmountFieldProps) { return } // ── AnnualMaximum (optional annual cap — only meaningful when recurring) ─ +/** + * Props accepted by {@link useDeductionForm}'s `Fields.AnnualMaximum` component. + * + * @public + */ export type AnnualMaximumFieldProps = HookFieldProps> +/** + * Number input bound to the `annualMaximum` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.AnnualMaximum` only when + * `status.isRecurring` is `true`. A zero value means "no cap" — the hook + * drops it on the wire. Always null-check before rendering. + * + * @param props - {@link AnnualMaximumFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered number input bound to `annualMaximum`. + * @public + */ export function AnnualMaximumField(props: AnnualMaximumFieldProps) { return } // ── GarnishmentType (court-ordered only) ─────────────────────────────── +/** + * Props accepted by {@link useDeductionForm}'s `Fields.GarnishmentType` component. + * + * @public + */ export type GarnishmentTypeFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Select bound to the `garnishmentType` field of {@link useDeductionForm}. + * + * @remarks + * Available on the hook result as `form.Fields.GarnishmentType` only when the + * hook is constructed with `courtOrdered: true`. Always null-check before + * rendering. Options: `Federal Tax Lien`, `State Tax Lien`, `Student Loan`, + * `Creditor Garnishment`, `Federal Loan`, `Other Garnishment`. For + * child-support garnishments, use {@link useChildSupportGarnishmentForm}. + * + * @param props - {@link GarnishmentTypeFieldProps} — accepts the standard hook field props plus `getOptionLabel` for garnishment-type display. + * @returns The rendered select bound to `garnishmentType`. + * @public + */ export function GarnishmentTypeField(props: GarnishmentTypeFieldProps) { return } diff --git a/src/components/Employee/Deductions/shared/useDeductionForm/index.ts b/src/components/Employee/Deductions/shared/useDeductionForm/index.ts index 92deec498..ff6e0a3d0 100644 --- a/src/components/Employee/Deductions/shared/useDeductionForm/index.ts +++ b/src/components/Employee/Deductions/shared/useDeductionForm/index.ts @@ -5,7 +5,6 @@ export { type UseDeductionFormReady, type DeductionFormFields, type DeductionFormFieldsMetadata, - type DeductionFormFieldsType, type DeductionFormOptionalFieldsToRequire, } from './useDeductionForm' export { @@ -14,8 +13,16 @@ export { type DeductionFormErrorCode, type DeductionFormData, type DeductionFormOutputs, - type DeductionFormField, } from './deductionFormSchema' +export { + DescriptionField, + RecurringField, + DeductAsPercentageField, + AmountField, + TotalAmountField, + AnnualMaximumField, + GarnishmentTypeField, +} from './fields' export type { RequiredValidation as DeductionFormRequiredValidation, NegativeAmountValidation as DeductionFormNegativeAmountValidation, diff --git a/src/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.tsx b/src/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.tsx index 54170f9c9..5664394f0 100644 --- a/src/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.tsx +++ b/src/components/Employee/Deductions/shared/useDeductionForm/useDeductionForm.tsx @@ -57,11 +57,22 @@ const GARNISHMENT_TYPES: readonly GarnishmentType[] = [ 'other_garnishment', ] as const +/** + * Configuration options for {@link useDeductionForm}. + * + * @remarks + * Presence or absence of `garnishmentId` selects the API verb — see the + * `garnishmentId` field description. `courtOrdered` selects between the + * post-tax custom variant and the court-ordered garnishment variant. + * + * @public + */ export interface UseDeductionFormProps { + /** UUID of the employee whose deduction is being created or edited. */ employeeId: string /** - * When set, loads that garnishment via the list query and updates it (PUT). - * When omitted, the form is in create mode (POST). + * When set, loads that garnishment and updates it (PUT). When omitted, the + * form is in create mode (POST). */ garnishmentId?: string /** @@ -71,19 +82,38 @@ export interface UseDeductionFormProps { * `garnishmentType` is excluded from the schema and submit payload. * * Note: this hook does NOT handle `garnishmentType: 'child_support'`. Use - * `useChildSupportGarnishmentForm` for child-support agency-keyed payloads. + * {@link useChildSupportGarnishmentForm} for child-support agency-keyed payloads. */ courtOrdered: boolean + /** Override fields that are optional on a given mode to be required. See {@link DeductionFormOptionalFieldsToRequire}. */ optionalFieldsToRequire?: DeductionFormOptionalFieldsToRequire + /** Pre-fill form values. Server data takes precedence on update. */ defaultValues?: Partial + /** Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler` so submit-time focus is coordinated across multiple forms. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Pre-bound field components exposed on `useDeductionForm().form.Fields`. + * + * @remarks + * Each property is either the field component or `undefined`. A field is + * `undefined` when conditions for rendering it aren't met — see each member + * for its visibility rule. Always null-check conditional fields (e.g. + * `{Fields.TotalAmount && }`) before rendering. + * + * @public + */ export interface DeductionFormFields { + /** Description text input. Always available. */ Description: typeof DescriptionField + /** Recurring vs one-time radio group. Always available. */ Recurring: typeof RecurringField + /** Fixed-amount vs percentage radio group. Always available. */ DeductAsPercentage: typeof DeductAsPercentageField + /** Deduction amount input. Always available. */ Amount: typeof AmountField /** Only available when `status.isRecurring` is true. */ TotalAmount: typeof TotalAmountField | undefined @@ -93,17 +123,32 @@ export interface DeductionFormFields { GarnishmentType: typeof GarnishmentTypeField | undefined } +/** + * Ready-state shape returned by {@link useDeductionForm} once data has loaded. + * + * @remarks + * Discriminated by `isLoading: false`. Extends {@link BaseFormHookReady} with + * the deduction-specific `data`, `status`, `actions`, and `form.Fields` shape. + * Static, entity-derived values live under `data.*`; reactive values that + * flip with form input live under `status.*`. + * + * @public + */ export interface UseDeductionFormReady extends BaseFormHookReady< FieldsMetadata, DeductionFormData, DeductionFormFields > { + /** Deduction-specific data payload: the loaded garnishment for update mode, or `null` in create mode. */ data: { /** The garnishment loaded for update; `null` in create mode. */ deduction: Garnishment | null } + /** Submission state and reactive flags derived from current form input. */ status: { + /** `true` while a create or update mutation is in flight. */ isPending: boolean + /** Reflects whether the next submit will POST a new deduction or PUT an existing one. */ mode: 'create' | 'update' /** * Mirrors the watched `recurring` value. Cap fields (`TotalAmount`, @@ -113,13 +158,85 @@ export interface UseDeductionFormReady extends BaseFormHookReady< */ isRecurring: boolean } + /** Submission action. */ actions: { + /** Submits the form. Returns the saved garnishment + mode on success, or `undefined` when validation fails or the request errored. */ onSubmit: () => Promise | undefined> } } +/** + * Return value of {@link useDeductionForm}. + * + * @remarks + * Discriminated union: {@link HookLoadingResult} while the existing garnishment + * is loading (update mode only); {@link UseDeductionFormReady} once data is + * ready. In create mode the hook returns the ready branch immediately. + * + * @public + */ export type UseDeductionFormResult = HookLoadingResult | UseDeductionFormReady +/** + * Headless hook for creating or updating a non-child-support deduction. + * + * @remarks + * Both variants — post-tax custom deductions and court-ordered garnishments — + * share the same field set (description, frequency, deduct-as-percentage, + * amount, optional caps) and differ only in whether the deduction is + * court-ordered and carries a `garnishmentType`. Set `courtOrdered: true` to + * surface the garnishment-type select; set it to `false` for a custom post-tax + * deduction. + * + * Presence or absence of `garnishmentId` selects the API verb: omit it to POST + * a new deduction, supply it to PUT updates against the existing row. For + * child-support garnishments, use {@link useChildSupportGarnishmentForm} + * instead — those require agency-keyed required attributes (case number, + * order number, remittance number, county) that this hook doesn't model. + * + * @param input - See {@link UseDeductionFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseDeductionFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { useDeductionForm, SDKFormProvider } from '@gusto/embedded-react-sdk' + * + * function CustomDeductionPage({ employeeId, garnishmentId }: { employeeId: string; garnishmentId?: string }) { + * const form = useDeductionForm({ employeeId, garnishmentId, courtOrdered: false }) + * + * if (form.isLoading) return

Loading…

+ * + * const { Fields } = form.form + * + * return ( + * + *
{ + * e.preventDefault() + * void form.actions.onSubmit() + * }} + * > + * + * (v ? 'Recurring' : 'One-time')} + * validationMessages={{ REQUIRED: 'Required' }} + * /> + * + * {Fields.TotalAmount && ( + * + * )} + * + * + *
+ * ) + * } + * ``` + */ export function useDeductionForm({ employeeId, garnishmentId, @@ -375,8 +492,18 @@ export function useDeductionForm({ } } +/** + * Per-field metadata returned by {@link useDeductionForm} as `form.fieldsMetadata`. + * + * @remarks + * Carries per-field `isRequired`, `isDisabled`, label, description, and option + * entries derived from the schema and form state. Use these to drive UI such + * as disabled state or option lists when not relying on the pre-bound + * {@link DeductionFormFields} components. + * + * @public + */ export type DeductionFormFieldsMetadata = UseDeductionFormReady['form']['fieldsMetadata'] -export type DeductionFormFieldsType = UseDeductionFormReady['form']['Fields'] // ── Internal loader ───────────────────────────────────────────────────── // diff --git a/src/components/Employee/Deductions/shared/useDeductionsList.tsx b/src/components/Employee/Deductions/shared/useDeductionsList.tsx index dfb7d5741..34068ed27 100644 --- a/src/components/Employee/Deductions/shared/useDeductionsList.tsx +++ b/src/components/Employee/Deductions/shared/useDeductionsList.tsx @@ -5,15 +5,17 @@ import { useBaseSubmit } from '@/components/Base/useBaseSubmit' import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult, HookSubmitResult } from '@/partner-hook-utils/types' +/** @internal */ export interface UseDeductionsListProps { employeeId: string } -export interface DeductionsListDeleteResult { +interface DeductionsListDeleteResult { garnishment: Garnishment remainingActiveCount: number } +/** @internal */ export interface UseDeductionsListReady extends BaseHookReady< { deductions: Garnishment[] }, { isFetching: boolean; isPending: boolean; deletingGarnishmentUuid?: string } @@ -25,8 +27,10 @@ export interface UseDeductionsListReady extends BaseHookReady< } } +/** @internal */ export type UseDeductionsListResult = HookLoadingResult | UseDeductionsListReady +/** @internal */ export function useDeductionsList({ employeeId }: UseDeductionsListProps): UseDeductionsListResult { const garnishmentsQuery = useGarnishmentsList({ employeeId }) const updateMutation = useGarnishmentsUpdateMutation() diff --git a/src/components/Employee/Deductions/shared/useDeleteDeduction.ts b/src/components/Employee/Deductions/shared/useDeleteDeduction.ts index a5f9ce78d..2b46c5684 100644 --- a/src/components/Employee/Deductions/shared/useDeleteDeduction.ts +++ b/src/components/Employee/Deductions/shared/useDeleteDeduction.ts @@ -7,6 +7,8 @@ import type { Garnishment } from '@gusto/embedded-api-v-2025-11-15/models/compon * `setPendingDeleteDeduction(...)` to open the dialog, and the dialog's * confirm calls `handleConfirmDelete`, which in turn invokes the * caller-supplied `handleDelete(garnishment)`. + * + * @internal */ export function useDeleteDeduction(handleDelete: (garnishment: Garnishment) => Promise) { const [pendingDeleteDeduction, setPendingDeleteDeduction] = useState(null) diff --git a/src/components/Employee/Documents/management/DocumentManager.tsx b/src/components/Employee/Documents/management/DocumentManager.tsx index 6ef4ea66e..a45cac520 100644 --- a/src/components/Employee/Documents/management/DocumentManager.tsx +++ b/src/components/Employee/Documents/management/DocumentManager.tsx @@ -8,6 +8,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useI18n } from '@/i18n' import { componentEvents } from '@/shared/constants' +/** @internal */ export interface DocumentManagerProps { employeeId: string formId: string @@ -18,6 +19,8 @@ export interface DocumentManagerProps { * selected form's PDF — including unsigned forms, which are shown as-is. * Signing is intentionally not offered here; forms are signed by the employee * during onboarding, not by an admin viewing the dashboard. + * + * @internal */ export function DocumentManager(props: DocumentManagerProps & BaseComponentInterface) { useI18n('Employee.DocumentManager') diff --git a/src/components/Employee/Documents/management/Documents.tsx b/src/components/Employee/Documents/management/Documents.tsx index afcafd72d..2f45a8fce 100644 --- a/src/components/Employee/Documents/management/Documents.tsx +++ b/src/components/Employee/Documents/management/Documents.tsx @@ -13,8 +13,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link Documents}. + * + * @public + */ export interface DocumentsProps extends CommonComponentInterface<'Employee.Management.Documents'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -34,6 +41,23 @@ function DocumentsFlow({ employeeId, onEvent }: DocumentsProps) { return } +/** + * Standalone employee documents management flow. + * + * @remarks + * Orchestrates the documents card and the per-form document manager. The flow + * starts on the documents card and routes to the document manager when a row's + * View CTA is selected; cancelling from the document manager returns to the + * card. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/documents/card/viewRequested` | Fired when a row's View CTA is clicked on the documents card | `{ employeeId: string; formId: string }` | + * + * @param props - See {@link DocumentsProps}. + * @returns The documents management flow. + * @public + */ export function Documents({ dictionary, FallbackComponent, diff --git a/src/components/Employee/Documents/management/DocumentsCard/DocumentsCard.tsx b/src/components/Employee/Documents/management/DocumentsCard/DocumentsCard.tsx index 1c6fda886..0fa5838d5 100644 --- a/src/components/Employee/Documents/management/DocumentsCard/DocumentsCard.tsx +++ b/src/components/Employee/Documents/management/DocumentsCard/DocumentsCard.tsx @@ -8,21 +8,31 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link DocumentsCard}. + * + * @public + */ export interface DocumentsCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when a row's View CTA is clicked. */ onEvent: OnEventType } /** * Standalone "Documents" (forms) card. Owns its own data fetch via * {@link useDocumentsList} and renders the employee's forms in a table with a - * per-row "View" action. Emits the management block's scoped event - * (`EMPLOYEE_MANAGEMENT_DOCUMENTS_CARD_VIEW_REQUESTED`) when a row's View CTA is - * clicked. The card is read-only — viewing or signing a form happens in the - * `DocumentManager` screen the orchestrator routes to — and has no alert API: - * alert rendering is the orchestrator's responsibility (the block's - * `DocumentsCardContextual` for standalone consumption; the dashboard chrome - * for dashboard consumption). + * per-row "View" action. Emits + * `employee/management/documents/card/viewRequested` with + * `{ employeeId, formId }` when a row's View CTA is clicked. The card is + * read-only — viewing or signing a form happens in the screen the parent + * routes to — and renders no alerts: alert rendering is the parent's + * responsibility. + * + * @param props - See {@link DocumentsCardProps}. + * @returns The documents card. + * @public */ export function DocumentsCard(props: DocumentsCardProps) { return ( diff --git a/src/components/Employee/Documents/management/DocumentsComponents.tsx b/src/components/Employee/Documents/management/DocumentsComponents.tsx index ad9f2cc75..e29bb27ea 100644 --- a/src/components/Employee/Documents/management/DocumentsComponents.tsx +++ b/src/components/Employee/Documents/management/DocumentsComponents.tsx @@ -3,6 +3,7 @@ import { DocumentManager } from './DocumentManager' import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export interface DocumentsContextInterface extends FlowContextInterface { employeeId?: string /** Set when transitioning to `viewForm` via the VIEW_REQUESTED event; @@ -10,11 +11,13 @@ export interface DocumentsContextInterface extends FlowContextInterface { formId?: string } +/** @internal */ export function DocumentsCardContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function DocumentManagerContextual() { const { employeeId, formId, onEvent } = useFlow() return ( diff --git a/src/components/Employee/Documents/management/documentsStateMachine.ts b/src/components/Employee/Documents/management/documentsStateMachine.ts index 15ae78405..eedab0388 100644 --- a/src/components/Employee/Documents/management/documentsStateMachine.ts +++ b/src/components/Employee/Documents/management/documentsStateMachine.ts @@ -20,6 +20,7 @@ const returnToCard = reduce( }), ) +/** @internal */ export const documentsStateMachine = { card: state( transition( diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Actions.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Actions.tsx index 12a3ca919..f46cadf8a 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Actions.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Actions.tsx @@ -3,6 +3,7 @@ import { useDocumentList } from './useDocumentList' import { ActionsLayout } from '@/components/Common' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** @internal */ export function Actions() { const { t } = useTranslation('Employee.DocumentSigner') const { handleContinue, hasSignedAllForms } = useDocumentList() diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/DocumentList.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/DocumentList.tsx index d0187c4f0..cc78e2764 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/DocumentList.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/DocumentList.tsx @@ -18,6 +18,7 @@ interface DocumentListProps extends CommonComponentInterface { employeeId: string } +/** @internal */ export function DocumentList(props: DocumentListProps & BaseComponentInterface) { return ( diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Head.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Head.tsx index 251e4ac0f..d8b9fbb57 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Head.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/Head.tsx @@ -1,6 +1,7 @@ import { useTranslation } from 'react-i18next' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** @internal */ function Head() { const { t } = useTranslation('Employee.DocumentSigner') const Components = useComponentContext() diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/List.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/List.tsx index eed4e95da..12b8b39fd 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/List.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/List.tsx @@ -2,6 +2,7 @@ import { useTranslation } from 'react-i18next' import { useDocumentList } from './useDocumentList' import { Flex, DocumentList as SharedDocumentList } from '@/components/Common' +/** @internal */ export function List() { const { employeeForms, handleRequestFormToSign, documentListError } = useDocumentList() const { t } = useTranslation('Employee.DocumentSigner') diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentSigner.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentSigner.tsx index ccb6caf36..90113292f 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentSigner.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/DocumentSigner.tsx @@ -13,11 +13,40 @@ import { BaseComponent, type BaseComponentInterface } from '@/components/Base' import { useComponentDictionary } from '@/i18n/I18n' import { I9_FORM_NAME } from '@/shared/constants' +/** + * Props for {@link DocumentSigner}. + * + * @public + */ export interface DocumentSignerProps extends BaseComponentInterface<'Employee.DocumentSigner'> { + /** The associated employee identifier. */ employeeId: string + /** When `true`, the flow routes through I-9 employment eligibility before listing documents for signing. Defaults to `false`. */ withEmployeeI9?: boolean } +/** + * Onboarding step for signing employee documents. + * + * @remarks + * Lists the employee's pending forms and routes through the signing UI for each + * one. When `withEmployeeI9` is `true` and the employee's I-9 has not been + * signed, the flow starts on the I-9 employment eligibility step before + * presenting the document list. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/employmentEligibility/done` | Fired after I-9 employment eligibility is captured | The updated I-9 authorization | + * | `employee/forms/view` | Fired when a form's "Sign" action is selected from the document list | `{ uuid: string; name?: string }` | + * | `employee/forms/sign` | Fired after a form is successfully signed | {@link Form} | + * | `employee/employmentEligibility/change` | Fired when the user requests to change their I-9 eligibility status | — | + * | `employee/forms/done` | Fired when all required forms have been signed and the parent flow can advance | — | + * | `cancel` | Fired when the user cancels signing a form and returns to the document list | — | + * + * @param props - See {@link DocumentSignerProps}. + * @returns The document signer flow. + * @public + */ export function DocumentSigner(props: DocumentSignerProps) { return ( diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.tsx index 88455ac79..4d9f0d849 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.tsx @@ -12,10 +12,33 @@ import { useBase } from '@/components/Base' import { useComponentDictionary, useI18n } from '@/i18n' import { componentEvents } from '@/shared/constants' +/** + * Props for {@link EmploymentEligibility}. + * + * @public + */ export interface EmploymentEligibilityProps extends BaseComponentInterface<'Employee.EmploymentEligibility'> { + /** The associated employee identifier. */ employeeId: string } +/** + * Captures the employee's I-9 employment eligibility (Section 1) before signing. + * + * @remarks + * Collects the employee's authorization status — U.S. citizen, noncitizen + * national, permanent resident, or alien authorized to work — and any + * document details required for that status. Updates the employee's I-9 + * authorization record on submit. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/employmentEligibility/done` | Fired after the I-9 authorization is saved | The updated I-9 authorization | + * + * @param props - See {@link EmploymentEligibilityProps}. + * @returns The employment eligibility form. + * @public + */ export function EmploymentEligibility(props: EmploymentEligibilityProps) { return ( diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.tsx index d2f3c330f..77e4fbd8e 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.tsx @@ -39,6 +39,7 @@ const statusDescriptionKeys = { alien: 'statusDescriptions.alien', } as const satisfies Record +/** @internal */ export const EmploymentEligibilityPresentation = ({ onSubmit, defaultValues, diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilitySchema.ts b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilitySchema.ts index 0b6a37684..869dc5161 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilitySchema.ts +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilitySchema.ts @@ -7,6 +7,7 @@ import { const isValidUscisNumber = (value: string) => /^[Aa]?\d{7,9}$/.test(value) const isValidI94Number = (value: string) => /^\d{9} ?[A-Za-z\d]\d$/.test(value) +/** @internal */ export const generateEmploymentEligibilitySchema = (hasDocumentNumber?: boolean | null) => z .object({ @@ -87,9 +88,11 @@ export const generateEmploymentEligibilitySchema = (hasDocumentNumber?: boolean } }) +/** @internal */ export type EmploymentEligibilityInputs = z.input< ReturnType > +/** @internal */ export type EmploymentEligibilityPayload = z.infer< ReturnType > diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/countries.ts b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/countries.ts index 53d7d9f82..b6e2edbc9 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/countries.ts +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/countries.ts @@ -1,3 +1,4 @@ +/** @internal */ export const COUNTRIES: { value: string; label: string }[] = [ { value: 'United States', label: 'United States' }, { value: 'Afghanistan', label: 'Afghanistan' }, diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/I9SignatureForm/I9SignatureForm.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/I9SignatureForm/I9SignatureForm.tsx index ee6ba0820..b95e0da78 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/I9SignatureForm/I9SignatureForm.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/I9SignatureForm/I9SignatureForm.tsx @@ -23,6 +23,7 @@ interface I9SignatureFormProps extends CommonComponentInterface { formId: string } +/** @internal */ export function I9SignatureForm(props: I9SignatureFormProps & BaseComponentInterface) { return ( diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/documentSignerStateMachine.tsx b/src/components/Employee/Documents/onboarding/DocumentSigner/documentSignerStateMachine.tsx index b892d2d99..33236faf9 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/documentSignerStateMachine.tsx +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/documentSignerStateMachine.tsx @@ -7,6 +7,7 @@ import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import type { componentEvents } from '@/shared/constants' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export type EventPayloads = { [componentEvents.EMPLOYEE_SIGN_FORM]: Form [componentEvents.EMPLOYEE_VIEW_FORM_TO_SIGN]: { uuid: string; name?: string } @@ -15,6 +16,7 @@ export type EventPayloads = { [componentEvents.CANCEL]: undefined } +/** @internal */ export interface DocumentSignerContextInterface extends FlowContextInterface { employeeId: string formId?: string @@ -22,12 +24,14 @@ export interface DocumentSignerContextInterface extends FlowContextInterface { isI9Form?: boolean } +/** @internal */ export function DocumentListContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function SignatureFormContextual() { const { employeeId, formId, onEvent } = useFlow() @@ -40,12 +44,14 @@ export function SignatureFormContextual() { ) } +/** @internal */ export function EmploymentEligibilityContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function I9SignatureFormContextual() { const { employeeId, formId, onEvent } = useFlow() diff --git a/src/components/Employee/Documents/onboarding/DocumentSigner/stateMachine.ts b/src/components/Employee/Documents/onboarding/DocumentSigner/stateMachine.ts index e488e696c..930feac4b 100644 --- a/src/components/Employee/Documents/onboarding/DocumentSigner/stateMachine.ts +++ b/src/components/Employee/Documents/onboarding/DocumentSigner/stateMachine.ts @@ -9,6 +9,7 @@ import { import { componentEvents, I9_FORM_NAME } from '@/shared/constants' import type { MachineEventType, MachineTransition } from '@/types/Helpers' +/** @internal */ export const documentSignerMachine = { employmentEligibility: state( transition( diff --git a/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.tsx b/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.tsx index f55dc0e6e..98c7d6cc7 100644 --- a/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.tsx +++ b/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.tsx @@ -21,11 +21,36 @@ import { useFlow } from '@/components/Flow/useFlow' import type { OnboardingContextInterface } from '@/components/Employee/OnboardingFlow/OnboardingFlowComponents' import { ensureRequired } from '@/helpers/ensureRequired' -interface EmployeeDocumentsProps extends BaseComponentInterface<'Employee.EmployeeDocuments'> { +/** + * Props for {@link EmployeeDocuments}. + * + * @public + */ +export interface EmployeeDocumentsProps extends BaseComponentInterface<'Employee.EmployeeDocuments'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } +/** + * Onboarding step for selecting which documents the employee must complete. + * + * @remarks + * Shows the I-9 toggle when the employee is self-onboarding (so the employee + * can choose whether their employer will collect I-9 verification) and a + * summary otherwise. Persists the selection to the employee's onboarding + * documents configuration and advances the parent flow. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/onboardingDocumentsConfig/updated` | Fired after the employee's documents configuration is saved | The updated documents configuration response | + * | `employee/documents/done` | Fired when the step is complete and the parent flow can advance | — | + * + * @param props - Component props including `employeeId` and `onEvent`. + * @returns The employee documents onboarding step. + * @public + */ export function EmployeeDocuments(props: EmployeeDocumentsProps) { return ( @@ -87,6 +112,7 @@ const Root = ({ employeeId, dictionary }: EmployeeDocumentsProps) => { ) } +/** @internal */ export const EmployeeDocumentsContextual = () => { const { employeeId, onEvent } = useFlow() diff --git a/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.tsx b/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.tsx index 3c562c50d..97cc2b46b 100644 --- a/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.tsx +++ b/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.tsx @@ -13,8 +13,10 @@ const EmployeeDocumentsSchema = z.object({ includeI9: z.boolean(), }) +/** @internal */ export type EmployeeDocumentsFormValues = z.infer +/** @internal */ export interface EmployeeDocumentsPresentationProps { isEmployeeSelfOnboarding: boolean currentI9Status: boolean @@ -23,6 +25,7 @@ export interface EmployeeDocumentsPresentationProps { isPending: boolean } +/** @internal */ export const EmployeeDocumentsPresentation = ({ isEmployeeSelfOnboarding, currentI9Status, diff --git a/src/components/Employee/Documents/onboarding/EmployeeDocuments/index.ts b/src/components/Employee/Documents/onboarding/EmployeeDocuments/index.ts index 59afa76fb..072d271f5 100644 --- a/src/components/Employee/Documents/onboarding/EmployeeDocuments/index.ts +++ b/src/components/Employee/Documents/onboarding/EmployeeDocuments/index.ts @@ -1 +1,5 @@ -export { EmployeeDocuments, EmployeeDocumentsContextual } from './EmployeeDocuments' +export { + EmployeeDocuments, + EmployeeDocumentsContextual, + type EmployeeDocumentsProps, +} from './EmployeeDocuments' diff --git a/src/components/Employee/Documents/shared/SignatureForm/SignatureForm.tsx b/src/components/Employee/Documents/shared/SignatureForm/SignatureForm.tsx index 2bb3bbd07..84887d74b 100644 --- a/src/components/Employee/Documents/shared/SignatureForm/SignatureForm.tsx +++ b/src/components/Employee/Documents/shared/SignatureForm/SignatureForm.tsx @@ -20,6 +20,7 @@ interface SignatureFormProps extends CommonComponentInterface { formId: string } +/** @internal */ export function SignatureForm(props: SignatureFormProps & BaseComponentInterface) { return ( diff --git a/src/components/Employee/Documents/shared/index.ts b/src/components/Employee/Documents/shared/index.ts deleted file mode 100644 index 973b06b2d..000000000 --- a/src/components/Employee/Documents/shared/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useDocumentsList } from './useDocumentsList' -export type { - UseDocumentsListParams, - UseDocumentsListResult, - UseDocumentsListReady, -} from './useDocumentsList' diff --git a/src/components/Employee/Documents/shared/useDocumentsList/index.ts b/src/components/Employee/Documents/shared/useDocumentsList/index.ts index 973b06b2d..3f9f91358 100644 --- a/src/components/Employee/Documents/shared/useDocumentsList/index.ts +++ b/src/components/Employee/Documents/shared/useDocumentsList/index.ts @@ -1,6 +1 @@ export { useDocumentsList } from './useDocumentsList' -export type { - UseDocumentsListParams, - UseDocumentsListResult, - UseDocumentsListReady, -} from './useDocumentsList' diff --git a/src/components/Employee/Documents/shared/useDocumentsList/useDocumentsList.tsx b/src/components/Employee/Documents/shared/useDocumentsList/useDocumentsList.tsx index 7b60d9f33..b9c2eeca3 100644 --- a/src/components/Employee/Documents/shared/useDocumentsList/useDocumentsList.tsx +++ b/src/components/Employee/Documents/shared/useDocumentsList/useDocumentsList.tsx @@ -3,20 +3,36 @@ import type { Form } from '@gusto/embedded-api-v-2025-11-15/models/components/fo import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult } from '@/partner-hook-utils/types' +/** + * Parameters for {@link useDocumentsList}. + * + * @public + */ export interface UseDocumentsListParams { + /** The associated employee identifier. */ employeeId: string } -export type UseDocumentsListReady = BaseHookReady<{ forms: Form[] }, { isFetching: boolean }> +type UseDocumentsListReady = BaseHookReady<{ forms: Form[] }, { isFetching: boolean }> +/** + * Result of {@link useDocumentsList} — a discriminated union of loading and ready states. + * + * @public + */ export type UseDocumentsListResult = HookLoadingResult | UseDocumentsListReady /** - * Standalone data hook for an employee's forms (documents). Wraps the - * `employeeFormsList` query in the `BaseHookReady` shape consumed by both the - * SDK's {@link DocumentsCard} and partners building a fully custom documents - * surface. Read-only — viewing or signing a form is handled by the - * `DocumentManager` screen the block routes to, so this hook exposes no actions. + * Standalone data hook for an employee's forms (documents). + * + * @remarks + * Wraps the `employeeFormsList` query in the standard `BaseHookReady` shape. + * Read-only — viewing or signing a form is handled by the screen the parent + * routes to, so this hook exposes no actions. + * + * @param params - See {@link UseDocumentsListParams}. + * @returns A {@link HookLoadingResult} while loading, or the ready state with `data.forms` once loaded. + * @public */ export function useDocumentsList({ employeeId }: UseDocumentsListParams): UseDocumentsListResult { // staleTime: Infinity — the SDK QueryClient invalidates on any mutation diff --git a/src/components/Employee/Documents/shared/useSignEmployeeForm/fields.tsx b/src/components/Employee/Documents/shared/useSignEmployeeForm/fields.tsx index 9fbce1014..fd24089be 100644 --- a/src/components/Employee/Documents/shared/useSignEmployeeForm/fields.tsx +++ b/src/components/Employee/Documents/shared/useSignEmployeeForm/fields.tsx @@ -13,154 +13,480 @@ import type { HookFieldProps } from '@/partner-hook-utils/types' // ── Validation types ────────────────────────────────────────────────── +/** + * The required-field error code emitted by every field of {@link useSignEmployeeForm}. + * + * @remarks + * Use this as the `validationMessages` key for any sign-employee-form field. + * See {@link SignEmployeeFormErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof SignEmployeeFormErrorCodes.REQUIRED // ── Shared preparer field prop types ────────────────────────────────── +/** + * Props accepted by the text-input preparer fields of {@link useSignEmployeeForm} (name, address, signature). + * + * @public + */ export type PreparerTextFieldProps = HookFieldProps> +/** + * Props accepted by the state-select preparer field of {@link useSignEmployeeForm}. + * + * @public + */ export type PreparerSelectFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Props accepted by the confirmation checkbox preparer field of {@link useSignEmployeeForm}. + * + * @public + */ export type PreparerCheckboxFieldProps = HookFieldProps> // ── Base fields (always present) ────────────────────────────────────── +/** + * Props accepted by {@link useSignEmployeeForm}'s `Fields.Signature` component. + * + * @public + */ export type SignatureFieldProps = HookFieldProps> +/** + * Text input bound to the `signature` field of {@link useSignEmployeeForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Signature`. The employee types + * their full legal name; required. + * + * @param props - {@link SignatureFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `signature`. + * @public + */ export function SignatureField(props: SignatureFieldProps) { return } +/** + * Props accepted by {@link useSignEmployeeForm}'s `Fields.ConfirmSignature` component. + * + * @public + */ export type ConfirmSignatureFieldProps = HookFieldProps> +/** + * Checkbox bound to the `confirmSignature` field of {@link useSignEmployeeForm}. + * + * @remarks + * Available on the hook result as `form.Fields.ConfirmSignature`. Captures the + * employee's electronic-signature consent; must be checked to submit. + * + * @param props - {@link ConfirmSignatureFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered checkbox bound to `confirmSignature`. + * @public + */ export function ConfirmSignatureField(props: ConfirmSignatureFieldProps) { return } // ── I-9 fields ──────────────────────────────────────────────────────── +/** + * Props accepted by {@link useSignEmployeeForm}'s `Fields.UsedPreparer` component. + * + * @public + */ export type UsedPreparerFieldProps = HookFieldProps> +/** + * Radio group bound to the `usedPreparer` field of {@link useSignEmployeeForm}. + * + * @remarks + * Available on the hook result as `form.Fields.UsedPreparer` only when the + * form being signed is an I-9; `undefined` otherwise. Selecting `'yes'` + * automatically reveals the first preparer field group; switching back to + * `'no'` removes all preparer sections. + * + * @param props - {@link UsedPreparerFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered radio group bound to `usedPreparer`. + * @public + */ export function UsedPreparerField(props: UsedPreparerFieldProps) { return } // ── Preparer 1 fields ───────────────────────────────────────────────── +/** + * Text input bound to the first preparer's first name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerFirstName`. + * @public + */ export function Preparer1FirstName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the first preparer's last name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerLastName`. + * @public + */ export function Preparer1LastName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the first preparer's street address line 1. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerStreet1`. + * @public + */ export function Preparer1Street1(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the first preparer's street address line 2 (optional). + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerStreet2`. + * @public + */ export function Preparer1Street2(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the first preparer's city. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerCity`. + * @public + */ export function Preparer1City(props: PreparerTextFieldProps) { return } +/** + * Select bound to the first preparer's state. Options are US state abbreviations. + * + * @param props - {@link PreparerSelectFieldProps}. + * @returns The rendered select bound to `preparerState`. + * @public + */ export function Preparer1State(props: PreparerSelectFieldProps) { return } +/** + * Text input bound to the first preparer's ZIP code. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerZip`. + * @public + */ export function Preparer1Zip(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the first preparer's typed signature. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparerSignature`. + * @public + */ export function Preparer1Signature(props: PreparerTextFieldProps) { return } +/** + * Checkbox bound to the first preparer's electronic-signature consent. + * + * @param props - {@link PreparerCheckboxFieldProps}. + * @returns The rendered checkbox bound to `preparerAgree`. + * @public + */ export function Preparer1ConfirmSignature(props: PreparerCheckboxFieldProps) { return } // ── Preparer 2 fields ───────────────────────────────────────────────── +/** + * Text input bound to the second preparer's first name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2FirstName`. + * @public + */ export function Preparer2FirstName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the second preparer's last name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2LastName`. + * @public + */ export function Preparer2LastName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the second preparer's street address line 1. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2Street1`. + * @public + */ export function Preparer2Street1(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the second preparer's street address line 2 (optional). + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2Street2`. + * @public + */ export function Preparer2Street2(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the second preparer's city. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2City`. + * @public + */ export function Preparer2City(props: PreparerTextFieldProps) { return } +/** + * Select bound to the second preparer's state. Options are US state abbreviations. + * + * @param props - {@link PreparerSelectFieldProps}. + * @returns The rendered select bound to `preparer2State`. + * @public + */ export function Preparer2State(props: PreparerSelectFieldProps) { return } +/** + * Text input bound to the second preparer's ZIP code. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2Zip`. + * @public + */ export function Preparer2Zip(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the second preparer's typed signature. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer2Signature`. + * @public + */ export function Preparer2Signature(props: PreparerTextFieldProps) { return } +/** + * Checkbox bound to the second preparer's electronic-signature consent. + * + * @param props - {@link PreparerCheckboxFieldProps}. + * @returns The rendered checkbox bound to `preparer2Agree`. + * @public + */ export function Preparer2ConfirmSignature(props: PreparerCheckboxFieldProps) { return } // ── Preparer 3 fields ───────────────────────────────────────────────── +/** + * Text input bound to the third preparer's first name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3FirstName`. + * @public + */ export function Preparer3FirstName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the third preparer's last name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3LastName`. + * @public + */ export function Preparer3LastName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the third preparer's street address line 1. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3Street1`. + * @public + */ export function Preparer3Street1(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the third preparer's street address line 2 (optional). + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3Street2`. + * @public + */ export function Preparer3Street2(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the third preparer's city. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3City`. + * @public + */ export function Preparer3City(props: PreparerTextFieldProps) { return } +/** + * Select bound to the third preparer's state. Options are US state abbreviations. + * + * @param props - {@link PreparerSelectFieldProps}. + * @returns The rendered select bound to `preparer3State`. + * @public + */ export function Preparer3State(props: PreparerSelectFieldProps) { return } +/** + * Text input bound to the third preparer's ZIP code. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3Zip`. + * @public + */ export function Preparer3Zip(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the third preparer's typed signature. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer3Signature`. + * @public + */ export function Preparer3Signature(props: PreparerTextFieldProps) { return } +/** + * Checkbox bound to the third preparer's electronic-signature consent. + * + * @param props - {@link PreparerCheckboxFieldProps}. + * @returns The rendered checkbox bound to `preparer3Agree`. + * @public + */ export function Preparer3ConfirmSignature(props: PreparerCheckboxFieldProps) { return } // ── Preparer 4 fields ───────────────────────────────────────────────── +/** + * Text input bound to the fourth preparer's first name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4FirstName`. + * @public + */ export function Preparer4FirstName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the fourth preparer's last name. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4LastName`. + * @public + */ export function Preparer4LastName(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the fourth preparer's street address line 1. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4Street1`. + * @public + */ export function Preparer4Street1(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the fourth preparer's street address line 2 (optional). + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4Street2`. + * @public + */ export function Preparer4Street2(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the fourth preparer's city. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4City`. + * @public + */ export function Preparer4City(props: PreparerTextFieldProps) { return } +/** + * Select bound to the fourth preparer's state. Options are US state abbreviations. + * + * @param props - {@link PreparerSelectFieldProps}. + * @returns The rendered select bound to `preparer4State`. + * @public + */ export function Preparer4State(props: PreparerSelectFieldProps) { return } +/** + * Text input bound to the fourth preparer's ZIP code. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4Zip`. + * @public + */ export function Preparer4Zip(props: PreparerTextFieldProps) { return } +/** + * Text input bound to the fourth preparer's typed signature. + * + * @param props - {@link PreparerTextFieldProps}. + * @returns The rendered text input bound to `preparer4Signature`. + * @public + */ export function Preparer4Signature(props: PreparerTextFieldProps) { return } +/** + * Checkbox bound to the fourth preparer's electronic-signature consent. + * + * @param props - {@link PreparerCheckboxFieldProps}. + * @returns The rendered checkbox bound to `preparer4Agree`. + * @public + */ export function Preparer4ConfirmSignature(props: PreparerCheckboxFieldProps) { return } diff --git a/src/components/Employee/Documents/shared/useSignEmployeeForm/index.ts b/src/components/Employee/Documents/shared/useSignEmployeeForm/index.ts index 32701f430..4fa8a9eda 100644 --- a/src/components/Employee/Documents/shared/useSignEmployeeForm/index.ts +++ b/src/components/Employee/Documents/shared/useSignEmployeeForm/index.ts @@ -21,11 +21,13 @@ export { type PreparerIndex, type PreparerFieldSuffix, } from './signEmployeeFormSchema' +export { SignatureField, ConfirmSignatureField, UsedPreparerField } from './fields' export type { RequiredValidation as SignEmployeeFormRequiredValidation, SignatureFieldProps, ConfirmSignatureFieldProps, UsedPreparerFieldProps, PreparerTextFieldProps, + PreparerSelectFieldProps, PreparerCheckboxFieldProps, } from './fields' diff --git a/src/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.ts b/src/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.ts index 21edbf5b8..60f2b23f5 100644 --- a/src/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.ts +++ b/src/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.ts @@ -6,19 +6,48 @@ import { // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the I-9 sign-employee form schema. Map + * these codes to localized copy in `validationMessages` when composing the + * hook. + * + * @public + */ export const SignEmployeeFormErrorCodes = { REQUIRED: 'REQUIRED', } as const +/** + * Union of validation error code strings emitted by the I-9 sign-employee + * form schema. + * + * @public + */ export type SignEmployeeFormErrorCode = (typeof SignEmployeeFormErrorCodes)[keyof typeof SignEmployeeFormErrorCodes] // ── Preparer naming helpers ──────────────────────────────────────────── +/** + * Maximum number of I-9 preparers and translators the form supports. + * + * @public + */ export const MAX_PREPARERS = 4 +/** + * One-based preparer index used to reference preparer field groups (1–4). + * + * @public + */ export type PreparerIndex = 1 | 2 | 3 | 4 +/** + * Suffix segment of a preparer field name — the part that follows + * `preparer` (or `preparerN`) in the field key. + * + * @public + */ export type PreparerFieldSuffix = | 'FirstName' | 'LastName' @@ -30,6 +59,7 @@ export type PreparerFieldSuffix = | 'Signature' | 'Agree' +/** @internal */ export function preparerFieldName(index: PreparerIndex, field: PreparerFieldSuffix): string { return index === 1 ? `preparer${field}` : `preparer${index}${field}` } @@ -97,6 +127,14 @@ const PREPARER_4 = { agree: 'preparer4Agree', } as const +/** + * Per-preparer field name maps indexed by preparer position (0-based). Use + * these to look up the form field name for a given preparer slot — for + * example `PREPARERS_BY_INDEX[1].firstName` resolves to + * `'preparer2FirstName'`. + * + * @public + */ export const PREPARERS_BY_INDEX = [ PREPARER_1, PREPARER_2, @@ -121,6 +159,12 @@ const PREPARER_4_FIELDS: SignEmployeeFormField[] = Object.values(PREPARER_4) as typeof PREPARER_4 >[] +/** + * Flat list of preparer field names per preparer slot (0-based), useful for + * iterating every field that belongs to a single preparer. + * + * @public + */ export const PREPARER_FIELDS_BY_INDEX: SignEmployeeFormField[][] = [ PREPARER_1_FIELDS, PREPARER_2_FIELDS, @@ -186,11 +230,27 @@ const fieldValidators = { [PREPARER_4.agree]: agreeValidator, } +/** + * Field names accepted by the I-9 sign-employee form. + * + * @public + */ export type SignEmployeeFormField = keyof typeof fieldValidators +/** + * Shape of the values managed by the I-9 sign-employee form. + * + * @public + */ export type SignEmployeeFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the I-9 sign-employee form on + * submit. + * + * @public + */ export type SignEmployeeFormOutputs = SignEmployeeFormData // ── Required fields config ───────────────────────────────────────────── @@ -204,11 +264,13 @@ const requiredFieldsConfig = { // ── Schema factory ───────────────────────────────────────────────────── +/** @internal */ interface SignEmployeeFormSchemaOptions { isI9?: boolean preparerCount?: number } +/** @internal */ export function createSignEmployeeFormSchema(options: SignEmployeeFormSchemaOptions = {}) { const { isI9 = false, preparerCount = 0 } = options diff --git a/src/components/Employee/Documents/shared/useSignEmployeeForm/useSignEmployeeForm.tsx b/src/components/Employee/Documents/shared/useSignEmployeeForm/useSignEmployeeForm.tsx index bdefb6027..dc363a519 100644 --- a/src/components/Employee/Documents/shared/useSignEmployeeForm/useSignEmployeeForm.tsx +++ b/src/components/Employee/Documents/shared/useSignEmployeeForm/useSignEmployeeForm.tsx @@ -120,51 +120,173 @@ const preparer4Fields = { ConfirmSignature: Preparer4ConfirmSignature, } +/** + * Field group exposed for each I-9 preparer/translator on {@link useSignEmployeeForm}. + * + * @remarks + * Each preparer (1–4) exposes the same nine sub-fields covering name, + * address, signature, and consent. Render the sub-fields directly on the + * group, e.g. ``. + * + * @public + */ export type PreparerFieldGroup = typeof preparer1Fields // ── Types ────────────────────────────────────────────────────────────── +/** + * Props for {@link useSignEmployeeForm}. + * + * @public + */ export interface UseSignEmployeeFormProps { + /** The associated employee identifier. */ employeeId: string + /** The UUID of the employee form to sign. */ formId: string } +/** + * Field components exposed by {@link useSignEmployeeForm} on `form.Fields`. + * + * @remarks + * `Signature` and `ConfirmSignature` are always present. `UsedPreparer` and + * the `Preparer1`–`Preparer4` field groups are only defined when the form + * being signed is an I-9 and the preparer count has reached that index — + * always null-check before rendering. + * + * @public + */ export interface SignEmployeeFormFieldComponents { + /** Text input for the employee's typed signature; always present. */ Signature: typeof SignatureField + /** Checkbox for the employee's electronic-signature consent; always present. */ ConfirmSignature: typeof ConfirmSignatureField + /** Radio group asking whether a preparer/translator assisted; defined only for I-9 forms. */ UsedPreparer: typeof UsedPreparerField | undefined + /** First preparer field group; defined only for I-9 forms when `preparers.count >= 1`. */ Preparer1: PreparerFieldGroup | undefined + /** Second preparer field group; defined only for I-9 forms when `preparers.count >= 2`. */ Preparer2: PreparerFieldGroup | undefined + /** Third preparer field group; defined only for I-9 forms when `preparers.count >= 3`. */ Preparer3: PreparerFieldGroup | undefined + /** Fourth preparer field group; defined only for I-9 forms when `preparers.count >= 4`. */ Preparer4: PreparerFieldGroup | undefined } +/** + * Ready-state shape returned by {@link useSignEmployeeForm} once the form metadata and PDF have loaded. + * + * @public + */ export interface UseSignEmployeeFormReady extends BaseFormHookReady< FieldsMetadata, SignEmployeeFormData, SignEmployeeFormFieldComponents > { + /** Loaded data — the form entity and a preview PDF URL. */ data: { + /** The employee form entity fetched from the API (includes `uuid`, `name`, `title`). */ form: Form + /** URL to the form's signed PDF for preview, or `undefined` while it is still being generated. */ pdfUrl: string | null | undefined } - status: { isPending: boolean; mode: 'create' } + /** Submit-state flags. */ + status: { + /** `true` while the sign mutation is in flight. */ + isPending: boolean + /** Always `'create'`; the hook always submits as a signing operation. */ + mode: 'create' + } + /** Imperative actions exposed by the hook. */ actions: { + /** Validates the form and submits the signature. Resolves with the signed form on success. */ onSubmit: () => Promise | undefined> + /** Adds an additional preparer/translator section (up to 4). Defined only for I-9 forms. */ addPreparer?: () => void + /** Removes the last preparer/translator section and unregisters its fields. Defined only for I-9 forms. */ removePreparer?: () => void } + /** Form bindings — `Fields`, `fieldsMetadata`, and I-9 preparer state. */ form: BaseFormHookReady< FieldsMetadata, SignEmployeeFormData, SignEmployeeFormFieldComponents >['form'] & { - preparers?: { count: number; canAdd: boolean; canRemove: boolean } + /** Preparer-section state. Defined only for I-9 forms. */ + preparers?: { + /** Current number of preparer sections, between 0 and 4. */ + count: number + /** `true` when fewer than 4 preparers are active. */ + canAdd: boolean + /** `true` when at least 1 preparer is active. */ + canRemove: boolean + } } } // ── Hook ─────────────────────────────────────────────────────────────── +/** + * Headless hook for signing an employee form — captures a typed signature, electronic consent, and (for I-9 forms) preparer/translator certification. + * + * @remarks + * The hook fetches the form metadata and PDF, then exposes the + * {@link BaseFormHookReady} contract with `Fields`, `fieldsMetadata`, + * `onSubmit`, and error handling. The hook inspects the form's `name` to + * detect I-9 forms; when the form is an I-9, `Fields.UsedPreparer` and the + * `Fields.Preparer1`–`Preparer4` field groups become defined, along with + * `actions.addPreparer` / `actions.removePreparer` and `form.preparers` + * state. Selecting `usedPreparer: 'yes'` automatically reveals the first + * preparer section; switching back to `'no'` removes all preparer sections + * and unregisters their fields. + * + * Unlike the CRUD-oriented form hooks (`useEmployeeDetailsForm`, + * `useCompensationForm`, `useWorkAddressForm`), this hook does not accept + * `defaultValues`, `requiredFields`, or `validationMode` — the form shape is + * fixed and all fields except preparer street-2 are required. + * + * @param props - See {@link UseSignEmployeeFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseSignEmployeeFormReady} once the form is loaded. + * @public + * + * @example + * ```tsx + * import { useSignEmployeeForm, SDKFormProvider } from '@gusto/embedded-react-sdk' + * + * function SignFormPage({ employeeId, formId }: { employeeId: string; formId: string }) { + * const signForm = useSignEmployeeForm({ employeeId, formId }) + * + * if (signForm.isLoading) return
Loading...
+ * + * const { Fields } = signForm.form + * + * return ( + * + *
{ + * e.preventDefault() + * void signForm.actions.onSubmit() + * }} + * > + * + * + * + * + *
+ * ) + * } + * ``` + */ export function useSignEmployeeForm({ employeeId, formId, @@ -381,6 +503,21 @@ function buildPreparerPayload(payload: SignEmployeeFormOutputs, count: number) { return result } +/** + * Result of {@link useSignEmployeeForm} — a discriminated union on `isLoading`. + * + * @public + */ export type UseSignEmployeeFormResult = HookLoadingResult | UseSignEmployeeFormReady +/** + * Shape of the `form.fieldsMetadata` object returned by {@link useSignEmployeeForm}. + * + * @public + */ export type SignEmployeeFormFieldsMetadata = UseSignEmployeeFormReady['form']['fieldsMetadata'] +/** + * Shape of the `form.Fields` object returned by {@link useSignEmployeeForm}. + * + * @public + */ export type SignEmployeeFormFields = UseSignEmployeeFormReady['form']['Fields'] diff --git a/src/components/Employee/EmployeeList/management/ManagementEmployeeList.tsx b/src/components/Employee/EmployeeList/management/ManagementEmployeeList.tsx index 00f1b69ff..948b22c4c 100644 --- a/src/components/Employee/EmployeeList/management/ManagementEmployeeList.tsx +++ b/src/components/Employee/EmployeeList/management/ManagementEmployeeList.tsx @@ -10,11 +10,24 @@ import { import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' -type EmployeeTab = 'active' | 'onboarding' | 'dismissed' +/** + * The tab currently selected on {@link ManagementEmployeeList}. + * + * @public + */ +export type EmployeeTab = 'active' | 'onboarding' | 'dismissed' -interface ManagementEmployeeListProps extends CommonComponentInterface<'Employee.ManagementEmployeeList'> { +/** + * Props for {@link ManagementEmployeeList}. + * + * @public + */ +export interface ManagementEmployeeListProps extends CommonComponentInterface<'Employee.ManagementEmployeeList'> { + /** The associated company identifier. */ companyId: string + /** Tab to render first: Active, Onboarding, or Dismissed. Defaults to `'active'`. */ initialTab?: EmployeeTab + /** Event handler fired on flow state changes. */ onEvent: BaseComponentInterface['onEvent'] } @@ -88,6 +101,21 @@ function ManagementEmployeeListRoot({ ) } +/** + * Renders a tabbed list of a company's employees split across Active, Onboarding, and Dismissed + * tabs, with per-row actions tailored to each tab (edit, delete, dismiss, rehire). + * + * @remarks + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/create` | Fired when the user clicks "Add employee". | — | + * | `employee/update` | Fired when the user selects "Edit" on a row. | `{ employeeId: string }` | + * | `employee/dismiss` | Fired when the user selects "Dismiss" on a row in the Active tab. | `{ employeeId: string }` | + * | `employee/deleted` | Fired after a row's delete action completes. | `{ employeeId: string }` | + * + * @public + */ export function ManagementEmployeeList({ FallbackComponent, ...props diff --git a/src/components/Employee/EmployeeList/management/ManagementEmployeeListView.tsx b/src/components/Employee/EmployeeList/management/ManagementEmployeeListView.tsx index b69d2cf5d..e8609e73c 100644 --- a/src/components/Employee/EmployeeList/management/ManagementEmployeeListView.tsx +++ b/src/components/Employee/EmployeeList/management/ManagementEmployeeListView.tsx @@ -14,6 +14,7 @@ import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' type EmployeeTab = 'active' | 'onboarding' | 'dismissed' +/** @internal */ export interface ManagementEmployeeListViewProps extends Pick< Extract, 'pagination' | 'status' @@ -28,6 +29,7 @@ export interface ManagementEmployeeListViewProps extends Pick< onAddEmployee: () => void } +/** @internal */ export function ManagementEmployeeListView({ selectedTab, onTabChange, diff --git a/src/components/Employee/EmployeeList/onboarding/EmployeeList.tsx b/src/components/Employee/EmployeeList/onboarding/EmployeeList.tsx index dba7a1dac..ad1a8b741 100644 --- a/src/components/Employee/EmployeeList/onboarding/EmployeeList.tsx +++ b/src/components/Employee/EmployeeList/onboarding/EmployeeList.tsx @@ -5,7 +5,13 @@ import { BaseBoundaries, BaseLayout, type BaseComponentInterface } from '@/compo import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' -interface EmployeeListProps extends BaseComponentInterface<'Employee.EmployeeList'> { +/** + * Props for {@link EmployeeList}. + * + * @public + */ +export interface EmployeeListProps extends BaseComponentInterface<'Employee.EmployeeList'> { + /** The associated company identifier. */ companyId: string } @@ -66,6 +72,22 @@ function EmployeeListRoot({ companyId, onEvent, dictionary }: EmployeeListProps) ) } +/** + * Renders a paginated list of a company's employees with per-row onboarding actions (edit, + * delete, review, cancel self-onboarding) and an "Add employee" entry point. + * + * @remarks + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/create` | Fired when the user clicks "Add employee". | — | + * | `employee/update` | Fired when the user selects "Edit" or "Review" on a row. | `{ employeeId: string, onboardingStatus?: OnboardingStatus }` | + * | `employee/deleted` | Fired after a row's delete action completes. | `{ employeeId: string }` | + * | `employee/onboardingStatus/updated` | Fired after the "Review" or "Cancel self-onboarding" action updates an employee's onboarding status. | The updated `EmployeeOnboardingStatus` record | + * | `employee/onboarding/done` | Fired when the user clicks the skip/done control to leave the onboarding employee list. | — | + * + * @public + */ export function EmployeeList({ FallbackComponent, ...props diff --git a/src/components/Employee/EmployeeList/onboarding/EmployeeListView.tsx b/src/components/Employee/EmployeeList/onboarding/EmployeeListView.tsx index 4aa531bce..f9524c296 100644 --- a/src/components/Employee/EmployeeList/onboarding/EmployeeListView.tsx +++ b/src/components/Employee/EmployeeList/onboarding/EmployeeListView.tsx @@ -11,6 +11,7 @@ import TrashCanSvg from '@/assets/icons/trashcan.svg?react' import { firstLastName } from '@/helpers/formattedStrings' import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' +/** @internal */ export interface EmployeeListViewProps extends Pick< Extract, 'pagination' | 'status' @@ -25,6 +26,7 @@ export interface EmployeeListViewProps extends Pick< onSkip: () => void } +/** @internal */ export function EmployeeListView({ employees, isFetching, diff --git a/src/components/Employee/EmployeeList/shared/useEmployeeList.tsx b/src/components/Employee/EmployeeList/shared/useEmployeeList.tsx index 60eabecfe..d48915bac 100644 --- a/src/components/Employee/EmployeeList/shared/useEmployeeList.tsx +++ b/src/components/Employee/EmployeeList/shared/useEmployeeList.tsx @@ -13,6 +13,12 @@ import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import { EmployeeOnboardingStatus, EmployeeSelfOnboardingStatuses } from '@/shared/constants' import type { HookLoadingResult, BaseHookReady } from '@/partner-hook-utils/types' +/** + * Action that may be performed on an employee row, determined by the employee's onboarding state + * and the `employeeType` filter passed to {@link useEmployeeList}. + * + * @public + */ export type EmployeeAction = | 'edit' | 'delete' @@ -21,32 +27,66 @@ export type EmployeeAction = | 'dismiss' | 'rehire' +/** + * An employee entity extended with the actions permitted on it and a reference to its primary job. + * + * @public + */ export interface EmployeeWithActions extends Employee { + /** Actions permitted for this employee given its onboarding status and the active filter. */ allowedActions: EmployeeAction[] + /** The employee's primary job, if one is marked primary. */ primaryJob?: Job } +/** + * Filter applied to {@link useEmployeeList} that scopes the result set and tailors the per-row action list. + * + * @public + */ export type EmployeeType = 'active' | 'onboarding' | 'terminated' +/** + * Props for {@link useEmployeeList}. + * + * @public + */ export interface UseEmployeeListProps { + /** The associated company identifier. */ companyId: string + /** Filters the list and tailors the allowed actions. Omit to list all employees. */ employeeType?: EmployeeType } +/** + * Ready state of {@link useEmployeeList}. + * + * @public + */ export interface UseEmployeeListReady extends BaseHookReady< { employees: EmployeeWithActions[] }, { isFetching: boolean; isPending: boolean } > { + /** Pagination controls for the current employee list page. */ pagination: PaginationControlProps + /** Actions that mutate an employee's state, gated by the entry's `allowedActions`. */ actions: { + /** Deletes the employee. */ onDelete: (employeeId: string) => Promise + /** Moves the employee into the admin-review onboarding status. Resolves to the updated record, or `undefined` if the call failed. */ onReview: (employeeId: string) => Promise + /** Reverts a self-onboarding employee to admin-driven onboarding. Resolves to the updated record, or `undefined` if the call failed. */ onCancelSelfOnboarding: ( employeeId: string, ) => Promise } } +/** + * Return type of {@link useEmployeeList}. + * + * @public + */ export type UseEmployeeListResult = HookLoadingResult | UseEmployeeListReady function deriveAllowedActions(employee: Employee, employeeType?: EmployeeType): EmployeeAction[] { @@ -97,6 +137,46 @@ function deriveAllowedActions(employee: Employee, employeeType?: EmployeeType): return actions } +/** + * Fetches a paginated list of a company's employees and decorates each entry with the actions + * allowed for its current onboarding state. + * + * @remarks + * `employeeType` maps to a server-side filter and changes which actions appear on each row: + * `'active'` adds `dismiss`, `'terminated'` adds `rehire`, `'onboarding'` adds none. Omit it + * to list every employee. + * + * Page changes use placeholder data: the previous page stays rendered while the next one loads, + * and `status.isFetching` flips to `true` during the request. + * + * @param input - Company and optional filter for the list. + * @returns A {@link HookLoadingResult} while the first page is in flight, or a {@link UseEmployeeListReady} once data has arrived. + * @public + * + * @example + * ```tsx + * import { useEmployeeList } from '@gusto/embedded-react-sdk' + * + * function EmployeeListPage({ companyId }: { companyId: string }) { + * const employeeList = useEmployeeList({ companyId, employeeType: 'onboarding' }) + * + * if (employeeList.isLoading) return
Loading...
+ * + * return ( + *
    + * {employeeList.data.employees.map(employee => ( + *
  • + * {employee.firstName} {employee.lastName} + * {employee.allowedActions.includes('delete') && ( + * + * )} + *
  • + * ))} + *
+ * ) + * } + * ``` + */ export function useEmployeeList({ companyId, employeeType, diff --git a/src/components/Employee/EmployeeListFlow/EmployeeListFlow.tsx b/src/components/Employee/EmployeeListFlow/EmployeeListFlow.tsx index d81478d21..702e65f88 100644 --- a/src/components/Employee/EmployeeListFlow/EmployeeListFlow.tsx +++ b/src/components/Employee/EmployeeListFlow/EmployeeListFlow.tsx @@ -8,6 +8,40 @@ import { } from './EmployeeListFlowComponents' import { Flow } from '@/components/Flow/Flow' +/** + * Top-level workflow that renders the employee list and transitions into the dashboard, termination, and onboarding flows. + * + * @remarks + * Drop-in entry point for managing all employees in a company. Begins on the + * management employee list and routes into {@link DashboardFlow}, + * {@link TerminationFlow}, or {@link EmployeeOnboarding.OnboardingExecutionFlow | OnboardingExecutionFlow} based on the + * action the admin invokes on a row (or the "Add employee" CTA). A "Back to + * employees" header is added to each sub-flow so the admin can return to the + * list at any time. + * + * The flow forwards every event emitted by its sub-components to `onEvent`; + * see the events table on each sub-component for the full set of events and + * payloads observable from this flow. + * + * @param props - See {@link EmployeeListFlowProps}. + * @returns The employee list workflow with internal navigation to the dashboard, termination, and onboarding flows. + * @public + * @group Flow Components + * + * @example + * ```tsx + * import { EmployeeManagement } from '@gusto/embedded-react-sdk' + * + * function MyApp() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export const EmployeeListFlow = ({ companyId, onEvent }: EmployeeListFlowProps) => { const machine = useMemo( () => diff --git a/src/components/Employee/EmployeeListFlow/EmployeeListFlowComponents.tsx b/src/components/Employee/EmployeeListFlow/EmployeeListFlowComponents.tsx index 5c85b712f..024e6e6c8 100644 --- a/src/components/Employee/EmployeeListFlow/EmployeeListFlowComponents.tsx +++ b/src/components/Employee/EmployeeListFlow/EmployeeListFlowComponents.tsx @@ -6,25 +6,35 @@ import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import type { BaseComponentInterface } from '@/components/Base' import { ensureRequired } from '@/helpers/ensureRequired' +/** + * Props for {@link EmployeeListFlow}. + * + * @public + */ export interface EmployeeListFlowProps extends BaseComponentInterface { + /** The associated company identifier. */ companyId: string } +/** @internal */ export interface EmployeeListFlowContextInterface extends FlowContextInterface { companyId: string employeeId?: string } +/** @internal */ export function EmployeeListContextual() { const { companyId, onEvent } = useFlow() return } +/** @internal */ export function DashboardFlowContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function TerminationFlowContextual() { const { companyId, employeeId, onEvent } = useFlow() return ( @@ -36,6 +46,7 @@ export function TerminationFlowContextual() { ) } +/** @internal */ export function OnboardingExecutionFlowContextual() { const { companyId, onEvent } = useFlow() return diff --git a/src/components/Employee/EmployeeListFlow/employeeListStateMachine.ts b/src/components/Employee/EmployeeListFlow/employeeListStateMachine.ts index 08a83b0e3..19fb345e2 100644 --- a/src/components/Employee/EmployeeListFlow/employeeListStateMachine.ts +++ b/src/components/Employee/EmployeeListFlow/employeeListStateMachine.ts @@ -33,6 +33,7 @@ const returnToList = reduce( }), ) +/** @internal */ export const employeeListStateMachine = { list: state( transition( diff --git a/src/components/Employee/FederalTaxes/index.ts b/src/components/Employee/FederalTaxes/index.ts index 9bc749e93..bf52d23b1 100644 --- a/src/components/Employee/FederalTaxes/index.ts +++ b/src/components/Employee/FederalTaxes/index.ts @@ -1,39 +1,2 @@ -export { FederalTaxes, FederalTaxesCard, FederalTaxesEditForm } from './management' -export type { - FederalTaxesProps, - FederalTaxesCardProps, - FederalTaxesEditFormProps, -} from './management' -export { - useFederalTaxesForm, - createFederalTaxesSchema, - FederalTaxesErrorCodes, - FILING_STATUS_VALUES, -} from './shared/useFederalTaxesForm' -export type { - FederalTaxesOptionalFieldsToRequire, - UseFederalTaxesFormProps, - UseFederalTaxesFormResult, - UseFederalTaxesFormReady, - FederalTaxesFieldsMetadata, - FederalTaxesFormFields, - FederalTaxesFields, - FederalTaxesErrorCode, - FederalTaxesFormData, - FederalTaxesFormOutputs, - FederalTaxesField, - FilingStatusValue, - FederalTaxesRequiredValidation, - FilingStatusFieldProps, - TwoJobsFieldProps, - DependentsAmountFieldProps, - OtherIncomeFieldProps, - DeductionsFieldProps, - ExtraWithholdingFieldProps, -} from './shared/useFederalTaxesForm' -export { - useFederalTaxesSummary, - type UseFederalTaxesSummaryParams, - type UseFederalTaxesSummaryReady, - type UseFederalTaxesSummaryResult, -} from './shared/useFederalTaxesSummary' +export { FederalTaxes } from './management' +export type { FederalTaxesProps } from './management' diff --git a/src/components/Employee/FederalTaxes/management/FederalTaxes.tsx b/src/components/Employee/FederalTaxes/management/FederalTaxes.tsx index 1b78b2dd7..aaabfadc2 100644 --- a/src/components/Employee/FederalTaxes/management/FederalTaxes.tsx +++ b/src/components/Employee/FederalTaxes/management/FederalTaxes.tsx @@ -16,8 +16,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link FederalTaxes}. + * + * @public + */ export interface FederalTaxesProps extends CommonComponentInterface<'Employee.Management.FederalTaxes'> { + /** The associated employee identifier. */ employeeId: string + /** Callback invoked when the block emits an event. See the events table on {@link FederalTaxes} for the available event types and payloads. */ onEvent: OnEventType } @@ -38,6 +45,26 @@ function FederalTaxesFlow({ employeeId, onEvent }: FederalTaxesProps) { return } +/** + * Self-contained block for viewing and editing an employee's federal tax (W-4) withholdings — the same experience the dashboard surfaces, but as a drop-in component that doesn't require the surrounding dashboard chrome. + * + * @remarks + * Renders a read-only card showing filing status, multiple-jobs flag, dependents, other income, deductions, and extra withholding, with an Edit CTA that swaps to the edit form. Submitting the form returns to the card; cancelling returns without saving. Wraps everything in error and suspense boundaries. + * + * The card and form surfaces ({@link FederalTaxesCard}, {@link FederalTaxesEditForm}) are also exported individually for cases where that orchestration is the wrong fit — for example, when the form needs to render in a modal or drawer, when the card needs to appear read-only with no edit affordance, or when the swap is driven by a router. Using them directly means owning the swap and any cross-component state yourself. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/federalTaxes/card/editRequested` | Fired when the card's Edit CTA is clicked; the block opens the edit form | `{ employeeId: string }` | + * | `employee/management/federalTaxes/editForm/submitted` | Fired after the edit form is saved; the block returns to the card view | The updated `EmployeeFederalTax` entity | + * | `employee/management/federalTaxes/editForm/cancelled` | Fired when the user cancels the edit form; the block returns to the card view | — | + * | `employee/management/federalTaxes/alertDismissed` | Fired when the user dismisses an alert above the card | `null` | + * + * @param props - See {@link FederalTaxesProps}. + * @returns The rendered federal taxes block. + * @public + * @group Block Components + */ export function FederalTaxes({ dictionary, FallbackComponent, diff --git a/src/components/Employee/FederalTaxes/management/FederalTaxesCard/FederalTaxesCard.tsx b/src/components/Employee/FederalTaxes/management/FederalTaxesCard/FederalTaxesCard.tsx index c8c983c53..0c4c1966e 100644 --- a/src/components/Employee/FederalTaxes/management/FederalTaxesCard/FederalTaxesCard.tsx +++ b/src/components/Employee/FederalTaxes/management/FederalTaxesCard/FederalTaxesCard.tsx @@ -9,8 +9,15 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link FederalTaxesCard}. + * + * @public + */ export interface FederalTaxesCardProps { + /** The associated employee identifier. */ employeeId: string + /** Callback invoked when the card emits an event. See the events table on {@link FederalTaxesCard} for the available event types and payloads. */ onEvent: OnEventType } @@ -20,6 +27,8 @@ export interface FederalTaxesCardProps { * `EMPLOYEE_MANAGEMENT_FEDERAL_TAXES_CARD_EDIT_REQUESTED` when the Edit * button is clicked. The card has no alert API — alert rendering (when * introduced) is the orchestrator's responsibility. + * + * @public */ export function FederalTaxesCard(props: FederalTaxesCardProps) { return ( diff --git a/src/components/Employee/FederalTaxes/management/FederalTaxesComponents.tsx b/src/components/Employee/FederalTaxes/management/FederalTaxesComponents.tsx index 37f3bcd32..916d8c747 100644 --- a/src/components/Employee/FederalTaxes/management/FederalTaxesComponents.tsx +++ b/src/components/Employee/FederalTaxes/management/FederalTaxesComponents.tsx @@ -7,13 +7,15 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { ensureRequired } from '@/helpers/ensureRequired' import { componentEvents } from '@/shared/constants' -export type FederalTaxesSuccessAlertCode = 'federalTaxesUpdated' +type FederalTaxesSuccessAlertCode = 'federalTaxesUpdated' +/** @internal */ export interface FederalTaxesContextInterface extends FlowContextInterface { employeeId?: string successAlert?: FederalTaxesSuccessAlertCode | null } +/** @internal */ export function FederalTaxesCardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.FederalTaxes') @@ -34,6 +36,7 @@ export function FederalTaxesCardContextual() { ) } +/** @internal */ export function FederalTaxesEditFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/FederalTaxes/management/FederalTaxesEditForm.tsx b/src/components/Employee/FederalTaxes/management/FederalTaxesEditForm.tsx index 5c9ef603e..acd3aa8a5 100644 --- a/src/components/Employee/FederalTaxes/management/FederalTaxesEditForm.tsx +++ b/src/components/Employee/FederalTaxes/management/FederalTaxesEditForm.tsx @@ -17,12 +17,36 @@ import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** + * Props for {@link FederalTaxesEditForm}. + * + * @public + */ export interface FederalTaxesEditFormProps extends CommonComponentInterface<'Employee.Management.FederalTaxes'> { + /** The associated employee identifier. */ employeeId: string + /** Pre-fill form values. Server data takes precedence when the employee already has values on file. */ defaultValues?: Partial + /** Callback invoked when the form emits an event. See the events table on {@link FederalTaxesEditForm} for the available event types and payloads. */ onEvent: BaseComponentInterface['onEvent'] } +/** + * Standalone form for editing an employee's federal tax (W-4) withholdings — filing status, multiple-jobs flag, dependents, other income, deductions, and extra withholding. + * + * @remarks + * Pair with {@link FederalTaxesCard} to route its `employee/management/federalTaxes/card/editRequested` event to this form. {@link FederalTaxes} bundles the card, this form, and the swap wiring as a single drop-in; reach for this form directly only when that orchestration is the wrong fit (for example, when the form needs to render in a modal or drawer, or when the swap is driven by a router). + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/federalTaxes/editForm/submitted` | Fired after the form is saved; use it to return to the card | The updated `EmployeeFederalTax` entity | + * | `employee/management/federalTaxes/editForm/cancelled` | Fired when the user clicks Cancel; use it to return to the card | — | + * + * @param props - See {@link FederalTaxesEditFormProps}. + * @returns The rendered federal taxes edit form. + * @public + * @group Block Components + */ export function FederalTaxesEditForm({ FallbackComponent, ...props diff --git a/src/components/Employee/FederalTaxes/management/federalTaxesStateMachine.ts b/src/components/Employee/FederalTaxes/management/federalTaxesStateMachine.ts index 99d24d307..cf83a9e70 100644 --- a/src/components/Employee/FederalTaxes/management/federalTaxesStateMachine.ts +++ b/src/components/Employee/FederalTaxes/management/federalTaxesStateMachine.ts @@ -25,6 +25,7 @@ const returnToCardWithAlert = (alert: FederalTaxesContextInterface['successAlert }), ) +/** @internal */ export const federalTaxesStateMachine = { card: state( transition( diff --git a/src/components/Employee/FederalTaxes/management/useViewDictionary.ts b/src/components/Employee/FederalTaxes/management/useViewDictionary.ts index 196f25c40..c4f82932e 100644 --- a/src/components/Employee/FederalTaxes/management/useViewDictionary.ts +++ b/src/components/Employee/FederalTaxes/management/useViewDictionary.ts @@ -7,6 +7,8 @@ import type { FederalTaxesViewDictionary } from '../shared' * `Employee.Management.FederalTaxes` namespace. Partner overrides supplied * through the management edit form's `dictionary` prop flow into the view * text via `t(...)` resolution at render time. + * + * @internal */ export function useManagementFederalTaxesViewDictionary(): FederalTaxesViewDictionary { const { t } = useTranslation('Employee.Management.FederalTaxes') diff --git a/src/components/Employee/FederalTaxes/onboarding/FederalTaxes.tsx b/src/components/Employee/FederalTaxes/onboarding/FederalTaxes.tsx index fb43069e2..d1b752b9e 100644 --- a/src/components/Employee/FederalTaxes/onboarding/FederalTaxes.tsx +++ b/src/components/Employee/FederalTaxes/onboarding/FederalTaxes.tsx @@ -17,12 +17,36 @@ import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** + * Props for {@link FederalTaxes}. + * + * @public + */ export interface FederalTaxesProps extends CommonComponentInterface<'Employee.FederalTaxes'> { + /** The associated employee identifier. */ employeeId: string + /** Pre-fill form values. Server data takes precedence when the employee already has values on file. */ defaultValues?: Partial + /** Callback invoked when the block emits an event. See the events table on {@link FederalTaxes} for the available event types and payloads. */ onEvent: BaseComponentInterface['onEvent'] } +/** + * Onboarding step for collecting an employee's federal tax (W-4) withholdings — filing status, multiple-jobs flag, dependents, other income, deductions, and extra withholding. + * + * @remarks + * The federal tax record is created automatically with the employee, so this step is always in update mode. Only the revised 2020 W-4 format is supported. All fields are required by the bundled form, mirroring the IRS-form UX. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/federalTaxes/updated` | Fired after the form is saved | The updated `EmployeeFederalTax` entity | + * | `employee/federalTaxes/done` | Fired after a successful save so the parent flow can advance | — | + * + * @param props - See {@link FederalTaxesProps}. + * @returns The federal taxes onboarding step. + * @public + * @group Block Components + */ export function FederalTaxes({ FallbackComponent, ...props diff --git a/src/components/Employee/FederalTaxes/onboarding/index.ts b/src/components/Employee/FederalTaxes/onboarding/index.ts deleted file mode 100644 index 15bccbbc6..000000000 --- a/src/components/Employee/FederalTaxes/onboarding/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { FederalTaxes, type FederalTaxesProps } from './FederalTaxes' diff --git a/src/components/Employee/FederalTaxes/onboarding/useViewDictionary.ts b/src/components/Employee/FederalTaxes/onboarding/useViewDictionary.ts index 0743c4505..0f3c261e1 100644 --- a/src/components/Employee/FederalTaxes/onboarding/useViewDictionary.ts +++ b/src/components/Employee/FederalTaxes/onboarding/useViewDictionary.ts @@ -7,6 +7,8 @@ import type { FederalTaxesViewDictionary } from '../shared' * `Employee.FederalTaxes` namespace. Partner overrides supplied through the * onboarding block's `dictionary` prop flow into the view text via `t(...)` * resolution at render time. + * + * @internal */ export function useOnboardingFederalTaxesViewDictionary(): FederalTaxesViewDictionary { const { t } = useTranslation('Employee.FederalTaxes') diff --git a/src/components/Employee/FederalTaxes/shared/FederalTaxesView.tsx b/src/components/Employee/FederalTaxes/shared/FederalTaxesView.tsx index dea1481d4..05695b18f 100644 --- a/src/components/Employee/FederalTaxes/shared/FederalTaxesView.tsx +++ b/src/components/Employee/FederalTaxes/shared/FederalTaxesView.tsx @@ -20,9 +20,12 @@ type ReadyFederalTaxesForm = Extract, { i * * The underlying `Employee.FederalTaxesView` namespace is an implementation * detail of the shared view — consumers shouldn't reference it directly. + * + * @internal */ export type FederalTaxesViewDictionary = ResourceDictionary<'Employee.FederalTaxesView'> +/** @internal */ export interface FederalTaxesViewProps { federalTaxes: ReadyFederalTaxesForm onSubmit: () => void | Promise @@ -39,6 +42,7 @@ export interface FederalTaxesViewProps { dictionary?: FederalTaxesViewDictionary } +/** @internal */ export function FederalTaxesView({ federalTaxes, onSubmit, diff --git a/src/components/Employee/FederalTaxes/shared/index.ts b/src/components/Employee/FederalTaxes/shared/index.ts index 92cec98cd..f8c4f9b70 100644 --- a/src/components/Employee/FederalTaxes/shared/index.ts +++ b/src/components/Employee/FederalTaxes/shared/index.ts @@ -1,12 +1,2 @@ -export { - FederalTaxesView, - type FederalTaxesViewProps, - type FederalTaxesViewDictionary, -} from './FederalTaxesView' +export { type FederalTaxesViewDictionary } from './FederalTaxesView' export * from './useFederalTaxesForm' -export { - useFederalTaxesSummary, - type UseFederalTaxesSummaryParams, - type UseFederalTaxesSummaryReady, - type UseFederalTaxesSummaryResult, -} from './useFederalTaxesSummary' diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.ts b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.ts index 567a73738..101830c2c 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.ts +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.ts @@ -9,15 +9,33 @@ import { coerceNaN, coerceStringBoolean } from '@/partner-hook-utils/form/prepro // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the federal taxes form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const FederalTaxesErrorCodes = { REQUIRED: 'REQUIRED', } as const +/** + * Union of validation error code strings emitted by the federal taxes form + * schema. + * + * @public + */ export type FederalTaxesErrorCode = (typeof FederalTaxesErrorCodes)[keyof typeof FederalTaxesErrorCodes] // ── Filing status options ────────────────────────────────────────────── +/** + * Supported W-4 filing status values: single, married filing jointly, head of + * household, and exempt from withholding. + * + * @public + */ export const FILING_STATUS_VALUES = [ FilingStatus.Single, FilingStatus.Married, @@ -25,6 +43,11 @@ export const FILING_STATUS_VALUES = [ FilingStatus.ExemptFromWithholding, ] as const +/** + * Union of filing status values that the form accepts. + * + * @public + */ export type FilingStatusValue = (typeof FILING_STATUS_VALUES)[number] // ── Field validators ─────────────────────────────────────────────────── @@ -42,11 +65,26 @@ const fieldValidators = { extraWithholding: z.preprocess(coerceNaN(0), z.number()), } +/** + * Field names accepted by the federal taxes form. + * + * @public + */ export type FederalTaxesField = keyof typeof fieldValidators +/** + * Shape of the values managed by the federal taxes form. + * + * @public + */ export type FederalTaxesFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the federal taxes form on submit. + * + * @public + */ export type FederalTaxesFormOutputs = FederalTaxesFormData // ── Required fields config ───────────────────────────────────────────── @@ -65,14 +103,22 @@ const requiredFieldsConfig = { // ── Schema factory ───────────────────────────────────────────────────── +/** + * Keys of optional federal taxes fields that can be promoted to required via + * the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type FederalTaxesOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface FederalTaxesSchemaOptions { optionalFieldsToRequire?: FederalTaxesOptionalFieldsToRequire } +/** @internal */ export function createFederalTaxesSchema(options: FederalTaxesSchemaOptions = {}) { const { optionalFieldsToRequire } = options diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.tsx b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.tsx index 78f80c6aa..2fc94b28c 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.tsx +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/fields.tsx @@ -9,48 +9,160 @@ import { } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * The required-field error code produced by {@link useFederalTaxesForm} fields. + * + * @remarks + * Used as the `validationMessages` key for every federal taxes field. See + * {@link FederalTaxesErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof FederalTaxesErrorCodes.REQUIRED +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.FilingStatus` component. + * + * @public + */ export type FilingStatusFieldProps = HookFieldProps< SelectHookFieldProps > +/** + * Select bound to the `filingStatus` field of {@link useFederalTaxesForm}. + * + * @remarks + * Available on the hook result as `form.Fields.FilingStatus`. Options are + * populated from `FILING_STATUS_VALUES` (`Single`, `Married`, + * `Head of Household`, `Exempt from withholding`). The default option label is + * the raw filing status value — pass `getOptionLabel` to localize. + * + * @param props - {@link FilingStatusFieldProps} — accepts the standard hook field props plus `getOptionLabel` for filing-status display. + * @returns The rendered select bound to `filingStatus`. + * @public + */ export function FilingStatusField(props: FilingStatusFieldProps) { return } +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.TwoJobs` component. + * + * @public + */ export type TwoJobsFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `twoJobs` field of {@link useFederalTaxesForm} for the W-4 multiple-jobs question (Step 2c). + * + * @remarks + * Available on the hook result as `form.Fields.TwoJobs`. Two options for + * `true` and `false`. The default labels are `Yes` and `No` — pass + * `getOptionLabel` to localize. The form submits a boolean value. + * + * @param props - {@link TwoJobsFieldProps} — accepts the standard hook field props plus `getOptionLabel` for option display. + * @returns The rendered radio group bound to `twoJobs`. + * @public + */ export function TwoJobsField(props: TwoJobsFieldProps) { return } +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.DependentsAmount` component. + * + * @public + */ export type DependentsAmountFieldProps = HookFieldProps< NumberInputHookFieldProps > +/** + * Currency-formatted number input bound to the `dependentsAmount` field of {@link useFederalTaxesForm} for the W-4 dependents total (Step 3). + * + * @remarks + * Available on the hook result as `form.Fields.DependentsAmount`. The field + * renders with `format="currency"` and `min={0}`. Empty values coerce to `0` + * and pass the required check. + * + * @param props - {@link DependentsAmountFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered currency-formatted number input bound to `dependentsAmount`. + * @public + */ export function DependentsAmountField(props: DependentsAmountFieldProps) { return } +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.OtherIncome` component. + * + * @public + */ export type OtherIncomeFieldProps = HookFieldProps> +/** + * Currency-formatted number input bound to the `otherIncome` field of {@link useFederalTaxesForm} for the W-4 other-income field (Step 4a). + * + * @remarks + * Available on the hook result as `form.Fields.OtherIncome`. The field + * renders with `format="currency"` and `min={0}`. Empty values coerce to `0` + * and pass the required check. + * + * @param props - {@link OtherIncomeFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered currency-formatted number input bound to `otherIncome`. + * @public + */ export function OtherIncomeField(props: OtherIncomeFieldProps) { return } +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.Deductions` component. + * + * @public + */ export type DeductionsFieldProps = HookFieldProps> +/** + * Currency-formatted number input bound to the `deductions` field of {@link useFederalTaxesForm} for the W-4 deductions field (Step 4b). + * + * @remarks + * Available on the hook result as `form.Fields.Deductions`. The field + * renders with `format="currency"` and `min={0}`. Empty values coerce to `0` + * and pass the required check. + * + * @param props - {@link DeductionsFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered currency-formatted number input bound to `deductions`. + * @public + */ export function DeductionsField(props: DeductionsFieldProps) { return } +/** + * Props accepted by {@link useFederalTaxesForm}'s `Fields.ExtraWithholding` component. + * + * @public + */ export type ExtraWithholdingFieldProps = HookFieldProps< NumberInputHookFieldProps > +/** + * Currency-formatted number input bound to the `extraWithholding` field of {@link useFederalTaxesForm} for the W-4 extra-withholding field (Step 4c). + * + * @remarks + * Available on the hook result as `form.Fields.ExtraWithholding`. The field + * renders with `format="currency"` and `min={0}`. Empty values coerce to `0` + * and pass the required check. + * + * @param props - {@link ExtraWithholdingFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered currency-formatted number input bound to `extraWithholding`. + * @public + */ export function ExtraWithholdingField(props: ExtraWithholdingFieldProps) { return } diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/index.ts b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/index.ts index 5af829f8f..b113814aa 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/index.ts +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/index.ts @@ -18,6 +18,14 @@ export { type FederalTaxesField, type FilingStatusValue, } from './federalTaxesSchema' +export { + FilingStatusField, + TwoJobsField, + DependentsAmountField, + OtherIncomeField, + DeductionsField, + ExtraWithholdingField, +} from './fields' export type { RequiredValidation as FederalTaxesRequiredValidation, FilingStatusFieldProps, diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/useFederalTaxesForm.tsx b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/useFederalTaxesForm.tsx index d5aec3c00..894c74eb4 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/useFederalTaxesForm.tsx +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/useFederalTaxesForm.tsx @@ -42,33 +42,77 @@ import { SDKInternalError } from '@/types/sdkError' export type { FederalTaxesOptionalFieldsToRequire } from './federalTaxesSchema' +/** + * Configuration options for {@link useFederalTaxesForm}. + * + * @remarks + * The federal tax record is created automatically with the employee, so the + * hook is always in update mode and only `employeeId` is required. + * + * @public + */ export interface UseFederalTaxesFormProps { + /** UUID of the employee whose federal tax record is being updated. */ employeeId: string + /** Override fields that are optional on update to be required. By default only `filingStatus` is required; pass `{ update: ['twoJobs', 'dependentsAmount', 'otherIncome', 'deductions', 'extraWithholding'] }` to require any subset. See {@link FederalTaxesOptionalFieldsToRequire}. */ optionalFieldsToRequire?: FederalTaxesOptionalFieldsToRequire + /** Pre-fill form values. Server data takes precedence when the employee already has values on file. */ defaultValues?: Partial + /** Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler` so submit-time focus is coordinated across multiple forms. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Pre-bound field components exposed on `useFederalTaxesForm().form.Fields`. + * + * @public + */ export interface FederalTaxesFields { + /** Filing status select. */ FilingStatus: typeof FilingStatusField + /** Multiple-jobs (Step 2c) radio group. */ TwoJobs: typeof TwoJobsField + /** Dependents amount (Step 3) currency input. */ DependentsAmount: typeof DependentsAmountField + /** Other income (Step 4a) currency input. */ OtherIncome: typeof OtherIncomeField + /** Deductions (Step 4b) currency input. */ Deductions: typeof DeductionsField + /** Extra withholding (Step 4c) currency input. */ ExtraWithholding: typeof ExtraWithholdingField } +/** + * Ready-state shape returned by {@link useFederalTaxesForm} once data has loaded. + * + * @remarks + * Discriminated by `isLoading: false`. Extends {@link BaseFormHookReady} with + * the federal-taxes specific `data`, `status`, and `actions`. + * + * @public + */ export interface UseFederalTaxesFormReady extends BaseFormHookReady< FieldsMetadata, FederalTaxesFormData, FederalTaxesFields > { + /** The loaded federal tax record. */ data: { + /** The current federal tax record for the employee. */ employeeFederalTax: EmployeeFederalTax } - status: { isPending: boolean; mode: 'update' } + /** Submission state. `mode` is always `'update'` — the federal tax record is created with the employee, so this hook has no create mode. */ + status: { + /** `true` while the update mutation is in flight. */ + isPending: boolean + /** Always `'update'` — the federal tax record is created when the employee is created. */ + mode: 'update' + } + /** Submit actions exposed by the hook. */ actions: { + /** Validates the form, runs the update mutation, and resolves to a {@link HookSubmitResult} containing the updated record. Resolves to `undefined` on validation failure or mutation error. */ onSubmit: () => Promise | undefined> } } @@ -88,6 +132,48 @@ function toNumber(value: string | null | undefined): number | undefined { return Number.isNaN(parsed) ? undefined : parsed } +/** + * Headless hook for updating an employee's federal tax (W-4) withholding information — filing status, multiple-jobs flag, dependents, other income, deductions, and extra withholding. + * + * @remarks + * The federal tax record is created automatically with the employee, so this hook is always in update mode. Only the revised 2020 W-4 format is supported for updates. By default only `filingStatus` is required; promote any of `twoJobs`, `dependentsAmount`, `otherIncome`, `deductions`, or `extraWithholding` to required via `optionalFieldsToRequire.update`. + * + * @param props - See {@link UseFederalTaxesFormProps}. + * @returns A {@link HookLoadingResult} while data is loading, or a {@link UseFederalTaxesFormReady} once the federal tax record is loaded. + * @public + * + * @example + * ```tsx + * import { useFederalTaxesForm, SDKFormProvider } from '@gusto/embedded-react-sdk' + * + * function FederalTaxesPage({ employeeId }: { employeeId: string }) { + * const federalTaxes = useFederalTaxesForm({ employeeId }) + * + * if (federalTaxes.isLoading) return
Loading...
+ * + * const { Fields } = federalTaxes.form + * + * return ( + * + *
{ + * e.preventDefault() + * void federalTaxes.actions.onSubmit() + * }} + * > + * + * + * + * + * + * + * + * + *
+ * ) + * } + * ``` + */ export function useFederalTaxesForm({ employeeId, optionalFieldsToRequire, @@ -248,6 +334,37 @@ export function useFederalTaxesForm({ } } +/** + * Discriminated union returned by {@link useFederalTaxesForm} — either the loading state or the ready state. + * + * @remarks + * Use this type when threading the hook result through helpers (e.g. + * presentational components). Discriminate on `isLoading` to narrow to + * {@link UseFederalTaxesFormReady}. + * + * @public + */ export type UseFederalTaxesFormResult = HookLoadingResult | UseFederalTaxesFormReady + +/** + * Metadata for each {@link useFederalTaxesForm} field, exposed on `form.fieldsMetadata`. + * + * @remarks + * Includes per-field `isDisabled`, `isRequired`, and the dynamic option list + * for select and radio fields (`filingStatus`, `twoJobs`). + * + * @public + */ export type FederalTaxesFieldsMetadata = UseFederalTaxesFormReady['form']['fieldsMetadata'] + +/** + * Pre-bound field components exposed on `useFederalTaxesForm().form.Fields`. + * + * @remarks + * Alias for the `Fields` shape on {@link UseFederalTaxesFormReady}. Use this + * type when typing a presentational component that consumes the hook's + * fields. + * + * @public + */ export type FederalTaxesFormFields = UseFederalTaxesFormReady['form']['Fields'] diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/index.ts b/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/index.ts index d94b7f968..0e39a074f 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/index.ts +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/index.ts @@ -1,6 +1 @@ export { useFederalTaxesSummary } from './useFederalTaxesSummary' -export type { - UseFederalTaxesSummaryParams, - UseFederalTaxesSummaryReady, - UseFederalTaxesSummaryResult, -} from './useFederalTaxesSummary' diff --git a/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/useFederalTaxesSummary.tsx b/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/useFederalTaxesSummary.tsx index e105c0374..0a72b6335 100644 --- a/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/useFederalTaxesSummary.tsx +++ b/src/components/Employee/FederalTaxes/shared/useFederalTaxesSummary/useFederalTaxesSummary.tsx @@ -7,21 +7,34 @@ type EmployeeFederalTax = NonNullable< GetV1EmployeesEmployeeIdFederalTaxesResponse['employeeFederalTax'] > +/** + * Parameters accepted by {@link useFederalTaxesSummary}. + * + * @public + */ export interface UseFederalTaxesSummaryParams { + /** UUID of the employee whose federal tax record is being read. */ employeeId: string } -export type UseFederalTaxesSummaryReady = BaseHookReady< +type UseFederalTaxesSummaryReady = BaseHookReady< { employeeFederalTax: EmployeeFederalTax | undefined }, { isFetching: boolean; isPending: boolean } > +/** + * Discriminated union returned by {@link useFederalTaxesSummary} — either the loading state or the ready state carrying the loaded federal tax record. + * + * @public + */ export type UseFederalTaxesSummaryResult = HookLoadingResult | UseFederalTaxesSummaryReady /** * Read-only data hook for the Federal Taxes management card. Wraps * `useEmployeeTaxSetupGetFederalTaxes` and returns the loaded federal-tax * record. Mutations live in `useFederalTaxesForm`. + * + * @public */ export function useFederalTaxesSummary({ employeeId, diff --git a/src/components/Employee/HomeAddress/management/HomeAddress.tsx b/src/components/Employee/HomeAddress/management/HomeAddress.tsx index facec6ebb..2c69a9cf2 100644 --- a/src/components/Employee/HomeAddress/management/HomeAddress.tsx +++ b/src/components/Employee/HomeAddress/management/HomeAddress.tsx @@ -13,8 +13,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link HomeAddress}. + * + * @public + */ export interface HomeAddressProps extends CommonComponentInterface<'Employee.Management.HomeAddress'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -34,6 +41,20 @@ function HomeAddressFlow({ employeeId, onEvent }: HomeAddressProps) { return } +/** + * Standalone employee home address management flow. + * + * @remarks + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/homeAddress/editRequested` | Manage button on the home address card clicked | `{ employeeId: string }` | + * | `employee/management/homeAddress/editCancelled` | User backed out of the edit form | — | + * | `employee/management/homeAddress/created` | A new home address was created | {@link EmployeeAddress} | + * | `employee/management/homeAddress/updated` | An existing home address was updated | {@link EmployeeAddress} | + * | `employee/management/homeAddress/deleted` | A home address was deleted | {@link EmployeeAddress} | + * + * @public + */ export function HomeAddress({ dictionary, FallbackComponent, diff --git a/src/components/Employee/HomeAddress/management/HomeAddressCard/HomeAddressCard.tsx b/src/components/Employee/HomeAddress/management/HomeAddressCard/HomeAddressCard.tsx index 58289decb..d2bd114c9 100644 --- a/src/components/Employee/HomeAddress/management/HomeAddressCard/HomeAddressCard.tsx +++ b/src/components/Employee/HomeAddress/management/HomeAddressCard/HomeAddressCard.tsx @@ -9,17 +9,29 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link HomeAddressCard}. + * + * @public + */ export interface HomeAddressCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the card's Manage button is clicked. */ onEvent: OnEventType } /** - * Standalone "Home address" card. Owns its own data fetch via - * `useHomeAddressSummary` and emits - * `EMPLOYEE_MANAGEMENT_HOME_ADDRESS_EDIT_REQUESTED` when the Manage - * button is clicked. The card has no alert API — alert rendering - * (when introduced) is the orchestrator's responsibility. + * Standalone employee home address summary card. + * + * @remarks + * Fetches the employee's active home address and renders it alongside a Manage button. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/homeAddress/editRequested` | Manage button clicked | `{ employeeId: string }` | + * + * @public */ export function HomeAddressCard(props: HomeAddressCardProps) { return ( diff --git a/src/components/Employee/HomeAddress/management/HomeAddressComponents.tsx b/src/components/Employee/HomeAddress/management/HomeAddressComponents.tsx index f525c41b1..db260667d 100644 --- a/src/components/Employee/HomeAddress/management/HomeAddressComponents.tsx +++ b/src/components/Employee/HomeAddress/management/HomeAddressComponents.tsx @@ -3,15 +3,18 @@ import { HomeAddressEditForm } from './HomeAddressEditForm' import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export interface HomeAddressContextInterface extends FlowContextInterface { employeeId?: string } +/** @internal */ export function CardContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function HomeAddressEditFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/HomeAddress/management/HomeAddressEditForm.tsx b/src/components/Employee/HomeAddress/management/HomeAddressEditForm.tsx index 1cfddcc74..78fbdb5db 100644 --- a/src/components/Employee/HomeAddress/management/HomeAddressEditForm.tsx +++ b/src/components/Employee/HomeAddress/management/HomeAddressEditForm.tsx @@ -14,8 +14,15 @@ import { useI18n, useComponentDictionary } from '@/i18n' import type { HookSubmitResult } from '@/partner-hook-utils/types' import { componentEvents } from '@/shared/constants' +/** + * Props for {@link HomeAddressEditForm}. + * + * @public + */ export interface HomeAddressEditFormProps extends CommonComponentInterface<'Employee.Management.HomeAddress'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on form save, cancel, and delete actions. */ onEvent: BaseComponentInterface['onEvent'] } @@ -61,6 +68,19 @@ function HomeAddressEditFormRoot({ employeeId, onEvent, dictionary }: HomeAddres ) } +/** + * Standalone employee home address edit form for creating, updating, and deleting addresses. + * + * @remarks + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/homeAddress/created` | A new home address was created | {@link EmployeeAddress} | + * | `employee/management/homeAddress/updated` | An existing home address was updated | {@link EmployeeAddress} | + * | `employee/management/homeAddress/deleted` | A home address was deleted | {@link EmployeeAddress} | + * | `employee/management/homeAddress/editCancelled` | User backed out of the edit form | — | + * + * @public + */ export function HomeAddressEditForm({ FallbackComponent, ...props diff --git a/src/components/Employee/HomeAddress/management/HomeAddressView.tsx b/src/components/Employee/HomeAddress/management/HomeAddressView.tsx index cfd53b1a8..53285f378 100644 --- a/src/components/Employee/HomeAddress/management/HomeAddressView.tsx +++ b/src/components/Employee/HomeAddress/management/HomeAddressView.tsx @@ -60,6 +60,7 @@ function HomeAddressCourtesyWithholdingBlock({ ) } +/** @internal */ export interface HomeAddressViewProps { editHomeAddressForm: UseHomeAddressFormReady createHomeAddressForm: UseHomeAddressFormReady @@ -76,6 +77,7 @@ export interface HomeAddressViewProps { isDeletePending?: boolean } +/** @internal */ export function HomeAddressView({ editHomeAddressForm, createHomeAddressForm, diff --git a/src/components/Employee/HomeAddress/management/getPendingFutureHomeAddress.ts b/src/components/Employee/HomeAddress/management/getPendingFutureHomeAddress.ts index dddbd4abf..d2dceec21 100644 --- a/src/components/Employee/HomeAddress/management/getPendingFutureHomeAddress.ts +++ b/src/components/Employee/HomeAddress/management/getPendingFutureHomeAddress.ts @@ -6,6 +6,8 @@ const startOfLocalDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.g /** * Returns the next inactive home address whose effective date is strictly after today (local), * or undefined when there is no such scheduled change. + * + * @internal */ export function getPendingFutureHomeAddress( addresses: EmployeeAddress[] | undefined, @@ -55,7 +57,11 @@ function formatCountryForDisplay(country: string | null | undefined): string { return USA_LABELS.has(c) ? 'United States' : c } -/** Single-line address for pending-change copy (matches product mock: street, city, ST zip, country). */ +/** + * Single-line address for pending-change copy (matches product mock: street, city, ST zip, country). + * + * @internal + */ export function formatPendingHomeAddressLine(address: EmployeeAddress): string { const streetLine = [address.street1, address.street2].filter(Boolean).join(', ') const cityStateZip = [address.city, [address.state, address.zip].filter(Boolean).join(' ')] diff --git a/src/components/Employee/HomeAddress/management/homeAddressStateMachine.ts b/src/components/Employee/HomeAddress/management/homeAddressStateMachine.ts index 4b53055e8..3d2954f3b 100644 --- a/src/components/Employee/HomeAddress/management/homeAddressStateMachine.ts +++ b/src/components/Employee/HomeAddress/management/homeAddressStateMachine.ts @@ -12,6 +12,7 @@ const returnToCard = reduce( }), ) +/** @internal */ export const homeAddressStateMachine = { card: state( transition( diff --git a/src/components/Employee/HomeAddress/management/useHomeAddressManagement.tsx b/src/components/Employee/HomeAddress/management/useHomeAddressManagement.tsx index 02629e0df..e4d80babf 100644 --- a/src/components/Employee/HomeAddress/management/useHomeAddressManagement.tsx +++ b/src/components/Employee/HomeAddress/management/useHomeAddressManagement.tsx @@ -20,12 +20,19 @@ import { firstLastName } from '@/helpers/formattedStrings' import { SDKInternalError } from '@/types/sdkError' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Params for {@link useHomeAddressManagement}. + * + * @public + */ export interface UseHomeAddressManagementParams { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when a home address is deleted. */ onEvent: OnEventType } -export interface UseHomeAddressManagementDataPendingForms extends Record { +interface UseHomeAddressManagementDataPendingForms extends Record { employeeDisplayName: string employeeHomeAddresses: EmployeeAddress[] | undefined editingHomeAddressUuid: string | undefined @@ -33,7 +40,7 @@ export interface UseHomeAddressManagementDataPendingForms extends Record { +interface UseHomeAddressManagementDataReady extends Record { employeeDisplayName: string employeeHomeAddresses: EmployeeAddress[] | undefined editingHomeAddressUuid: string | undefined @@ -41,41 +48,59 @@ export interface UseHomeAddressManagementDataReady extends Record { +interface UseHomeAddressManagementStatusEmployeeError extends Record { isDeletePending: boolean isEmployeeError: true } -export interface UseHomeAddressManagementStatusSuccess extends Record { +interface UseHomeAddressManagementStatusSuccess extends Record { isDeletePending: boolean isEmployeeError: false } -export interface UseHomeAddressManagementActions { +interface UseHomeAddressManagementActions { setEditAddressTarget: (homeAddressUuid: string | undefined) => void confirmDeleteHomeAddress: (homeAddressUuid: string) => Promise } -export interface UseHomeAddressManagementReadyEmployeeError extends BaseHookReady< +interface UseHomeAddressManagementReadyEmployeeError extends BaseHookReady< UseHomeAddressManagementDataPendingForms, UseHomeAddressManagementStatusEmployeeError > { actions: UseHomeAddressManagementActions } +/** + * Ready state of {@link useHomeAddressManagement} when the employee was fetched successfully. + * + * @public + */ export interface UseHomeAddressManagementReadySuccess extends BaseHookReady< UseHomeAddressManagementDataReady, UseHomeAddressManagementStatusSuccess > { + /** Actions for changing edit target and confirming home address deletion. */ actions: UseHomeAddressManagementActions } -export type UseHomeAddressManagementReady = +type UseHomeAddressManagementReady = | UseHomeAddressManagementReadyEmployeeError | UseHomeAddressManagementReadySuccess +/** + * Return type of {@link useHomeAddressManagement}. + * + * @public + */ export type UseHomeAddressManagementResult = HookLoadingResult | UseHomeAddressManagementReady +/** + * Type guard for the success branch of {@link useHomeAddressManagement}. + * + * @param value - The hook result to narrow. + * @returns `true` when the hook has finished loading and the employee fetch succeeded. + * @public + */ export function isUseHomeAddressManagementSuccess( value: UseHomeAddressManagementResult, ): value is UseHomeAddressManagementReadySuccess { @@ -101,6 +126,19 @@ function homeAddressFormsReady( } } +/** + * Headless hook for managing an employee's home addresses. + * + * @remarks + * Fetches the employee and their home addresses, exposes edit and create form hooks + * for the address modal, and provides an action to delete a non-active address. + * Use {@link isUseHomeAddressManagementSuccess} to narrow the ready state when the + * employee fetch succeeded. + * + * @param params - {@link UseHomeAddressManagementParams} + * @returns A {@link HookLoadingResult} while loading, or the ready state once data is available. + * @public + */ export function useHomeAddressManagement({ employeeId, onEvent, diff --git a/src/components/Employee/HomeAddress/shared/index.ts b/src/components/Employee/HomeAddress/shared/index.ts deleted file mode 100644 index 7135afee9..000000000 --- a/src/components/Employee/HomeAddress/shared/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useHomeAddressSummary } from './useHomeAddressSummary' -export type { - UseHomeAddressSummaryParams, - UseHomeAddressSummaryReady, - UseHomeAddressSummaryResult, -} from './useHomeAddressSummary' diff --git a/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/index.ts b/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/index.ts index 7135afee9..64d11b6e9 100644 --- a/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/index.ts +++ b/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/index.ts @@ -1,6 +1 @@ export { useHomeAddressSummary } from './useHomeAddressSummary' -export type { - UseHomeAddressSummaryParams, - UseHomeAddressSummaryReady, - UseHomeAddressSummaryResult, -} from './useHomeAddressSummary' diff --git a/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/useHomeAddressSummary.tsx b/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/useHomeAddressSummary.tsx index 5921db50f..97de519fb 100644 --- a/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/useHomeAddressSummary.tsx +++ b/src/components/Employee/HomeAddress/shared/useHomeAddressSummary/useHomeAddressSummary.tsx @@ -3,11 +3,17 @@ import type { EmployeeAddress } from '@gusto/embedded-api-v-2025-11-15/models/co import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult } from '@/partner-hook-utils/types' +/** + * Params for {@link useHomeAddressSummary}. + * + * @public + */ export interface UseHomeAddressSummaryParams { + /** The associated employee identifier. */ employeeId: string } -export type UseHomeAddressSummaryReady = BaseHookReady< +type UseHomeAddressSummaryReady = BaseHookReady< { currentHomeAddress: EmployeeAddress | undefined employeeAddressList: EmployeeAddress[] @@ -15,14 +21,22 @@ export type UseHomeAddressSummaryReady = BaseHookReady< { isFetching: boolean; isPending: boolean } > +/** + * Return type of {@link useHomeAddressSummary}. + * + * @public + */ export type UseHomeAddressSummaryResult = HookLoadingResult | UseHomeAddressSummaryReady /** - * Read-only data hook for the Home address management card. Wraps - * `useEmployeeAddressesGet` and surfaces the active row plus the full - * list (the latter lets partners build their own history/pending UI). - * Mutations live in `useHomeAddressManagement` (the form-driven hook - * the edit form consumes). + * Read-only headless hook returning the employee's active home address and full address list. + * + * @remarks + * Use {@link useHomeAddressManagement} when you need create, update, or delete actions. + * + * @param params - {@link UseHomeAddressSummaryParams} + * @returns A {@link HookLoadingResult} while loading, or the ready state with `currentHomeAddress` and `employeeAddressList`. + * @public */ export function useHomeAddressSummary({ employeeId, diff --git a/src/components/Employee/Landing/Landing.tsx b/src/components/Employee/Landing/Landing.tsx index 957e8e114..c49f7b635 100644 --- a/src/components/Employee/Landing/Landing.tsx +++ b/src/components/Employee/Landing/Landing.tsx @@ -21,6 +21,12 @@ interface SummaryProps extends CommonComponentInterface<'Employee.Landing'> { companyId: string } +/** + * Landing page for the employee self-onboarding flow. Displays a welcome + * message and the list of onboarding steps the employee needs to complete. + * + * @public + */ export function Landing(props: SummaryProps & BaseComponentInterface) { useI18n('Employee.Landing') useComponentDictionary('Employee.Landing', props.dictionary) diff --git a/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.tsx b/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.tsx index 73eabd753..cf9dcc454 100644 --- a/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.tsx +++ b/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.tsx @@ -13,18 +13,61 @@ import { Flow } from '@/components/Flow/Flow' import type { OnEventType } from '@/components/Base/useBase' import type { EventType, EmployeeOnboardingStatus } from '@/shared/constants' +/** + * Props for {@link OnboardingExecutionFlow}. + * + * @public + */ export interface OnboardingExecutionFlowProps { + /** The associated company identifier. */ companyId: string + /** Callback invoked when the flow emits an event. */ onEvent: OnEventType + /** The step the flow starts on. Defaults to `employeeProfile`. */ initialState?: OnboardingExecutionInitialState + /** The associated employee identifier to resume onboarding for. Omit to begin onboarding a new employee. */ initialEmployeeId?: string + /** The current onboarding status of the employee being onboarded. Drives skip behavior for self-onboarding and document steps. */ initialOnboardingStatus?: (typeof EmployeeOnboardingStatus)[keyof typeof EmployeeOnboardingStatus] + /** Default values for individual flow step components. */ defaultValues?: OnboardingDefaultValues + /** When true, the flow renders in the admin context. When false, it is configured for employee self-onboarding. Defaults to `true`. */ isAdmin?: boolean + /** When true, presents the self-onboarding toggle on the profile step. Defaults to `true`. */ isSelfOnboardingEnabled?: boolean + /** When true, enables the Employee Documents step in the flow, allowing the admin to configure I-9 document requirements. Defaults to `false`. */ withEmployeeI9?: boolean } +/** + * The multi-step onboarding execution flow — profile, compensation, taxes, payment method, deductions, documents, and summary. + * + * @remarks + * Drives the per-employee onboarding experience used by both {@link OnboardingFlow} (admin) and {@link SelfOnboardingFlow} (employee). Each step is also exported as a standalone block — see {@link Profile}, {@link Compensation}, {@link FederalTaxes}, {@link StateTaxes}, {@link PaymentMethod}, {@link Deductions}, {@link EmployeeDocuments}, and {@link OnboardingSummary} — for composing a custom workflow when this orchestration is the wrong fit. + * + * Self-onboarding statuses cause the federal-taxes, state-taxes, and payment-method steps to be skipped (the employee fills those in themselves); the documents step is also skipped unless `withEmployeeI9` is true and the documents config has not yet been completed. + * + * The flow forwards every event emitted by its sub-components to `onEvent`; see the events table on each sub-component for the full set of events and payloads observable from this flow. + * + * @param props - See {@link OnboardingExecutionFlowProps}. + * @returns The multi-step onboarding execution flow. + * @public + * @group Flow Components + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyApp() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function OnboardingExecutionFlow({ companyId, onEvent, diff --git a/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlowComponents.tsx b/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlowComponents.tsx index 666348f5a..7f57a0e13 100644 --- a/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlowComponents.tsx +++ b/src/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlowComponents.tsx @@ -9,11 +9,25 @@ import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import type { EmployeeOnboardingStatus } from '@/shared/constants' import type { RequireAtLeastOne } from '@/types/Helpers' +/** + * Default values for the onboarding flow's per-step form components. + * + * @remarks + * At least one of the step-level keys must be provided. Per-step values are + * forwarded to the matching step component (e.g. `profile` to {@link Profile}, + * `compensation` to {@link Compensation}). If employee data is available via + * the API, the corresponding values are overwritten. + * + * @public + */ export type OnboardingDefaultValues = RequireAtLeastOne<{ + /** Default values for the profile step. */ profile?: ProfileDefaultValues + /** Default values for the compensation step. */ compensation?: CompensationDefaultValues }> +/** @internal */ export interface OnboardingContextInterface extends FlowContextInterface { companyId: string employeeId?: string @@ -26,16 +40,19 @@ export interface OnboardingContextInterface extends FlowContextInterface { withEmployeeI9?: boolean } +/** @internal */ export function FederalTaxesContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function StateTaxesContextual() { const { employeeId, onEvent, isAdmin } = useFlow() return } +/** @internal */ export function DeductionsContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/OnboardingExecutionFlow/index.ts b/src/components/Employee/OnboardingExecutionFlow/index.ts index d7fbb061b..d3c4658a2 100644 --- a/src/components/Employee/OnboardingExecutionFlow/index.ts +++ b/src/components/Employee/OnboardingExecutionFlow/index.ts @@ -2,11 +2,5 @@ export { OnboardingExecutionFlow, type OnboardingExecutionFlowProps, } from './OnboardingExecutionFlow' -export { - onboardingExecutionMachine, - type OnboardingExecutionInitialState, -} from './onboardingExecutionStateMachine' -export type { - OnboardingContextInterface, - OnboardingDefaultValues, -} from './OnboardingExecutionFlowComponents' +export { type OnboardingDefaultValues } from './OnboardingExecutionFlowComponents' +export { type OnboardingExecutionInitialState } from './onboardingExecutionStateMachine' diff --git a/src/components/Employee/OnboardingExecutionFlow/onboardingExecutionStateMachine.ts b/src/components/Employee/OnboardingExecutionFlow/onboardingExecutionStateMachine.ts index 80291e2fe..f0e0ee997 100644 --- a/src/components/Employee/OnboardingExecutionFlow/onboardingExecutionStateMachine.ts +++ b/src/components/Employee/OnboardingExecutionFlow/onboardingExecutionStateMachine.ts @@ -57,6 +57,7 @@ const selfOnboardingGuard = (ctx: OnboardingContextInterface) => ) : true +/** @internal */ export const onboardingExecutionMachine = { employeeProfile: state( transition( @@ -135,8 +136,14 @@ export const onboardingExecutionMachine = { summary: state(), } +/** @internal */ export const INITIAL_COMPONENT_MAP = { employeeProfile: ProfileContextual, } as const +/** + * The set of steps {@link OnboardingExecutionFlow} can be started on. + * + * @public + */ export type OnboardingExecutionInitialState = keyof typeof INITIAL_COMPONENT_MAP diff --git a/src/components/Employee/OnboardingFlow/OnboardingFlow.tsx b/src/components/Employee/OnboardingFlow/OnboardingFlow.tsx index 653337bb1..0012742e8 100644 --- a/src/components/Employee/OnboardingFlow/OnboardingFlow.tsx +++ b/src/components/Employee/OnboardingFlow/OnboardingFlow.tsx @@ -10,13 +10,72 @@ import { Flow } from '@/components/Flow/Flow' import type { BaseComponentInterface } from '@/components/Base' import type { RequireAtLeastOne } from '@/types/Helpers' +/** + * Props for {@link OnboardingFlow}. + * + * @public + */ export interface OnboardingFlowProps extends BaseComponentInterface { + /** The associated company identifier. */ companyId: string + /** Default values for individual flow step components. */ defaultValues?: RequireAtLeastOne + /** + * When true, presents the self-onboarding toggle allowing the admin to opt + * the employee into self-onboarding. When false, the option to self-onboard + * is not available. Defaults to `true`. + */ isSelfOnboardingEnabled?: boolean + /** + * When true, enables the Employee Documents step in the onboarding flow, + * allowing the admin to configure I-9 document requirements. Defaults to + * `false`. + */ withEmployeeI9?: boolean } +/** + * Complete workflow for onboarding an employee — profile, compensation, taxes, payment method, and document signing. + * + * @remarks + * Renders a multi-step experience that collects every piece of information + * required to add an employee to payroll. Begins on the employee list and + * transitions into the onboarding execution flow when "Add employee" or a + * row's "Edit"/"Review" action is invoked; returning from the execution flow + * surfaces the list again. The flow is driven by an internal state machine + * and wraps each step in error and suspense boundaries. + * + * Each step of the flow is also exported as a standalone block — see + * {@link EmployeeList}, {@link Profile}, {@link Compensation}, + * {@link FederalTaxes}, {@link StateTaxes}, {@link PaymentMethod}, + * {@link Deductions}, {@link EmployeeDocuments}, and + * {@link OnboardingSummary} — for composing a custom workflow when this + * orchestration is the wrong fit. + * + * The flow forwards every event emitted by its sub-components to `onEvent`; + * see the events table on each sub-component for the full set of events and + * payloads observable from this flow. + * + * @param props - See {@link OnboardingFlowProps}. + * @returns The multi-step onboarding flow with internal navigation between the employee list and the per-step screens. + * @public + * @group Flow Components + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyApp() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export const OnboardingFlow = ({ companyId, onEvent, diff --git a/src/components/Employee/OnboardingFlow/OnboardingFlowComponents.tsx b/src/components/Employee/OnboardingFlow/OnboardingFlowComponents.tsx index ed009ac62..02dd6795c 100644 --- a/src/components/Employee/OnboardingFlow/OnboardingFlowComponents.tsx +++ b/src/components/Employee/OnboardingFlow/OnboardingFlowComponents.tsx @@ -8,17 +8,14 @@ export type { OnboardingContextInterface, OnboardingDefaultValues, } from '../OnboardingExecutionFlow/OnboardingExecutionFlowComponents' -export { - FederalTaxesContextual, - StateTaxesContextual, - DeductionsContextual, -} from '../OnboardingExecutionFlow/OnboardingExecutionFlowComponents' +/** @internal */ export const EmployeeListContextual = () => { const { companyId, onEvent } = useFlow() return } +/** @internal */ export function OnboardingExecutionFlowContextual() { const { companyId, diff --git a/src/components/Employee/OnboardingFlow/onboardingStateMachine.ts b/src/components/Employee/OnboardingFlow/onboardingStateMachine.ts index 972005ae7..529626add 100644 --- a/src/components/Employee/OnboardingFlow/onboardingStateMachine.ts +++ b/src/components/Employee/OnboardingFlow/onboardingStateMachine.ts @@ -23,6 +23,7 @@ const returnToIndex = reduce( }), ) +/** @internal */ export const employeeOnboardingMachine = { index: state( transition( diff --git a/src/components/Employee/OnboardingSummary/OnboardingSummary.tsx b/src/components/Employee/OnboardingSummary/OnboardingSummary.tsx index d3cd1ee44..79cbdca55 100644 --- a/src/components/Employee/OnboardingSummary/OnboardingSummary.tsx +++ b/src/components/Employee/OnboardingSummary/OnboardingSummary.tsx @@ -26,6 +26,12 @@ interface SummaryProps extends CommonComponentInterface<'Employee.OnboardingSumm isAdmin?: boolean } +/** + * Displays a summary of an employee's onboarding status, listing completed and + * outstanding steps. Rendered as a standalone step inside `OnboardingFlow`. + * + * @public + */ export function OnboardingSummary(props: SummaryProps & BaseComponentInterface) { useI18n('Employee.OnboardingSummary') useComponentDictionary('Employee.OnboardingSummary', props.dictionary) @@ -151,6 +157,7 @@ const Root = ({ employeeId, className, isAdmin = false }: SummaryProps) => { ) } +/** @internal */ export const OnboardingSummaryContextual = () => { const { employeeId, onEvent, isAdmin } = useFlow() const { t } = useTranslation('common') diff --git a/src/components/Employee/PaymentMethod/management/PaymentMethod.tsx b/src/components/Employee/PaymentMethod/management/PaymentMethod.tsx index e8045701f..e93bb4b34 100644 --- a/src/components/Employee/PaymentMethod/management/PaymentMethod.tsx +++ b/src/components/Employee/PaymentMethod/management/PaymentMethod.tsx @@ -18,11 +18,21 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link PaymentMethod}. + * + * @public + */ export interface PaymentMethodProps extends CommonComponentInterface<'Employee.Management.PaymentMethod'> { + /** The associated employee identifier. */ employeeId: string + /** Not used — payment method management edits live data. */ defaultValues?: never + /** Whether the current viewer is an admin. Defaults to `true`. */ isAdmin?: boolean + /** Step to render first: the list card, the add-account form, or the split-paycheck form. Defaults to `'list'`. */ initialState?: 'list' | 'add' | 'split' + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -60,6 +70,35 @@ function PaymentMethodFlow({ return } +/** + * Management flow for editing an employee's payment method. + * + * @remarks + * Orchestrates the list card, add-bank-account form, and split-paycheck form + * for an existing employee. Routes between steps based on user actions + * starting from `initialState`. Composed of the smaller standalone components + * ({@link PaymentMethodCard}, {@link PaymentMethodBankForm}, + * {@link PaymentMethodSplitForm}) which can also be used directly when an + * orchestrator other than this flow is needed. + * + * @param props - See {@link PaymentMethodProps}. + * @returns The payment method management flow. + * @public + * + * @example + * ```tsx + * import { EmployeeManagement } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function PaymentMethod({ dictionary, FallbackComponent, diff --git a/src/components/Employee/PaymentMethod/management/PaymentMethodBankForm.tsx b/src/components/Employee/PaymentMethod/management/PaymentMethodBankForm.tsx index 49c0c43e6..bfd0e3f26 100644 --- a/src/components/Employee/PaymentMethod/management/PaymentMethodBankForm.tsx +++ b/src/components/Employee/PaymentMethod/management/PaymentMethodBankForm.tsx @@ -4,18 +4,35 @@ import { useManagementBankFormDictionary } from './useFormDictionary' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link PaymentMethodBankForm}. + * + * @public + */ export interface PaymentMethodBankFormProps extends Omit { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on bank-form lifecycle events. */ onEvent: OnEventType } /** - * Standalone bank-account form for the management flow. Renders the shared - * {@link BankFormBody} and emits the per-component scoped events - * `EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_BANK_FORM_SUBMITTED` and - * `EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_BANK_FORM_CANCELLED`. Reads its copy from - * the dedicated `Employee.Management.PaymentMethodBankForm` namespace so partner - * overrides on the management bank form don't leak into the onboarding form. + * Standalone bank-account form for the management flow. + * + * @remarks + * Renders the shared bank-account form and emits per-component scoped events + * when the form is submitted or cancelled. Reads its copy from the dedicated + * `Employee.Management.PaymentMethodBankForm` namespace so partner overrides on + * the management bank form don't leak into the onboarding form. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/paymentMethod/bankForm/submitted` | Fired after the bank account is successfully created | The created bank account | + * | `employee/management/paymentMethod/bankForm/cancelled` | Fired when the user cancels the form | — | + * + * @param props - See {@link PaymentMethodBankFormProps}. + * @returns The bank-account form. + * @public */ export function PaymentMethodBankForm({ employeeId, diff --git a/src/components/Employee/PaymentMethod/management/PaymentMethodCard.tsx b/src/components/Employee/PaymentMethod/management/PaymentMethodCard.tsx index 850736911..c96028927 100644 --- a/src/components/Employee/PaymentMethod/management/PaymentMethodCard.tsx +++ b/src/components/Employee/PaymentMethod/management/PaymentMethodCard.tsx @@ -19,19 +19,36 @@ import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' import PercentCircleIcon from '@/assets/icons/percent-circle.svg?react' import TrashCanSvg from '@/assets/icons/trashcan.svg?react' +/** + * Props for {@link PaymentMethodCard}. + * + * @public + */ export interface PaymentMethodCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on card interactions. */ onEvent: OnEventType } /** - * Standalone "Payment" card. Owns its own data fetch via - * {@link usePaymentMethodList} and emits the management block's scoped events - * (`EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_*`) when the user clicks the card's - * CTAs or confirms a bank-account deletion. The card has no alert API — alert - * rendering is the orchestrator's responsibility (the block's - * `PaymentMethodCardContextual` for standalone consumption; the dashboard - * chrome for dashboard consumption). + * Standalone "Payment" card. + * + * @remarks + * Owns its own data fetch and emits the management block's scoped events + * when the user clicks the card's CTAs or confirms a bank-account deletion. + * The card has no alert API — alert rendering is the orchestrator's + * responsibility. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/paymentMethod/card/addRequested` | Fired when the user clicks the add-account CTA | — | + * | `employee/management/paymentMethod/card/splitRequested` | Fired when the user clicks the split-paycheck CTA | — | + * | `employee/management/paymentMethod/card/bankAccountDeleted` | Fired after a bank account is successfully deleted | The delete response payload | + * + * @param props - See {@link PaymentMethodCardProps}. + * @returns The "Payment" card. + * @public */ export function PaymentMethodCard(props: PaymentMethodCardProps) { return ( diff --git a/src/components/Employee/PaymentMethod/management/PaymentMethodComponents.tsx b/src/components/Employee/PaymentMethod/management/PaymentMethodComponents.tsx index 797c22600..71ac7c1f6 100644 --- a/src/components/Employee/PaymentMethod/management/PaymentMethodComponents.tsx +++ b/src/components/Employee/PaymentMethod/management/PaymentMethodComponents.tsx @@ -7,17 +7,20 @@ import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' import { componentEvents } from '@/shared/constants' +/** @internal */ export type PaymentMethodSuccessAlertCode = | 'bankAccountAdded' | 'bankAccountDeleted' | 'splitUpdated' +/** @internal */ export interface PaymentMethodContextInterface extends FlowContextInterface { employeeId: string isAdmin: boolean successAlert?: PaymentMethodSuccessAlertCode | null } +/** @internal */ export function PaymentMethodCardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.PaymentMethod') @@ -38,11 +41,13 @@ export function PaymentMethodCardContextual() { ) } +/** @internal */ export function PaymentMethodBankFormContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function PaymentMethodSplitFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/PaymentMethod/management/PaymentMethodSplitForm.tsx b/src/components/Employee/PaymentMethod/management/PaymentMethodSplitForm.tsx index 972f18dba..37429c059 100644 --- a/src/components/Employee/PaymentMethod/management/PaymentMethodSplitForm.tsx +++ b/src/components/Employee/PaymentMethod/management/PaymentMethodSplitForm.tsx @@ -4,18 +4,35 @@ import { useManagementSplitFormDictionary } from './useFormDictionary' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link PaymentMethodSplitForm}. + * + * @public + */ export interface PaymentMethodSplitFormProps extends Omit { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on split-form lifecycle events. */ onEvent: OnEventType } /** - * Standalone split-paycheck form for the management flow. Renders the shared - * {@link SplitPaymentsFormBody} and emits the per-component scoped events - * `EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_SPLIT_FORM_SUBMITTED` and - * `EMPLOYEE_MANAGEMENT_PAYMENT_METHOD_SPLIT_FORM_CANCELLED`. Reads its copy from - * the dedicated `Employee.Management.PaymentMethodSplitForm` namespace so partner - * overrides on the management split form don't leak into the onboarding form. + * Standalone split-paycheck form for the management flow. + * + * @remarks + * Renders the shared split-payments form and emits per-component scoped events + * when the form is submitted or cancelled. Reads its copy from the dedicated + * `Employee.Management.PaymentMethodSplitForm` namespace so partner overrides + * on the management split form don't leak into the onboarding form. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/paymentMethod/splitForm/submitted` | Fired after the splits are successfully saved | The updated payment method | + * | `employee/management/paymentMethod/splitForm/cancelled` | Fired when the user cancels the form | — | + * + * @param props - See {@link PaymentMethodSplitFormProps}. + * @returns The split-paycheck form. + * @public */ export function PaymentMethodSplitForm({ employeeId, diff --git a/src/components/Employee/PaymentMethod/management/paymentMethodStateMachine.ts b/src/components/Employee/PaymentMethod/management/paymentMethodStateMachine.ts index bbabd8f6e..d3656ea9f 100644 --- a/src/components/Employee/PaymentMethod/management/paymentMethodStateMachine.ts +++ b/src/components/Employee/PaymentMethod/management/paymentMethodStateMachine.ts @@ -29,6 +29,7 @@ const returnToListWithAlert = (alert: PaymentMethodSuccessAlertCode) => }), ) +/** @internal */ export const paymentMethodStateMachine = { list: state( transition( diff --git a/src/components/Employee/PaymentMethod/management/useFormDictionary.ts b/src/components/Employee/PaymentMethod/management/useFormDictionary.ts index cffffbde6..517819760 100644 --- a/src/components/Employee/PaymentMethod/management/useFormDictionary.ts +++ b/src/components/Employee/PaymentMethod/management/useFormDictionary.ts @@ -8,6 +8,8 @@ import { useI18n } from '@/i18n' * Resolves the shared `BankFormBody`'s text against management's dedicated * `Employee.Management.PaymentMethodBankForm` namespace, so partner overrides on * the management bank form don't leak into the onboarding form. + * + * @internal */ export function useManagementBankFormDictionary(): BankFormBodyDictionary { useI18n('Employee.Management.PaymentMethodBankForm') @@ -44,6 +46,8 @@ export function useManagementBankFormDictionary(): BankFormBodyDictionary { * Interpolated templates (`splitAmountLabel`, * `validations.percentageErrorWithTotal`) are passed through unresolved so the * body interpolates them at render time. + * + * @internal */ export function useManagementSplitFormDictionary(): SplitPaymentsFormBodyDictionary { useI18n('Employee.Management.PaymentMethodSplitForm') diff --git a/src/components/Employee/PaymentMethod/onboarding/BankForm.tsx b/src/components/Employee/PaymentMethod/onboarding/BankForm.tsx index e2bece237..b30b44eea 100644 --- a/src/components/Employee/PaymentMethod/onboarding/BankForm.tsx +++ b/src/components/Employee/PaymentMethod/onboarding/BankForm.tsx @@ -4,11 +4,13 @@ import { useOnboardingBankFormDictionary } from './useFormDictionary' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** @internal */ export interface BankFormProps extends Omit { employeeId: string onEvent: OnEventType } +/** @internal */ export function BankForm({ employeeId, onEvent, ...hookProps }: BankFormProps) { const dictionary = useOnboardingBankFormDictionary() diff --git a/src/components/Employee/PaymentMethod/onboarding/ListView.tsx b/src/components/Employee/PaymentMethod/onboarding/ListView.tsx index 09ac5e1f1..ef0d4583b 100644 --- a/src/components/Employee/PaymentMethod/onboarding/ListView.tsx +++ b/src/components/Employee/PaymentMethod/onboarding/ListView.tsx @@ -31,6 +31,7 @@ interface ListViewProps { onEvent: OnEventType } +/** @internal */ export function ListView({ employeeId, isAdmin, onEvent }: ListViewProps) { const paymentMethodList = usePaymentMethodList({ employeeId }) const paymentMethodForm = usePaymentMethodForm({ employeeId }) diff --git a/src/components/Employee/PaymentMethod/onboarding/PaymentMethod.tsx b/src/components/Employee/PaymentMethod/onboarding/PaymentMethod.tsx index ae4cc504a..d5ff03d6b 100644 --- a/src/components/Employee/PaymentMethod/onboarding/PaymentMethod.tsx +++ b/src/components/Employee/PaymentMethod/onboarding/PaymentMethod.tsx @@ -17,10 +17,19 @@ import { useI18n } from '@/i18n' import { ensureRequired } from '@/helpers/ensureRequired' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link PaymentMethod}. + * + * @public + */ export interface PaymentMethodProps extends CommonComponentInterface<'Employee.PaymentMethod'> { + /** The associated employee identifier. */ employeeId: string + /** Not used — onboarding payment method editing operates on live data. */ defaultValues?: never + /** Whether the current viewer is an admin. Defaults to `false`. */ isAdmin?: boolean + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -45,6 +54,39 @@ function PaymentMethodFlow({ employeeId, isAdmin = false, onEvent }: PaymentMeth return } +/** + * Onboarding step for setting up an employee's payment method. + * + * @remarks + * Lets the employee (or admin acting on their behalf) choose between Direct + * Deposit and Check, add bank accounts, and configure split-paycheck + * allocations across multiple accounts. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/paymentMethod/updated` | Fired after the payment method is saved | The updated payment method | + * | `employee/paymentMethod/done` | Fired when payment method setup is complete and the parent flow can advance | — | + * | `employee/bankAccount/created` | Fired after a bank account is successfully added | The created bank account | + * | `employee/bankAccount/deleted` | Fired after a bank account is successfully removed | — | + * + * @param props - See {@link PaymentMethodProps}. + * @returns The payment method onboarding step. + * @public + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function PaymentMethod({ dictionary, FallbackComponent, @@ -58,6 +100,7 @@ export function PaymentMethod({ ) } +/** @internal */ export function PaymentMethodContextual() { const { employeeId, onEvent, isAdmin } = useFlow() return ( diff --git a/src/components/Employee/PaymentMethod/onboarding/PaymentMethodComponents.tsx b/src/components/Employee/PaymentMethod/onboarding/PaymentMethodComponents.tsx index 20d58b239..5ad940c2c 100644 --- a/src/components/Employee/PaymentMethod/onboarding/PaymentMethodComponents.tsx +++ b/src/components/Employee/PaymentMethod/onboarding/PaymentMethodComponents.tsx @@ -4,21 +4,25 @@ import { SplitView } from './SplitView' import { useFlow } from '@/components/Flow/useFlow' import type { FlowContextInterface } from '@/components/Flow/useFlow' +/** @internal */ export interface PaymentMethodContextInterface extends FlowContextInterface { employeeId: string isAdmin: boolean } +/** @internal */ export function ListViewContextual() { const { employeeId, isAdmin, onEvent } = useFlow() return } +/** @internal */ export function BankFormContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function SplitViewContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/PaymentMethod/onboarding/SplitView.tsx b/src/components/Employee/PaymentMethod/onboarding/SplitView.tsx index e3b998145..328f5699c 100644 --- a/src/components/Employee/PaymentMethod/onboarding/SplitView.tsx +++ b/src/components/Employee/PaymentMethod/onboarding/SplitView.tsx @@ -4,11 +4,13 @@ import { useOnboardingSplitFormDictionary } from './useFormDictionary' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** @internal */ export interface SplitViewProps extends Omit { employeeId: string onEvent: OnEventType } +/** @internal */ export function SplitView({ employeeId, onEvent, ...hookProps }: SplitViewProps) { const dictionary = useOnboardingSplitFormDictionary() diff --git a/src/components/Employee/PaymentMethod/onboarding/paymentMethodStateMachine.ts b/src/components/Employee/PaymentMethod/onboarding/paymentMethodStateMachine.ts index d4a6b30aa..ebe947d5b 100644 --- a/src/components/Employee/PaymentMethod/onboarding/paymentMethodStateMachine.ts +++ b/src/components/Employee/PaymentMethod/onboarding/paymentMethodStateMachine.ts @@ -9,6 +9,7 @@ import { import { componentEvents } from '@/shared/constants' import type { MachineTransition } from '@/types/Helpers' +/** @internal */ export const paymentMethodStateMachine = { list: state( transition( diff --git a/src/components/Employee/PaymentMethod/onboarding/useFormDictionary.ts b/src/components/Employee/PaymentMethod/onboarding/useFormDictionary.ts index a9c9fac35..0aa960bab 100644 --- a/src/components/Employee/PaymentMethod/onboarding/useFormDictionary.ts +++ b/src/components/Employee/PaymentMethod/onboarding/useFormDictionary.ts @@ -10,6 +10,8 @@ import { useI18n } from '@/i18n' * `cancelAddCta` (the bank form's "Cancel" button) onto the body's `cancelCta`, * preserving backward compatibility for partners overriding the onboarding keys * through the block's `dictionary` prop. + * + * @internal */ export function useOnboardingBankFormDictionary(): BankFormBodyDictionary { useI18n('Employee.PaymentMethod') @@ -45,6 +47,8 @@ export function useOnboardingBankFormDictionary(): BankFormBodyDictionary { * (`splitAmountLabel`, `validations.percentageErrorWithTotal`) are passed * through unresolved so the body interpolates them at render time. The cancel * action maps onboarding's `cancelAddCta` onto the body's `cancelCta`. + * + * @internal */ export function useOnboardingSplitFormDictionary(): SplitPaymentsFormBodyDictionary { useI18n('Employee.PaymentMethod') diff --git a/src/components/Employee/PaymentMethod/shared/BankFormBody/BankFormBody.tsx b/src/components/Employee/PaymentMethod/shared/BankFormBody/BankFormBody.tsx index b0b836cd4..ecc0f3106 100644 --- a/src/components/Employee/PaymentMethod/shared/BankFormBody/BankFormBody.tsx +++ b/src/components/Employee/PaymentMethod/shared/BankFormBody/BankFormBody.tsx @@ -9,8 +9,10 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useComponentDictionary, useI18n } from '@/i18n' import type { ResourceDictionary } from '@/types/Helpers' +/** @internal */ export type BankFormBodyDictionary = ResourceDictionary<'Employee.BankFormBody'> +/** @internal */ export interface BankFormBodyProps extends Omit { employeeId: string /** @@ -30,6 +32,8 @@ export interface BankFormBodyProps extends Omit * `Employee.BankFormBody` namespace; consuming surfaces inject their own copy * via the `dictionary` prop and map the `onSaved`/`onCancel` callbacks onto * their surface-specific events. + * + * @internal */ export function BankFormBody({ employeeId, diff --git a/src/components/Employee/PaymentMethod/shared/BankFormBody/index.ts b/src/components/Employee/PaymentMethod/shared/BankFormBody/index.ts index 1bd42f6db..01c28c207 100644 --- a/src/components/Employee/PaymentMethod/shared/BankFormBody/index.ts +++ b/src/components/Employee/PaymentMethod/shared/BankFormBody/index.ts @@ -1 +1 @@ -export { BankFormBody, type BankFormBodyProps, type BankFormBodyDictionary } from './BankFormBody' +export { BankFormBody, type BankFormBodyDictionary } from './BankFormBody' diff --git a/src/components/Employee/PaymentMethod/shared/DeleteBankAccountDialog.tsx b/src/components/Employee/PaymentMethod/shared/DeleteBankAccountDialog.tsx index a276f936d..cfa37082e 100644 --- a/src/components/Employee/PaymentMethod/shared/DeleteBankAccountDialog.tsx +++ b/src/components/Employee/PaymentMethod/shared/DeleteBankAccountDialog.tsx @@ -5,6 +5,8 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon * Presentational confirm dialog for deleting a bank account. All copy is * passed in by the caller so each consumer owns its own translation strings * — partner overrides on one flow's namespace won't leak into another. + * + * @internal */ export function DeleteBankAccountDialog({ pendingDeleteAccount, diff --git a/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/SplitPaymentsFormBody.tsx b/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/SplitPaymentsFormBody.tsx index c60f1f32a..b56856160 100644 --- a/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/SplitPaymentsFormBody.tsx +++ b/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/SplitPaymentsFormBody.tsx @@ -18,8 +18,10 @@ import { useComponentDictionary, useI18n } from '@/i18n' import { SPLIT_BY } from '@/shared/constants' import type { ResourceDictionary } from '@/types/Helpers' +/** @internal */ export type SplitPaymentsFormBodyDictionary = ResourceDictionary<'Employee.SplitPaymentsFormBody'> +/** @internal */ export interface SplitPaymentsFormBodyProps extends UseSplitPaymentsFormProps { /** * Translation overrides for the form's strings. Each consuming surface passes @@ -38,6 +40,8 @@ export interface SplitPaymentsFormBodyProps extends UseSplitPaymentsFormProps { * Reads its copy from the internal `Employee.SplitPaymentsFormBody` namespace; * consuming surfaces inject their own copy via the `dictionary` prop and map the * `onSaved`/`onCancel` callbacks onto their surface-specific events. + * + * @internal */ export function SplitPaymentsFormBody({ dictionary, diff --git a/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/index.ts b/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/index.ts index 2cd6c1766..7e3aaf4eb 100644 --- a/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/index.ts +++ b/src/components/Employee/PaymentMethod/shared/SplitPaymentsFormBody/index.ts @@ -1,5 +1,4 @@ export { SplitPaymentsFormBody, - type SplitPaymentsFormBodyProps, type SplitPaymentsFormBodyDictionary, } from './SplitPaymentsFormBody' diff --git a/src/components/Employee/PaymentMethod/shared/useBankForm/fields.tsx b/src/components/Employee/PaymentMethod/shared/useBankForm/fields.tsx index 71e70198f..fb3bae599 100644 --- a/src/components/Employee/PaymentMethod/shared/useBankForm/fields.tsx +++ b/src/components/Employee/PaymentMethod/shared/useBankForm/fields.tsx @@ -4,42 +4,124 @@ import type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/ import { TextInputHookField, RadioGroupHookField } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * Validation error codes emitted by {@link useBankForm} fields that only emit `REQUIRED`. + * + * @public + */ export type RequiredValidation = typeof BankFormErrorCodes.REQUIRED + +/** + * Validation error codes emitted by the `routingNumber` field of {@link useBankForm}. + * + * @public + */ export type RoutingNumberValidation = (typeof BankFormErrorCodes)[keyof Pick< typeof BankFormErrorCodes, 'REQUIRED' | 'INVALID_ROUTING_NUMBER' >] + +/** + * Validation error codes emitted by the `accountNumber` field of {@link useBankForm}. + * + * @public + */ export type AccountNumberValidation = (typeof BankFormErrorCodes)[keyof Pick< typeof BankFormErrorCodes, 'REQUIRED' | 'INVALID_ACCOUNT_NUMBER' >] +/** + * Props accepted by {@link useBankForm}'s `Fields.Name` component. + * + * @public + */ export type NameFieldProps = HookFieldProps> +/** + * Text input bound to the `name` field of {@link useBankForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Name`. Captures the account + * nickname. + * + * @param props - See {@link NameFieldProps}. + * @returns The rendered text input bound to `name`. + * @public + */ export function NameField(props: NameFieldProps) { return } +/** + * Props accepted by {@link useBankForm}'s `Fields.RoutingNumber` component. + * + * @public + */ export type RoutingNumberFieldProps = HookFieldProps< TextInputHookFieldProps > +/** + * Text input bound to the `routingNumber` field of {@link useBankForm}. + * + * @remarks + * Available on the hook result as `form.Fields.RoutingNumber`. Validates the + * value against a 9-digit numeric pattern. + * + * @param props - See {@link RoutingNumberFieldProps}. + * @returns The rendered text input bound to `routingNumber`. + * @public + */ export function RoutingNumberField(props: RoutingNumberFieldProps) { return } +/** + * Props accepted by {@link useBankForm}'s `Fields.AccountNumber` component. + * + * @public + */ export type AccountNumberFieldProps = HookFieldProps< TextInputHookFieldProps > +/** + * Text input bound to the `accountNumber` field of {@link useBankForm}. + * + * @remarks + * Available on the hook result as `form.Fields.AccountNumber`. Validates the + * value against a 1–17 digit numeric pattern. + * + * @param props - See {@link AccountNumberFieldProps}. + * @returns The rendered text input bound to `accountNumber`. + * @public + */ export function AccountNumberField(props: AccountNumberFieldProps) { return } +/** + * Props accepted by {@link useBankForm}'s `Fields.AccountType` component. + * + * @public + */ export type AccountTypeFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `accountType` field of {@link useBankForm}. + * + * @remarks + * Available on the hook result as `form.Fields.AccountType`. Options are + * `Checking` and `Savings`; defaults to `Checking` when no value is supplied. + * Supply `getOptionLabel` to translate the option labels. + * + * @param props - See {@link AccountTypeFieldProps}. + * @returns The rendered radio group bound to `accountType`. + * @public + */ export function AccountTypeField(props: AccountTypeFieldProps) { return } diff --git a/src/components/Employee/PaymentMethod/shared/useBankForm/index.ts b/src/components/Employee/PaymentMethod/shared/useBankForm/index.ts index 5824d9e5a..1a6b2da96 100644 --- a/src/components/Employee/PaymentMethod/shared/useBankForm/index.ts +++ b/src/components/Employee/PaymentMethod/shared/useBankForm/index.ts @@ -6,7 +6,6 @@ export type { UseBankFormReady, BankFormFields, BankFormFieldsMetadata, - BankFormFieldsType, } from './useBankForm' export { ACCOUNT_TYPES, diff --git a/src/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.tsx b/src/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.tsx index c8da87441..2c7e3298b 100644 --- a/src/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.tsx +++ b/src/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.tsx @@ -27,34 +27,65 @@ import type { import { useBaseSubmit } from '@/components/Base/useBaseSubmit' import { SDKInternalError } from '@/types/sdkError' +/** + * Optional submit-time overrides for {@link useBankForm}'s `onSubmit`. + * + * @public + */ export interface BankFormSubmitOptions { /** Override the `employeeId` configured at hook construction. Useful when the employee is created in the same submit chain. */ employeeId?: string } +/** + * Props for {@link useBankForm}. + * + * @public + */ export interface UseBankFormProps { /** Employee for whom to create the bank account. May be supplied later via `BankFormSubmitOptions.employeeId`. */ employeeId?: string + /** Override optional fields to be required. Reserved for future schema expansion — every field is required by default. */ optionalFieldsToRequire?: BankFormOptionalFieldsToRequire + /** Pre-fill form values. `accountType` defaults to `'Checking'` when not supplied. */ defaultValues?: Partial + /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler`. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Field components exposed by {@link useBankForm} on `form.Fields`. + * + * @public + */ export interface BankFormFields { + /** Bound to `name` — see {@link NameField}. */ Name: typeof NameField + /** Bound to `routingNumber` — see {@link RoutingNumberField}. */ RoutingNumber: typeof RoutingNumberField + /** Bound to `accountNumber` — see {@link AccountNumberField}. */ AccountNumber: typeof AccountNumberField + /** Bound to `accountType` — see {@link AccountTypeField}. */ AccountType: typeof AccountTypeField } +/** + * Ready-state return value of {@link useBankForm}. + * + * @public + */ export interface UseBankFormReady extends BaseFormHookReady< FieldsMetadata, BankFormData, BankFormFields > { + /** No server-fetched data — the create form derives everything from user input. */ data: Record + /** `isPending` reflects the in-flight create mutation; `mode` is always `'create'`. */ status: { isPending: boolean; mode: 'create' } + /** Submit the form. Optional {@link BankFormSubmitOptions} can override the `employeeId` supplied to the hook. */ actions: { onSubmit: ( options?: BankFormSubmitOptions, @@ -62,6 +93,49 @@ export interface UseBankFormReady extends BaseFormHookReady< } } +/** + * Headless React Hook Form hook for creating an employee bank account. + * + * @remarks + * Captures the account nickname, routing number, account number, and account + * type. Creating a bank account also updates the employee's payment method on + * the Gusto API. Returns the standard `HookLoadingResult | UseBankFormReady` + * discriminated union; in practice the hook transitions to the ready state + * immediately because it does not fetch any server data. + * + * @param props - See {@link UseBankFormProps}. + * @returns A loading-state result while the hook is initializing, or a {@link UseBankFormReady} ready to render. + * @public + * + * @example + * ```tsx + * import { useBankForm, SDKFormProvider } from '@gusto/embedded-react-sdk' + * + * function AddBankAccount({ employeeId }: { employeeId: string }) { + * const bankForm = useBankForm({ employeeId }) + * + * if (bankForm.isLoading) return null + * const { Fields } = bankForm.form + * + * return ( + * + *
{ + * e.preventDefault() + * void bankForm.actions.onSubmit() + * }} + * > + * + * + * + * + * + * + *
+ * ) + * } + * ``` + */ export function useBankForm({ employeeId, optionalFieldsToRequire, @@ -183,6 +257,16 @@ export function useBankForm({ } } +/** + * Return type of {@link useBankForm} — a discriminated union on `isLoading`. + * + * @public + */ export type UseBankFormResult = HookLoadingResult | UseBankFormReady + +/** + * Per-field metadata exposed on `form.fieldsMetadata` for {@link useBankForm}. + * + * @public + */ export type BankFormFieldsMetadata = UseBankFormReady['form']['fieldsMetadata'] -export type BankFormFieldsType = UseBankFormReady['form']['Fields'] diff --git a/src/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.ts b/src/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.ts index 988a53841..bbc70dac5 100644 --- a/src/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.ts +++ b/src/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.ts @@ -5,18 +5,40 @@ import { type RequiredFieldConfig, } from '@/partner-hook-utils/form/buildFormSchema' +/** + * Validation error codes emitted by the bank account form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const BankFormErrorCodes = { REQUIRED: 'REQUIRED', INVALID_ROUTING_NUMBER: 'INVALID_ROUTING_NUMBER', INVALID_ACCOUNT_NUMBER: 'INVALID_ACCOUNT_NUMBER', } as const +/** + * Union of validation error code strings emitted by the bank account form + * schema. + * + * @public + */ export type BankFormErrorCode = (typeof BankFormErrorCodes)[keyof typeof BankFormErrorCodes] const ROUTING_NUMBER_REGEX = /^[0-9]{9}$/ const ACCOUNT_NUMBER_REGEX = /^[0-9]{1,17}$/ +/** + * Supported bank account type values: checking and savings. + * + * @public + */ export const ACCOUNT_TYPES = ['Checking', 'Savings'] as const +/** + * Union of bank account type values that the form accepts. + * + * @public + */ export type AccountType = (typeof ACCOUNT_TYPES)[number] const fieldValidators = { @@ -30,21 +52,44 @@ const fieldValidators = { accountType: z.enum(ACCOUNT_TYPES), } +/** + * Field names accepted by the bank account form. + * + * @public + */ export type BankFormField = keyof typeof fieldValidators +/** + * Shape of the values managed by the bank account form. + * + * @public + */ export type BankFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the bank account form on submit. + * + * @public + */ export type BankFormOutputs = BankFormData const requiredFieldsConfig = {} satisfies RequiredFieldConfig +/** + * Keys of optional bank account fields that can be promoted to required via + * the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type BankFormOptionalFieldsToRequire = OptionalFieldsToRequire +/** @internal */ interface BankFormSchemaOptions { optionalFieldsToRequire?: BankFormOptionalFieldsToRequire } +/** @internal */ export function createBankFormSchema(options: BankFormSchemaOptions = {}) { return buildFormSchema(fieldValidators, { requiredFieldsConfig, diff --git a/src/components/Employee/PaymentMethod/shared/useDeleteBankAccount.ts b/src/components/Employee/PaymentMethod/shared/useDeleteBankAccount.ts index 964dd5d40..bf04db06a 100644 --- a/src/components/Employee/PaymentMethod/shared/useDeleteBankAccount.ts +++ b/src/components/Employee/PaymentMethod/shared/useDeleteBankAccount.ts @@ -1,5 +1,6 @@ import { useState } from 'react' +/** @internal */ export function useDeleteBankAccount(handleDelete: (uuid: string) => Promise) { const [pendingDeleteAccount, setPendingDeleteAccount] = useState<{ uuid: string diff --git a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/fields.tsx b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/fields.tsx index e0319bc1b..a8d897f2b 100644 --- a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/fields.tsx +++ b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/fields.tsx @@ -3,12 +3,34 @@ import type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/ import { RadioGroupHookField } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * Validation error codes emitted by {@link usePaymentMethodForm} fields that only emit `REQUIRED`. + * + * @public + */ export type RequiredValidation = typeof PaymentMethodFormErrorCodes.REQUIRED +/** + * Props accepted by {@link usePaymentMethodForm}'s `Fields.Type` component. + * + * @public + */ export type TypeFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `type` field of {@link usePaymentMethodForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Type`. Options are + * `Direct Deposit` and `Check`; defaults to the employee's existing payment + * method type. Supply `getOptionLabel` to translate the option labels. + * + * @param props - See {@link TypeFieldProps}. + * @returns The rendered radio group bound to `type`. + * @public + */ export function TypeField(props: TypeFieldProps) { return } diff --git a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/index.ts b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/index.ts index 8da38be58..c1a60a9f8 100644 --- a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/index.ts +++ b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/index.ts @@ -5,7 +5,6 @@ export type { UsePaymentMethodFormReady, PaymentMethodFormFields, PaymentMethodFormFieldsMetadata, - PaymentMethodFormFieldsType, } from './usePaymentMethodForm' export { PAYMENT_METHOD_TYPES, @@ -19,7 +18,7 @@ export { type PaymentMethodType, } from './usePaymentMethodFormSchema' export { - TypeField, + TypeField as PaymentMethodTypeField, type TypeFieldProps, type RequiredValidation as PaymentMethodFormRequiredValidation, } from './fields' diff --git a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.tsx b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.tsx index f84684043..ea234bd65 100644 --- a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.tsx +++ b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.tsx @@ -29,32 +29,106 @@ import { useBaseSubmit } from '@/components/Base/useBaseSubmit' import { SDKInternalError } from '@/types/sdkError' import { PAYMENT_METHODS, SPLIT_BY } from '@/shared/constants' +/** + * Props for {@link usePaymentMethodForm}. + * + * @public + */ export interface UsePaymentMethodFormProps { + /** Employee whose payment method is being edited. */ employeeId: string + /** Override optional fields to be required. Reserved for future schema expansion — `type` is always required and always has a default. */ optionalFieldsToRequire?: PaymentMethodFormOptionalFieldsToRequire + /** Pre-fill form values. Server data (the current payment method) is used when no override is supplied. */ defaultValues?: Partial + /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler`. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Field components exposed by {@link usePaymentMethodForm} on `form.Fields`. + * + * @public + */ export interface PaymentMethodFormFields { + /** Bound to `type` — see {@link TypeField}. */ Type: typeof TypeField } +/** + * Ready-state return value of {@link usePaymentMethodForm}. + * + * @public + */ export interface UsePaymentMethodFormReady extends BaseFormHookReady< FieldsMetadata, PaymentMethodFormData, PaymentMethodFormFields > { + /** The employee's current payment method, loaded from the API. */ data: { paymentMethod: EmployeePaymentMethod } + /** `isPending` reflects the in-flight update mutation; `mode` is always `'update'`. */ status: { isPending: boolean; mode: 'update' } + /** Submit the form. Returns the updated payment method on success or `undefined` on validation/mutation failure. */ actions: { onSubmit: () => Promise | undefined> } } +/** + * Headless React Hook Form hook for updating an employee's payment method. + * + * @remarks + * Switches between Direct Deposit and Check. Always operates in update mode — + * every employee has a payment method, defaulting to Check. Switching to Check + * sends a minimal request body; switching to or staying on Direct Deposit + * preserves the existing splits and version so split allocations are not lost + * when only the type changes. + * + * @param props - See {@link UsePaymentMethodFormProps}. + * @returns A loading-state result while the current payment method is loading, or a {@link UsePaymentMethodFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { + * usePaymentMethodForm, + * SDKFormProvider, + * PAYMENT_METHODS, + * type PaymentMethodType, + * } from '@gusto/embedded-react-sdk' + * + * function PaymentMethodScreen({ employeeId }: { employeeId: string }) { + * const paymentMethodForm = usePaymentMethodForm({ employeeId }) + * + * if (paymentMethodForm.isLoading) return null + * const { Fields } = paymentMethodForm.form + * + * return ( + * + *
{ + * e.preventDefault() + * void paymentMethodForm.actions.onSubmit() + * }} + * > + * + * value === PAYMENT_METHODS.directDeposit ? 'Direct Deposit' : 'Check' + * } + * /> + * + * + *
+ * ) + * } + * ``` + */ export function usePaymentMethodForm({ employeeId, optionalFieldsToRequire, @@ -175,6 +249,16 @@ export function usePaymentMethodForm({ } } +/** + * Return type of {@link usePaymentMethodForm} — a discriminated union on `isLoading`. + * + * @public + */ export type UsePaymentMethodFormResult = HookLoadingResult | UsePaymentMethodFormReady + +/** + * Per-field metadata exposed on `form.fieldsMetadata` for {@link usePaymentMethodForm}. + * + * @public + */ export type PaymentMethodFormFieldsMetadata = UsePaymentMethodFormReady['form']['fieldsMetadata'] -export type PaymentMethodFormFieldsType = UsePaymentMethodFormReady['form']['Fields'] diff --git a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.ts b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.ts index 0f115c005..4222f8f57 100644 --- a/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.ts +++ b/src/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.ts @@ -6,38 +6,83 @@ import { } from '@/partner-hook-utils/form/buildFormSchema' import { PAYMENT_METHODS } from '@/shared/constants' +/** + * Validation error codes emitted by the payment method form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const PaymentMethodFormErrorCodes = { REQUIRED: 'REQUIRED', } as const +/** + * Union of validation error code strings emitted by the payment method form + * schema. + * + * @public + */ export type PaymentMethodFormErrorCode = (typeof PaymentMethodFormErrorCodes)[keyof typeof PaymentMethodFormErrorCodes] +/** + * Supported payment method type values: direct deposit and check. + * + * @public + */ export const PAYMENT_METHOD_TYPES = [PAYMENT_METHODS.directDeposit, PAYMENT_METHODS.check] as const +/** + * Union of payment method type values that the form accepts. + * + * @public + */ export type PaymentMethodType = (typeof PAYMENT_METHOD_TYPES)[number] const fieldValidators = { type: z.enum(PAYMENT_METHOD_TYPES), } +/** + * Field names accepted by the payment method form. + * + * @public + */ export type PaymentMethodFormField = keyof typeof fieldValidators +/** + * Shape of the values managed by the payment method form. + * + * @public + */ export type PaymentMethodFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the payment method form on submit. + * + * @public + */ export type PaymentMethodFormOutputs = PaymentMethodFormData const requiredFieldsConfig = {} satisfies RequiredFieldConfig +/** + * Keys of optional payment method fields that can be promoted to required via + * the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type PaymentMethodFormOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface PaymentMethodFormSchemaOptions { optionalFieldsToRequire?: PaymentMethodFormOptionalFieldsToRequire } +/** @internal */ export function createPaymentMethodFormSchema(options: PaymentMethodFormSchemaOptions = {}) { return buildFormSchema(fieldValidators, { requiredFieldsConfig, diff --git a/src/components/Employee/PaymentMethod/shared/usePaymentMethodList.ts b/src/components/Employee/PaymentMethod/shared/usePaymentMethodList.ts index b98791353..d6ea3f64a 100644 --- a/src/components/Employee/PaymentMethod/shared/usePaymentMethodList.ts +++ b/src/components/Employee/PaymentMethod/shared/usePaymentMethodList.ts @@ -10,21 +10,27 @@ import { useBaseSubmit } from '@/components/Base/useBaseSubmit' import type { BaseHookReady, HookLoadingResult, HookSubmitResult } from '@/partner-hook-utils/types' import { SPLIT_BY } from '@/shared/constants' +/** @internal */ export interface UsePaymentMethodListParams { + /** Employee whose payment method and bank accounts to load. */ employeeId: string } +/** @internal */ export interface UsePaymentMethodListReady extends BaseHookReady< { paymentMethod: EmployeePaymentMethod; bankAccounts: EmployeeBankAccount[] }, { isFetching: boolean; isPending: boolean; deletePendingBankAccountUuid?: string } > { + /** Delete a bank account by UUID. Returns the delete response on success or `undefined` on failure. */ actions: { onDelete: (bankAccountUuid: string) => Promise | undefined> } } +/** @internal */ export type UsePaymentMethodListResult = HookLoadingResult | UsePaymentMethodListReady +/** @internal */ export function usePaymentMethodList({ employeeId, }: UsePaymentMethodListParams): UsePaymentMethodListResult { diff --git a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/fields.tsx b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/fields.tsx index 87dcdade4..cb06db5e9 100644 --- a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/fields.tsx +++ b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/fields.tsx @@ -3,12 +3,34 @@ import { RadioGroupHookField } from '@/partner-hook-utils/form/fields' import type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/RadioGroupHookField' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * Validation error codes emitted by {@link useSplitPaymentsForm} fields that only emit `REQUIRED`. + * + * @public + */ export type RequiredValidation = typeof SplitPaymentsFormErrorCodes.REQUIRED +/** + * Props accepted by {@link useSplitPaymentsForm}'s `Fields.SplitBy` component. + * + * @public + */ export type SplitByFieldProps = HookFieldProps< RadioGroupHookFieldProps > +/** + * Radio group bound to the `splitBy` field of {@link useSplitPaymentsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.SplitBy`. Options are + * `Percentage` and `Amount`; defaults to the employee's existing `splitBy` or + * `Percentage`. Toggling the value resets per-split amounts. + * + * @param props - See {@link SplitByFieldProps}. + * @returns The rendered radio group bound to `splitBy`. + * @public + */ export function SplitByField(props: SplitByFieldProps) { return } diff --git a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/index.ts b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/index.ts index cbe61f803..7ab7d7fe6 100644 --- a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/index.ts +++ b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/index.ts @@ -5,7 +5,6 @@ export type { UseSplitPaymentsFormReady, SplitPaymentsFormFields, SplitPaymentsFormFieldsMetadata, - SplitPaymentsFormFieldsType, WorkingSplit, } from './useSplitPaymentsForm' export { @@ -20,7 +19,6 @@ export { type SplitByValue, } from './useSplitPaymentsFormSchema' export { - SplitByField, type SplitByFieldProps, type RequiredValidation as SplitPaymentsFormRequiredValidation, } from './fields' diff --git a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.tsx b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.tsx index 82024b75c..fc113d512 100644 --- a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.tsx +++ b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/splitFieldFactory.tsx @@ -15,6 +15,8 @@ import { SPLIT_BY } from '@/shared/constants' * (Amount mode, `value < 0`), `INVALID_PERCENTAGE` (Percentage mode, non-integer * or out of `0..100`). Supply translations for all three via `validationMessages`. * The sum-to-100 invariant is surfaced separately via `status.hasPercentageImbalance`. + * + * @public */ export type SplitFieldValidation = | typeof SplitPaymentsFormErrorCodes.REQUIRED @@ -27,22 +29,43 @@ export type SplitFieldValidation = * formats values as currency in Amount mode and as a percentage in * Percentage mode. The remainder split is auto-disabled and treated as not * required by the hook; the rest are required. + * + * @public */ export interface SplitFieldProps { + /** Label shown above the input. */ label: string + /** Optional descriptive text rendered below the label. */ description?: ReactNode + /** Pass-through of the parent form hook result for cross-field validation context. */ formHookResult?: FormHookResult + /** Override the default localized validation message(s). */ validationMessages?: ValidationMessages + /** Forwarded to the underlying number input. */ min?: NumberInputProps['min'] + /** Forwarded to the underlying number input. */ max?: NumberInputProps['max'] + /** Forwarded to the underlying number input. */ placeholder?: NumberInputProps['placeholder'] + /** Override the rendered number input component. */ FieldComponent?: ComponentType } +/** + * Single per-account entry surfaced on `form.Fields.splits`. Each entry + * carries identifying metadata for the underlying bank account plus the bound + * Field component for its split amount. + * + * @public + */ export interface SplitFieldEntry { + /** Bank account uuid that this split targets. */ uuid: string + /** Display name of the bank account, when available. */ name: string | null + /** Last-four masking string for the bank account number, when available. */ hiddenAccountNumber: string | null + /** Bound Field component for this split's amount input. */ Field: ComponentType } @@ -93,6 +116,8 @@ function createBoundSplitField(uuid: string): ComponentType { * memoizing on the stable set of split uuids so Field identity stays stable * across mode toggles and reorders — those changes are observed inside each * Field rather than baked into the closure. + * + * @internal */ export function buildSplitFieldEntries(splits: BuildSplitFieldsInput[]): SplitFieldEntry[] { return splits.map(split => ({ diff --git a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.tsx b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.tsx index 25c4f3687..8c0367416 100644 --- a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.tsx +++ b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.tsx @@ -36,56 +36,100 @@ import { SDKInternalError } from '@/types/sdkError' import { centsToDollars, dollarsToCents } from '@/helpers/currencyHelpers' import { PAYMENT_METHODS, SPLIT_BY } from '@/shared/constants' +/** + * A single split entry — pairs a bank account identifier with its current split allocation. + * + * @remarks + * Surfaced on `data.splits` from {@link useSplitPaymentsForm}. Derived from + * `paymentMethod.splits` when present, otherwise from the employee's bank + * accounts (one entry per account, no allocated amount). Carries the raw + * domain data — use it for label construction or lookups by uuid. + * + * @public + */ export interface WorkingSplit { + /** UUID of the underlying bank account. */ uuid: string + /** Account nickname, when available. */ name: string | null + /** Masked account number suffix, when available. */ hiddenAccountNumber: string | null + /** Allocation amount — `null` for the remainder split in Amount mode and for splits that haven't been allocated yet. */ splitAmount: number | null + /** Ordering value — splits are processed in ascending priority; the highest priority is the remainder. */ priority: number } +/** + * Props for {@link useSplitPaymentsForm}. + * + * @public + */ export interface UseSplitPaymentsFormProps { + /** Employee whose payment splits are being edited. */ employeeId: string + /** Override optional fields to be required. Currently a no-op — `splitBy` and `priority` are always required, and per-split `splitAmount` required-ness is automatic. */ optionalFieldsToRequire?: SplitPaymentsFormOptionalFieldsToRequire + /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler`. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Field components exposed by {@link useSplitPaymentsForm} on `form.Fields`. + * + * @public + */ export interface SplitPaymentsFormFields { + /** Bound to `splitBy` — see {@link SplitByField}. */ SplitBy: ComponentType + /** One entry per bank account, each carrying a pre-bound `Field` component for the per-split amount. */ splits: SplitFieldEntry[] } +/** + * Ready-state return value of {@link useSplitPaymentsForm}. + * + * @public + */ export interface UseSplitPaymentsFormReady extends BaseFormHookReady< FieldsMetadata, SplitPaymentsFormData, SplitPaymentsFormFields > { + /** Server-fetched data and derived working values. */ data: { + /** The employee's current payment method. */ paymentMethod: EmployeePaymentMethod + /** All bank accounts available to allocate splits across. */ bankAccounts: EmployeeBankAccount[] + /** The current working split entries, one per bank account. */ splits: WorkingSplit[] /** UUID of the split that absorbs the remainder in Amount mode (always the last by priority). */ remainderId: string } + /** Submission state and reactive form-level flags. */ status: { + /** `true` while the update mutation is in flight. */ isPending: boolean + /** Always `'update'` — the hook always edits an existing payment method. */ mode: 'update' /** Current `splitBy` value, reactively tracked. */ splitBy: SplitByValue /** Live sum of `splitAmount` values; useful for displaying the current total in Percentage mode. */ percentageTotal: number /** - * Mirrors the schema-emitted `PERCENTAGE_TOTAL_MISMATCH` error at the - * synthetic form path. Tracks `formState.errors` directly and follows - * the standard react-hook-form validation lifecycle: with the default - * `validationMode: 'onSubmit'`, becomes `true` after the first failed - * Save attempt and clears live as the user corrects the total. Only - * surfaces in Percentage mode. + * `true` after a failed Percentage-mode Save when the splits don't sum to + * 100; clears live as the user corrects the total. Follows the standard + * react-hook-form validation lifecycle (controlled by `validationMode`). + * Only surfaces in Percentage mode. */ hasPercentageImbalance: boolean } + /** Actions that mutate the form or submit it. */ actions: { + /** Submit the form. Returns the updated payment method on success or `undefined` on validation/mutation failure. */ onSubmit: () => Promise | undefined> /** * Reorder splits by uuid (Amount mode). Pass the ordered list of split @@ -119,6 +163,70 @@ const buildWorkingSplits = ( })) } +/** + * Headless React Hook Form hook for splitting an employee's Direct Deposit across multiple bank accounts. + * + * @remarks + * Supports two split modes: Percentage (whole-number shares that sum to 100) + * and Amount (dollar amounts, with the last-priority split absorbing the + * remainder). Always operates in update mode against the employee's existing + * payment method. + * + * The Percentage sum-to-100 invariant is surfaced via + * `status.hasPercentageImbalance` (not as a per-field error). With the default + * `validationMode: 'onSubmit'`, the imbalance flag appears after the first + * failed Save and clears live as the user corrects the total. + * + * @param props - See {@link UseSplitPaymentsFormProps}. + * @returns A loading-state result while the payment method and bank accounts are loading, or a {@link UseSplitPaymentsFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { + * useSplitPaymentsForm, + * SDKFormProvider, + * type SplitByValue, + * type UseSplitPaymentsFormReady, + * } from '@gusto/embedded-react-sdk' + * + * function SplitPaycheckScreen({ employeeId }: { employeeId: string }) { + * const splitForm = useSplitPaymentsForm({ employeeId }) + * + * if (splitForm.isLoading) return null + * return + * } + * + * function SplitPaycheckReady({ splitForm }: { splitForm: UseSplitPaymentsFormReady }) { + * const { Fields } = splitForm.form + * const { hasPercentageImbalance, percentageTotal } = splitForm.status + * + * return ( + * + *
{ + * e.preventDefault() + * void splitForm.actions.onSubmit() + * }} + * > + * {hasPercentageImbalance && ( + *
Splits must total 100%. Currently {percentageTotal}%.
+ * )} + * value} /> + * {Fields.splits.map(split => ( + * + * ))} + * + * + *
+ * ) + * } + * ``` + */ export function useSplitPaymentsForm({ employeeId, optionalFieldsToRequire, @@ -434,6 +542,16 @@ export function useSplitPaymentsForm({ } } +/** + * Return type of {@link useSplitPaymentsForm} — a discriminated union on `isLoading`. + * + * @public + */ export type UseSplitPaymentsFormResult = HookLoadingResult | UseSplitPaymentsFormReady + +/** + * Per-field metadata exposed on `form.fieldsMetadata` for {@link useSplitPaymentsForm}. + * + * @public + */ export type SplitPaymentsFormFieldsMetadata = UseSplitPaymentsFormReady['form']['fieldsMetadata'] -export type SplitPaymentsFormFieldsType = UseSplitPaymentsFormReady['form']['Fields'] diff --git a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsFormSchema.ts b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsFormSchema.ts index eff9a230f..39952e1b5 100644 --- a/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsFormSchema.ts +++ b/src/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsFormSchema.ts @@ -6,6 +6,12 @@ import { } from '@/partner-hook-utils/form/buildFormSchema' import { SPLIT_BY } from '@/shared/constants' +/** + * Validation error codes emitted by the split payments form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const SplitPaymentsFormErrorCodes = { REQUIRED: 'REQUIRED', INVALID_PERCENTAGE: 'INVALID_PERCENTAGE', @@ -18,13 +24,32 @@ export const SplitPaymentsFormErrorCodes = { * Synthetic form path where the schema emits the percentage-sum-to-100 * invariant. The hook subscribes to errors at this path to drive * `status.hasPercentageImbalance`. + * + * @internal */ export const PERCENTAGE_TOTAL_PATH = 'percentageTotal' as const +/** + * Union of validation error code strings emitted by the split payments form + * schema. + * + * @public + */ export type SplitPaymentsFormErrorCode = (typeof SplitPaymentsFormErrorCodes)[keyof typeof SplitPaymentsFormErrorCodes] +/** + * Supported split-by modes: split by percentage of net pay, or by fixed dollar + * amount per account. + * + * @public + */ export const SPLIT_BY_VALUES = [SPLIT_BY.percentage, SPLIT_BY.amount] as const +/** + * Union of split-by mode values that the form accepts. + * + * @public + */ export type SplitByValue = (typeof SPLIT_BY_VALUES)[number] // Cleared NumberInput emits `NaN`. Normalize NaN to `null` at the schema @@ -42,21 +67,47 @@ const fieldValidators = { priority: z.record(z.string(), z.number()), } +/** + * Field names accepted by the split payments form. + * + * @public + */ export type SplitPaymentsFormField = keyof typeof fieldValidators +/** + * Shape of the values managed by the split payments form. `splitAmount` and + * `priority` are keyed by bank account uuid. + * + * @public + */ export type SplitPaymentsFormData = { + /** Selected split mode — by percentage or by fixed amount. */ splitBy: SplitByValue + /** Per-account split values keyed by bank account uuid (percent or dollars depending on `splitBy`). */ splitAmount: Record + /** Per-account priority values keyed by bank account uuid; the highest priority receives the remainder. */ priority: Record } +/** + * Shape of the validated values produced by the split payments form on submit. + * + * @public + */ export type SplitPaymentsFormOutputs = SplitPaymentsFormData const requiredFieldsConfig = {} satisfies RequiredFieldConfig +/** + * Keys of optional split payments fields that can be promoted to required via + * the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type SplitPaymentsFormOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface SplitPaymentsFormSchemaOptions { optionalFieldsToRequire?: SplitPaymentsFormOptionalFieldsToRequire } @@ -66,7 +117,7 @@ interface SplitPaymentsFormSchemaOptions { * Exported so the hook can mirror the same selection rule when deriving * dynamic field metadata. */ -export function resolveRemainderUuid(priority: Record): string { +function resolveRemainderUuid(priority: Record): string { return Object.entries(priority).reduce((maxId, [uuid, value]) => { if (!maxId) return uuid const currentMax = priority[maxId] ?? 0 @@ -74,6 +125,7 @@ export function resolveRemainderUuid(priority: Record): string { }, '') } +/** @internal */ export function createSplitPaymentsFormSchema(options: SplitPaymentsFormSchemaOptions = {}) { return buildFormSchema(fieldValidators, { requiredFieldsConfig, diff --git a/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx b/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx index a93ec2ade..f46b68f83 100644 --- a/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx +++ b/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx @@ -21,8 +21,15 @@ import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' import DownloadCloudIcon from '@/assets/icons/download-cloud.svg?react' +/** + * Props for {@link PaystubsCard}. + * + * @public + */ export interface PaystubsCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when paystub interactions occur. */ onEvent: OnEventType } @@ -34,6 +41,8 @@ export interface PaystubsCardProps { * download success. The card has no edit transitions and no alert API — * paystubs is a read-only surface whose only action is a download side * effect that opens the PDF in a new tab. + * + * @public */ export function PaystubsCard(props: PaystubsCardProps) { return ( diff --git a/src/components/Employee/Paystubs/shared/index.ts b/src/components/Employee/Paystubs/shared/index.ts deleted file mode 100644 index 2499de057..000000000 --- a/src/components/Employee/Paystubs/shared/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { usePaystubsList } from './usePaystubsList' -export type { - UsePaystubsListParams, - UsePaystubsListResult, - UsePaystubsListReady, - EmployeePayStub, -} from './usePaystubsList' diff --git a/src/components/Employee/Paystubs/shared/usePaystubsList/index.ts b/src/components/Employee/Paystubs/shared/usePaystubsList/index.ts index 2499de057..5b7c2b474 100644 --- a/src/components/Employee/Paystubs/shared/usePaystubsList/index.ts +++ b/src/components/Employee/Paystubs/shared/usePaystubsList/index.ts @@ -1,7 +1,2 @@ export { usePaystubsList } from './usePaystubsList' -export type { - UsePaystubsListParams, - UsePaystubsListResult, - UsePaystubsListReady, - EmployeePayStub, -} from './usePaystubsList' +export type { UsePaystubsListReady, EmployeePayStub } from './usePaystubsList' diff --git a/src/components/Employee/Paystubs/shared/usePaystubsList/usePaystubsList.ts b/src/components/Employee/Paystubs/shared/usePaystubsList/usePaystubsList.ts index 1b430dce4..1317255fe 100644 --- a/src/components/Employee/Paystubs/shared/usePaystubsList/usePaystubsList.ts +++ b/src/components/Employee/Paystubs/shared/usePaystubsList/usePaystubsList.ts @@ -13,21 +13,39 @@ import type { PaginationItemsPerPage, } from '@/components/Common/PaginationControl/PaginationControlTypes' +/** + * A single paystub entry returned by {@link usePaystubsList}. + * + * @public + */ export type EmployeePayStub = NonNullable< GetV1EmployeesEmployeeUuidPayStubsResponse['employeePayStubsList'] >[number] +/** + * Parameters for {@link usePaystubsList}. + * + * @public + */ export interface UsePaystubsListParams { + /** The associated employee identifier. */ employeeId: string /** Items per page for the paystubs list. Defaults to 10. */ defaultItemsPerPage?: PaginationItemsPerPage } +/** + * Ready-state shape returned by {@link usePaystubsList} once data has loaded. + * + * @public + */ export interface UsePaystubsListReady extends BaseHookReady< { payStubs: EmployeePayStub[] }, { isFetching: boolean; isPending: boolean } > { + /** Pagination controls for the paystubs list. */ pagination: { payStubs?: PaginationControlProps } + /** Actions exposed by the hook. */ actions: { /** Fetch the paystub PDF for the given payroll. Returns a Blob on success * so the caller decides how to surface it (open in a new tab, save to @@ -36,6 +54,11 @@ export interface UsePaystubsListReady extends BaseHookReady< } } +/** + * Return type of {@link usePaystubsList}. + * + * @public + */ export type UsePaystubsListResult = HookLoadingResult | UsePaystubsListReady /** @@ -43,6 +66,8 @@ export type UsePaystubsListResult = HookLoadingResult | UsePaystubsListReady * paystubs and an action to download an individual paystub PDF. Used by the * standalone `PaystubsCard` component and consumable directly by partners * building a fully custom paystubs UI. + * + * @public */ export function usePaystubsList({ employeeId, diff --git a/src/components/Employee/Profile/management/Profile.tsx b/src/components/Employee/Profile/management/Profile.tsx index 2e4f6863f..0bd8aad8a 100644 --- a/src/components/Employee/Profile/management/Profile.tsx +++ b/src/components/Employee/Profile/management/Profile.tsx @@ -13,8 +13,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link Profile}. + * + * @public + */ export interface ProfileProps extends CommonComponentInterface<'Employee.Management.Profile'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -35,6 +42,24 @@ function ProfileFlow({ employeeId, onEvent }: ProfileProps) { return } +/** + * Management surface for viewing and editing an employee's basic profile details after onboarding. + * + * @remarks + * Drives the read-view card and edit form via an internal state machine. + * Emits events on the supplied `onEvent` handler when the user requests an + * edit, saves changes, or cancels. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/profile/editRequested` | Fired when the user clicks Edit on the read-view card | `{ employeeId: string }` | + * | `employee/management/profile/updated` | Fired after the profile is successfully saved | {@link Employee} | + * | `employee/management/profile/editCancelled` | Fired when the user cancels editing | — | + * + * @param props - See {@link ProfileProps}. + * @returns The employee profile management surface. + * @public + */ export function Profile({ dictionary, FallbackComponent, diff --git a/src/components/Employee/Profile/management/ProfileCard/ProfileCard.tsx b/src/components/Employee/Profile/management/ProfileCard/ProfileCard.tsx index de4865b9f..5e7466ff9 100644 --- a/src/components/Employee/Profile/management/ProfileCard/ProfileCard.tsx +++ b/src/components/Employee/Profile/management/ProfileCard/ProfileCard.tsx @@ -9,18 +9,34 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link ProfileCard}. + * + * @public + */ export interface ProfileCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the user requests to edit the profile. */ onEvent: OnEventType } /** - * Standalone "Basic details" card. Owns its own data fetch via - * `useEmployeeProfileSummary` and emits - * `EMPLOYEE_MANAGEMENT_PROFILE_EDIT_REQUESTED` when the Edit button is - * clicked. The card has no alert API — alert rendering is the - * orchestrator's responsibility (block's `CardContextual` for standalone - * consumption, dashboard chrome for dashboard consumption). + * Read-only card showing an employee's basic profile details with an Edit action. + * + * @remarks + * Standalone card that fetches its own data. Emits an event when the user + * clicks Edit so the parent can switch to the edit form. The card does not + * render success or error alerts itself — alert presentation is the + * surrounding surface's responsibility. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/profile/editRequested` | Fired when the user clicks the Edit button | `{ employeeId: string }` | + * + * @param props - See {@link ProfileCardProps}. + * @returns The basic-details profile card. + * @public */ export function ProfileCard(props: ProfileCardProps) { return ( diff --git a/src/components/Employee/Profile/management/ProfileComponents.tsx b/src/components/Employee/Profile/management/ProfileComponents.tsx index 159022d0b..1bcfeb579 100644 --- a/src/components/Employee/Profile/management/ProfileComponents.tsx +++ b/src/components/Employee/Profile/management/ProfileComponents.tsx @@ -7,13 +7,15 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { ensureRequired } from '@/helpers/ensureRequired' import { componentEvents } from '@/shared/constants' -export type ProfileSuccessAlertCode = 'profileUpdated' +type ProfileSuccessAlertCode = 'profileUpdated' +/** @internal */ export interface ProfileContextInterface extends FlowContextInterface { employeeId?: string successAlert?: ProfileSuccessAlertCode | null } +/** @internal */ export function CardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.Profile') @@ -34,6 +36,7 @@ export function CardContextual() { ) } +/** @internal */ export function ProfileEditFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/Profile/management/ProfileEditForm.tsx b/src/components/Employee/Profile/management/ProfileEditForm.tsx index 3448885a6..a47af56ba 100644 --- a/src/components/Employee/Profile/management/ProfileEditForm.tsx +++ b/src/components/Employee/Profile/management/ProfileEditForm.tsx @@ -17,11 +17,36 @@ import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** + * Props for {@link ProfileEditForm}. + * + * @public + */ export interface ProfileEditFormProps extends CommonComponentInterface<'Employee.Management.Profile'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the user saves changes or cancels editing. */ onEvent: BaseComponentInterface['onEvent'] } +/** + * Standalone edit form for an employee's basic profile details. + * + * @remarks + * Renders fields for first name, middle initial, last name, email, SSN, and + * date of birth — all required on update — and shows a success alert when + * the save completes. Save and Cancel both emit events so the parent can + * return to the read view. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/profile/updated` | Fired after the employee profile is successfully saved | {@link Employee} | + * | `employee/management/profile/editCancelled` | Fired when the user clicks Cancel | — | + * + * @param input - See {@link ProfileEditFormProps}. + * @returns The employee profile edit form. + * @public + */ export function ProfileEditForm({ FallbackComponent, ...props diff --git a/src/components/Employee/Profile/management/profileStateMachine.ts b/src/components/Employee/Profile/management/profileStateMachine.ts index 8011a030a..c3d63da4b 100644 --- a/src/components/Employee/Profile/management/profileStateMachine.ts +++ b/src/components/Employee/Profile/management/profileStateMachine.ts @@ -22,6 +22,7 @@ const returnToCardWithAlert = (alert: ProfileContextInterface['successAlert']) = }), ) +/** @internal */ export const profileStateMachine = { card: state( transition( diff --git a/src/components/Employee/Profile/onboarding/AdminProfile.tsx b/src/components/Employee/Profile/onboarding/AdminProfile.tsx index 296a87761..8585e3586 100644 --- a/src/components/Employee/Profile/onboarding/AdminProfile.tsx +++ b/src/components/Employee/Profile/onboarding/AdminProfile.tsx @@ -48,6 +48,7 @@ function computeOptionalFieldsToRequire( } } +/** @internal */ export function AdminProfile({ companyId, employeeId, diff --git a/src/components/Employee/Profile/onboarding/EmployeeProfile.tsx b/src/components/Employee/Profile/onboarding/EmployeeProfile.tsx index 7d5f39e5d..8529d2ff5 100644 --- a/src/components/Employee/Profile/onboarding/EmployeeProfile.tsx +++ b/src/components/Employee/Profile/onboarding/EmployeeProfile.tsx @@ -25,6 +25,7 @@ const SELF_OPTIONAL_FIELDS: EmployeeDetailsOptionalFieldsToRequire = { update: ['firstName', 'lastName', 'dateOfBirth', 'ssn'], } +/** @internal */ export function EmployeeProfile({ companyId, employeeId, diff --git a/src/components/Employee/Profile/onboarding/Profile.tsx b/src/components/Employee/Profile/onboarding/Profile.tsx index cd97e9f93..684a9c6b1 100644 --- a/src/components/Employee/Profile/onboarding/Profile.tsx +++ b/src/components/Employee/Profile/onboarding/Profile.tsx @@ -10,33 +10,93 @@ import type { RequireAtLeastOne } from '@/types/Helpers' import { useFlow } from '@/components/Flow/useFlow' import { ensureRequired } from '@/helpers/ensureRequired' +/** + * Pre-fill values for the {@link Profile} onboarding step. + * + * @remarks + * At least one of the listed fields must be provided. When employee data is + * already available via the API, those values take precedence over the + * defaults. + * + * @public + */ export type ProfileDefaultValues = RequireAtLeastOne<{ + /** Pre-fill values for the employee details section. At least one nested field must be set. */ employee?: RequireAtLeastOne<{ + /** The employee's first name. */ firstName?: string + /** The employee's middle initial. */ middleInitial?: string + /** The employee's last name. */ lastName?: string + /** The employee's personal email address. */ email?: string + /** The employee's date of birth as an ISO date string (`YYYY-MM-DD`). */ dateOfBirth?: string }> + /** Pre-fill values for the home address section. At least one nested field must be set. */ homeAddress?: RequireAtLeastOne<{ + /** First line of the street address. */ street1?: string + /** Second line of the street address (optional). */ street2?: string + /** City. */ city?: string + /** Two-letter state abbreviation. */ state?: string + /** ZIP code. */ zip?: string }> + /** When `true`, the admin form opens with the self-onboarding toggle enabled by default in create mode. */ inviteEmployeeDefault?: boolean }> +/** + * Props for {@link Profile}. + * + * @public + */ export interface ProfileProps extends CommonComponentInterface<'Employee.Profile'> { + /** The associated employee identifier. Omit to create a new employee. */ employeeId?: string + /** The associated company identifier. */ companyId: string + /** Pre-fill values for the form fields. */ defaultValues?: ProfileDefaultValues + /** When `true`, renders the admin variant (collects work address, start date, and self-onboarding toggle). Defaults to `false`. */ isAdmin?: boolean + /** When `true`, the admin variant exposes the self-onboarding toggle. Defaults to `true`. */ isSelfOnboardingEnabled?: boolean + /** Event handler fired on profile creation, update, and address changes. */ onEvent: BaseComponentInterface['onEvent'] } +/** + * Onboarding step for collecting an employee's basic profile and addresses. + * + * @remarks + * Switches between an admin-facing variant (collects employee details, + * work address, start date, and an optional self-onboarding invitation + * toggle) and an employee-facing variant (collects employee details and + * home address only — the active work address is read-only) based on + * `isAdmin`. Both variants create the employee on submit when `employeeId` + * is omitted. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/created` | Fired after an employee is successfully created | {@link Employee} | + * | `employee/updated` | Fired after an employee is successfully updated | {@link Employee} | + * | `employee/onboardingStatus/updated` | Fired when toggling self-onboarding changes the employee's onboarding status (admin variant) | The updated onboarding status | + * | `employee/homeAddress/created` | Fired after the home address is created | {@link EmployeeAddress} | + * | `employee/homeAddress/updated` | Fired after the home address is updated | {@link EmployeeAddress} | + * | `employee/workAddress/created` | Fired after the work address is created (admin variant) | {@link EmployeeWorkAddress} | + * | `employee/workAddress/updated` | Fired after the work address is updated (admin variant) | {@link EmployeeWorkAddress} | + * | `employee/profile/done` | Fired when all profile saves complete and the parent flow can advance | {@link Employee} extended with `startDate` (admin variant) | + * + * @param input - See {@link ProfileProps}. + * @returns The employee profile onboarding step. + * @public + */ export function Profile({ FallbackComponent, isAdmin = false, @@ -49,6 +109,7 @@ export function Profile({ ) } +/** @internal */ export const ProfileContextual = () => { const { companyId, employeeId, onEvent, isAdmin, defaultValues, isSelfOnboardingEnabled } = useFlow() diff --git a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.ts b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.ts index 20bad41ef..7ac8e79e4 100644 --- a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.ts +++ b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.ts @@ -8,6 +8,13 @@ import { SSN_REGEX, NAME_REGEX } from '@/helpers/validations' // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the employee details form schema. Map + * these codes to localized copy in `validationMessages` when composing the + * hook. + * + * @public + */ export const EmployeeDetailsErrorCodes = { REQUIRED: 'REQUIRED', INVALID_NAME: 'INVALID_NAME', @@ -16,6 +23,12 @@ export const EmployeeDetailsErrorCodes = { EMAIL_REQUIRED_FOR_SELF_ONBOARDING: 'EMAIL_REQUIRED_FOR_SELF_ONBOARDING', } as const +/** + * Union of validation error code strings emitted by the employee details form + * schema. + * + * @public + */ export type EmployeeDetailsErrorCode = (typeof EmployeeDetailsErrorCodes)[keyof typeof EmployeeDetailsErrorCodes] @@ -46,11 +59,27 @@ const fieldValidators = { selfOnboarding: z.boolean(), } +/** + * Field names accepted by the employee details form. + * + * @public + */ export type EmployeeDetailsField = Exclude +/** + * Shape of the values managed by the employee details form. + * + * @public + */ export type EmployeeDetailsFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the employee details form on + * submit. + * + * @public + */ export type EmployeeDetailsFormOutputs = EmployeeDetailsFormData // ── Required fields config ───────────────────────────────────────────── @@ -66,16 +95,24 @@ const requiredFieldsConfig = { // ── Schema factory ───────────────────────────────────────────────────── +/** + * Keys of optional employee details fields that can be promoted to required + * via the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type EmployeeDetailsOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface EmployeeDetailsSchemaOptions { mode?: 'create' | 'update' optionalFieldsToRequire?: EmployeeDetailsOptionalFieldsToRequire hasSsn?: boolean } +/** @internal */ export function createEmployeeDetailsSchema(options: EmployeeDetailsSchemaOptions = {}) { const { mode = 'create', optionalFieldsToRequire, hasSsn = false } = options diff --git a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.tsx b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.tsx index bf3938bee..b07c26e58 100644 --- a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.tsx +++ b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/fields.tsx @@ -11,49 +11,202 @@ import { useFormFieldsMetadataContext } from '@/partner-hook-utils/form/FormFiel import type { HookFieldProps } from '@/partner-hook-utils/types' import { normalizeSSN, usePlaceholderSSN } from '@/helpers/ssn' +/** + * The required-field error code produced by {@link useEmployeeDetailsForm} fields that only emit `REQUIRED`. + * + * @remarks + * Used as the `validationMessages` key for the middle initial and date of + * birth fields. See {@link EmployeeDetailsErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof EmployeeDetailsErrorCodes.REQUIRED + +/** + * Validation error codes emitted by the name fields of {@link useEmployeeDetailsForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.FirstName` and + * `Fields.LastName`. See {@link EmployeeDetailsErrorCodes} for the full + * description of each code. + * + * @public + */ export type NameValidation = (typeof EmployeeDetailsErrorCodes)['REQUIRED' | 'INVALID_NAME'] + +/** + * Validation error codes emitted by the `email` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.Email`. The + * `EMAIL_REQUIRED_FOR_SELF_ONBOARDING` code fires when self-onboarding is + * enabled but the email is empty (create mode only). See + * {@link EmployeeDetailsErrorCodes}. + * + * @public + */ export type EmailValidation = (typeof EmployeeDetailsErrorCodes)[ | 'REQUIRED' | 'INVALID_EMAIL' | 'EMAIL_REQUIRED_FOR_SELF_ONBOARDING'] + +/** + * The format-validation error code emitted by the `ssn` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Use as a key in `validationMessages` on `Fields.Ssn`. See + * {@link EmployeeDetailsErrorCodes}. + * + * @public + */ export type SsnValidation = typeof EmployeeDetailsErrorCodes.INVALID_SSN + +/** + * The required-field error code for the `ssn` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * The required rule is automatically waived when the employee already has + * an SSN on file, even if `ssn` is included in `optionalFieldsToRequire`. + * + * @public + */ export type SsnRequiredValidation = typeof EmployeeDetailsErrorCodes.REQUIRED +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.FirstName` component. + * + * @public + */ export type FirstNameFieldProps = HookFieldProps> +/** + * Text input bound to the `firstName` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.FirstName`. Required on + * create; can be made required on update via `optionalFieldsToRequire`. + * + * @param props - {@link FirstNameFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `firstName`. + * @public + */ export function FirstNameField(props: FirstNameFieldProps) { return } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.MiddleInitial` component. + * + * @public + */ export type MiddleInitialFieldProps = HookFieldProps> +/** + * Text input bound to the `middleInitial` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.MiddleInitial`. Always + * optional. + * + * @param props - {@link MiddleInitialFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `middleInitial`. + * @public + */ export function MiddleInitialField(props: MiddleInitialFieldProps) { return } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.LastName` component. + * + * @public + */ export type LastNameFieldProps = HookFieldProps> +/** + * Text input bound to the `lastName` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.LastName`. Required on + * create; can be made required on update via `optionalFieldsToRequire`. + * + * @param props - {@link LastNameFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `lastName`. + * @public + */ export function LastNameField(props: LastNameFieldProps) { return } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.Email` component. + * + * @public + */ export type EmailFieldProps = HookFieldProps> +/** + * Text input bound to the `email` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Email`. Optional by default + * — opt in via `optionalFieldsToRequire`. Also enforces a required rule + * whenever the self-onboarding toggle is enabled in create mode, reported + * via the `EMAIL_REQUIRED_FOR_SELF_ONBOARDING` code. + * + * @param props - {@link EmailFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `email`. + * @public + */ export function EmailField(props: EmailFieldProps) { return } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.DateOfBirth` component. + * + * @public + */ export type DateOfBirthFieldProps = HookFieldProps> +/** + * Date picker bound to the `dateOfBirth` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.DateOfBirth`. Optional by + * default — opt in via `optionalFieldsToRequire`. + * + * @param props - {@link DateOfBirthFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered date picker bound to `dateOfBirth`. + * @public + */ export function DateOfBirthField(props: DateOfBirthFieldProps) { return } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.Ssn` component. + * + * @public + */ export type SsnFieldProps = HookFieldProps< TextInputHookFieldProps > +/** + * Text input bound to the `ssn` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Ssn`. Auto-formats input + * with dashes (`XXX-XX-XXXX`). When the employee already has an SSN on + * file, the field shows a masked placeholder and the required rule is + * automatically waived even if `ssn` is listed in + * `optionalFieldsToRequire`. + * + * @param props - {@link SsnFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `ssn`. + * @public + */ export function SsnField(props: SsnFieldProps) { const metadataContext = useFormFieldsMetadataContext() const metadata = props.formHookResult?.form.fieldsMetadata ?? metadataContext?.metadata ?? {} @@ -68,8 +221,29 @@ export function SsnField(props: SsnFieldProps) { ) } +/** + * Props accepted by {@link useEmployeeDetailsForm}'s `Fields.SelfOnboarding` component. + * + * @public + */ export type SelfOnboardingFieldProps = HookFieldProps +/** + * Switch bound to the `selfOnboarding` field of {@link useEmployeeDetailsForm}. + * + * @remarks + * Available on the hook result as `form.Fields.SelfOnboarding` when the + * field is toggleable. The field is `undefined` when + * `withSelfOnboardingField` is `false`, or when the employee's + * onboarding status no longer allows toggling (e.g. self-onboarding is + * already in progress or completed). Always null-check before rendering. + * When enabled, the employee receives an invitation to enter their own + * personal, tax, and banking details. + * + * @param props - {@link SelfOnboardingFieldProps} — accepts the standard hook field props (label, description, FieldComponent override). + * @returns The rendered switch bound to `selfOnboarding`. + * @public + */ export function SelfOnboardingField(props: SelfOnboardingFieldProps) { return } diff --git a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/index.ts b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/index.ts index 81d971303..2a6d1d13b 100644 --- a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/index.ts +++ b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/index.ts @@ -2,6 +2,7 @@ export { useEmployeeDetailsForm } from './useEmployeeDetailsForm' export type { EmployeeDetailsSubmitCallbacks, EmployeeDetailsOptionalFieldsToRequire, + UseEmployeeDetailsFormSharedProps, UseEmployeeDetailsFormProps, UseEmployeeDetailsFormResult, UseEmployeeDetailsFormReady, @@ -16,11 +17,21 @@ export { type EmployeeDetailsFormOutputs, type EmployeeDetailsField, } from './employeeDetailsSchema' +export { + FirstNameField, + MiddleInitialField, + LastNameField, + EmailField, + DateOfBirthField, + SsnField, + SelfOnboardingField, +} from './fields' export type { RequiredValidation as EmployeeDetailsRequiredValidation, NameValidation, EmailValidation, SsnValidation, + SsnRequiredValidation, FirstNameFieldProps, MiddleInitialFieldProps, LastNameFieldProps, @@ -29,3 +40,4 @@ export type { SsnFieldProps, SelfOnboardingFieldProps, } from './fields' +export type { EmployeeDetailsFields } from './useEmployeeDetailsForm' diff --git a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.tsx b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.tsx index 3a70052e4..85eafd4f9 100644 --- a/src/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.tsx +++ b/src/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.tsx @@ -41,44 +41,116 @@ import { removeNonDigits } from '@/helpers/formattedStrings' export type { EmployeeDetailsOptionalFieldsToRequire } from './employeeDetailsSchema' +/** + * Optional callbacks passed to {@link UseEmployeeDetailsFormReady.actions.onSubmit | onSubmit}. + * + * @remarks + * Only the callback matching the submit mode fires — + * `onEmployeeCreated` on create, `onEmployeeUpdated` on update. + * `onOnboardingStatusUpdated` fires when toggling the self-onboarding + * switch changes the employee's onboarding status as part of an update. + * + * @public + */ export interface EmployeeDetailsSubmitCallbacks { + /** Fired after a new employee is successfully created. */ onEmployeeCreated?: (employee: Employee) => void + /** Fired after an existing employee is successfully updated. */ onEmployeeUpdated?: (employee: Employee) => void + /** Fired when an update toggles self-onboarding and the employee's onboarding status changes. */ onOnboardingStatusUpdated?: (status: unknown) => void } -type UseEmployeeDetailsFormSharedProps = { +/** + * Shared options merged into both branches of {@link UseEmployeeDetailsFormProps}. + * + * @public + */ +export type UseEmployeeDetailsFormSharedProps = { + /** Whether to expose the self-onboarding toggle as `form.Fields.SelfOnboarding`. Defaults to `true`. */ withSelfOnboardingField?: boolean + /** Fields that are optional by default but should be promoted to required for this form instance. */ optionalFieldsToRequire?: EmployeeDetailsOptionalFieldsToRequire + /** Initial values applied before any employee data loads. */ defaultValues?: Partial + /** When validation runs. Forwarded to react-hook-form's `mode`. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Whether react-hook-form should focus the first error on validation failure. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Options for {@link useEmployeeDetailsForm}. + * + * @remarks + * Discriminated by mode: in create mode supply `companyId` and omit + * `employeeId`; in update mode supply `employeeId` (and optionally + * `companyId`). + * + * @public + */ export type UseEmployeeDetailsFormProps = | (UseEmployeeDetailsFormSharedProps & { companyId: string; employeeId?: never }) | (UseEmployeeDetailsFormSharedProps & { employeeId: string; companyId?: string }) +/** + * The Field components exposed by {@link useEmployeeDetailsForm} as `form.Fields`. + * + * @remarks + * Each entry is a component bound to a specific form field — see + * {@link FirstNameField}, {@link MiddleInitialField}, {@link LastNameField}, + * {@link EmailField}, {@link DateOfBirthField}, {@link SsnField}, and + * {@link SelfOnboardingField}. `SelfOnboarding` may be `undefined` when + * the field is not toggleable. + * + * @public + */ export interface EmployeeDetailsFields { + /** Text input bound to `firstName`. See {@link FirstNameField}. */ FirstName: typeof FirstNameField + /** Text input bound to `middleInitial`. See {@link MiddleInitialField}. */ MiddleInitial: typeof MiddleInitialField + /** Text input bound to `lastName`. See {@link LastNameField}. */ LastName: typeof LastNameField + /** Text input bound to `email`. See {@link EmailField}. */ Email: typeof EmailField + /** Date picker bound to `dateOfBirth`. See {@link DateOfBirthField}. */ DateOfBirth: typeof DateOfBirthField + /** Text input bound to `ssn`. See {@link SsnField}. */ Ssn: typeof SsnField + /** Switch bound to `selfOnboarding`, or `undefined` when the field is not toggleable. See {@link SelfOnboardingField}. */ SelfOnboarding: typeof SelfOnboardingField | undefined } +/** + * The ready-state result returned by {@link useEmployeeDetailsForm} once data has loaded. + * + * @remarks + * Provides the form's `data` snapshot, pending `status`, submit `actions`, + * error handling, and the `form.Fields` map. + * + * @public + */ export interface UseEmployeeDetailsFormReady extends BaseFormHookReady< FieldsMetadata, EmployeeDetailsFormData, EmployeeDetailsFields > { + /** The loaded employee data, or `null` in create mode. */ data: { + /** The employee being edited, or `null` in create mode. */ employee: Employee | null } - status: { isPending: boolean; mode: 'create' | 'update' } + /** Submit status and form mode. */ + status: { + /** `true` while the create, update, or onboarding-status mutation is in flight. */ + isPending: boolean + /** `'create'` when no `employeeId` was supplied, `'update'` otherwise. */ + mode: 'create' | 'update' + } + /** Submit and related actions. */ actions: { + /** Validates the form and submits the changes. Returns the created or updated employee, or `undefined` when validation fails. */ onSubmit: ( callbacks?: EmployeeDetailsSubmitCallbacks, ) => Promise | undefined> @@ -106,6 +178,61 @@ const canToggleSelfOnboarding = (employee?: Employee) => { ) } +/** + * Headless hook for creating or updating an employee's profile details — name, email, SSN, date of birth, and self-onboarding preference. + * + * @remarks + * Returns a discriminated union: a loading variant while the underlying + * employee fetch resolves, and a ready variant exposing the form's data, + * pending status, submit action, error handling, and bound `Fields`. + * Self-onboarding is only toggleable when the employee's onboarding status + * allows it; otherwise `form.Fields.SelfOnboarding` is `undefined`. + * + * @param input - See {@link UseEmployeeDetailsFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseEmployeeDetailsFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { + * useEmployeeDetailsForm, + * SDKFormProvider, + * type UseEmployeeDetailsFormReady, + * } from '@gusto/embedded-react-sdk' + * + * function EmployeeDetailsPage({ companyId, employeeId }: { companyId: string; employeeId?: string }) { + * const employeeDetails = useEmployeeDetailsForm({ companyId, employeeId }) + * + * if (employeeDetails.isLoading) return
Loading...
+ * + * return + * } + * + * function EmployeeDetailsReady({ employeeDetails }: { employeeDetails: UseEmployeeDetailsFormReady }) { + * const { Fields } = employeeDetails.form + * + * const handleSubmit = async () => { + * await employeeDetails.actions.onSubmit({ + * onEmployeeCreated: emp => console.log('Created:', emp.uuid), + * onEmployeeUpdated: emp => console.log('Updated:', emp.uuid), + * }) + * } + * + * return ( + * + *
{ e.preventDefault(); void handleSubmit() }}> + * + * + * + * + * + * + * + *
+ * ) + * } + * ``` + */ export function useEmployeeDetailsForm({ companyId, employeeId, @@ -306,6 +433,23 @@ export function useEmployeeDetailsForm({ } } +/** + * Return type of {@link useEmployeeDetailsForm}. + * + * @public + */ export type UseEmployeeDetailsFormResult = HookLoadingResult | UseEmployeeDetailsFormReady + +/** + * Shape of `form.fieldsMetadata` returned by {@link useEmployeeDetailsForm}. + * + * @public + */ export type EmployeeDetailsFieldsMetadata = UseEmployeeDetailsFormReady['form']['fieldsMetadata'] + +/** + * Shape of `form.Fields` returned by {@link useEmployeeDetailsForm}. + * + * @public + */ export type EmployeeDetailsFormFields = UseEmployeeDetailsFormReady['form']['Fields'] diff --git a/src/components/Employee/Profile/shared/useEmployeeProfileSummary/index.ts b/src/components/Employee/Profile/shared/useEmployeeProfileSummary/index.ts index 7fb260a25..257ae9a0a 100644 --- a/src/components/Employee/Profile/shared/useEmployeeProfileSummary/index.ts +++ b/src/components/Employee/Profile/shared/useEmployeeProfileSummary/index.ts @@ -1,6 +1 @@ export { useEmployeeProfileSummary } from './useEmployeeProfileSummary' -export type { - UseEmployeeProfileSummaryParams, - UseEmployeeProfileSummaryReady, - UseEmployeeProfileSummaryResult, -} from './useEmployeeProfileSummary' diff --git a/src/components/Employee/Profile/shared/useEmployeeProfileSummary/useEmployeeProfileSummary.tsx b/src/components/Employee/Profile/shared/useEmployeeProfileSummary/useEmployeeProfileSummary.tsx index 162156607..ba1c7d773 100644 --- a/src/components/Employee/Profile/shared/useEmployeeProfileSummary/useEmployeeProfileSummary.tsx +++ b/src/components/Employee/Profile/shared/useEmployeeProfileSummary/useEmployeeProfileSummary.tsx @@ -3,21 +3,53 @@ import type { Employee } from '@gusto/embedded-api-v-2025-11-15/models/component import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult } from '@/partner-hook-utils/types' +/** + * Options for {@link useEmployeeProfileSummary}. + * + * @public + */ export interface UseEmployeeProfileSummaryParams { + /** The associated employee identifier. */ employeeId: string } -export type UseEmployeeProfileSummaryReady = BaseHookReady< +type UseEmployeeProfileSummaryReady = BaseHookReady< { employee: Employee }, { isFetching: boolean; isPending: boolean } > +/** + * Return type of {@link useEmployeeProfileSummary}. + * + * @public + */ export type UseEmployeeProfileSummaryResult = HookLoadingResult | UseEmployeeProfileSummaryReady /** - * Read-only data hook for the Profile management card. Wraps `useEmployeesGet` - * without `?include=all_compensations` so the basic-details surface fetches - * only the fields it displays. Mutations live in `useEmployeeDetailsForm`. + * Read-only data hook for the basic-details Profile card. + * + * @remarks + * Fetches a single employee record scoped to the fields the + * basic-details surface displays. Pair with {@link useEmployeeDetailsForm} + * to render an edit form against the same record. + * + * @param input - See {@link UseEmployeeProfileSummaryParams}. + * @returns A {@link HookLoadingResult} while loading, or the ready result with the loaded employee once available. + * @public + * + * @example + * ```tsx + * import { useEmployeeProfileSummary } from '@gusto/embedded-react-sdk' + * + * function ProfileSummary({ employeeId }: { employeeId: string }) { + * const summary = useEmployeeProfileSummary({ employeeId }) + * + * if (summary.isLoading) return
Loading...
+ * + * const { employee } = summary.data + * return

{employee.firstName} {employee.lastName}

+ * } + * ``` */ export function useEmployeeProfileSummary({ employeeId, diff --git a/src/components/Employee/Profile/shared/useHomeAddressForm/fields.tsx b/src/components/Employee/Profile/shared/useHomeAddressForm/fields.tsx index c9e265770..a0317cf05 100644 --- a/src/components/Employee/Profile/shared/useHomeAddressForm/fields.tsx +++ b/src/components/Employee/Profile/shared/useHomeAddressForm/fields.tsx @@ -11,49 +11,180 @@ import { } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * The required-field error code produced by {@link useHomeAddressForm} fields that only emit `REQUIRED`. + * + * @remarks + * Used as the `validationMessages` key for the street, city, state, courtesy + * withholding, and effective date fields. See {@link HomeAddressErrorCodes}. + * + * @public + */ export type RequiredValidation = typeof HomeAddressErrorCodes.REQUIRED + +/** + * Validation error codes emitted by the `zip` field of {@link useHomeAddressForm}. + * + * @remarks + * Use these as keys in `validationMessages` on `Fields.Zip`. See + * {@link HomeAddressErrorCodes}. + * + * @public + */ export type ZipValidation = (typeof HomeAddressErrorCodes)['REQUIRED' | 'INVALID_ZIP'] +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.Street1` component. + * + * @public + */ export type Street1FieldProps = HookFieldProps> +/** + * Text input bound to the `street1` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Street1`. Required. + * + * @param props - {@link Street1FieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `street1`. + * @public + */ export function Street1Field(props: Street1FieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.Street2` component. + * + * @public + */ export type Street2FieldProps = HookFieldProps> +/** + * Text input bound to the `street2` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Street2`. Optional. + * + * @param props - {@link Street2FieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `street2`. + * @public + */ export function Street2Field(props: Street2FieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.City` component. + * + * @public + */ export type CityFieldProps = HookFieldProps> +/** + * Text input bound to the `city` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.City`. Required. + * + * @param props - {@link CityFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `city`. + * @public + */ export function CityField(props: CityFieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.State` component. + * + * @public + */ export type StateFieldProps = HookFieldProps> +/** + * Select bound to the `state` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.State`. Options are the + * standard two-letter US state abbreviations. Required. + * + * @param props - {@link StateFieldProps} — accepts the standard hook field props plus `getOptionLabel` to localize state names. + * @returns The rendered select bound to `state`. + * @public + */ export function StateField(props: StateFieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.Zip` component. + * + * @public + */ export type ZipFieldProps = HookFieldProps> +/** + * Text input bound to the `zip` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Zip`. Required; also + * validates ZIP code format and emits `INVALID_ZIP` when the value does + * not match. + * + * @param props - {@link ZipFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered text input bound to `zip`. + * @public + */ export function ZipField(props: ZipFieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.CourtesyWithholding` component. + * + * @public + */ export type CourtesyWithholdingFieldProps = HookFieldProps< CheckboxHookFieldProps > +/** + * Checkbox bound to the `courtesyWithholding` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.CourtesyWithholding`. When + * checked, the employer agrees to withhold the employee's home-state taxes + * as a courtesy even when the work and home states differ. + * + * @param props - {@link CourtesyWithholdingFieldProps} — accepts the standard hook field props (label, description, FieldComponent override). + * @returns The rendered checkbox bound to `courtesyWithholding`. + * @public + */ export function CourtesyWithholdingField(props: CourtesyWithholdingFieldProps) { return } +/** + * Props accepted by {@link useHomeAddressForm}'s `Fields.EffectiveDate` component. + * + * @public + */ export type EffectiveDateFieldProps = HookFieldProps> +/** + * Date picker bound to the `effectiveDate` field of {@link useHomeAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.EffectiveDate` when + * `withEffectiveDateField` is `true`; `undefined` otherwise. Always + * null-check before rendering. + * + * @param props - {@link EffectiveDateFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered date picker bound to `effectiveDate`. + * @public + */ export function EffectiveDateField(props: EffectiveDateFieldProps) { return } diff --git a/src/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.ts b/src/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.ts index 4860eb198..0a0b440d3 100644 --- a/src/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.ts +++ b/src/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.ts @@ -7,11 +7,23 @@ import { // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the home address form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const HomeAddressErrorCodes = { REQUIRED: 'REQUIRED', INVALID_ZIP: 'INVALID_ZIP', } as const +/** + * Union of validation error code strings emitted by the home address form + * schema. + * + * @public + */ export type HomeAddressErrorCode = (typeof HomeAddressErrorCodes)[keyof typeof HomeAddressErrorCodes] @@ -29,11 +41,26 @@ const fieldValidators = { effectiveDate: z.iso.date({ error: () => HomeAddressErrorCodes.REQUIRED }), } +/** + * Field names accepted by the home address form. + * + * @public + */ export type HomeAddressField = keyof typeof fieldValidators +/** + * Shape of the values managed by the home address form. + * + * @public + */ export type HomeAddressFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the home address form on submit. + * + * @public + */ export type HomeAddressFormOutputs = HomeAddressFormData // ── Required fields config ───────────────────────────────────────────── @@ -44,16 +71,24 @@ const requiredFieldsConfig = { // ── Schema factory ───────────────────────────────────────────────────── +/** + * Keys of optional home address fields that can be promoted to required via + * the hook's `optionalFieldsToRequire` option. + * + * @public + */ export type HomeAddressOptionalFieldsToRequire = OptionalFieldsToRequire< typeof requiredFieldsConfig > +/** @internal */ interface HomeAddressSchemaOptions { mode?: 'create' | 'update' optionalFieldsToRequire?: HomeAddressOptionalFieldsToRequire withEffectiveDateField?: boolean } +/** @internal */ export function createHomeAddressSchema(options: HomeAddressSchemaOptions = {}) { const { mode = 'create', optionalFieldsToRequire, withEffectiveDateField = true } = options diff --git a/src/components/Employee/Profile/shared/useHomeAddressForm/index.ts b/src/components/Employee/Profile/shared/useHomeAddressForm/index.ts index 32d5f2473..b7aed8d90 100644 --- a/src/components/Employee/Profile/shared/useHomeAddressForm/index.ts +++ b/src/components/Employee/Profile/shared/useHomeAddressForm/index.ts @@ -8,6 +8,7 @@ export type { UseHomeAddressFormReady, HomeAddressFieldsMetadata, HomeAddressFormFields, + HomeAddressFields, } from './useHomeAddressForm' export type { UseCurrentHomeAddressFormProps } from './useCurrentHomeAddressForm' export { @@ -18,6 +19,15 @@ export { type HomeAddressFormOutputs, type HomeAddressField, } from './homeAddressSchema' +export { + Street1Field, + Street2Field, + CityField, + StateField, + ZipField, + CourtesyWithholdingField, + EffectiveDateField, +} from './fields' export type { RequiredValidation as HomeAddressRequiredValidation, ZipValidation, diff --git a/src/components/Employee/Profile/shared/useHomeAddressForm/useCurrentHomeAddressForm.tsx b/src/components/Employee/Profile/shared/useHomeAddressForm/useCurrentHomeAddressForm.tsx index 105d62351..e776f810a 100644 --- a/src/components/Employee/Profile/shared/useHomeAddressForm/useCurrentHomeAddressForm.tsx +++ b/src/components/Employee/Profile/shared/useHomeAddressForm/useCurrentHomeAddressForm.tsx @@ -3,8 +3,53 @@ import { useHomeAddressForm } from './useHomeAddressForm' import type { UseHomeAddressFormProps, UseHomeAddressFormResult } from './useHomeAddressForm' import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' +/** + * Options for {@link useCurrentHomeAddressForm}. + * + * @remarks + * Same shape as {@link UseHomeAddressFormProps} minus `homeAddressUuid` — + * the hook resolves the current home address itself. + * + * @public + */ export type UseCurrentHomeAddressFormProps = Omit +/** + * Convenience wrapper around {@link useHomeAddressForm} that auto-resolves the employee's current home address. + * + * @remarks + * Lists the employee's home addresses and selects the active one (or the + * first when none are active) as the row to edit. When the employee has no + * home address on file the hook operates in create mode. The returned + * shape is identical to {@link useHomeAddressForm}, so the same `Fields`, + * `actions.onSubmit`, and `errorHandling` apply. + * + * @param props - See {@link UseCurrentHomeAddressFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseHomeAddressFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { useCurrentHomeAddressForm } from '@gusto/embedded-react-sdk' + * + * function HomeAddressEditor({ employeeId }: { employeeId: string }) { + * const homeAddress = useCurrentHomeAddressForm({ employeeId }) + * + * if (homeAddress.isLoading) return
Loading...
+ * + * const { Fields } = homeAddress.form + * return ( + *
{ e.preventDefault(); void homeAddress.actions.onSubmit() }}> + * + * + * + * + * + * + * ) + * } + * ``` + */ export function useCurrentHomeAddressForm( props: UseCurrentHomeAddressFormProps, ): UseHomeAddressFormResult { diff --git a/src/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.tsx b/src/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.tsx index a64aca7a5..eb107d9a2 100644 --- a/src/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.tsx +++ b/src/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.tsx @@ -39,13 +39,29 @@ import { STATES_ABBR } from '@/shared/constants' export type { HomeAddressOptionalFieldsToRequire } from './homeAddressSchema' +/** + * Optional overrides passed to {@link UseHomeAddressFormReady.actions.onSubmit | onSubmit}. + * + * @public + */ export interface HomeAddressSubmitOptions { + /** Override the employee identifier supplied to the hook (e.g. after creating a new employee in the same flow). */ employeeId?: string - /** When omitted on update without an effective-date field, the row’s `effectiveDate` from the fetched address is used. */ + /** Override the effective date submitted with the address. When omitted on update without an effective-date field, the row's `effectiveDate` from the fetched address is used. */ effectiveDate?: string } +/** + * Configuration options for {@link useHomeAddressForm}. + * + * @remarks + * Presence or absence of `homeAddressUuid` selects the API verb — see the + * `homeAddressUuid` field description. + * + * @public + */ export interface UseHomeAddressFormProps { + /** UUID of the employee whose home address is being created or edited. */ employeeId: string /** * When set, loads that home address via GET `/v1/home_addresses/{uuid}` and updates it (PUT). @@ -57,33 +73,66 @@ export interface UseHomeAddressFormProps { * instead of issuing a GET — useful when the parent already has the row from a list query. */ initialAddress?: EmployeeAddress + /** When `true`, renders `Fields.EffectiveDate`; otherwise it is `undefined`. Defaults to `true`. */ withEffectiveDateField?: boolean + /** Override fields that are optional on a given mode to be required. See `HomeAddressOptionalFieldsToRequire`. */ optionalFieldsToRequire?: HomeAddressOptionalFieldsToRequire + /** Pre-fill form values. Server data takes precedence on update. */ defaultValues?: Partial + /** Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler` so submit-time focus is coordinated across multiple forms. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Pre-bound field components exposed on `useHomeAddressForm().form.Fields`. + * + * @remarks + * `EffectiveDate` is `undefined` when `withEffectiveDateField` is `false`. + * Always null-check it before rendering. + * + * @public + */ export interface HomeAddressFields { + /** Street address line 1 text input. Always available. */ Street1: typeof Street1Field + /** Street address line 2 text input. Always available. */ Street2: typeof Street2Field + /** City text input. Always available. */ City: typeof CityField + /** State selector. Always available. */ State: typeof StateField + /** ZIP code text input. Always available. */ Zip: typeof ZipField + /** Courtesy withholding checkbox. Always available. */ CourtesyWithholding: typeof CourtesyWithholdingField + /** Effective-date picker. Only available when `withEffectiveDateField` is `true`. */ EffectiveDate: typeof EffectiveDateField | undefined } +/** + * Ready-state shape returned by {@link useHomeAddressForm} once data has loaded. + * + * @remarks + * Discriminated by `isLoading: false`. Extends {@link BaseFormHookReady} with + * the home-address-specific `data`, `status`, `actions`, and `form.Fields` shape. + * + * @public + */ export interface UseHomeAddressFormReady extends BaseFormHookReady< FieldsMetadata, HomeAddressFormData, HomeAddressFields > { + /** Static entity data resolved from the API. */ data: { /** The address row loaded for update; `null` in create mode. */ homeAddress: EmployeeAddress | null } + /** Reactive status flags. */ status: { isPending: boolean; mode: 'create' | 'update' } + /** Available actions. */ actions: { onSubmit: ( options?: HomeAddressSubmitOptions, @@ -91,6 +140,18 @@ export interface UseHomeAddressFormReady extends BaseFormHookReady< } } +/** + * Form hook for creating or editing an employee's home address. + * + * @remarks + * When `homeAddressUuid` is supplied the hook loads that address and issues a PUT on submit; + * when omitted it operates in create mode and issues a POST. Pass `initialAddress` to + * skip the fetch when the parent already holds the row. + * + * @param props - See {@link UseHomeAddressFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseHomeAddressFormReady} once ready. + * @public + */ export function useHomeAddressForm({ employeeId, homeAddressUuid, @@ -308,6 +369,21 @@ export function useHomeAddressForm({ } } +/** + * Discriminated union returned by {@link useHomeAddressForm}. + * + * @public + */ export type UseHomeAddressFormResult = HookLoadingResult | UseHomeAddressFormReady +/** + * Type of `form.fieldsMetadata` returned by {@link useHomeAddressForm}. + * + * @public + */ export type HomeAddressFieldsMetadata = UseHomeAddressFormReady['form']['fieldsMetadata'] +/** + * Type of `form.Fields` returned by {@link useHomeAddressForm}. + * + * @public + */ export type HomeAddressFormFields = UseHomeAddressFormReady['form']['Fields'] diff --git a/src/components/Employee/Profile/shared/useWorkAddressForm/fields.tsx b/src/components/Employee/Profile/shared/useWorkAddressForm/fields.tsx index 022fc2578..cf59f6fbc 100644 --- a/src/components/Employee/Profile/shared/useWorkAddressForm/fields.tsx +++ b/src/components/Employee/Profile/shared/useWorkAddressForm/fields.tsx @@ -5,16 +5,59 @@ import type { DatePickerHookFieldProps } from '@/partner-hook-utils/form/fields/ import { SelectHookField, DatePickerHookField } from '@/partner-hook-utils/form/fields' import type { HookFieldProps } from '@/partner-hook-utils/types' +/** + * The required-field error code produced by {@link useWorkAddressForm} fields that only emit `REQUIRED`. + * + * @remarks + * Used as the `validationMessages` key for the location and effective date fields. + * See `WorkAddressErrorCodes`. + * + * @public + */ export type RequiredValidation = typeof WorkAddressErrorCodes.REQUIRED +/** + * Props accepted by {@link useWorkAddressForm}'s `Fields.Location` component. + * + * @public + */ export type LocationFieldProps = HookFieldProps> +/** + * Select bound to the `locationUuid` field of {@link useWorkAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.Location`. Options are the + * company's active locations; the hook populates them from the locations + * query. Required. + * + * @param props - {@link LocationFieldProps} — accepts the standard hook field props plus `getOptionLabel` to format location display names. + * @returns The rendered select bound to `locationUuid`. + * @public + */ export function LocationField(props: LocationFieldProps) { return } +/** + * Props accepted by {@link useWorkAddressForm}'s `Fields.EffectiveDate` component. + * + * @public + */ export type EffectiveDateFieldProps = HookFieldProps> +/** + * Date picker bound to the `effectiveDate` field of {@link useWorkAddressForm}. + * + * @remarks + * Available on the hook result as `form.Fields.EffectiveDate` when + * `withEffectiveDateField` is `true`; `undefined` otherwise. Always + * null-check before rendering. + * + * @param props - {@link EffectiveDateFieldProps} — accepts the standard hook field props (label, description, validationMessages, FieldComponent override). + * @returns The rendered date picker bound to `effectiveDate`. + * @public + */ export function EffectiveDateField(props: EffectiveDateFieldProps) { return } diff --git a/src/components/Employee/Profile/shared/useWorkAddressForm/index.ts b/src/components/Employee/Profile/shared/useWorkAddressForm/index.ts index 25022a3b1..db05a25ee 100644 --- a/src/components/Employee/Profile/shared/useWorkAddressForm/index.ts +++ b/src/components/Employee/Profile/shared/useWorkAddressForm/index.ts @@ -10,6 +10,7 @@ export type { UseWorkAddressFormReady, WorkAddressFieldsMetadata, WorkAddressFormFields, + WorkAddressFields, } from './useWorkAddressForm' export { createWorkAddressSchema, @@ -19,6 +20,7 @@ export { type WorkAddressFormOutputs, type WorkAddressField, } from './workAddressSchema' +export { LocationField, EffectiveDateField } from './fields' export type { RequiredValidation as WorkAddressRequiredValidation, LocationFieldProps, diff --git a/src/components/Employee/Profile/shared/useWorkAddressForm/useCurrentWorkAddressForm.tsx b/src/components/Employee/Profile/shared/useWorkAddressForm/useCurrentWorkAddressForm.tsx index 4f971e6aa..78e71618b 100644 --- a/src/components/Employee/Profile/shared/useWorkAddressForm/useCurrentWorkAddressForm.tsx +++ b/src/components/Employee/Profile/shared/useWorkAddressForm/useCurrentWorkAddressForm.tsx @@ -3,8 +3,50 @@ import { useWorkAddressForm } from './useWorkAddressForm' import type { UseWorkAddressFormProps, UseWorkAddressFormResult } from './useWorkAddressForm' import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' +/** + * Options for {@link useCurrentWorkAddressForm}. + * + * @remarks + * Same shape as {@link UseWorkAddressFormProps} minus `workAddressUuid` — + * the hook resolves the current work address itself. + * + * @public + */ export type UseCurrentWorkAddressFormProps = Omit +/** + * Convenience wrapper around {@link useWorkAddressForm} that auto-resolves the employee's current work address. + * + * @remarks + * Lists the employee's work addresses and selects the active one (or the + * first when none are active) as the row to edit. When the employee has no + * work address on file the hook operates in create mode. The returned shape + * is identical to {@link useWorkAddressForm}, so the same `Fields`, + * `actions.onSubmit`, and `errorHandling` apply. + * + * @param props - See {@link UseCurrentWorkAddressFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseWorkAddressFormReady} once ready. + * @public + * + * @example + * ```tsx + * import { useCurrentWorkAddressForm } from '@gusto/embedded-react-sdk' + * + * function WorkAddressEditor({ employeeId, companyId }: { employeeId: string; companyId: string }) { + * const workAddress = useCurrentWorkAddressForm({ employeeId, companyId }) + * + * if (workAddress.isLoading) return
Loading...
+ * + * const { Fields } = workAddress.form + * return ( + *
{ e.preventDefault(); void workAddress.actions.onSubmit() }}> + * + * + * + * ) + * } + * ``` + */ export function useCurrentWorkAddressForm( props: UseCurrentWorkAddressFormProps, ): UseWorkAddressFormResult { diff --git a/src/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.tsx b/src/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.tsx index c04dbf89d..86fa9b33e 100644 --- a/src/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.tsx +++ b/src/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.tsx @@ -33,19 +33,48 @@ import { addressInline } from '@/helpers/formattedStrings' export type { WorkAddressOptionalFieldsToRequire } from './workAddressSchema' +/** + * Optional callbacks passed to {@link UseWorkAddressFormReady.actions.onSubmit | onSubmit}. + * + * @remarks + * Only the callback matching the submit mode fires — + * `onWorkAddressCreated` on create, `onWorkAddressUpdated` on update. + * + * @public + */ export interface WorkAddressSubmitCallbacks { + /** Fired after a new work address is successfully created. */ onWorkAddressCreated?: (workAddress: EmployeeWorkAddress) => void + /** Fired after an existing work address is successfully updated. */ onWorkAddressUpdated?: (workAddress: EmployeeWorkAddress) => void } +/** + * Optional overrides passed to {@link UseWorkAddressFormReady.actions.onSubmit | onSubmit}. + * + * @public + */ export interface WorkAddressSubmitOptions { + /** Override the employee identifier supplied to the hook (e.g. after creating a new employee in the same flow). */ employeeId?: string + /** Override the effective date submitted with the address. */ effectiveDate?: string } +/** + * Configuration options for {@link useWorkAddressForm}. + * + * @remarks + * Presence or absence of `workAddressUuid` selects the API verb — see the + * `workAddressUuid` field description. `companyId` is required to fetch + * the location list; pass it when it is known. + * + * @public + */ export interface UseWorkAddressFormProps { /** Company UUID for locations; omit or leave unset while resolving from the employee record. */ companyId?: string + /** UUID of the employee whose work address is being created or edited. */ employeeId: string /** * When set, loads that work address via GET `/v1/work_addresses/{work_address_uuid}` and updates it (PUT). @@ -57,29 +86,58 @@ export interface UseWorkAddressFormProps { * instead of issuing a GET — useful when the parent already has the row from a list query. */ initialAddress?: EmployeeWorkAddress + /** When `true`, renders `Fields.EffectiveDate`; otherwise it is `undefined`. Defaults to `true`. */ withEffectiveDateField?: boolean + /** Override fields that are optional on a given mode to be required. See `WorkAddressOptionalFieldsToRequire`. */ optionalFieldsToRequire?: WorkAddressOptionalFieldsToRequire + /** Pre-fill form values. Server data takes precedence on update. */ defaultValues?: Partial + /** Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Set to `false` when using `composeSubmitHandler` so submit-time focus is coordinated across multiple forms. Defaults to `true`. */ shouldFocusError?: boolean } +/** + * Pre-bound field components exposed on `useWorkAddressForm().form.Fields`. + * + * @remarks + * `EffectiveDate` is `undefined` when `withEffectiveDateField` is `false`. + * Always null-check it before rendering. + * + * @public + */ export interface WorkAddressFields { + /** Location selector. Always available. */ Location: typeof LocationField + /** Effective-date picker. Only available when `withEffectiveDateField` is `true`. */ EffectiveDate: typeof EffectiveDateField | undefined } +/** + * Ready-state shape returned by {@link useWorkAddressForm} once data has loaded. + * + * @remarks + * Discriminated by `isLoading: false`. Extends {@link BaseFormHookReady} with + * the work-address-specific `data`, `status`, `actions`, and `form.Fields` shape. + * + * @public + */ export interface UseWorkAddressFormReady extends BaseFormHookReady< FieldsMetadata, WorkAddressFormData, WorkAddressFields > { + /** Static entity data resolved from the API. */ data: { /** The address row loaded for update; `null` in create mode. */ workAddress: EmployeeWorkAddress | null + /** Company locations available for selection; `undefined` until the locations query resolves. */ companyLocations: Location[] | undefined } + /** Reactive status flags. */ status: { isPending: boolean; mode: 'create' | 'update' } + /** Available actions. */ actions: { onSubmit: ( callbacks?: WorkAddressSubmitCallbacks, @@ -88,6 +146,18 @@ export interface UseWorkAddressFormReady extends BaseFormHookReady< } } +/** + * Form hook for creating or editing an employee's work address. + * + * @remarks + * When `workAddressUuid` is supplied the hook loads that address and issues a PUT on submit; + * when omitted it operates in create mode and issues a POST. The hook requires `companyId` + * to fetch the company's location list — it stays in loading state until `companyId` is known. + * + * @param props - See {@link UseWorkAddressFormProps}. + * @returns A {@link HookLoadingResult} while loading, or a {@link UseWorkAddressFormReady} once ready. + * @public + */ export function useWorkAddressForm({ companyId, employeeId, @@ -300,6 +370,21 @@ export function useWorkAddressForm({ } } +/** + * Discriminated union returned by {@link useWorkAddressForm}. + * + * @public + */ export type UseWorkAddressFormResult = HookLoadingResult | UseWorkAddressFormReady +/** + * Type of `form.fieldsMetadata` returned by {@link useWorkAddressForm}. + * + * @public + */ export type WorkAddressFieldsMetadata = UseWorkAddressFormReady['form']['fieldsMetadata'] +/** + * Type of `form.Fields` returned by {@link useWorkAddressForm}. + * + * @public + */ export type WorkAddressFormFields = UseWorkAddressFormReady['form']['Fields'] diff --git a/src/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.ts b/src/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.ts index c2146cae8..059257579 100644 --- a/src/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.ts +++ b/src/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.ts @@ -7,10 +7,22 @@ import { // ── Error codes ──────────────────────────────────────────────────────── +/** + * Validation error codes emitted by the work address form schema. Map these + * codes to localized copy in `validationMessages` when composing the hook. + * + * @public + */ export const WorkAddressErrorCodes = { REQUIRED: 'REQUIRED', } as const +/** + * Union of validation error code strings emitted by the work address form + * schema. + * + * @public + */ export type WorkAddressErrorCode = (typeof WorkAddressErrorCodes)[keyof typeof WorkAddressErrorCodes] @@ -21,11 +33,26 @@ const fieldValidators = { effectiveDate: z.iso.date({ error: () => WorkAddressErrorCodes.REQUIRED }), } +/** + * Field names accepted by the work address form. + * + * @public + */ export type WorkAddressField = keyof typeof fieldValidators +/** + * Shape of the values managed by the work address form. + * + * @public + */ export type WorkAddressFormData = { [K in keyof typeof fieldValidators]: z.infer<(typeof fieldValidators)[K]> } +/** + * Shape of the validated values produced by the work address form on submit. + * + * @public + */ export type WorkAddressFormOutputs = WorkAddressFormData // ── Required fields config ───────────────────────────────────────────── @@ -34,16 +61,24 @@ const requiredFieldsConfig = {} satisfies RequiredFieldConfig +/** @internal */ interface WorkAddressSchemaOptions { mode?: 'create' | 'update' optionalFieldsToRequire?: WorkAddressOptionalFieldsToRequire withEffectiveDateField?: boolean } +/** @internal */ export function createWorkAddressSchema(options: WorkAddressSchemaOptions = {}) { const { mode = 'create', optionalFieldsToRequire, withEffectiveDateField = true } = options diff --git a/src/components/Employee/SelfOnboardingFlow/SelfOnboardingComponents.tsx b/src/components/Employee/SelfOnboardingFlow/SelfOnboardingComponents.tsx index c45f787b9..525114bec 100644 --- a/src/components/Employee/SelfOnboardingFlow/SelfOnboardingComponents.tsx +++ b/src/components/Employee/SelfOnboardingFlow/SelfOnboardingComponents.tsx @@ -11,11 +11,21 @@ import { PaymentMethod as PaymentMethodComponent } from '@/components/Employee/P import { OnboardingSummary as OnboardingSummaryComponent } from '@/components/Employee/OnboardingSummary' import { DocumentSigner as DocumentSignerComponent } from '@/components/Employee/Documents/onboarding/DocumentSigner' +/** + * Props for {@link SelfOnboardingFlow}. + * + * @public + */ export interface SelfOnboardingFlowProps extends BaseComponentInterface { + /** The associated company identifier. */ companyId: string + /** The associated employee identifier. */ employeeId: string + /** When true, the Document Signer step checks if the employee has I-9 enabled and routes to the Employment Eligibility and I-9 signature form steps. Defaults to `false`. */ withEmployeeI9?: boolean } + +/** @internal */ export interface SelfOnboardingContextInterface extends FlowContextInterface { companyId: string employeeId: string @@ -23,6 +33,7 @@ export interface SelfOnboardingContextInterface extends FlowContextInterface { paymentMethod?: PaymentMethodBankAccount } +/** @internal */ export function Landing() { const { companyId, employeeId, onEvent } = useFlow() return ( @@ -34,6 +45,7 @@ export function Landing() { ) } +/** @internal */ export function Profile() { const { companyId, employeeId, onEvent } = useFlow() return ( @@ -46,11 +58,13 @@ export function Profile() { ) } +/** @internal */ export function FederalTaxes() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function StateTaxes() { const { employeeId, onEvent } = useFlow() return ( @@ -62,11 +76,13 @@ export function StateTaxes() { ) } +/** @internal */ export function PaymentMethod() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function OnboardingSummary() { const { employeeId, onEvent } = useFlow() return ( @@ -78,6 +94,7 @@ export function OnboardingSummary() { ) } +/** @internal */ export function DocumentSigner() { const { employeeId, withEmployeeI9 = false, onEvent } = useFlow() return ( diff --git a/src/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.tsx b/src/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.tsx index 00b317314..958598a24 100644 --- a/src/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.tsx +++ b/src/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.tsx @@ -8,6 +8,37 @@ import { Landing } from './SelfOnboardingComponents' import { employeeSelfOnboardingMachine } from './selfOnboardingMachine' import { Flow } from '@/components/Flow/Flow' +/** + * Employee-driven onboarding workflow — landing, profile, taxes, payment method, and document signing. + * + * @remarks + * Hands the employee responsibility for submitting their own profile, tax, payment, and document-signing information. Drives a multi-step flow keyed to the employee being self-onboarded; when `withEmployeeI9` is enabled, the Document Signer step checks whether the employee has I-9 enabled and, if so, routes them through the employment-eligibility form before presenting the I-9 form alongside other required documents. + * + * Each step is also exported as a standalone block — see {@link Landing}, {@link Profile}, {@link FederalTaxes}, {@link StateTaxes}, {@link PaymentMethod}, {@link DocumentSigner}, {@link EmploymentEligibility}, and {@link OnboardingSummary} — for composing a custom workflow when this orchestration is the wrong fit. + * + * The flow forwards every event emitted by its sub-components to `onEvent`; see the events table on each sub-component for the full set of events and payloads observable from this flow. + * + * @param props - See {@link SelfOnboardingFlowProps}. + * @returns The multi-step self-onboarding flow. + * @public + * @group Flow Components + * + * @example + * ```tsx + * import { EmployeeOnboarding } from '@gusto/embedded-react-sdk' + * + * function MyApp() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export const SelfOnboardingFlow = ({ companyId, employeeId, diff --git a/src/components/Employee/SelfOnboardingFlow/selfOnboardingMachine.ts b/src/components/Employee/SelfOnboardingFlow/selfOnboardingMachine.ts index 7dd622063..31d7b853b 100644 --- a/src/components/Employee/SelfOnboardingFlow/selfOnboardingMachine.ts +++ b/src/components/Employee/SelfOnboardingFlow/selfOnboardingMachine.ts @@ -11,6 +11,7 @@ import { import { componentEvents } from '@/shared/constants' import type { MachineTransition } from '@/types/Helpers' +/** @internal */ export const employeeSelfOnboardingMachine = { index: state( transition( diff --git a/src/components/Employee/StateTaxes/index.ts b/src/components/Employee/StateTaxes/index.ts index efa7098be..0937d6610 100644 --- a/src/components/Employee/StateTaxes/index.ts +++ b/src/components/Employee/StateTaxes/index.ts @@ -1,9 +1,2 @@ -export { - StateTaxes, - StateTaxesCard, - StateTaxesEditForm, - type StateTaxesProps, - type StateTaxesCardProps, - type StateTaxesEditFormProps, -} from './management' +export { StateTaxes } from './management' export * from './shared' diff --git a/src/components/Employee/StateTaxes/management/StateTaxes.tsx b/src/components/Employee/StateTaxes/management/StateTaxes.tsx index 0cb30c21d..54a6745ab 100644 --- a/src/components/Employee/StateTaxes/management/StateTaxes.tsx +++ b/src/components/Employee/StateTaxes/management/StateTaxes.tsx @@ -13,8 +13,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link StateTaxes}. + * + * @public + */ export interface StateTaxesProps extends CommonComponentInterface<'Employee.Management.StateTaxes'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -34,6 +41,23 @@ function StateTaxesFlow({ employeeId, onEvent }: StateTaxesProps) { return } +/** + * Standalone state-tax management flow for a given employee. Renders the + * read-only summary card and the edit form, switching between them as the + * partner-emitted events from {@link StateTaxesCard} and {@link StateTaxesEditForm} + * drive the internal state machine. + * + * @remarks + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/stateTaxes/editRequested` | Edit button on the summary card was clicked | `{ employeeId: string }` | + * | `employee/management/stateTaxes/editCancelled` | Cancel button on the edit form was clicked | — | + * | `employee/management/stateTaxes/updated` | Edit form was submitted successfully | `{ employeeStateTaxesList: EmployeeStateTaxesList[] }` | + * + * @param props - The component props. + * @public + */ export function StateTaxes({ dictionary, FallbackComponent, diff --git a/src/components/Employee/StateTaxes/management/StateTaxesCard/StateTaxesCard.tsx b/src/components/Employee/StateTaxes/management/StateTaxesCard/StateTaxesCard.tsx index 61d6ab5f4..978798d1a 100644 --- a/src/components/Employee/StateTaxes/management/StateTaxesCard/StateTaxesCard.tsx +++ b/src/components/Employee/StateTaxes/management/StateTaxesCard/StateTaxesCard.tsx @@ -10,18 +10,33 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link StateTaxesCard}. + * + * @public + */ export interface StateTaxesCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the Edit button is clicked. */ onEvent: OnEventType } /** - * Standalone "State taxes" card. Owns its own data fetch via - * `useStateTaxesSummary` and emits - * `EMPLOYEE_MANAGEMENT_STATE_TAXES_EDIT_REQUESTED` when the Edit - * button is clicked. The Edit button is hidden when no state on - * record has any tax-withholding questions (e.g. WA), matching the - * product rule that a state with no income tax has nothing to edit. + * Standalone read-only summary card showing an employee's per-state tax + * withholding answers. Fetches its own data and surfaces an Edit button + * that emits an event for the orchestrator to swap in the edit form. + * + * @remarks + * The Edit button is hidden when no state on record has any tax-withholding + * questions (e.g. states with no income tax), since there is nothing to edit. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/stateTaxes/editRequested` | Edit button was clicked | `{ employeeId: string }` | + * + * @param props - The component props. + * @public */ export function StateTaxesCard(props: StateTaxesCardProps) { return ( diff --git a/src/components/Employee/StateTaxes/management/StateTaxesComponents.tsx b/src/components/Employee/StateTaxes/management/StateTaxesComponents.tsx index 4a37e43b1..23c3c5f92 100644 --- a/src/components/Employee/StateTaxes/management/StateTaxesComponents.tsx +++ b/src/components/Employee/StateTaxes/management/StateTaxesComponents.tsx @@ -7,13 +7,16 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { componentEvents } from '@/shared/constants' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export type StateTaxesSuccessAlertCode = 'stateTaxesUpdated' +/** @internal */ export interface StateTaxesContextInterface extends FlowContextInterface { employeeId?: string successAlert?: StateTaxesSuccessAlertCode | null } +/** @internal */ export function StateTaxesCardContextual() { const { employeeId, onEvent, successAlert } = useFlow() const { t } = useTranslation('Employee.Management.StateTaxes') @@ -34,6 +37,7 @@ export function StateTaxesCardContextual() { ) } +/** @internal */ export function StateTaxesEditFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/StateTaxes/management/StateTaxesEditForm.tsx b/src/components/Employee/StateTaxes/management/StateTaxesEditForm.tsx index bcfd88437..3578845a3 100644 --- a/src/components/Employee/StateTaxes/management/StateTaxesEditForm.tsx +++ b/src/components/Employee/StateTaxes/management/StateTaxesEditForm.tsx @@ -12,24 +12,36 @@ import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** + * Props for {@link StateTaxesEditForm}. + * + * @public + */ export type StateTaxesEditFormProps = Omit< CommonComponentInterface<'Employee.Management.StateTaxes'>, 'children' > & { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the form is submitted or cancelled. */ onEvent: BaseComponentInterface['onEvent'] } /** - * Standalone state-tax edit screen for the management flow. Wraps the shared - * {@link useEmployeeStateTaxesForm} hook with scoped events and the - * `Employee.Management.StateTaxes` namespace; the shared `EmployeeStateTaxesView` - * resolves its text through `useManagementStateTaxesViewDictionary` so partner - * overrides on the management namespace don't leak into onboarding. + * Standalone edit screen for the state-tax management flow. Renders the shared + * state-tax form against the `Employee.Management.StateTaxes` namespace and + * emits scoped management events on submit and cancel, so partner copy + * overrides on the management namespace do not leak into the onboarding flow. + * + * @remarks + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/stateTaxes/updated` | Form was submitted successfully | `{ employeeStateTaxesList: EmployeeStateTaxesList[] }` | + * | `employee/management/stateTaxes/editCancelled` | Cancel button was clicked | — | * - * Emits `EMPLOYEE_MANAGEMENT_STATE_TAXES_UPDATED` on a successful save and - * `EMPLOYEE_MANAGEMENT_STATE_TAXES_EDIT_CANCELLED` on Cancel. The orchestrator - * (the block or the dashboard) handles both by returning to the card surface. + * @param props - The component props. + * @public */ export function StateTaxesEditForm({ FallbackComponent, diff --git a/src/components/Employee/StateTaxes/management/stateTaxesStateMachine.ts b/src/components/Employee/StateTaxes/management/stateTaxesStateMachine.ts index fc3564938..f9a0c9888 100644 --- a/src/components/Employee/StateTaxes/management/stateTaxesStateMachine.ts +++ b/src/components/Employee/StateTaxes/management/stateTaxesStateMachine.ts @@ -22,6 +22,7 @@ const returnToCardWithAlert = (alert: StateTaxesSuccessAlertCode) => }), ) +/** @internal */ export const stateTaxesStateMachine = { card: state( transition( diff --git a/src/components/Employee/StateTaxes/management/useViewDictionary.ts b/src/components/Employee/StateTaxes/management/useViewDictionary.ts index 36b05a4b7..855320922 100644 --- a/src/components/Employee/StateTaxes/management/useViewDictionary.ts +++ b/src/components/Employee/StateTaxes/management/useViewDictionary.ts @@ -7,6 +7,8 @@ import type { StateTaxesViewDictionary } from '../shared' * `Employee.Management.StateTaxes` namespace. Partner overrides supplied * through the management edit form's `dictionary` prop flow into the view * text via `t(...)` resolution at render time. + * + * @internal */ export function useManagementStateTaxesViewDictionary(): StateTaxesViewDictionary { const { t } = useTranslation('Employee.Management.StateTaxes') diff --git a/src/components/Employee/StateTaxes/onboarding/StateTaxes.tsx b/src/components/Employee/StateTaxes/onboarding/StateTaxes.tsx index dac948e22..be3904b43 100644 --- a/src/components/Employee/StateTaxes/onboarding/StateTaxes.tsx +++ b/src/components/Employee/StateTaxes/onboarding/StateTaxes.tsx @@ -12,13 +12,35 @@ import { useI18n, useComponentDictionary } from '@/i18n' import { componentEvents } from '@/shared/constants' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +/** + * Props for {@link StateTaxes}. + * + * @public + */ export type StateTaxesProps = Omit, 'children'> & { + /** The associated employee identifier. */ employeeId: string /** Render admin-only questions and submit them. Defaults to `false`. */ isAdmin?: boolean + /** Event handler fired when the form is submitted successfully. */ onEvent: BaseComponentInterface['onEvent'] } +/** + * Onboarding step that collects an employee's per-state tax withholding + * answers. The set of fields is driven by the API response for each state + * on record. + * + * @remarks + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/stateTaxes/updated` | Form was submitted successfully | `{ employeeStateTaxesList: EmployeeStateTaxesList[] }` | + * | `employee/stateTaxes/done` | Onboarding step has finished — emitted immediately after `updated` | — | + * + * @param props - The component props. + * @public + */ export function StateTaxes({ FallbackComponent, ...props diff --git a/src/components/Employee/StateTaxes/onboarding/useViewDictionary.ts b/src/components/Employee/StateTaxes/onboarding/useViewDictionary.ts index 047d3118a..9db4949f2 100644 --- a/src/components/Employee/StateTaxes/onboarding/useViewDictionary.ts +++ b/src/components/Employee/StateTaxes/onboarding/useViewDictionary.ts @@ -7,6 +7,8 @@ import type { StateTaxesViewDictionary } from '../shared' * `Employee.StateTaxes` namespace. Partner overrides supplied through the * onboarding block's `dictionary` prop flow into the view text via `t(...)` * resolution at render time. + * + * @internal */ export function useOnboardingStateTaxesViewDictionary(): StateTaxesViewDictionary { const { t } = useTranslation('Employee.StateTaxes') diff --git a/src/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.tsx b/src/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.tsx index d8d6dab2c..12b52469c 100644 --- a/src/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.tsx +++ b/src/components/Employee/StateTaxes/shared/EmployeeStateTaxesView.tsx @@ -24,9 +24,12 @@ type ReadyEmployeeStateTaxesForm = Extract< * * The underlying `Employee.StateTaxesView` namespace is an implementation * detail of the shared view — consumers shouldn't reference it directly. + * + * @internal */ export type StateTaxesViewDictionary = ResourceDictionary<'Employee.StateTaxesView'> +/** @internal */ export interface EmployeeStateTaxesViewProps { stateTaxes: ReadyEmployeeStateTaxesForm onSubmit: () => void | Promise @@ -42,6 +45,7 @@ export interface EmployeeStateTaxesViewProps { dictionary?: StateTaxesViewDictionary } +/** @internal */ export function EmployeeStateTaxesView({ stateTaxes, onSubmit, diff --git a/src/components/Employee/StateTaxes/shared/index.ts b/src/components/Employee/StateTaxes/shared/index.ts index 47e523186..deca66075 100644 --- a/src/components/Employee/StateTaxes/shared/index.ts +++ b/src/components/Employee/StateTaxes/shared/index.ts @@ -1,12 +1,2 @@ -export { - EmployeeStateTaxesView, - type EmployeeStateTaxesViewProps, - type StateTaxesViewDictionary, -} from './EmployeeStateTaxesView' +export { EmployeeStateTaxesView, type StateTaxesViewDictionary } from './EmployeeStateTaxesView' export * from './useEmployeeStateTaxesForm' -export { - useStateTaxesSummary, - type UseStateTaxesSummaryParams, - type UseStateTaxesSummaryReady, - type UseStateTaxesSummaryResult, -} from './useStateTaxesSummary' diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/employeeStateTaxesSchema.ts b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/employeeStateTaxesSchema.ts index f26444913..675305dd2 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/employeeStateTaxesSchema.ts +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/employeeStateTaxesSchema.ts @@ -1,6 +1,5 @@ import { z } from 'zod' import type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist' -import type { EmployeeStateTaxQuestion } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxquestion' import { getQuestionVariant, type StateTaxQuestionVariant } from './fieldMapping' import { snakeCaseToCamelCase } from '@/helpers/formattedStrings' import type { @@ -27,17 +26,42 @@ export const EmployeeStateTaxesErrorCodes = { REQUIRED: 'REQUIRED', } as const +/** + * Union of validation error code strings emitted by the employee state taxes + * form schema. + * + * @public + */ export type EmployeeStateTaxesErrorCode = (typeof EmployeeStateTaxesErrorCodes)[keyof typeof EmployeeStateTaxesErrorCodes] // ── Form data shape ──────────────────────────────────────────────────── +/** + * Union of value types a single state-tax answer may hold in the form. The + * shape depends on the API-provided question variant. + * + * @public + */ export type StateTaxValue = string | number | boolean | Date | null | undefined +/** + * Shape of the values managed by the employee state taxes form. Keyed by + * two-letter state code, then by question key (camelCased from the API key). + * + * @public + */ export interface EmployeeStateTaxesFormData { + /** Per-state answer map: state code → (camelCased question key → value). */ states: Record> } +/** + * Shape of the validated values produced by the employee state taxes form on + * submit. + * + * @public + */ export type EmployeeStateTaxesFormOutputs = EmployeeStateTaxesFormData // ── Empty-value detection ────────────────────────────────────────────── @@ -60,6 +84,7 @@ function isEmpty(value: unknown): boolean { // ── Schema factory ───────────────────────────────────────────────────── +/** @internal */ export interface EmployeeStateTaxesSchemaOptions { isAdmin?: boolean } @@ -81,6 +106,7 @@ interface QuestionEntry { initialValue: unknown } +/** @internal */ export interface EmployeeStateTaxesQuestionMeta { state: string isWorkState: boolean @@ -91,6 +117,7 @@ export interface EmployeeStateTaxesQuestionMeta { isWireSelectWithBooleanOptions: boolean } +/** @internal */ export interface EmployeeStateTaxesMetadataConfig extends FieldsMetadataConfig< Record > { @@ -102,6 +129,7 @@ export interface EmployeeStateTaxesMetadataConfig extends FieldsMetadataConfig< }> } +/** @internal */ export type EmployeeStateTaxesSchemaResult = [ schema: z.ZodType, metadataConfig: EmployeeStateTaxesMetadataConfig, @@ -261,5 +289,3 @@ function normalizeOptions( } return result.length > 0 ? result : undefined } - -export type EmployeeStateTaxesQuestion = EmployeeStateTaxQuestion diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.tsx b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.tsx index ce1143b13..4dd5f2ffb 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.tsx +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldComponents.tsx @@ -55,6 +55,7 @@ function useResolvedBaseProps( } } +/** @internal */ export function SelectStateTaxField({ meta, ...props }: MetaProps & SelectStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: SelectHookFieldProps = { @@ -65,6 +66,7 @@ export function SelectStateTaxField({ meta, ...props }: MetaProps & SelectStateT return } +/** @internal */ export function RadioStateTaxField({ meta, ...props }: MetaProps & RadioStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: RadioGroupHookFieldProps = { @@ -74,6 +76,7 @@ export function RadioStateTaxField({ meta, ...props }: MetaProps & RadioStateTax return } +/** @internal */ export function TextStateTaxField({ meta, ...props }: MetaProps & TextStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: TextInputHookFieldProps = { @@ -83,6 +86,7 @@ export function TextStateTaxField({ meta, ...props }: MetaProps & TextStateTaxFi return } +/** @internal */ export function NumberStateTaxField({ meta, ...props }: MetaProps & NumberStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: NumberInputHookFieldProps = { @@ -93,6 +97,7 @@ export function NumberStateTaxField({ meta, ...props }: MetaProps & NumberStateT return } +/** @internal */ export function CurrencyStateTaxField({ meta, ...props }: MetaProps & CurrencyStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: NumberInputHookFieldProps = { @@ -103,6 +108,7 @@ export function CurrencyStateTaxField({ meta, ...props }: MetaProps & CurrencySt return } +/** @internal */ export function DateStateTaxField({ meta, ...props }: MetaProps & DateStateTaxFieldProps) { const base = useResolvedBaseProps(meta, props) const hookProps: DatePickerHookFieldProps = { diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldMeta.ts b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldMeta.ts index 33c6110a9..60b049fa7 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldMeta.ts +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldMeta.ts @@ -1,4 +1,8 @@ -/** Per-question metadata baked into each bound Field component. */ +/** + * Per-question metadata baked into each bound Field component. + * + * @internal + */ export interface BoundFieldMeta { name: string apiLabel: string diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldProps.ts b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldProps.ts index e0b1876c0..d140b239e 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldProps.ts +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldProps.ts @@ -7,43 +7,95 @@ import type { TextInputProps } from '@/components/Common/UI/TextInput/TextInputT import type { NumberInputProps } from '@/components/Common/UI/NumberInput/NumberInputTypes' import type { DatePickerProps } from '@/components/Common/UI/DatePicker/DatePickerTypes' +/** + * Localized validation messages supported by the state-tax field components. + * Every variant surfaces a single error code, `REQUIRED`. + * + * @public + */ export type StateTaxValidationMessages = ValidationMessages< typeof EmployeeStateTaxesErrorCodes.REQUIRED > +/** + * Props shared by every state-tax `Field` variant. Each variant extends this + * with a variant-specific `FieldComponent` shape; `select` and `text` also add + * a `placeholder`. + * + * @public + */ export interface BaseStateTaxFieldProps { /** Overrides the API-supplied label. When omitted, falls back to `question.label`. */ label?: string /** Overrides the API-supplied description. When omitted, falls back to `question.description` * (sanitized internally by the underlying field via DOMPurify). */ description?: ReactNode + /** When using the hook outside an `SDKFormProvider`, pass the form-hook result here so the field can connect to it. */ formHookResult?: FormHookResult /** Override the default localized validation message(s). */ validationMessages?: StateTaxValidationMessages } +/** + * Props for a `Field` rendered as a select (dropdown). + * + * @public + */ export type SelectStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Placeholder shown when no option is selected. */ placeholder?: string + /** Replace the underlying SDK Select primitive with a component of your own. */ FieldComponent?: ComponentType } +/** + * Props for a `Field` rendered as a radio group. + * + * @public + */ export type RadioStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Replace the underlying SDK RadioGroup primitive with a component of your own. */ FieldComponent?: ComponentType } +/** + * Props for a `Field` rendered as a single-line text input. + * + * @public + */ export type TextStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Placeholder shown when the field is empty. */ placeholder?: string + /** Replace the underlying SDK TextInput primitive with a component of your own. */ FieldComponent?: ComponentType } +/** + * Props for a `Field` rendered as a decimal number input. + * + * @public + */ export type NumberStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Replace the underlying SDK NumberInput primitive with a component of your own. */ FieldComponent?: ComponentType } +/** + * Props for a `Field` rendered as a currency-formatted number input. + * + * @public + */ export type CurrencyStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Replace the underlying SDK NumberInput primitive with a component of your own. */ FieldComponent?: ComponentType } +/** + * Props for a `Field` rendered as a date picker. + * + * @public + */ export type DateStateTaxFieldProps = BaseStateTaxFieldProps & { + /** Replace the underlying SDK DatePicker primitive with a component of your own. */ FieldComponent?: ComponentType } diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx index b7de075bb..6079d4370 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx @@ -22,13 +22,11 @@ import type { import { snakeCaseToCamelCase } from '@/helpers/formattedStrings' export type { - BaseStateTaxFieldProps, CurrencyStateTaxFieldProps, DateStateTaxFieldProps, NumberStateTaxFieldProps, RadioStateTaxFieldProps, SelectStateTaxFieldProps, - StateTaxValidationMessages, TextStateTaxFieldProps, } from './fieldProps' @@ -43,6 +41,14 @@ interface SharedQuestionMetadata { description: string | null } +/** + * One question entry within a {@link StateTaxFieldsGroup}, discriminated by + * `type` to identify which input variant the question uses. Each entry carries + * a `Field` component pre-bound to its API-supplied metadata so callers can + * render the input directly. + * + * @public + */ export type StateTaxQuestionFieldEntry = | ({ type: 'select'; Field: ComponentType } & SharedQuestionMetadata) | ({ type: 'radio'; Field: ComponentType } & SharedQuestionMetadata) @@ -54,17 +60,27 @@ export type StateTaxQuestionFieldEntry = } & SharedQuestionMetadata) | ({ type: 'date'; Field: ComponentType } & SharedQuestionMetadata) +/** + * Group of state-tax questions for a single jurisdiction returned by + * {@link useStateFields}. + * + * @public + */ export interface StateTaxFieldsGroup { + /** Two-letter state code. */ state: string + /** Ordered list of question entries for this state, post admin-only filtering. */ questions: StateTaxQuestionFieldEntry[] } // ── Factory ──────────────────────────────────────────────────────────── +/** @internal */ export interface CreateStateFieldsOptions { isAdmin: boolean } +/** @internal */ export function createStateFields( employeeStateTaxes: EmployeeStateTaxesList[], options: CreateStateFieldsOptions, diff --git a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx index 603ca2448..6ebb6f940 100644 --- a/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx +++ b/src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx @@ -33,7 +33,13 @@ import { SDKInternalError } from '@/types/sdkError' const DEFAULT_TAX_VALID_FROM = '2010-01-01' +/** + * Options accepted by {@link useEmployeeStateTaxesForm}. + * + * @public + */ export interface UseEmployeeStateTaxesFormProps { + /** The UUID of the employee whose state taxes are being updated. */ employeeId: string /** * When `true`, admin-only questions are visible and submitted. When @@ -41,22 +47,35 @@ export interface UseEmployeeStateTaxesFormProps { * questions is preserved unchanged on submit. */ isAdmin?: boolean + /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */ validationMode?: UseFormProps['mode'] + /** Auto-focus the first invalid field on submit. Defaults to `true`. Set to `false` when composing with other forms. */ shouldFocusError?: boolean } +/** + * Ready-state return value of {@link useEmployeeStateTaxesForm} — the + * `isLoading: false` branch of {@link UseEmployeeStateTaxesFormResult}. + * + * @public + */ export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady< FieldsMetadata, EmployeeStateTaxesFormData, StateTaxFieldsGroup[] > { + /** Current per-state tax records returned by the server. */ data: { employeeStateTaxes: EmployeeStateTaxesList[] } + /** Submission status. `mode` is always `'update'` since state-tax records are created with the employee. */ status: { isPending: boolean; mode: 'update' } + /** Form actions. */ actions: { + /** Validates and submits the form, resolving to the updated records on success or `undefined` when validation blocked the submit. */ onSubmit: () => Promise | undefined> } + /** Form internals plus the iterable per-state `Fields` array. */ form: BaseFormHookReady< FieldsMetadata, EmployeeStateTaxesFormData, @@ -67,8 +86,83 @@ export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady< } } +/** + * Discriminated union returned by {@link useEmployeeStateTaxesForm}. Loading + * branch carries only `errorHandling`; ready branch carries form data, + * fields, status, and actions. + * + * @public + */ export type UseEmployeeStateTaxesFormResult = HookLoadingResult | UseEmployeeStateTaxesFormReady +/** + * Headless form hook for updating an employee's state tax withholding answers. + * The set of questions is driven by the API response per state, so + * `form.Fields` is an array of state groups with discriminated, render-ready + * `Field` components rather than a fixed named object. + * + * @remarks + * The state-tax record(s) are created automatically with the employee, so this + * hook is always in update mode. When the form has no states with submittable + * answers (e.g. an employee in a no-income-tax state), submit resolves with + * the existing record list without making a network request. + * + * @param props - Hook options. + * @returns A loading result while data is fetching, or a ready result with + * form data, fields, status, actions, and error handling. + * @public + * + * @example + * ```tsx + * import { + * useEmployeeStateTaxesForm, + * SDKFormProvider, + * type UseEmployeeStateTaxesFormReady, + * } from '@gusto/embedded-react-sdk' + * + * function StateTaxesPage({ employeeId }: { employeeId: string }) { + * const stateTaxes = useEmployeeStateTaxesForm({ employeeId }) + * + * if (stateTaxes.isLoading) return
Loading...
+ * + * return + * } + * + * function StateTaxesFormReady({ + * stateTaxes, + * }: { + * stateTaxes: UseEmployeeStateTaxesFormReady + * }) { + * const handleSubmit = async () => { + * const result = await stateTaxes.actions.onSubmit() + * if (result) console.log('Updated state tax records:', result.data) + * } + * + * return ( + * + *
{ + * e.preventDefault() + * void handleSubmit() + * }} + * > + * {stateTaxes.form.Fields.map(group => ( + *
+ *

{group.state}

+ * {group.questions.map(question => ( + * + * ))} + *
+ * ))} + * + *
+ *
+ * ) + * } + * ``` + */ export function useEmployeeStateTaxesForm({ employeeId, isAdmin = false, @@ -310,6 +404,19 @@ function serializeStatesPayload( return result } +/** + * Static field metadata keyed by full form path (`states..`), + * with `isRequired` / `isDisabled` and option lists. + * + * @public + */ export type EmployeeStateTaxesFieldsMetadata = UseEmployeeStateTaxesFormReady['form']['fieldsMetadata'] + +/** + * The array of per-state field groups exposed by + * {@link useEmployeeStateTaxesForm} on `form.Fields`. + * + * @public + */ export type EmployeeStateTaxesFormFields = UseEmployeeStateTaxesFormReady['form']['Fields'] diff --git a/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/index.ts b/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/index.ts index 24c1acc5d..b2fdd14a4 100644 --- a/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/index.ts +++ b/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/index.ts @@ -1,6 +1 @@ export { useStateTaxesSummary } from './useStateTaxesSummary' -export type { - UseStateTaxesSummaryParams, - UseStateTaxesSummaryReady, - UseStateTaxesSummaryResult, -} from './useStateTaxesSummary' diff --git a/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/useStateTaxesSummary.tsx b/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/useStateTaxesSummary.tsx index fb27aa043..57f6e920e 100644 --- a/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/useStateTaxesSummary.tsx +++ b/src/components/Employee/StateTaxes/shared/useStateTaxesSummary/useStateTaxesSummary.tsx @@ -3,24 +3,20 @@ import type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/mo import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult } from '@/partner-hook-utils/types' +/** @internal */ export interface UseStateTaxesSummaryParams { employeeId: string } -export type UseStateTaxesSummaryReady = BaseHookReady< +type UseStateTaxesSummaryReady = BaseHookReady< { employeeStateTaxesList: EmployeeStateTaxesList[] }, { isFetching: boolean; isPending: boolean } > +/** @internal */ export type UseStateTaxesSummaryResult = HookLoadingResult | UseStateTaxesSummaryReady -/** - * Read-only data hook for the State taxes management card. Wraps - * `useEmployeeTaxSetupGetStateTaxes` and returns the full list of - * per-state tax records in `BaseHookReady` shape. Mutations live in - * `useEmployeeStateTaxesForm` (the form-driven hook the edit form - * consumes). - */ +/** @internal */ export function useStateTaxesSummary({ employeeId, }: UseStateTaxesSummaryParams): UseStateTaxesSummaryResult { diff --git a/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.tsx b/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.tsx index e28792028..4627b1fe7 100644 --- a/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.tsx +++ b/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.tsx @@ -23,16 +23,69 @@ import { componentEvents } from '@/shared/constants' import { useComponentDictionary, useI18n } from '@/i18n' import { firstLastName } from '@/helpers/formattedStrings' +/** + * Props for {@link TerminateEmployee}. + * + * @public + */ export interface TerminateEmployeeProps extends BaseComponentInterface<'Employee.Terminations.TerminateEmployee'> { + /** The employee identifier to terminate. */ employeeId: string + /** The associated company identifier. */ companyId: string } +/** + * Form values collected by {@link TerminateEmployee}. + * + * @public + */ export interface TerminateEmployeeFormData { + /** The effective date of the termination — the employee's last day of work. */ lastDayOfWork: Date + /** How to process the employee's final paycheck. */ payrollOption: PayrollOption } +/** + * Standalone form for capturing an employee's termination details — last day of work and how to process final payroll. + * + * @remarks + * The main termination form used inside {@link TerminationFlow}. Detects existing + * terminations and pre-populates for editing when one is active, or routes to + * the summary view (via the `employee/termination/viewSummary` event) when the + * employee is already terminated. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/termination/created` | Fired when a new termination is created | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption }` | + * | `employee/termination/updated` | Fired when an existing termination is updated | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption }` | + * | `employee/termination/done` | Fired when the termination form is completed | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption, payrollUuid?: string }` | + * | `employee/termination/viewSummary` | Fired when redirecting to view an existing termination | `{ employeeId: string, effectiveDate: string }` | + * | `employee/termination/payrollCreated` | Fired after a dismissal-payroll period was successfully created | `{ payrolls: PayrollUnprocessed[] }` | + * | `employee/termination/payrollFailed` | Fired if creating a dismissal payroll fails | `{ employeeId: string, error: unknown }` | + * | `CANCEL` | Fired when the user clicks Cancel | — | + * + * @param props - See {@link TerminateEmployeeProps}. + * @returns The termination form. + * @public + * @group Block Components + * + * @example + * ```tsx + * import { EmployeeManagement } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function TerminateEmployee(props: TerminateEmployeeProps) { return ( diff --git a/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.tsx b/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.tsx index 716d3613c..67d7110fb 100644 --- a/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.tsx +++ b/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.tsx @@ -25,6 +25,7 @@ const terminateEmployeeSchema = z.object({ }), }) +/** @internal */ export function TerminateEmployeePresentation({ employeeName, existingTermination, diff --git a/src/components/Employee/Terminations/TerminationFlow/TerminationFlow.tsx b/src/components/Employee/Terminations/TerminationFlow/TerminationFlow.tsx index b456d3850..2d7e04356 100644 --- a/src/components/Employee/Terminations/TerminationFlow/TerminationFlow.tsx +++ b/src/components/Employee/Terminations/TerminationFlow/TerminationFlow.tsx @@ -9,6 +9,53 @@ import { TerminateEmployeeContextual } from './TerminationFlowComponents' import { Flow } from '@/components/Flow/Flow' import { buildBreadcrumbs } from '@/helpers/breadcrumbHelpers' +/** + * Guided workflow for terminating an employee — pick termination date, choose how to process final payroll, review details, and manage offboarding. + * + * @remarks + * Provides a complete experience for terminating an employee — guides the user through selecting a termination date, choosing how to process final payroll, reviewing termination details, and managing the offboarding process. Drives a multi-step flow with breadcrumb navigation between the termination form, the summary, and the dismissal payroll flow (when the partner selects the dismissal payroll option). + * + * On mount, the flow detects existing terminations: if an active termination exists, the form is pre-populated for editing; if the employee is already terminated, the user is routed to the summary view. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/termination/created` | Fired when a new termination is created | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption }` | + * | `employee/termination/updated` | Fired when an existing termination is updated | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption }` | + * | `employee/termination/done` | Fired when the termination process is complete | `{ employeeId: string, effectiveDate: string, payrollOption: PayrollOption, payrollUuid?: string }` | + * | `employee/termination/viewSummary` | Fired when viewing an existing termination summary | `{ employeeId: string, effectiveDate: string }` | + * | `employee/termination/edit` | Fired when user clicks to edit termination details | `{ employeeId: string }` | + * | `employee/termination/cancelled` | Fired when a termination is cancelled | `{ employeeId: string, alert?: `{@link TerminationFlowAlert}` }` | + * | `employee/termination/runPayroll` | Fired when user chooses to run termination payroll | `{ employeeId: string, companyId: string, effectiveDate: string }` | + * | `employee/termination/runOffCyclePayroll` | Fired when user chooses to run an off-cycle payroll | `{ employeeId: string, companyId: string }` | + * | `employee/termination/payrollCreated` | Fired when an off-cycle payroll is created for termination | `{ employeeId: string, effectiveDate: string }` | + * | `employee/termination/payrollFailed` | Fired when off-cycle payroll creation fails | `{ employeeId: string }` | + * + * The {@link PayrollOption} on each event identifies how the partner has chosen to handle the employee's final paycheck: + * + * - `dismissalPayroll` — Run a dismissal payroll (the most guided option). The flow swaps the employee's last regular payroll into a dismissal payroll with the termination date as the pay-period end and makes a default PTO payout recommendation. + * - `regularPayroll` — Include the final pay in the employee's next scheduled regular payroll. The termination can still be cancelled after the fact. + * - `anotherWay` — Handle final pay outside of Gusto. Triggers the off-cycle payroll creation flow and removes the employee from unprocessed future payrolls. The termination can still be cancelled after the fact. + * + * @param props - See {@link TerminationFlowProps}. + * @returns The multi-step termination workflow. + * @public + * @group Flow Components + * + * @example + * ```tsx + * import { EmployeeManagement } from '@gusto/embedded-react-sdk' + * + * function MyApp() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export const TerminationFlow = ({ companyId, employeeId, onEvent }: TerminationFlowProps) => { const terminationFlow = useMemo( () => diff --git a/src/components/Employee/Terminations/TerminationFlow/TerminationFlowComponents.tsx b/src/components/Employee/Terminations/TerminationFlow/TerminationFlowComponents.tsx index d8aecb99f..ead89167b 100644 --- a/src/components/Employee/Terminations/TerminationFlow/TerminationFlowComponents.tsx +++ b/src/components/Employee/Terminations/TerminationFlow/TerminationFlowComponents.tsx @@ -13,17 +13,33 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Props for {@link TerminationFlow}. + * + * @public + */ export interface TerminationFlowProps extends BaseComponentInterface { + /** The associated company identifier. */ companyId: string + /** The employee identifier to terminate. */ employeeId: string } +/** + * Alert payload surfaced by {@link TerminationFlow} on selected events (e.g. `employee/termination/cancelled`). + * + * @public + */ export type TerminationFlowAlert = { + /** Visual severity of the alert. */ type: 'error' | 'info' | 'success' + /** Alert title. */ title: string + /** Optional alert body content. */ content?: ReactNode } +/** @internal */ export interface TerminationFlowContextInterface extends FlowContextInterface { companyId: string employeeId: string @@ -32,6 +48,7 @@ export interface TerminationFlowContextInterface extends FlowContextInterface { alerts?: TerminationFlowAlert[] } +/** @internal */ export function TerminateEmployeeContextual() { const { companyId, employeeId, onEvent, alerts } = useFlow() const { Alert } = useComponentContext() @@ -53,6 +70,7 @@ export function TerminateEmployeeContextual() { ) } +/** @internal */ export function TerminationSummaryContextual() { const { companyId, employeeId, payrollOption, payrollUuid, onEvent } = useFlow() @@ -84,6 +102,7 @@ export function TerminationSummaryContextual() { ) } +/** @internal */ export function DismissalFlowContextual() { const { companyId, employeeId, payrollUuid, onEvent } = useFlow() @@ -97,6 +116,7 @@ export function DismissalFlowContextual() { ) } +/** @internal */ export function PayrollLandingContextual() { const { companyId, onEvent } = useFlow() diff --git a/src/components/Employee/Terminations/TerminationFlow/index.ts b/src/components/Employee/Terminations/TerminationFlow/index.ts deleted file mode 100644 index a9d4fde48..000000000 --- a/src/components/Employee/Terminations/TerminationFlow/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { TerminationFlow } from './TerminationFlow' -export type { TerminationFlowProps } from './TerminationFlowComponents' diff --git a/src/components/Employee/Terminations/TerminationFlow/terminationStateMachine.ts b/src/components/Employee/Terminations/TerminationFlow/terminationStateMachine.ts index b840739e9..1d7ecceeb 100644 --- a/src/components/Employee/Terminations/TerminationFlow/terminationStateMachine.ts +++ b/src/components/Employee/Terminations/TerminationFlow/terminationStateMachine.ts @@ -45,6 +45,7 @@ type EventPayloads = { } } +/** @internal */ export const terminationBreadcrumbNodes: BreadcrumbNodes = { form: { parent: null, @@ -118,6 +119,7 @@ const summaryBreadcrumbTransition = transition( reduce(toSummaryReducer), ) +/** @internal */ export const terminationMachine = { form: state( transition( diff --git a/src/components/Employee/Terminations/TerminationSummary/TerminationSummary.tsx b/src/components/Employee/Terminations/TerminationSummary/TerminationSummary.tsx index c2c56750e..d501127ac 100644 --- a/src/components/Employee/Terminations/TerminationSummary/TerminationSummary.tsx +++ b/src/components/Employee/Terminations/TerminationSummary/TerminationSummary.tsx @@ -16,13 +16,61 @@ import { useBase } from '@/components/Base/useBase' import { componentEvents } from '@/shared/constants' import { useComponentDictionary, useI18n } from '@/i18n' +/** + * Props for {@link TerminationSummary}. + * + * @public + */ export interface TerminationSummaryProps extends BaseComponentInterface<'Employee.Terminations.TerminationSummary'> { + /** The associated employee identifier. */ employeeId: string + /** The associated company identifier. */ companyId: string + /** The selected payroll processing option. When provided, the summary surfaces a success alert confirming the action taken. */ payrollOption?: PayrollOption + /** UUID of the created off-cycle payroll (when applicable). */ payrollUuid?: string } +/** + * Termination summary with edit, cancel, and run-payroll actions plus an offboarding checklist. + * + * @remarks + * Displays termination details and provides actions for managing the termination. Includes an offboarding checklist covering payroll timing, tax forms, and account disconnection. The available actions depend on the termination state: + * + * - **Edit** is available when the termination date is in the future and the employee is not yet terminated. The effective date cannot be edited if it is in the past. + * - **Cancel** is available when the termination is still cancellable — `regularPayroll` or `anotherWay` options can be cancelled; `dismissalPayroll` cannot. + * - **Run termination payroll** is shown for the `dismissalPayroll` option and navigates to the dismissal payroll flow. + * - **Run off-cycle payroll** is shown for the `anotherWay` option and navigates to the off-cycle payroll creation flow. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/termination/edit` | Fired when user clicks to edit termination details | `{ employeeId: string }` | + * | `employee/termination/cancelled` | Fired when a termination is successfully cancelled | `{ employeeId: string, alert?: `{@link TerminationFlowAlert}` }` | + * | `employee/termination/runPayroll` | Fired when user clicks to run termination payroll | `{ employeeId: string, companyId: string, effectiveDate: string }` | + * | `employee/termination/runOffCyclePayroll` | Fired when user clicks to run an off-cycle payroll | `{ employeeId: string, companyId: string }` | + * + * @param props - See {@link TerminationSummaryProps}. + * @returns The termination summary view. + * @public + * @group Block Components + * + * @example + * ```tsx + * import { EmployeeManagement } from '@gusto/embedded-react-sdk' + * + * function MyComponent() { + * return ( + * {}} + * /> + * ) + * } + * ``` + */ export function TerminationSummary(props: TerminationSummaryProps) { return ( diff --git a/src/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.tsx b/src/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.tsx index 8cd38da80..d39c3f0b7 100644 --- a/src/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.tsx +++ b/src/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.tsx @@ -23,6 +23,7 @@ interface TerminationSummaryPresentationProps { isCancelling: boolean } +/** @internal */ export function TerminationSummaryPresentation({ employeeName, effectiveDate, diff --git a/src/components/Employee/Terminations/TerminationsData.tsx b/src/components/Employee/Terminations/TerminationsData.tsx deleted file mode 100644 index 345b47bfc..000000000 --- a/src/components/Employee/Terminations/TerminationsData.tsx +++ /dev/null @@ -1,1431 +0,0 @@ -import { Suspense, useState } from 'react' -import { useQueryClient } from '@tanstack/react-query' -import { usePayrollsListSuspense } from '@gusto/embedded-api-v-2025-11-15/react-query/payrollsList' -import { usePaySchedulesGetUnprocessedTerminationPeriodsSuspense } from '@gusto/embedded-api-v-2025-11-15/react-query/paySchedulesGetUnprocessedTerminationPeriods' -import { - useEmployeesListSuspense, - invalidateAllEmployeesList, -} from '@gusto/embedded-api-v-2025-11-15/react-query/employeesList' -import { useGustoEmbeddedContext } from '@gusto/embedded-api-v-2025-11-15/react-query/_context' -import { payrollsPrepare } from '@gusto/embedded-api-v-2025-11-15/funcs/payrollsPrepare' -import { - ProcessingStatuses, - QueryParamPayrollTypes, -} from '@gusto/embedded-api-v-2025-11-15/models/operations/getv1companiescompanyidpayrolls' -// @ts-expect-error — module path may not exist in all API package versions -import { OffCycleReasonType } from '@gusto/embedded-api-v-2025-11-15/models/components/offcyclereasontype' -import type { Payroll } from '@gusto/embedded-api-v-2025-11-15/models/components/payroll' -import type { UnprocessedTerminationPayPeriod } from '@gusto/embedded-api-v-2025-11-15/models/components/unprocessedterminationpayperiod' -// @ts-expect-error — module path may not exist in all API package versions -import type { PayrollPrepared } from '@gusto/embedded-api-v-2025-11-15/models/components/payrollprepared' -import type { ShowEmployees } from '@gusto/embedded-api-v-2025-11-15/models/components/showemployees' -import { TerminateEmployee } from './TerminateEmployee/TerminateEmployee' -import { TerminationSummary } from './TerminationSummary/TerminationSummary' -import { TerminationFlow } from './TerminationFlow/TerminationFlow' -import { componentEvents } from '@/shared/constants' - -interface TerminationsDataProps { - companyId: string - useMockData?: boolean -} - -const MOCK_TERMINATION_PERIODS: UnprocessedTerminationPayPeriod[] = [ - { - employeeUuid: 'mock-employee-past-123', - employeeName: 'John Doe (Past Termination - 3 weeks ago)', - startDate: '2024-12-01', - endDate: '2024-12-07', - checkDate: '2024-12-10', - debitDate: '2024-12-08', - payScheduleUuid: 'mock-pay-schedule-1', - }, - { - employeeUuid: 'mock-employee-past-123', - employeeName: 'John Doe (Past Termination - 3 weeks ago)', - startDate: '2024-12-08', - endDate: '2024-12-14', - checkDate: '2024-12-17', - debitDate: '2024-12-15', - payScheduleUuid: 'mock-pay-schedule-1', - }, - { - employeeUuid: 'mock-employee-past-123', - employeeName: 'John Doe (Past Termination - 3 weeks ago)', - startDate: '2024-12-15', - endDate: '2024-12-21', - checkDate: '2024-12-24', - debitDate: '2024-12-22', - payScheduleUuid: 'mock-pay-schedule-1', - }, - { - employeeUuid: 'mock-employee-recent-456', - employeeName: 'Jane Smith (Recent Termination)', - startDate: '2024-12-22', - endDate: '2024-12-28', - checkDate: '2024-12-31', - debitDate: '2024-12-29', - payScheduleUuid: 'mock-pay-schedule-2', - }, -] - -const MOCK_TERMINATED_EMPLOYEES: ShowEmployees[] = [ - { - uuid: 'mock-employee-past-123', - firstName: 'John', - lastName: 'Doe', - terminated: true, - terminations: [ - { - effectiveDate: '2024-12-01', - active: true, - runTerminationPayroll: true, - cancelable: false, - }, - ], - } as ShowEmployees, - { - uuid: 'mock-employee-recent-456', - firstName: 'Jane', - lastName: 'Smith', - terminated: true, - terminations: [ - { - effectiveDate: '2024-12-22', - active: true, - runTerminationPayroll: true, - cancelable: true, - }, - ], - } as ShowEmployees, -] - -const MOCK_DISMISSAL_PAYROLLS: Payroll[] = [ - { - payrollUuid: 'mock-payroll-dismissal-1', - companyUuid: 'mock-company', - processed: false, - offCycle: true, - offCycleReason: OffCycleReasonType.DismissedEmployee, - checkDate: '2024-12-10', - payPeriod: { - startDate: '2024-12-01', - endDate: '2024-12-07', - }, - finalTerminationPayroll: true, - } as Payroll, - { - payrollUuid: 'mock-payroll-dismissal-2', - companyUuid: 'mock-company', - processed: false, - offCycle: true, - offCycleReason: OffCycleReasonType.DismissedEmployee, - checkDate: '2024-12-17', - payPeriod: { - startDate: '2024-12-08', - endDate: '2024-12-14', - }, - finalTerminationPayroll: true, - } as Payroll, - { - payrollUuid: 'mock-payroll-dismissal-3', - companyUuid: 'mock-company', - processed: false, - offCycle: true, - offCycleReason: OffCycleReasonType.DismissedEmployee, - checkDate: '2024-12-24', - payPeriod: { - startDate: '2024-12-15', - endDate: '2024-12-21', - }, - finalTerminationPayroll: true, - } as Payroll, - { - payrollUuid: 'mock-payroll-dismissal-4', - companyUuid: 'mock-company', - processed: false, - offCycle: true, - offCycleReason: OffCycleReasonType.DismissedEmployee, - checkDate: '2024-12-31', - payPeriod: { - startDate: '2024-12-22', - endDate: '2024-12-28', - }, - finalTerminationPayroll: true, - } as Payroll, -] - -type EmployeeInfo = { - uuid: string - firstName: string | null | undefined - lastName: string | null | undefined - excluded?: boolean -} - -const MOCK_EMPLOYEES_BY_PAYROLL: Record = { - 'mock-payroll-dismissal-1': [ - { uuid: 'mock-employee-past-123', firstName: 'John', lastName: 'Doe', excluded: false }, - ], - 'mock-payroll-dismissal-2': [ - { uuid: 'mock-employee-past-123', firstName: 'John', lastName: 'Doe', excluded: false }, - ], - 'mock-payroll-dismissal-3': [ - { uuid: 'mock-employee-past-123', firstName: 'John', lastName: 'Doe', excluded: false }, - ], - 'mock-payroll-dismissal-4': [ - { uuid: 'mock-employee-recent-456', firstName: 'Jane', lastName: 'Smith', excluded: false }, - ], -} - -const mockDataBannerStyles: React.CSSProperties = { - backgroundColor: '#fef3c7', - border: '2px dashed #f59e0b', - borderRadius: '8px', - padding: '12px 16px', - marginBottom: '24px', - display: 'flex', - alignItems: 'center', - gap: '12px', -} - -const mockBadgeStyles: React.CSSProperties = { - display: 'inline-block', - padding: '2px 8px', - borderRadius: '4px', - fontSize: '11px', - fontWeight: 600, - backgroundColor: '#f59e0b', - color: 'white', - marginLeft: '8px', - textTransform: 'uppercase', - letterSpacing: '0.5px', -} - -type PayrollCategory = 'Regular' | 'Off-Cycle' | 'Dismissal' - -const getPayrollCategory = (payroll: Payroll): PayrollCategory => { - if ( - payroll.offCycleReason === OffCycleReasonType.DismissedEmployee || - payroll.finalTerminationPayroll - ) { - return 'Dismissal' - } - if (payroll.offCycle) { - return 'Off-Cycle' - } - return 'Regular' -} - -const tableStyles: React.CSSProperties = { - width: '100%', - borderCollapse: 'collapse', - marginBottom: '24px', - fontSize: '14px', -} - -const thStyles: React.CSSProperties = { - textAlign: 'left', - padding: '12px 8px', - borderBottom: '2px solid #e5e7eb', - backgroundColor: '#f9fafb', - fontWeight: 600, -} - -const tdStyles: React.CSSProperties = { - padding: '12px 8px', - borderBottom: '1px solid #e5e7eb', -} - -const sectionStyles: React.CSSProperties = { - marginBottom: '32px', -} - -const headingStyles: React.CSSProperties = { - fontSize: '18px', - fontWeight: 600, - marginBottom: '16px', - color: '#111827', -} - -const badgeStyles: Record = { - Regular: { - display: 'inline-block', - padding: '2px 8px', - borderRadius: '4px', - fontSize: '12px', - fontWeight: 500, - backgroundColor: '#dbeafe', - color: '#1e40af', - }, - 'Off-Cycle': { - display: 'inline-block', - padding: '2px 8px', - borderRadius: '4px', - fontSize: '12px', - fontWeight: 500, - backgroundColor: '#fef3c7', - color: '#92400e', - }, - Dismissal: { - display: 'inline-block', - padding: '2px 8px', - borderRadius: '4px', - fontSize: '12px', - fontWeight: 500, - backgroundColor: '#fee2e2', - color: '#991b1b', - }, -} - -const boolDisplayValue = (value: boolean | null | undefined): string => { - if (value === true) return 'Yes' - if (value === false) return 'No' - return 'N/A' -} - -const tooltipStyles: React.CSSProperties = { - position: 'absolute', - bottom: '100%', - left: '50%', - transform: 'translateX(-50%)', - backgroundColor: '#1f2937', - color: 'white', - padding: '8px 12px', - borderRadius: '6px', - fontSize: '12px', - whiteSpace: 'normal', - zIndex: 1000, - marginBottom: '4px', - boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)', - maxWidth: '250px', - minWidth: '150px', -} - -const modalOverlayStyles: React.CSSProperties = { - position: 'fixed', - top: 0, - left: 0, - right: 0, - bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.5)', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - zIndex: 9999, -} - -const modalContentStyles: React.CSSProperties = { - backgroundColor: 'white', - borderRadius: '12px', - padding: '24px', - maxWidth: '600px', - width: '90%', - maxHeight: '90vh', - overflow: 'auto', - boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', -} - -const selectStyles: React.CSSProperties = { - width: '100%', - padding: '10px 12px', - fontSize: '14px', - border: '1px solid #d1d5db', - borderRadius: '6px', - backgroundColor: 'white', - cursor: 'pointer', - marginBottom: '20px', -} - -type PayrollEmployeeData = { - loading: boolean - loaded: boolean - employees: EmployeeInfo[] - error?: string -} - -function EmployeeCountCell({ - payroll, - companyId, - isMockData, -}: { - payroll: Payroll - companyId: string - isMockData?: boolean -}) { - const gustoEmbedded = useGustoEmbeddedContext() - const payrollId = payroll.payrollUuid || payroll.uuid - const isMockPayroll = payrollId?.startsWith('mock-') - - const mockEmployees = isMockPayroll && payrollId ? MOCK_EMPLOYEES_BY_PAYROLL[payrollId] || [] : [] - - const [employeeData, setEmployeeData] = useState(() => { - if (isMockPayroll) { - return { - loading: false, - loaded: true, - employees: mockEmployees, - } - } - return { - loading: false, - loaded: false, - employees: [], - } - }) - const [showTooltip, setShowTooltip] = useState(false) - - const loadEmployees = async () => { - if (isMockPayroll || employeeData.loaded || employeeData.loading) return - - setEmployeeData(prev => ({ ...prev, loading: true })) - - if (!payrollId) { - setEmployeeData({ loading: false, loaded: true, employees: [], error: 'No payroll ID' }) - return - } - - const result = await payrollsPrepare(gustoEmbedded, { companyId, payrollId }) - - if (!result.ok) { - setEmployeeData({ - loading: false, - loaded: true, - employees: [], - error: 'Failed to load', - }) - return - } - - const preparedPayroll = result.value as { payrollPrepared?: PayrollPrepared } - const employeeCompensations = preparedPayroll.payrollPrepared?.employeeCompensations || [] - - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - const employees: EmployeeInfo[] = employeeCompensations.map((ec: Record) => ({ - uuid: (ec.employeeUuid as string) || '', - firstName: ec.firstName as string | undefined, - lastName: ec.lastName as string | undefined, - excluded: ec.excluded as boolean | undefined, - })) - - setEmployeeData({ - loading: false, - loaded: true, - employees, - }) - } - - const getDisplayText = () => { - if (employeeData.loading) return 'Loading...' - if (employeeData.error) return 'Error' - if (employeeData.loaded) { - const active = employeeData.employees.filter(e => !e.excluded).length - const total = employeeData.employees.length - return active === total ? `${total}` : `${active}/${total}` - } - return 'Click to load' - } - - const renderEmployeeList = () => { - return ( -
    - {employeeData.employees.map((e, idx) => { - const name = `${e.firstName || ''} ${e.lastName || ''}`.trim() || 'Unknown' - return ( -
  • - {e.excluded ? `${name} (excluded)` : name} -
  • - ) - })} -
- ) - } - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault() - void loadEmployees() - } - } - - return ( - - - - ) -} - -function PayrollTable({ - payrolls, - companyId, - isMockData, -}: { - payrolls: Payroll[] - companyId: string - isMockData?: boolean -}) { - if (payrolls.length === 0) { - return

No payrolls found.

- } - - return ( - - - - - - - - - - - - - {isMockData && } - - - - {payrolls.map(payroll => { - const category = getPayrollCategory(payroll) - const payPeriodDisplay = payroll.payPeriod - ? `${payroll.payPeriod.startDate} - ${payroll.payPeriod.endDate}` - : 'N/A' - const isMockRow = payroll.payrollUuid?.startsWith('mock-') - - return ( - - - - - - - - - - - {isMockData && ( - - )} - - ) - })} - -
Pay PeriodCheck DateTypeEmployeesOff-CycleOff-Cycle ReasonFinal TermStatusPayroll IDSource
- {payPeriodDisplay} - {isMockRow && Mock} - {payroll.checkDate || 'N/A'} - {category} - {boolDisplayValue(payroll.offCycle)}{payroll.offCycleReason || '-'}{boolDisplayValue(payroll.finalTerminationPayroll)}{payroll.processed ? 'Processed' : 'Unprocessed'} - {payroll.payrollUuid || payroll.uuid} - - - {isMockRow ? 'Mock' : 'Real'} - -
- ) -} - -function TerminationPayPeriodsTable({ - periods, - isMockData, -}: { - periods: UnprocessedTerminationPayPeriod[] - isMockData?: boolean -}) { - if (periods.length === 0) { - return ( -

- No unprocessed termination pay periods found. -

- ) - } - - return ( - - - - - - - - - {isMockData && } - - - - {periods.map((period, index) => { - const payPeriodDisplay = - period.startDate && period.endDate ? `${period.startDate} - ${period.endDate}` : 'N/A' - const isMockRow = period.employeeUuid?.startsWith('mock-') - - return ( - - - - - - - {isMockData && ( - - )} - - ) - })} - -
EmployeePay PeriodCheck DateDebit DateEmployee IDSource
- {period.employeeName || 'Unknown'} - {isMockRow && Mock} - {payPeriodDisplay}{period.checkDate || 'N/A'}{period.debitDate || 'N/A'} - {period.employeeUuid} - - - {isMockRow ? 'Mock' : 'Real'} - -
- ) -} - -function TerminatedEmployeesTable({ - employees, - isMockData, - onViewSummary, -}: { - employees: ShowEmployees[] - isMockData?: boolean - onViewSummary: (employeeId: string) => void -}) { - if (employees.length === 0) { - return

No terminated employees found.

- } - - return ( - - - - - - - - - - {isMockData && } - - - - - {employees.map(employee => { - const termination = employee.terminations?.[0] - const employeeName = - `${employee.firstName || ''} ${employee.lastName || ''}`.trim() || 'Unknown' - const isMockRow = employee.uuid.startsWith('mock-') - - return ( - - - - - - - - {isMockData && ( - - )} - - - ) - })} - -
EmployeeEffective DateActiveDismissal PayrollCancelableEmployee IDSourceActions
- {employeeName} - {isMockRow && Mock} - {termination?.effectiveDate || 'N/A'} - - {termination?.active ? 'Terminated' : 'Scheduled'} - - {boolDisplayValue(termination?.runTerminationPayroll)}{boolDisplayValue(termination?.cancelable)} - {employee.uuid} - - - {isMockRow ? 'Mock' : 'Real'} - - - -
- ) -} - -interface TerminationModalProps { - isOpen: boolean - onClose: () => void - companyId: string - activeEmployees: ShowEmployees[] - onTerminationComplete: () => void -} - -function TerminationModal({ - isOpen, - onClose, - companyId, - activeEmployees, - onTerminationComplete, -}: TerminationModalProps) { - const [selectedEmployeeId, setSelectedEmployeeId] = useState('') - - if (!isOpen) return null - - const handleClose = () => { - onClose() - setSelectedEmployeeId('') - } - - const handleTerminationEvent = (event: string) => { - if (event === componentEvents.EMPLOYEE_TERMINATION_DONE || event === componentEvents.CANCEL) { - onTerminationComplete() - handleClose() - } - } - - return ( -
- -
- -
- - -
- - {selectedEmployeeId ? ( -
- - Loading employee data... -
- } - > - - - - ) : ( -

- Select an employee to begin the termination process. -

- )} - - - ) -} - -interface TerminationSummaryModalProps { - isOpen: boolean - onClose: () => void - companyId: string - employeeId: string | null -} - -function TerminationSummaryModal({ - isOpen, - onClose, - companyId, - employeeId, -}: TerminationSummaryModalProps) { - if (!isOpen || !employeeId) return null - - const handleEvent = (event: string) => { - if ( - event === componentEvents.EMPLOYEE_TERMINATION_CANCELLED || - event === componentEvents.EMPLOYEE_TERMINATION_EDIT || - event === componentEvents.EMPLOYEE_TERMINATION_RUN_PAYROLL || - event === componentEvents.EMPLOYEE_TERMINATION_RUN_OFF_CYCLE_PAYROLL - ) { - onClose() - } - } - - return ( -
- -
- - - Loading termination summary... - - } - > - - - - - ) -} - -interface TerminationFlowModalProps { - isOpen: boolean - onClose: () => void - companyId: string - activeEmployees: ShowEmployees[] - onTerminationComplete: () => void -} - -function TerminationFlowModal({ - isOpen, - onClose, - companyId, - activeEmployees, - onTerminationComplete, -}: TerminationFlowModalProps) { - const [selectedEmployeeId, setSelectedEmployeeId] = useState('') - - if (!isOpen) return null - - const handleClose = () => { - onClose() - setSelectedEmployeeId('') - } - - const handleFlowEvent = (event: string) => { - if ( - event === componentEvents.EMPLOYEE_TERMINATION_DONE || - event === componentEvents.CANCEL || - event === componentEvents.EMPLOYEE_TERMINATION_CANCELLED - ) { - onTerminationComplete() - handleClose() - } - } - - return ( -
- -
- -
- - -
- - {selectedEmployeeId ? ( -
- - Loading termination flow... -
- } - > - - - - ) : ( -

- Select an employee to begin the full termination flow. -

- )} - - - ) -} - -function TerminationsDataContent({ companyId, useMockData }: TerminationsDataProps) { - const queryClient = useQueryClient() - const [isModalOpen, setIsModalOpen] = useState(false) - const [isFlowModalOpen, setIsFlowModalOpen] = useState(false) - const [showMockData, setShowMockData] = useState(useMockData ?? false) - const [summaryEmployeeId, setSummaryEmployeeId] = useState(null) - - const today = new Date() - const threeMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 3, today.getDate()) - const threeMonthsFromNow = new Date(today.getFullYear(), today.getMonth() + 3, today.getDate()) - const formatDate = (date: Date) => date.toISOString().split('T')[0] - - const { data: payrollsData, refetch: refetchPayrolls } = usePayrollsListSuspense({ - companyId, - processingStatuses: [ProcessingStatuses.Unprocessed], - payrollTypes: [QueryParamPayrollTypes.Regular, QueryParamPayrollTypes.OffCycle], - includeOffCycle: true, - startDate: formatDate(threeMonthsAgo), - endDate: formatDate(threeMonthsFromNow), - }) - - const { data: terminationPeriodsData } = usePaySchedulesGetUnprocessedTerminationPeriodsSuspense({ - companyId, - }) - - const { data: terminatedEmployeesData } = useEmployeesListSuspense({ - companyId, - terminated: true, - }) - - const { data: activeEmployeesData } = useEmployeesListSuspense({ - companyId, - terminated: false, - onboarded: true, - }) - - const handleRefresh = () => { - void refetchPayrolls() - } - - const handleTerminationComplete = () => { - void invalidateAllEmployeesList(queryClient) - void refetchPayrolls() - } - - const realPayrollList = payrollsData.payrollList || [] - const realTerminationPeriods = terminationPeriodsData.unprocessedTerminationPayPeriods || [] - const realTerminatedEmployees = terminatedEmployeesData.showEmployees || [] - const activeEmployees = activeEmployeesData.showEmployees || [] - - const payrollList = showMockData - ? [...MOCK_DISMISSAL_PAYROLLS, ...realPayrollList] - : realPayrollList - - const terminationPeriods = showMockData - ? [...MOCK_TERMINATION_PERIODS, ...realTerminationPeriods] - : realTerminationPeriods - - const terminatedEmployees = showMockData - ? [...MOCK_TERMINATED_EMPLOYEES, ...realTerminatedEmployees] - : realTerminatedEmployees - - const regularPayrolls = payrollList.filter(p => getPayrollCategory(p) === 'Regular') - const offCyclePayrolls = payrollList.filter(p => getPayrollCategory(p) === 'Off-Cycle') - const dismissalPayrolls = payrollList.filter(p => getPayrollCategory(p) === 'Dismissal') - - const mockPeriodCount = showMockData ? MOCK_TERMINATION_PERIODS.length : 0 - const mockEmployeeCount = showMockData ? MOCK_TERMINATED_EMPLOYEES.length : 0 - const mockPayrollCount = showMockData ? MOCK_DISMISSAL_PAYROLLS.length : 0 - - return ( -
-
-

- Terminations Data - Payroll Overview -

-
- - - - -
-
- - {showMockData && ( -
- 🧪 -
- Mock Data Mode Enabled -

- Simulating a past-dated termination scenario: John Doe was terminated 3 weeks ago with{' '} - {mockPeriodCount} unprocessed pay periods and{' '} - {mockPayrollCount} corresponding dismissal payrolls (one for each - period). This demonstrates how our EmployeeTerminations component creates separate - payrolls for each unprocessed period. Mock rows are highlighted in yellow with a - "MOCK" badge. -

-
-
- )} - -
-
-
{payrollList.length}
-
Total Unprocessed
-
-
-
{regularPayrolls.length}
-
Regular
-
-
-
{offCyclePayrolls.length}
-
Off-Cycle
-
-
-
{dismissalPayrolls.length}
-
Dismissal
-
-
- -
-

- All Unprocessed Payrolls - {showMockData && ( - - +{mockPayrollCount} Mock Dismissal - - )} -

- -
- -
-

Regular Payrolls

- -
- -
-

Off-Cycle Payrolls

- -
- -
-

- Dismissal Payrolls - {showMockData && ( - +{mockPayrollCount} Mock - )} -

-

- Off-cycle payrolls created for dismissed employees. - {showMockData && ( - - {' '} - These 3 mock payrolls correspond to John Doe's 3 unprocessed pay periods - each - created by our EmployeeTerminations component. - - )} -

- -
- -
-

- Unprocessed Termination Pay Periods - {showMockData && ( - +{mockPeriodCount} Mock - )} -

-

- These are pay periods for employees who selected "Dismissal Payroll" as their - final payroll option. Match the pay period dates with the payrolls above to identify which - payroll corresponds to each terminated employee. - {showMockData && ( - - {' '} - Note: John Doe has 3 unprocessed pay periods (simulating a past-dated termination). - - )} -

- -
- -
-

- All Terminated Employees ({terminatedEmployees.length}) - {showMockData && ( - +{mockEmployeeCount} Mock - )} -

-

- All employees who have been terminated or are scheduled to be terminated. -

- -
- - { - setIsModalOpen(false) - }} - companyId={companyId} - activeEmployees={activeEmployees} - onTerminationComplete={handleTerminationComplete} - /> - - { - setSummaryEmployeeId(null) - }} - companyId={companyId} - employeeId={summaryEmployeeId} - /> - - { - setIsFlowModalOpen(false) - }} - companyId={companyId} - activeEmployees={activeEmployees} - onTerminationComplete={handleTerminationComplete} - /> -
- ) -} - -export function TerminationsData({ companyId, useMockData }: TerminationsDataProps) { - return ( - Loading payroll data...} - > - - - ) -} diff --git a/src/components/Employee/Terminations/index.tsx b/src/components/Employee/Terminations/index.tsx deleted file mode 100644 index 9812fcc05..000000000 --- a/src/components/Employee/Terminations/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export { TerminateEmployee } from './TerminateEmployee/TerminateEmployee' -export type { TerminateEmployeeProps } from './TerminateEmployee/TerminateEmployee' -export { TerminationSummary } from './TerminationSummary/TerminationSummary' -export type { TerminationSummaryProps } from './TerminationSummary/TerminationSummary' -export { TerminationFlow } from './TerminationFlow/TerminationFlow' -export type { TerminationFlowProps } from './TerminationFlow/TerminationFlowComponents' -export type { PayrollOption } from './types' diff --git a/src/components/Employee/Terminations/types.ts b/src/components/Employee/Terminations/types.ts index f61ceed9d..781759ab4 100644 --- a/src/components/Employee/Terminations/types.ts +++ b/src/components/Employee/Terminations/types.ts @@ -1 +1,17 @@ +/** + * How an employee's final paycheck is processed during {@link TerminationFlow}. + * + * @remarks + * - `dismissalPayroll` — Run a dismissal payroll. The most guided option: the + * employee's last regular payroll is swapped into a dismissal payroll with + * the termination date as the pay-period end and a default PTO payout + * recommendation. A termination created with this option cannot be cancelled. + * - `regularPayroll` — Include the final pay in the next scheduled regular + * payroll. The termination can still be cancelled after the fact. + * - `anotherWay` — Handle final pay outside of Gusto. Triggers the off-cycle + * payroll creation flow and removes the employee from unprocessed future + * payrolls. The termination can still be cancelled after the fact. + * + * @public + */ export type PayrollOption = 'dismissalPayroll' | 'regularPayroll' | 'anotherWay' diff --git a/src/components/Employee/WorkAddress/management/WorkAddress.tsx b/src/components/Employee/WorkAddress/management/WorkAddress.tsx index 55ef62757..8af317bfc 100644 --- a/src/components/Employee/WorkAddress/management/WorkAddress.tsx +++ b/src/components/Employee/WorkAddress/management/WorkAddress.tsx @@ -16,8 +16,15 @@ import { useComponentDictionary } from '@/i18n/I18n' import { useI18n } from '@/i18n' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link WorkAddress}. + * + * @public + */ export interface WorkAddressProps extends CommonComponentInterface<'Employee.Management.WorkAddress'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on flow state changes. */ onEvent: OnEventType } @@ -37,6 +44,20 @@ function WorkAddressFlow({ employeeId, onEvent }: WorkAddressProps) { return } +/** + * Standalone employee work address management flow. + * + * @remarks + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/workAddress/editRequested` | Manage button on the work address card clicked | `{ employeeId: string }` | + * | `employee/management/workAddress/editCancelled` | User backed out of the edit form | — | + * | `employee/management/workAddress/created` | A new work address was created | {@link EmployeeWorkAddress} | + * | `employee/management/workAddress/updated` | An existing work address was updated | {@link EmployeeWorkAddress} | + * | `employee/management/workAddress/deleted` | A work address was deleted | {@link EmployeeWorkAddress} | + * + * @public + */ export function WorkAddress({ dictionary, FallbackComponent, diff --git a/src/components/Employee/WorkAddress/management/WorkAddressCard/WorkAddressCard.tsx b/src/components/Employee/WorkAddress/management/WorkAddressCard/WorkAddressCard.tsx index c440344a3..2c4e357a8 100644 --- a/src/components/Employee/WorkAddress/management/WorkAddressCard/WorkAddressCard.tsx +++ b/src/components/Employee/WorkAddress/management/WorkAddressCard/WorkAddressCard.tsx @@ -8,18 +8,29 @@ import { useI18n } from '@/i18n' import { componentEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +/** + * Props for {@link WorkAddressCard}. + * + * @public + */ export interface WorkAddressCardProps { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when the card's Manage button is clicked. */ onEvent: OnEventType } /** - * Standalone "Work address" card. Owns its own data fetch via - * `useEmployeeWorkAddressSummary` and emits - * `EMPLOYEE_MANAGEMENT_WORK_ADDRESS_EDIT_REQUESTED` when the Manage button - * is clicked. The card has no alert API — alert rendering is the - * orchestrator's responsibility (block's `WorkAddressCardContextual` for - * standalone consumption, dashboard chrome for dashboard consumption). + * Standalone employee work address summary card. + * + * @remarks + * Fetches the employee's active work address and renders it alongside a Manage button. + * + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/workAddress/editRequested` | Manage button clicked | `{ employeeId: string }` | + * + * @public */ export function WorkAddressCard(props: WorkAddressCardProps) { return ( diff --git a/src/components/Employee/WorkAddress/management/WorkAddressComponents.tsx b/src/components/Employee/WorkAddress/management/WorkAddressComponents.tsx index dfb959fb6..863d25d04 100644 --- a/src/components/Employee/WorkAddress/management/WorkAddressComponents.tsx +++ b/src/components/Employee/WorkAddress/management/WorkAddressComponents.tsx @@ -3,15 +3,18 @@ import { WorkAddressEditForm } from './WorkAddressEditForm' import { useFlow, type FlowContextInterface } from '@/components/Flow/useFlow' import { ensureRequired } from '@/helpers/ensureRequired' +/** @internal */ export interface WorkAddressContextInterface extends FlowContextInterface { employeeId?: string } +/** @internal */ export function WorkAddressCardContextual() { const { employeeId, onEvent } = useFlow() return } +/** @internal */ export function WorkAddressEditFormContextual() { const { employeeId, onEvent } = useFlow() return diff --git a/src/components/Employee/WorkAddress/management/WorkAddressEditForm.tsx b/src/components/Employee/WorkAddress/management/WorkAddressEditForm.tsx index 906851d72..05792819a 100644 --- a/src/components/Employee/WorkAddress/management/WorkAddressEditForm.tsx +++ b/src/components/Employee/WorkAddress/management/WorkAddressEditForm.tsx @@ -14,8 +14,15 @@ import { useI18n, useComponentDictionary } from '@/i18n' import type { HookSubmitResult } from '@/partner-hook-utils/types' import { componentEvents } from '@/shared/constants' +/** + * Props for {@link WorkAddressEditForm}. + * + * @public + */ export interface WorkAddressEditFormProps extends CommonComponentInterface<'Employee.Management.WorkAddress'> { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired on form save, cancel, and delete actions. */ onEvent: BaseComponentInterface['onEvent'] } @@ -61,6 +68,19 @@ function WorkAddressEditFormRoot({ employeeId, dictionary, onEvent }: WorkAddres ) } +/** + * Standalone employee work address edit form for creating, updating, and deleting addresses. + * + * @remarks + * | Event | Description | Data | + * | ----- | ----------- | ---- | + * | `employee/management/workAddress/created` | A new work address was created | {@link EmployeeWorkAddress} | + * | `employee/management/workAddress/updated` | An existing work address was updated | {@link EmployeeWorkAddress} | + * | `employee/management/workAddress/deleted` | A work address was deleted | {@link EmployeeWorkAddress} | + * | `employee/management/workAddress/editCancelled` | User backed out of the edit form | — | + * + * @public + */ export function WorkAddressEditForm({ FallbackComponent, ...props diff --git a/src/components/Employee/WorkAddress/management/WorkAddressView.tsx b/src/components/Employee/WorkAddress/management/WorkAddressView.tsx index b9e3ded92..69c4d7b55 100644 --- a/src/components/Employee/WorkAddress/management/WorkAddressView.tsx +++ b/src/components/Employee/WorkAddress/management/WorkAddressView.tsx @@ -30,6 +30,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { addDays, formatDateLongWithYear, normalizeToDate } from '@/helpers/dateFormatting' import { getCityStateZip, getStreet } from '@/helpers/formattedStrings' +/** @internal */ export interface WorkAddressViewProps { editWorkAddressForm: UseWorkAddressFormReady changeWorkAddressForm: UseWorkAddressFormReady @@ -69,6 +70,7 @@ function formatWorkAddressLines( return { primary: street, secondary: locality } } +/** @internal */ export function WorkAddressView({ editWorkAddressForm, changeWorkAddressForm, diff --git a/src/components/Employee/WorkAddress/management/getPendingFutureWorkAddress.ts b/src/components/Employee/WorkAddress/management/getPendingFutureWorkAddress.ts index caa82ffc2..13333bb8c 100644 --- a/src/components/Employee/WorkAddress/management/getPendingFutureWorkAddress.ts +++ b/src/components/Employee/WorkAddress/management/getPendingFutureWorkAddress.ts @@ -5,6 +5,7 @@ import { addressInline } from '@/helpers/formattedStrings' const startOfLocalDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()) +/** @internal */ export function getPendingFutureWorkAddress( addresses: EmployeeWorkAddress[] | undefined, now: Date = new Date(), @@ -43,6 +44,7 @@ export function getPendingFutureWorkAddress( return pending[0] } +/** @internal */ export function formatPendingWorkAddressLine( address: EmployeeWorkAddress, companyLocations: Location[] | undefined, diff --git a/src/components/Employee/WorkAddress/management/useWorkAddressManagement.tsx b/src/components/Employee/WorkAddress/management/useWorkAddressManagement.tsx index b7f54356f..06f1672e2 100644 --- a/src/components/Employee/WorkAddress/management/useWorkAddressManagement.tsx +++ b/src/components/Employee/WorkAddress/management/useWorkAddressManagement.tsx @@ -20,12 +20,19 @@ import { firstLastName } from '@/helpers/formattedStrings' import { normalizeToSDKError, SDKInternalError } from '@/types/sdkError' import { componentEvents, type EventType } from '@/shared/constants' +/** + * Params for {@link useWorkAddressManagement}. + * + * @public + */ export interface UseWorkAddressManagementParams { + /** The associated employee identifier. */ employeeId: string + /** Event handler fired when a work address is deleted. */ onEvent: OnEventType } -export interface UseWorkAddressManagementDataPendingForms extends Record { +interface UseWorkAddressManagementDataPendingForms extends Record { employeeDisplayName: string employeeWorkAddresses: EmployeeWorkAddress[] | undefined editTargetUuid: string | undefined @@ -33,7 +40,7 @@ export interface UseWorkAddressManagementDataPendingForms extends Record { +interface UseWorkAddressManagementDataReady extends Record { employeeDisplayName: string employeeWorkAddresses: EmployeeWorkAddress[] | undefined editTargetUuid: string | undefined @@ -41,41 +48,59 @@ export interface UseWorkAddressManagementDataReady extends Record { +interface UseWorkAddressManagementStatusEmployeeError extends Record { isDeletePending: boolean isEmployeeError: true } -export interface UseWorkAddressManagementStatusSuccess extends Record { +interface UseWorkAddressManagementStatusSuccess extends Record { isDeletePending: boolean isEmployeeError: false } -export interface UseWorkAddressManagementActions { +interface UseWorkAddressManagementActions { setEditTargetUuid: (workAddressUuid: string | undefined) => void confirmDeleteWorkAddress: (workAddressUuid: string) => Promise } -export interface UseWorkAddressManagementReadyEmployeeError extends BaseHookReady< +interface UseWorkAddressManagementReadyEmployeeError extends BaseHookReady< UseWorkAddressManagementDataPendingForms, UseWorkAddressManagementStatusEmployeeError > { actions: UseWorkAddressManagementActions } +/** + * Ready state of {@link useWorkAddressManagement} when the employee was fetched successfully. + * + * @public + */ export interface UseWorkAddressManagementReadySuccess extends BaseHookReady< UseWorkAddressManagementDataReady, UseWorkAddressManagementStatusSuccess > { + /** Actions for changing the edit target and confirming work address deletion. */ actions: UseWorkAddressManagementActions } -export type UseWorkAddressManagementReady = +type UseWorkAddressManagementReady = | UseWorkAddressManagementReadyEmployeeError | UseWorkAddressManagementReadySuccess +/** + * Return type of {@link useWorkAddressManagement}. + * + * @public + */ export type UseWorkAddressManagementResult = HookLoadingResult | UseWorkAddressManagementReady +/** + * Type guard for the success branch of {@link useWorkAddressManagement}. + * + * @param value - The hook result to narrow. + * @returns `true` when the hook has finished loading and the employee fetch succeeded. + * @public + */ export function isUseWorkAddressManagementSuccess( value: UseWorkAddressManagementResult, ): value is UseWorkAddressManagementReadySuccess { @@ -101,6 +126,19 @@ function workAddressFormsReady( } } +/** + * Headless hook for managing an employee's work addresses. + * + * @remarks + * Fetches the employee and their work addresses, exposes edit and change form hooks + * for the address modal, and provides an action to delete a non-active address. + * Use {@link isUseWorkAddressManagementSuccess} to narrow the ready state when the + * employee fetch succeeded. + * + * @param params - {@link UseWorkAddressManagementParams} + * @returns A {@link HookLoadingResult} while loading, or the ready state once data is available. + * @public + */ export function useWorkAddressManagement({ employeeId, onEvent, diff --git a/src/components/Employee/WorkAddress/management/workAddressStateMachine.ts b/src/components/Employee/WorkAddress/management/workAddressStateMachine.ts index 936ab50b6..32bc22e2d 100644 --- a/src/components/Employee/WorkAddress/management/workAddressStateMachine.ts +++ b/src/components/Employee/WorkAddress/management/workAddressStateMachine.ts @@ -12,6 +12,7 @@ const returnToCard = reduce( }), ) +/** @internal */ export const workAddressStateMachine = { card: state( transition( diff --git a/src/components/Employee/WorkAddress/shared/index.ts b/src/components/Employee/WorkAddress/shared/index.ts deleted file mode 100644 index eee2dcf67..000000000 --- a/src/components/Employee/WorkAddress/shared/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useEmployeeWorkAddressSummary } from './useEmployeeWorkAddressSummary' -export type { - UseEmployeeWorkAddressSummaryParams, - UseEmployeeWorkAddressSummaryReady, - UseEmployeeWorkAddressSummaryResult, -} from './useEmployeeWorkAddressSummary' diff --git a/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/index.ts b/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/index.ts index eee2dcf67..01d3e185b 100644 --- a/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/index.ts +++ b/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/index.ts @@ -1,6 +1 @@ export { useEmployeeWorkAddressSummary } from './useEmployeeWorkAddressSummary' -export type { - UseEmployeeWorkAddressSummaryParams, - UseEmployeeWorkAddressSummaryReady, - UseEmployeeWorkAddressSummaryResult, -} from './useEmployeeWorkAddressSummary' diff --git a/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/useEmployeeWorkAddressSummary.tsx b/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/useEmployeeWorkAddressSummary.tsx index 051371186..94e2f2e2d 100644 --- a/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/useEmployeeWorkAddressSummary.tsx +++ b/src/components/Employee/WorkAddress/shared/useEmployeeWorkAddressSummary/useEmployeeWorkAddressSummary.tsx @@ -3,23 +3,39 @@ import type { EmployeeWorkAddress } from '@gusto/embedded-api-v-2025-11-15/model import { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler' import type { BaseHookReady, HookLoadingResult } from '@/partner-hook-utils/types' +/** + * Params for {@link useEmployeeWorkAddressSummary}. + * + * @public + */ export interface UseEmployeeWorkAddressSummaryParams { + /** The associated employee identifier. */ employeeId: string } -export type UseEmployeeWorkAddressSummaryReady = BaseHookReady< +type UseEmployeeWorkAddressSummaryReady = BaseHookReady< { currentWorkAddress: EmployeeWorkAddress | undefined }, { isFetching: boolean; isPending: boolean } > +/** + * Return type of {@link useEmployeeWorkAddressSummary}. + * + * @public + */ export type UseEmployeeWorkAddressSummaryResult = | HookLoadingResult | UseEmployeeWorkAddressSummaryReady /** - * Read-only data hook for the Work address management card. Wraps - * `useEmployeeAddressesGetWorkAddresses` and selects the active row, returning - * `BaseHookReady`-shaped data. Mutations live in the work-address forms hook. + * Read-only data hook for the employee work address summary card. + * + * @remarks + * Fetches the employee's work addresses and selects the active row. + * + * @param params - {@link UseEmployeeWorkAddressSummaryParams} + * @returns A {@link HookLoadingResult} while loading, or the ready state with `currentWorkAddress` once data is available. + * @public */ export function useEmployeeWorkAddressSummary({ employeeId, diff --git a/src/components/Employee/exports/employeeManagement.ts b/src/components/Employee/exports/employeeManagement.ts index 995fd00cf..aee40ed95 100644 --- a/src/components/Employee/exports/employeeManagement.ts +++ b/src/components/Employee/exports/employeeManagement.ts @@ -1,4 +1,8 @@ -export { ManagementEmployeeList as EmployeeList } from '../EmployeeList/management/ManagementEmployeeList' +export { + ManagementEmployeeList as EmployeeList, + type ManagementEmployeeListProps, + type EmployeeTab, +} from '../EmployeeList/management/ManagementEmployeeList' export { EmployeeListFlow } from '../EmployeeListFlow' export type { EmployeeListFlowProps } from '../EmployeeListFlow' export { Documents, DocumentsCard, DocumentManager } from '../Documents/management' @@ -7,8 +11,8 @@ export type { DocumentsCardProps, DocumentManagerProps, } from '../Documents/management' -export { DashboardFlow } from '../Dashboard' -export type { DashboardFlowProps } from '../Dashboard' +export { DashboardFlow, Dashboard } from '../Dashboard' +export type { DashboardFlowProps, DashboardProps } from '../Dashboard' export { HomeAddress, HomeAddressCard, HomeAddressEditForm } from '../HomeAddress/management' export type { HomeAddressProps, @@ -68,5 +72,9 @@ export type { CompensationAddAnotherJobFormProps, } from '../Compensation/management' export { TerminateEmployee } from '../Terminations/TerminateEmployee/TerminateEmployee' +export type { TerminateEmployeeProps } from '../Terminations/TerminateEmployee/TerminateEmployee' export { TerminationSummary } from '../Terminations/TerminationSummary/TerminationSummary' +export type { TerminationSummaryProps } from '../Terminations/TerminationSummary/TerminationSummary' export { TerminationFlow } from '../Terminations/TerminationFlow/TerminationFlow' +export type { TerminationFlowProps } from '../Terminations/TerminationFlow/TerminationFlowComponents' +export type { PayrollOption } from '../Terminations/types' diff --git a/src/components/Employee/exports/employeeOnboarding.ts b/src/components/Employee/exports/employeeOnboarding.ts index 026bb4cdb..888e6212c 100644 --- a/src/components/Employee/exports/employeeOnboarding.ts +++ b/src/components/Employee/exports/employeeOnboarding.ts @@ -1,20 +1,40 @@ -export { OnboardingFlow } from '../OnboardingFlow/OnboardingFlow' +export { OnboardingFlow, type OnboardingFlowProps } from '../OnboardingFlow/OnboardingFlow' export { OnboardingExecutionFlow, type OnboardingExecutionFlowProps, type OnboardingExecutionInitialState, + type OnboardingDefaultValues, } from '../OnboardingExecutionFlow' export { SelfOnboardingFlow } from '../SelfOnboardingFlow/SelfOnboardingFlow' -export { EmployeeList } from '../EmployeeList/onboarding/EmployeeList' +export { EmployeeList, type EmployeeListProps } from '../EmployeeList/onboarding/EmployeeList' export { OnboardingSummary } from '../OnboardingSummary' export { Landing } from '../Landing' -export { DocumentSigner } from '../Documents/onboarding/DocumentSigner' -export { EmploymentEligibility } from '../Documents/onboarding/DocumentSigner/EmploymentEligibility' -export { EmployeeDocuments } from '../Documents/onboarding/EmployeeDocuments' +export { DocumentSigner, type DocumentSignerProps } from '../Documents/onboarding/DocumentSigner' +export { + EmploymentEligibility, + type EmploymentEligibilityProps, +} from '../Documents/onboarding/DocumentSigner/EmploymentEligibility' +export { + EmployeeDocuments, + type EmployeeDocumentsProps, +} from '../Documents/onboarding/EmployeeDocuments' -export { Profile } from '../Profile/onboarding/Profile' -export { Compensation } from '../Compensation' +export { + Profile, + type ProfileProps, + type ProfileDefaultValues, +} from '../Profile/onboarding/Profile' +export { + Compensation, + type CompensationProps, + type CompensationDefaultValues, +} from '../Compensation' +export { JobsList, type JobsListProps } from '../Compensation/onboarding/JobsList' +export { + EditCompensation, + type EditCompensationProps, +} from '../Compensation/onboarding/EditCompensation' export { FederalTaxes, type FederalTaxesProps } from '../FederalTaxes/onboarding/FederalTaxes' export { StateTaxes, type StateTaxesProps } from '../StateTaxes/onboarding' -export { Deductions } from '../Deductions' +export { Deductions, type DeductionsProps } from '../Deductions' export { PaymentMethod, type PaymentMethodProps } from '../PaymentMethod/onboarding' diff --git a/src/components/Payroll/Dismissal/index.ts b/src/components/Payroll/Dismissal/index.ts index 5e0615866..c1c3df404 100644 --- a/src/components/Payroll/Dismissal/index.ts +++ b/src/components/Payroll/Dismissal/index.ts @@ -1,2 +1,4 @@ export { DismissalFlow } from './DismissalFlow' export type { DismissalFlowProps, DismissalFlowContextInterface } from './DismissalFlowComponents' +export { DismissalPayPeriodSelection } from './DismissalPayPeriodSelection' +export type { DismissalPayPeriodSelectionProps } from './DismissalPayPeriodSelection' diff --git a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.test.tsx b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.test.tsx index d9b5e9610..73d67310d 100644 --- a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.test.tsx +++ b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.test.tsx @@ -951,7 +951,7 @@ describe('PayrollEditEmployeePresentation', () => { expect(screen.getByText('$25.00')).toBeInTheDocument() }) - it('always renders the reimbursements section header and Add link when withReimbursements is true', () => { + it('always renders the reimbursements section header and empty-state Add button when withReimbursements is true', () => { const propsWithoutReimbursements = { ...defaultPropsWithAdditionalEarnings, employeeCompensation: { @@ -1411,7 +1411,7 @@ describe('PayrollEditEmployeePresentation', () => { }, } - it('renders the Add one-time reimbursement link', async () => { + it('renders the empty-state Add reimbursement button when no reimbursements exist', async () => { renderWithProviders() expect( @@ -1592,11 +1592,7 @@ describe('PayrollEditEmployeePresentation', () => { expect(await screen.findByText('Phone stipend')).toBeInTheDocument() expect(screen.getByText('$50.00')).toBeInTheDocument() - expect( - screen.getByRole('img', { - name: 'Recurring reimbursements are managed outside of payroll.', - }), - ).toBeInTheDocument() + expect(screen.getByText('Recurring')).toBeInTheDocument() expect(screen.queryByLabelText(/Description/i)).not.toBeInTheDocument() expect(screen.queryByLabelText('Amount')).not.toBeInTheDocument() expect(screen.queryByRole('button', { name: /Remove/i })).not.toBeInTheDocument() diff --git a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx index 6e89a65d0..9fc51136c 100644 --- a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx +++ b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx @@ -15,7 +15,15 @@ import { z } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' import styles from './PayrollEditEmployeePresentation.module.scss' import { TimeOffField, PayoutTimeOffField } from './TimeOffField' -import { Flex, Grid, TextInputField, RadioGroupField } from '@/components/Common' +import { + Flex, + Grid, + TextInputField, + RadioGroupField, + DataView, + useDataView, + EmptyData, +} from '@/components/Common' import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' import { useI18n } from '@/i18n' import { Form } from '@/components/Common/Form' @@ -38,7 +46,6 @@ import { import useContainerBreakpoints from '@/hooks/useContainerBreakpoints/useContainerBreakpoints' import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' import TrashCanSvg from '@/assets/icons/trashcan.svg?react' -import InfoIcon from '@/assets/icons/info.svg?react' interface PayrollEditEmployeeProps { onSave: (updatedCompensation: PayrollEmployeeCompensationsType) => void @@ -386,6 +393,14 @@ export const PayrollEditEmployeePresentation = ({ } } + type VisibleReimbursementRow = (typeof reimbursementFields)[number] & { + originalIndex: number + } + + const visibleReimbursementRows: VisibleReimbursementRow[] = reimbursementFields + .map((field, originalIndex) => ({ ...field, originalIndex })) + .filter(row => parseFloat(row.amount || '0') !== 0) + const [isAddingReimbursement, setIsAddingReimbursement] = useState(false) const [draftReimbursementDescription, setDraftReimbursementDescription] = useState('') const [draftReimbursementAmount, setDraftReimbursementAmount] = useState('') @@ -412,6 +427,56 @@ export const PayrollEditEmployeePresentation = ({ resetReimbursementDraft() } + const reimbursementDataViewProps = useDataView({ + data: visibleReimbursementRows, + columns: [ + { + key: 'description', + title: t('reimbursementDescriptionColumn'), + render: row => row.description.trim() || t('reimbursementUnnamedFallback'), + }, + { + key: 'amount', + title: t('reimbursementAmountColumn'), + render: row => formatNumberAsCurrency(parseFloat(row.amount || '0')), + }, + { + key: 'recurring', + title: t('reimbursementTypeColumn'), + render: row => + row.recurring ? t('reimbursementTypeRecurring') : t('reimbursementTypeOneTime'), + }, + ], + itemMenu: row => { + if (row.recurring) return null + const displayDescription = row.description.trim() || t('reimbursementUnnamedFallback') + return ( + { + handleRemoveReimbursement(row.originalIndex) + }} + aria-label={t('removeReimbursementLabel', { description: displayDescription })} + > + + + ) + }, + emptyState: () => ( + + + + ), + }) + const watchedFormData = useWatch({ control: formHandlers.control, }) @@ -652,56 +717,9 @@ export const PayrollEditEmployeePresentation = ({ {withReimbursements && usesItemizedReimbursements && (
{t('reimbursementTitle')} - {reimbursementFields.map((field, index) => { - const isSoftDeleted = parseFloat(field.amount || '0') === 0 - if (isSoftDeleted) { - return null - } - - const displayDescription = - field.description.trim() || t('reimbursementUnnamedFallback') - const formattedAmount = formatNumberAsCurrency(parseFloat(field.amount || '0')) - - if (field.recurring) { - return ( - - {displayDescription} - - {formattedAmount} - - - - ) - } - - return ( - - {displayDescription} - - {formattedAmount} - { - handleRemoveReimbursement(index) - }} - aria-label={t('removeReimbursementLabel', { - description: displayDescription, - })} - > - - - - - ) - })} + {!(visibleReimbursementRows.length === 0 && isAddingReimbursement) && ( + + )} {isAddingReimbursement ? ( @@ -733,18 +751,20 @@ export const PayrollEditEmployeePresentation = ({ ) : ( -
- -
+ visibleReimbursementRows.length > 0 && ( +
+ +
+ ) )}
)} diff --git a/src/components/Payroll/index.ts b/src/components/Payroll/index.ts index 7ce162248..598812150 100644 --- a/src/components/Payroll/index.ts +++ b/src/components/Payroll/index.ts @@ -37,6 +37,8 @@ export { OffCycleFlow } from './OffCycle' export type { OffCycleFlowContextInterface, OffCycleFlowProps } from './OffCycle' export { DismissalFlow } from './Dismissal' export type { DismissalFlowProps, DismissalFlowContextInterface } from './Dismissal' +export { DismissalPayPeriodSelection } from './Dismissal' +export type { DismissalPayPeriodSelectionProps } from './Dismissal' export { TransitionFlow } from './Transition' export type { TransitionFlowContextInterface, TransitionFlowProps } from './Transition' export { TransitionCreation } from './TransitionCreation' diff --git a/src/components/TimeOff/index.ts b/src/components/TimeOff/index.ts index 6dc6ee2f4..94a361c05 100644 --- a/src/components/TimeOff/index.ts +++ b/src/components/TimeOff/index.ts @@ -4,8 +4,10 @@ export { PolicyTypeSelector } from './PolicyTypeSelector/PolicyTypeSelector' export type { PolicyTypeSelectorProps } from './PolicyTypeSelector/PolicyTypeSelector' export { PolicyConfigurationForm } from './TimeOffManagement/PolicyConfigurationForm' export type { PolicyConfigurationFormProps } from './TimeOffManagement/PolicyConfigurationForm' -export { PolicySettingsPresentation as PolicySettings } from './PolicySettings/PolicySettingsPresentation' -export type { PolicySettingsPresentationProps as PolicySettingsProps } from './PolicySettings/PolicySettingsTypes' +export { PolicySettings } from './PolicySettings/PolicySettings' +export type { PolicySettingsProps } from './PolicySettings/PolicySettings' +export { PolicySettingsPresentation } from './PolicySettings/PolicySettingsPresentation' +export type { PolicySettingsPresentationProps } from './PolicySettings/PolicySettingsTypes' export { AddEmployeesToPolicy } from './AddEmployeesToPolicy/AddEmployeesToPolicy' export type { AddEmployeesToPolicyProps } from './AddEmployeesToPolicy/AddEmployeesToPolicy' export { HolidaySelectionForm } from './HolidaySelectionForm/HolidaySelectionForm' @@ -22,6 +24,8 @@ export type { HolidayPolicyDetailPresentationProps, HolidayPolicyDetailEmployee, } from './HolidayPolicyDetail' +export { TimeOffPolicyDetail } from './TimeOffPolicyDetail/TimeOffPolicyDetail' +export type { TimeOffPolicyDetailProps } from './TimeOffPolicyDetail/TimeOffPolicyDetail' export { TimeOffPolicyDetailPresentation } from './TimeOffPolicyDetail' export type { TimeOffPolicyDetailPresentationProps, diff --git a/src/components/index.ts b/src/components/index.ts index 1f2a2596a..edaa98802 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,9 +1,3 @@ -/** @deprecated Use `CompanyOnboarding` (or future `CompanyManagement`) instead. Will be removed in a future major version. */ -export * as Company from './Company' -/** @deprecated Use `ContractorOnboarding` (or future `ContractorManagement`) instead. Will be removed in a future major version. */ -export * as Contractor from './Contractor' -/** @deprecated Use `EmployeeOnboarding` or `EmployeeManagement` instead. Will be removed in a future major version. */ -export * as Employee from './Employee' export * as InformationRequests from './InformationRequests' export * as Payroll from './Payroll' export * as TimeOff from './TimeOff' @@ -13,3 +7,4 @@ export * as EmployeeOnboarding from './Employee/exports/employeeOnboarding' export * as EmployeeManagement from './Employee/exports/employeeManagement' export * as CompanyOnboarding from './Company/exports/companyOnboarding' export * as ContractorOnboarding from './Contractor/exports/contractorOnboarding' +export * as ContractorManagement from './Contractor/exports/contractorManagement' diff --git a/src/contexts/GustoApiProvider/index.ts b/src/contexts/GustoApiProvider/index.ts deleted file mode 100644 index b4500f6bf..000000000 --- a/src/contexts/GustoApiProvider/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** @deprecated Import from `GustoProvider` instead */ -export * from '../GustoProvider' diff --git a/src/contexts/GustoProvider/GustoProvider.tsx b/src/contexts/GustoProvider/GustoProvider.tsx index 3f1bcb2a3..0d1b1491d 100644 --- a/src/contexts/GustoProvider/GustoProvider.tsx +++ b/src/contexts/GustoProvider/GustoProvider.tsx @@ -62,11 +62,3 @@ const GustoProvider: React.FC = props => { } export { GustoProvider } - -/** - * Alias for {@link GustoProvider}. - * - * @deprecated Use {@link GustoProvider} instead. - * @public - */ -export const GustoApiProvider = GustoProvider diff --git a/src/contexts/GustoProvider/index.ts b/src/contexts/GustoProvider/index.ts index e9fb5be04..25c9c629e 100644 --- a/src/contexts/GustoProvider/index.ts +++ b/src/contexts/GustoProvider/index.ts @@ -1,4 +1,4 @@ -export { GustoProvider, GustoApiProvider } from './GustoProvider' +export { GustoProvider } from './GustoProvider' export type { GustoApiProps } from './GustoProvider' export { GustoProviderCustomUIAdapter } from './GustoProviderCustomUIAdapter' diff --git a/src/contexts/index.ts b/src/contexts/index.ts index ffcc6b2ab..d930da31c 100644 --- a/src/contexts/index.ts +++ b/src/contexts/index.ts @@ -1,4 +1,3 @@ -export { GustoApiProvider } from './GustoApiProvider' export { GustoProvider, GustoProviderCustomUIAdapter } from './GustoProvider' export type { GustoProviderProps, diff --git a/src/i18n/I18n.ts b/src/i18n/I18n.ts index 7294707ed..2c80a63f8 100644 --- a/src/i18n/I18n.ts +++ b/src/i18n/I18n.ts @@ -74,7 +74,7 @@ export const useI18n = ( | Array | null, ) => { - //Getting our instance of i18n -> supplied by the provider set in GustoApiProvider + //Getting our instance of i18n -> supplied by the provider set in GustoProvider const { i18n: i18nInstance } = useTranslation() //Abort when namespace is not provided if (!namespaces) return @@ -96,7 +96,7 @@ export const useI18n = ( resource, true, false, - ) //Last argument is set to false to prevent override of keys provided by partners on GustoApiProvider level through dictionary prop + ) //Last argument is set to false to prevent override of keys provided by partners on GustoProvider level through dictionary prop } } } diff --git a/src/i18n/en/Payroll.PayrollEditEmployee.json b/src/i18n/en/Payroll.PayrollEditEmployee.json index bbcbffb95..e56311736 100644 --- a/src/i18n/en/Payroll.PayrollEditEmployee.json +++ b/src/i18n/en/Payroll.PayrollEditEmployee.json @@ -25,6 +25,14 @@ "reimbursementDescriptionPlaceholder": "e.g., Office supplies", "reimbursementAmountLabel": "Amount", "reimbursementUnnamedFallback": "Reimbursement", + "reimbursementsTableLabel": "Reimbursements", + "reimbursementDescriptionColumn": "Description", + "reimbursementAmountColumn": "Amount", + "reimbursementTypeColumn": "Type", + "reimbursementTypeRecurring": "Recurring", + "reimbursementTypeOneTime": "One-time", + "reimbursementEmptyTitle": "No reimbursements", + "addReimbursementCta": "Add one-time reimbursement", "addReimbursementLink": "Add one-time reimbursement", "saveReimbursementCta": "Save reimbursement", "cancelReimbursementCta": "Cancel reimbursement", diff --git a/src/index.ts b/src/index.ts index 78588bd62..46405e3e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export { EmployeeSelfOnboardingStatuses, ContractorOnboardingStatus, ContractorSelfOnboardingStatuses, + PAY_PERIODS, } from '@/shared/constants' export type { EventType } from '@/shared/constants' export type { @@ -93,6 +94,13 @@ export { useDeductionForm, DeductionFormErrorCodes, createDeductionFormSchema, + DescriptionField, + RecurringField, + DeductAsPercentageField, + AmountField as DeductionAmountField, + TotalAmountField, + AnnualMaximumField, + GarnishmentTypeField, } from '@/components/Employee/Deductions/shared/useDeductionForm' export type { UseDeductionFormProps, @@ -123,6 +131,14 @@ export { createChildSupportGarnishmentFormSchema, getRequiredAttrKeys, SUPPORTED_REQUIRED_ATTR_KEYS, + StateField as ChildSupportStateField, + FipsCodeField, + CaseNumberField, + OrderNumberField, + RemittanceNumberField, + PayPeriodMaximumField, + AmountField as ChildSupportAmountField, + PaymentPeriodField, } from '@/components/Employee/Deductions/shared/useChildSupportGarnishmentForm' export type { UseChildSupportGarnishmentFormProps, @@ -155,6 +171,13 @@ export { useCompensationForm, CompensationErrorCodes, createCompensationSchema, + TitleField as CompensationTitleField, + FlsaStatusField as CompensationFlsaStatusField, + RateField as CompensationRateField, + PaymentUnitField as CompensationPaymentUnitField, + AdjustForMinimumWageField as CompensationAdjustForMinimumWageField, + MinimumWageIdField as CompensationMinimumWageIdField, + EffectiveDateField as CompensationEffectiveDateField, } from '@/components/Employee/Compensation/shared/useCompensationForm' export type { CompensationSubmitOptions, @@ -184,6 +207,11 @@ export { useJobForm, JobErrorCodes, createJobSchema, + JobTitleField, + HireDateField, + TwoPercentShareholderField, + StateWcCoveredField, + StateWcClassCodeField, } from '@/components/Employee/Compensation/shared/useJobForm' export type { JobSubmitOptions, @@ -208,10 +236,18 @@ export { useEmployeeDetailsForm, EmployeeDetailsErrorCodes, createEmployeeDetailsSchema, + FirstNameField, + MiddleInitialField, + LastNameField, + EmailField, + DateOfBirthField, + SsnField, + SelfOnboardingField, } from '@/components/Employee/Profile/shared/useEmployeeDetailsForm' export type { EmployeeDetailsSubmitCallbacks, EmployeeDetailsOptionalFieldsToRequire, + UseEmployeeDetailsFormSharedProps, UseEmployeeDetailsFormProps, UseEmployeeDetailsFormResult, UseEmployeeDetailsFormReady, @@ -232,6 +268,8 @@ export type { DateOfBirthFieldProps, SsnFieldProps, SelfOnboardingFieldProps, + SsnRequiredValidation, + EmployeeDetailsFields, } from '@/components/Employee/Profile/shared/useEmployeeDetailsForm' export { @@ -239,6 +277,8 @@ export { useCurrentWorkAddressForm, WorkAddressErrorCodes, createWorkAddressSchema, + LocationField as WorkAddressLocationField, + EffectiveDateField as WorkAddressEffectiveDateField, } from '@/components/Employee/Profile/shared/useWorkAddressForm' export type { WorkAddressSubmitCallbacks, @@ -257,6 +297,7 @@ export type { WorkAddressRequiredValidation, LocationFieldProps, EffectiveDateFieldProps, + WorkAddressFields, } from '@/components/Employee/Profile/shared/useWorkAddressForm' export { @@ -264,6 +305,13 @@ export { useCurrentHomeAddressForm, HomeAddressErrorCodes, createHomeAddressSchema, + Street1Field, + Street2Field, + CityField, + StateField as HomeAddressStateField, + ZipField, + CourtesyWithholdingField, + EffectiveDateField as HomeAddressEffectiveDateField, } from '@/components/Employee/Profile/shared/useHomeAddressForm' export type { HomeAddressSubmitOptions, @@ -287,6 +335,7 @@ export type { ZipFieldProps, CourtesyWithholdingFieldProps, HomeAddressEffectiveDateFieldProps, + HomeAddressFields, } from '@/components/Employee/Profile/shared/useHomeAddressForm' export { @@ -294,6 +343,10 @@ export { BankFormErrorCodes, createBankFormSchema, ACCOUNT_TYPES, + NameField, + RoutingNumberField, + AccountNumberField, + AccountTypeField, } from '@/components/Employee/PaymentMethod/shared/useBankForm' export type { BankFormSubmitOptions, @@ -322,6 +375,7 @@ export { PaymentMethodFormErrorCodes, createPaymentMethodFormSchema, PAYMENT_METHOD_TYPES, + PaymentMethodTypeField, } from '@/components/Employee/PaymentMethod/shared/usePaymentMethodForm' export type { UsePaymentMethodFormProps, @@ -370,6 +424,12 @@ export { FederalTaxesErrorCodes, createFederalTaxesSchema, FILING_STATUS_VALUES, + FilingStatusField, + TwoJobsField, + DependentsAmountField, + OtherIncomeField, + DeductionsField, + ExtraWithholdingField, } from '@/components/Employee/FederalTaxes/shared/useFederalTaxesForm' export { useEmployeeStateTaxesForm, @@ -432,6 +492,9 @@ export { MAX_PREPARERS, PREPARER_FIELDS_BY_INDEX, preparerFieldName, + SignatureField, + ConfirmSignatureField, + UsedPreparerField, } from '@/components/Employee/Documents/shared/useSignEmployeeForm' export type { UseSignEmployeeFormProps, @@ -452,6 +515,7 @@ export type { ConfirmSignatureFieldProps as SignEmployeeFormConfirmSignatureFieldProps, UsedPreparerFieldProps, PreparerTextFieldProps, + PreparerSelectFieldProps, PreparerCheckboxFieldProps, } from '@/components/Employee/Documents/shared/useSignEmployeeForm' diff --git a/src/shared/constants.ts b/src/shared/constants.ts index 3d84f13e5..3856e543f 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -715,7 +715,11 @@ export const SIGNATORY_TITLES = { MEMBER: 'member', } as const -/** @internal */ +/** + * Pay period unit values for the `paymentUnit` field on a compensation, describing the unit a pay rate is expressed against. + * + * @public + */ export const PAY_PERIODS = { HOUR: 'Hour', WEEK: 'Week', diff --git a/src/types/i18next.d.ts b/src/types/i18next.d.ts index a60039314..9ed3faff2 100644 --- a/src/types/i18next.d.ts +++ b/src/types/i18next.d.ts @@ -3359,6 +3359,14 @@ export interface PayrollPayrollEditEmployee{ "reimbursementDescriptionPlaceholder":string; "reimbursementAmountLabel":string; "reimbursementUnnamedFallback":string; +"reimbursementsTableLabel":string; +"reimbursementDescriptionColumn":string; +"reimbursementAmountColumn":string; +"reimbursementTypeColumn":string; +"reimbursementTypeRecurring":string; +"reimbursementTypeOneTime":string; +"reimbursementEmptyTitle":string; +"addReimbursementCta":string; "addReimbursementLink":string; "saveReimbursementCta":string; "cancelReimbursementCta":string;