Skip to content

fix: wire TIME_OFF_EDIT_POLICY and TIME_OFF_CHANGE_SETTINGS transitions#1695

Merged
jeffredodd merged 3 commits intomainfrom
fix/wire-edit-policy-and-change-settings-transitions
May 6, 2026
Merged

fix: wire TIME_OFF_EDIT_POLICY and TIME_OFF_CHANGE_SETTINGS transitions#1695
jeffredodd merged 3 commits intomainfrom
fix/wire-edit-policy-and-change-settings-transitions

Conversation

@jeffredodd
Copy link
Copy Markdown
Contributor

@jeffredodd jeffredodd commented May 6, 2026

Summary

Wires up two missing transitions on viewTimeOffPolicyDetail and ensures the Change settings round-trip actually returns to the policy detail view.

  • TIME_OFF_EDIT_POLICYpolicyDetailsForm (reduces policyId into context)
  • TIME_OFF_CHANGE_SETTINGSeditPolicySettings (reduces policyId into context)
  • New editPolicySettings state whose TIME_OFF_POLICY_SETTINGS_DONE and TIME_OFF_POLICY_SETTINGS_BACK transitions return to viewTimeOffPolicyDetail with policyId preserved. The create-flow policySettings state and its outbound routing (DONE → addEmployeesToPolicy, BACK → policyDetailsForm) are unchanged.
  • PolicySettings invalidates the policy cache after a successful update so the detail view re-renders with fresh data.
  • Renamed EditPolicyPayloadPolicyIdPayload since the same payload shape is used by both edit-policy and change-settings transitions.

Why a separate editPolicySettings state

The original wiring (PR initial commit) routed TIME_OFF_CHANGE_SETTINGS into the same policySettings state used by the create flow. That state's DONE and BACK transitions assume create-flow continuation: DONE → add-employees, BACK → create-policy form. So Change settings would dump the user into the add-employees flow on save and into the create form on back. Splitting the edit path into its own state keeps the create-flow wiring intact and gives the edit path the right round-trip without conditionals.

Scope note: PolicyConfigurationForm edit-mode is still a follow-up

PolicySettings already supports edit mode (loads via useTimeOffPoliciesGetSuspense, saves via useTimeOffPoliciesUpdateMutation), so Change settings now works end-to-end.

PolicyConfigurationForm (the policy-details form) remains create-only. After this PR, Edit policy still navigates to that form, but the form will be empty and submit would attempt to create a new policy. The form's edit-mode (prefill via useTimeOffPoliciesGetSuspense + useTimeOffPoliciesUpdateMutation + return-to-detail on submit) is a follow-up — likely a parallel editPolicyDetailsForm state mirroring the pattern introduced here. Coordinate with Kristine before starting.

This is PR 10 in the time-off bug-fix slate captured in ~/.claude/plans/ok-i-want-to-partitioned-balloon.md.

Addresses Copilot review feedback

  • Renamed EditPolicyPayloadPolicyIdPayload (Copilot, timeOffStateMachine.ts:23).
  • Fixed the policySettings round-trip routing for the edit flow by introducing editPolicySettings (Copilot, line 309 of the prior diff).
  • Added round-trip coverage for the edit-from-detail path (Copilot, timeOffStateMachine.test.ts:340).

Test plan

  • npm run test -- --run src/components/UNSTABLE_TimeOff/TimeOffFlow/ src/components/UNSTABLE_TimeOff/PolicySettings/ — 71/71 passing (added DONE/BACK/CANCEL round-trip tests + a regression test pinning the create-flow DONE behavior)
  • npm run test -- --run src/components/UNSTABLE_TimeOff — 303/303 passing (full TimeOff suite)
  • npx tsc --noEmit — clean
  • npm run lint — clean
  • Manual: from a sick policy detail → click Change on the Settings card → form opens prefilled with the policy's current settings → save returns to the same policy detail with the updated values shown
  • Manual: same flow, but click Back instead of save → returns to the same policy detail unchanged
  • Manual (known limitation): from a sick policy detail → click Edit policy → verify the form is reached. Form will be empty and submit would create a duplicate policy — that is the deferred follow-up scope.

🤖 Generated with Claude Code

The Edit policy and Change settings buttons on the time-off policy
detail screen emit TIME_OFF_EDIT_POLICY and TIME_OFF_CHANGE_SETTINGS,
but viewTimeOffPolicyDetail had no matching transitions, so both
buttons appeared to do nothing.

Add transitions on viewTimeOffPolicyDetail for both events that reduce
the payload's policyId into context:
  - TIME_OFF_EDIT_POLICY → policyDetailsForm
  - TIME_OFF_CHANGE_SETTINGS → policySettings

PolicySettings already accepts an existing policyId and prefills its
form via useTimeOffPoliciesGetSuspense, so Change settings works
end-to-end after this state-machine wiring. The PolicyConfigurationForm
side currently only supports create — its edit-mode (prefill +
useTimeOffPoliciesUpdateMutation) is a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeffredodd jeffredodd force-pushed the fix/wire-edit-policy-and-change-settings-transitions branch from 2920e87 to 100b8d4 Compare May 6, 2026 02:36
@jeffredodd jeffredodd marked this pull request as ready for review May 6, 2026 02:45
@jeffredodd jeffredodd requested a review from dmortal as a code owner May 6, 2026 02:45
Copilot AI review requested due to automatic review settings May 6, 2026 02:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR wires missing state-machine transitions for the time-off policy detail screen so that the Edit policy and Change settings buttons actually navigate to their intended flows within UNSTABLE_TimeOff/TimeOffFlow.

Changes:

  • Added TIME_OFF_EDIT_POLICY -> policyDetailsForm transition from viewTimeOffPolicyDetail, reducing policyId into context.
  • Added TIME_OFF_CHANGE_SETTINGS -> policySettings transition from viewTimeOffPolicyDetail, reducing policyId into context.
  • Added unit tests covering these two new transitions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/components/UNSTABLE_TimeOff/TimeOffFlow/timeOffStateMachine.ts Adds the missing transitions from the policy detail state to the edit/details form and settings form.
src/components/UNSTABLE_TimeOff/TimeOffFlow/timeOffStateMachine.test.ts Adds regression tests validating the new transitions fire and carry policyId.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

type PolicyCreatedPayload = { policyId: string; accrualMethod?: string }
type ErrorPayload = { alert?: TimeOffFlowAlert }
type ViewPolicyPayload = { policyId: string; policyType: 'sick' | 'vacation' | 'holiday' }
type EditPolicyPayload = { policyId: string }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed to PolicyIdPayload in 03ff1c7 since the same shape is used by both TIME_OFF_EDIT_POLICY and TIME_OFF_CHANGE_SETTINGS.

Comment on lines +294 to +309
transition(
componentEvents.TIME_OFF_CHANGE_SETTINGS,
'policySettings',
reduce(
(
ctx: TimeOffFlowContextInterface,
ev: { payload: EditPolicyPayload },
): TimeOffFlowContextInterface => ({
...ctx,
component: PolicySettingsContextual,
policyId: ev.payload.policyId,
alerts: undefined,
}),
),
),
backToListTransition,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — fixed in 03ff1c7. Added a dedicated editPolicySettings state whose TIME_OFF_POLICY_SETTINGS_DONE and TIME_OFF_POLICY_SETTINGS_BACK transitions return to viewTimeOffPolicyDetail with policyId preserved, and re-pointed the TIME_OFF_CHANGE_SETTINGS transition there. The create-flow policySettings state and its outbound routing are unchanged. Also pinned a regression test that the create-flow DONE still routes to addEmployeesToPolicy.


expect(service.machine.current).toBe('policySettings')
expect(service.context.policyId).toBe('policy-existing')
})
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added round-trip coverage in 03ff1c7 — tests for DONE → viewTimeOffPolicyDetail, BACK → viewTimeOffPolicyDetail, and CANCEL → policyList from editPolicySettings, plus a regression test pinning the create-flow DONE behavior.

The TIME_OFF_CHANGE_SETTINGS transition reused the create-flow
policySettings state, where TIME_OFF_POLICY_SETTINGS_DONE routes to
addEmployeesToPolicy and TIME_OFF_POLICY_SETTINGS_BACK routes to
policyDetailsForm. From the policy detail view, that meant saving
settings dumped the user into the add-employees flow and hitting
back dumped them into the create-policy form.

Add a dedicated editPolicySettings state whose DONE/BACK transitions
return to viewTimeOffPolicyDetail so the round-trip lands the user
back where they came from with policyId preserved. Re-point the
TIME_OFF_CHANGE_SETTINGS transition to the new state. The create
flow's policySettings state and its outgoing transitions are
unchanged.

Also invalidate the policy cache in PolicySettings on a successful
update so the detail view re-renders with fresh data, and rename
EditPolicyPayload → PolicyIdPayload now that the same payload shape
is used for both edit-policy and change-settings.

Addresses Copilot review feedback on PR #1695.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…and-change-settings-transitions

# Conflicts:
#	src/components/UNSTABLE_TimeOff/TimeOffFlow/timeOffStateMachine.test.ts
#	src/components/UNSTABLE_TimeOff/TimeOffFlow/timeOffStateMachine.ts
@jeffredodd jeffredodd enabled auto-merge (squash) May 6, 2026 16:17
@jeffredodd jeffredodd merged commit d038c66 into main May 6, 2026
19 checks passed
@jeffredodd jeffredodd deleted the fix/wire-edit-policy-and-change-settings-transitions branch May 6, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants