Jump to today, and open a period on the dates it actually has
The month can now be reached in one click instead of paging back through the year. The button sits left of the month dropdown and sizes to its label, so Idag and Today both fit. Opening a period showed the wish's first year rather than the occurrence that was clicked: a 2028 week of a yearly wish opened on 2026, and a flexible period opened on its bounding range instead of where the planner put it. The popover now prefills from the clicked band's own dates. Saving a yearly wish keeps its anchor year, since the edited dates describe the recurring pattern and not one occurrence — moving a single year is a separate choice that does not exist yet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ei7gCZzdd751uZtPzb1Pep
This commit is contained in:
@@ -86,7 +86,13 @@ describe('PeriodPopover', () => {
|
||||
})
|
||||
|
||||
it('prefills name/dates/parent/repeat from the wish', () => {
|
||||
render(<PeriodPopover {...defaultProps} wish={wish} />)
|
||||
// startDate/endDate here are the clicked band's real placed dates
|
||||
// (the 2028 occurrence, which happens to equal the wish's first
|
||||
// occurrence) — see the dedicated "later-year occurrence" tests below
|
||||
// for the case where they diverge from `wish.firstYear`.
|
||||
render(
|
||||
<PeriodPopover {...defaultProps} wish={wish} startDate="2028-06-15" endDate="2028-07-26" />,
|
||||
)
|
||||
expect(screen.getByTestId('period-name-input')).toHaveValue('Sommar')
|
||||
expect(screen.getByTestId('period-start-input')).toHaveValue('2028-06-15')
|
||||
expect(screen.getByTestId('period-end-input')).toHaveValue('2028-07-26')
|
||||
@@ -94,6 +100,12 @@ describe('PeriodPopover', () => {
|
||||
expect(screen.getByTestId('period-repeat-yearly')).toBeChecked()
|
||||
})
|
||||
|
||||
it('falls back to the wish\'s window-derived dates when no placed dates are supplied', () => {
|
||||
render(<PeriodPopover {...defaultProps} wish={wish} startDate="" endDate="" />)
|
||||
expect(screen.getByTestId('period-start-input')).toHaveValue('2028-06-15')
|
||||
expect(screen.getByTestId('period-end-input')).toHaveValue('2028-07-26')
|
||||
})
|
||||
|
||||
it('shows the wrapping window correctly for a Jul-style wish (end year = firstYear + 1)', () => {
|
||||
const jul = makeLeaveWish({
|
||||
windowStartMonth: 12,
|
||||
@@ -102,11 +114,54 @@ describe('PeriodPopover', () => {
|
||||
windowEndDay: 16,
|
||||
firstYear: 2028,
|
||||
})
|
||||
render(<PeriodPopover {...defaultProps} wish={jul} />)
|
||||
render(<PeriodPopover {...defaultProps} wish={jul} startDate="2028-12-20" endDate="2029-01-16" />)
|
||||
expect(screen.getByTestId('period-start-input')).toHaveValue('2028-12-20')
|
||||
expect(screen.getByTestId('period-end-input')).toHaveValue('2029-01-16')
|
||||
})
|
||||
|
||||
it('prefills the clicked later-year occurrence\'s dates, not the wish\'s first-occurrence window', () => {
|
||||
// The wish was first taken in 2026; the user clicked its 2028 band.
|
||||
const yearlyFrom2026 = makeLeaveWish({
|
||||
windowStartMonth: 6,
|
||||
windowStartDay: 15,
|
||||
windowEndMonth: 7,
|
||||
windowEndDay: 26,
|
||||
firstYear: 2026,
|
||||
recurrence: 'yearly',
|
||||
})
|
||||
render(
|
||||
<PeriodPopover
|
||||
{...defaultProps}
|
||||
wish={yearlyFrom2026}
|
||||
startDate="2028-06-15"
|
||||
endDate="2028-07-26"
|
||||
/>,
|
||||
)
|
||||
expect(screen.getByTestId('period-start-input')).toHaveValue('2028-06-15')
|
||||
expect(screen.getByTestId('period-end-input')).toHaveValue('2028-07-26')
|
||||
// Non-date fields still come from the wish itself, unaffected by which
|
||||
// occurrence was clicked.
|
||||
expect(screen.getByTestId('period-repeat-yearly')).toBeChecked()
|
||||
expect(screen.getByTestId('period-parent-select')).toHaveValue('either')
|
||||
})
|
||||
|
||||
it('prefills a flexible wish\'s actual placed dates, not its bounding window', () => {
|
||||
// A flexible/wrapping wish whose *window* spans Dec 20 - Jan 16, but
|
||||
// the allocator actually placed this occurrence a few days later.
|
||||
const flexible = makeLeaveWish({
|
||||
windowStartMonth: 12,
|
||||
windowStartDay: 20,
|
||||
windowEndMonth: 1,
|
||||
windowEndDay: 16,
|
||||
firstYear: 2028,
|
||||
})
|
||||
render(
|
||||
<PeriodPopover {...defaultProps} wish={flexible} startDate="2028-12-27" endDate="2029-01-10" />,
|
||||
)
|
||||
expect(screen.getByTestId('period-start-input')).toHaveValue('2028-12-27')
|
||||
expect(screen.getByTestId('period-end-input')).toHaveValue('2029-01-10')
|
||||
})
|
||||
|
||||
it('shows "until age 4" checked when lastYear is null', () => {
|
||||
render(<PeriodPopover {...defaultProps} wish={wish} />)
|
||||
expect(screen.getByTestId('period-until-age4')).toBeChecked()
|
||||
|
||||
@@ -64,13 +64,27 @@ function parseISO(date: string): { year: number; month: number; day: number } {
|
||||
return { year: year ?? 1970, month: month ?? 1, day: day ?? 1 }
|
||||
}
|
||||
|
||||
function formStateFromWish(wish: LeaveWish, t: (key: TranslationKey) => string): FormState {
|
||||
function formStateFromWish(
|
||||
wish: LeaveWish,
|
||||
startDate: string,
|
||||
endDate: string,
|
||||
t: (key: TranslationKey) => string,
|
||||
): FormState {
|
||||
// Prefer the clicked band's actual placed dates (the `startDate`/`endDate`
|
||||
// props — see `PeriodPopoverProps`'s doc comment) over recomputing from
|
||||
// the wish's static recurring window. `wish.firstYear` + the window only
|
||||
// describes the *first* occurrence; clicking a later-year occurrence of a
|
||||
// yearly wish (or any occurrence of a flexible wish, whose placement can
|
||||
// drift inside its bounding range) needs the real placed dates, not the
|
||||
// anchor year's. Fall back to the window-derived dates if the caller
|
||||
// didn't supply real placed dates (defensive — callers are expected to
|
||||
// always pass them).
|
||||
const wraps = windowWraps(wish.windowStartMonth, wish.windowStartDay, wish.windowEndMonth, wish.windowEndDay)
|
||||
const endYear = wraps ? wish.firstYear + 1 : wish.firstYear
|
||||
return {
|
||||
name: resolveWishName(wish, t),
|
||||
startDate: formatISO(wish.firstYear, wish.windowStartMonth, wish.windowStartDay),
|
||||
endDate: formatISO(endYear, wish.windowEndMonth, wish.windowEndDay),
|
||||
startDate: startDate || formatISO(wish.firstYear, wish.windowStartMonth, wish.windowStartDay),
|
||||
endDate: endDate || formatISO(endYear, wish.windowEndMonth, wish.windowEndDay),
|
||||
parentMode: wish.parentMode,
|
||||
parentPersonalDataUuid: wish.parentPersonalDataUuid,
|
||||
recurrence: wish.recurrence,
|
||||
@@ -105,7 +119,7 @@ export function PeriodPopover({
|
||||
|
||||
useEffect(() => {
|
||||
if (wish) {
|
||||
setForm(formStateFromWish(wish, t))
|
||||
setForm(formStateFromWish(wish, startDate, endDate, t))
|
||||
} else {
|
||||
setForm({
|
||||
name: '',
|
||||
|
||||
Reference in New Issue
Block a user