feat: scaffold CompanyManagement.PaySchedule with PayScheduleOverview - #2746
mariechatfield wants to merge 4 commits into
Conversation
…ScheduleOverview Adds the new CompanyManagement namespace behind the managePaySchedules unstable feature flag, per SDK-1292. PayScheduleOverview shows a single pay schedule's name, frequency, and (opt-in) AutoPilot status, reusing the existing PayScheduleForm for editing. Manage and AutoPilot Edit are wired to emit events but don't transition anywhere yet — that lands in follow-up tickets for PayScheduleAssignment and AutoPilotDialog. Also wires the new namespace into the sdk-app dev harness (registry, prop-analysis script, default props) so it's previewable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
| // PayScheduleEditFormContextual reuses the onboarding PayScheduleForm, whose translations | ||
| // live under its own namespace and are otherwise never loaded from this flow. | ||
| useI18n('Company.PaySchedule') |
There was a problem hiding this comment.
I'm not sure it makes sense to use the onboarding version of pay schedule form as-is, but for now I think this is fine. I suspect we'll want to make a management-focused variant with its own copy soon
| <div className={styles.rows}> | ||
| <Row | ||
| label={t('labels.name')} | ||
| value={schedule.customName ?? schedule.name} |
There was a problem hiding this comment.
Quick one — schedule.name is actually the hourly/salaried/department field in the API model, not a name, and customName looks like it's basically always set. Is the ?? schedule.name fallback doing anything here, or can we just drop it?
| /> | ||
| } | ||
| > | ||
| {schedule ? ( |
There was a problem hiding this comment.
What happens if schedules comes back empty? Looks like schedule would be undefined and we'd show Loading forever instead of an actual empty state. Is that reachable in practice, or worth handling explicitly?
| label={t('autoPilot.label')} | ||
| value={schedule.autoPayroll ? t('autoPilot.enabled') : t('autoPilot.disabled')} | ||
| action={ | ||
| <Components.Button variant="secondary" onClick={onEditAutoPilot}> |
There was a problem hiding this comment.
Since the Name row and AutoPilot row both just say "Edit," would it be worth giving each button its own aria-label so screen readers can tell them apart?
| PAY_SCHEDULE_DELETED: 'paySchedule/deleted', | ||
| PAY_SCHEDULE_DONE: 'paySchedule/done', | ||
| PAY_SCHEDULE_MANAGE_ASSIGNMENT: 'paySchedule/management/manageAssignment', | ||
| AUTO_PILOT_EDIT: 'paySchedule/management/autoPilotEdit', |
There was a problem hiding this comment.
Small one — should this be PAY_SCHEDULE_AUTO_PILOT_EDIT to match the PAY_SCHEDULE_* naming everything else in this object uses?
| enableAutoPilot={enableAutoPilot} | ||
| enableMultipleSchedules={enableMultipleSchedules} | ||
| onEditSchedule={() => { | ||
| onEvent(componentEvents.PAY_SCHEDULE_UPDATE, { uuid: schedule?.uuid }) |
There was a problem hiding this comment.
Is it safe to pass schedule?.uuid here long-term? It's optional on this side but the reducer expects a required uuid string — wondering if it's worth guarding so this can't fire before schedule exists.
Summary
CompanyManagement.PaySchedulecomponent (single-schedule variant), gated behind the newmanagePaySchedulesunstable feature flagPayScheduleOverviewshows Name, Frequency, and (opt-in viaenableAutoPilot) AutoPilot status as individually-divided rows, each with its own scoped Edit action;Manage(opt-in viaenableMultipleSchedules) sits in the header. Layout matches the tech spec's reference screenshot.Editreuses the existing onboardingPayScheduleForm.Manageand AutoPilotEditcurrently fire events (paySchedule/management/manageAssignment,paySchedule/management/autoPilotEdit) without transitioning anywhere — those land in the follow-upPayScheduleAssignment/AutoPilotDialogtickets.enableMultipleScheduleson.@alpha(not@public) since this is one slice of a larger epic — full TSDoc lands when it graduates.Test plan
npm run test -- --run src/components/Company/PaySchedule/management— 10/10 passingnpx tsc --noEmit— cleannpx eslinton changed files — cleannpm run build— cleanPayScheduleOverviewPresentation(Default, AutoPilot enabled/disabled, single-schedule-only, loading)🤖 Generated with Claude Code