Author leave on the calendar itself

Planning used to mean filling in a wish list on one tab, pressing a button to
see a suggestion, then pressing another to accept it — with nothing on screen
telling you whether a plan was active. Dragging a range on the calendar now
creates the period directly, clicking a band opens it for editing, and each
change is recomputed and saved in one step. A period repeats never or yearly,
matching what the planner can actually express.

Clicking a day edits that day: its funding type, which pins it so the planner
leaves it alone, and whether the day counts as worked or off. That switch used
to be a mode covering the whole grid, which is what made the calendar confusing.

The season presets move to a rail beside the grid. Picking one lets the planner
choose the placement, then jumps there and flashes it, rather than asking the
user to guess dates the engine already knows.

A sync that funds nothing now says so, naming the period and how many days it
fell short, instead of leaving the screen unchanged and looking broken.
This commit is contained in:
2026-09-17 21:31:54 +02:00
parent 5e96c352fb
commit c2e64b504d
19 changed files with 3440 additions and 745 deletions
+44
View File
@@ -49,6 +49,10 @@ export const calendar = {
'plannedDayModal.leaveTypeLabel': 'Typ av ledighet',
'plannedDayModal.newTitle': 'Planera en dag',
'plannedDayModal.parentLabel': 'Förälder',
'plannedDayModal.pinnedNotice': 'Den här dagen är låst av dig — planeraren ändrar den inte automatiskt.',
'plannedDayModal.dayStatusLabel': 'Den här dagen är:',
'plannedDayModal.workdayOption': 'Arbetsdag',
'plannedDayModal.dayOffOption': 'Ledig',
'plannedDayModal.rangeTitle': 'Planera {count} dagar',
'plannedDayModal.saveButton': 'Spara',
'plannedDayModal.saveError': 'Det gick inte att spara den planerade dagen',
@@ -63,4 +67,44 @@ export const calendar = {
'redDaysList.overrideFree': 'Undantag: ledig dag',
'redDaysList.overrideWorking': 'Undantag: arbetsdag',
'redDaysList.prevWindow': 'Föregående 4 år',
// §Task7 — the calendar becomes the plan: drag-select, period popover,
// preset rail, and the sync toast/undo.
'calendar.newPeriodName': 'Ny period',
'calendar.periodCreateError': 'Det gick inte att skapa perioden',
'calendar.syncError': 'Det gick inte att synka planen',
'calendar.syncingLabel': 'Synkroniserar…',
'calendar.toastChangedDays': '{name}: {count} dag(ar) ändrades',
'calendar.toastGenericPeriod': 'Perioden',
'calendar.toastShortfallNone':
'{name} ({start}–{end}): inget av de {weeksWished} önskade veckorna kunde finansieras — {shortfallDays} dag(ar) saknas',
'calendar.toastShortfallPartial':
'{name} ({start}–{end}): endast {weeksFunded} av {weeksWished} veckor finansierades — {shortfallDays} dag(ar) saknas',
'calendar.undoButton': 'Ångra',
'calendar.undoError': 'Det gick inte att ångra ändringen',
'calendar.dismissToastAria': 'Stäng meddelandet',
'calendar.railHeading': 'Lägg till ledighet',
'calendar.railHint': 'Klicka för att lägga till — kalendern hoppar till där den passar bäst.',
'calendar.presetAddAria': 'Lägg till {name}',
'calendar.periodPopoverTitle': 'Redigera period',
'calendar.periodAdHocTitle': 'Period',
'calendar.periodAdHocNotice': 'Den här perioden är inte kopplad till en sparad önskan.',
'calendar.periodNameLabel': 'Namn',
'calendar.periodNameAria': 'Periodens namn',
'calendar.periodStartLabel': 'Startdatum',
'calendar.periodEndLabel': 'Slutdatum',
'calendar.periodRepeatLabel': 'Upprepning',
'calendar.periodRepeatNever': 'Aldrig',
'calendar.periodRepeatYearly': 'Varje år',
'calendar.periodLastYearLabel': 'Sista året',
'calendar.periodSaveButton': 'Spara period',
'calendar.periodSavingButton': 'Sparar…',
'calendar.periodDeleteButton': 'Ta bort period',
'calendar.periodDeletingButton': 'Tar bort…',
'calendar.periodDeleteConfirm': 'Är du säker på att du vill ta bort den här perioden?',
'calendar.periodDeleteAdHocButton': 'Ta bort dessa dagar',
'calendar.periodCancelButton': 'Avbryt',
'calendar.periodCloseAria': 'Stäng',
} as const