diff --git a/docs/de/features/calendar.md b/docs/de/features/calendar.md index 3e692707..78c00266 100644 --- a/docs/de/features/calendar.md +++ b/docs/de/features/calendar.md @@ -1,4 +1,4 @@ - + # Kalender @@ -41,7 +41,7 @@ bekommt, und was jeder bekommt, der direkt dorthin navigiert oder einem Link fol ## Die vier Ansichten -Tag, Woche, Monat und Agenda. Eine Ansicht ist Teil der URL — `/calendar/week/2026-08-05` — und +Tag, 7 Tage, Monat und Agenda. Eine Ansicht ist Teil der URL — `/calendar/week/2026-08-05` — und nicht etwas, das sich der Browser merkt. Damit ist jede Ansicht jedes Datums als Lesezeichen brauchbar, die Zurück-Schaltfläche des Browsers tut das Naheliegende, und der Zeitraum dahinter bleibt eine einzige indizierte Abfrage. @@ -49,20 +49,21 @@ bleibt eine einzige indizierte Abfrage. | Ansicht | Was sie abdeckt | |---|---| | **Tag** | Den einen Tag. | -| **Woche** | Montag bis Sonntag. | +| **7 Tage** | Die sieben Tage ab heute — oder ab dem Tag, zu dem du gesprungen bist. Heute steht vorn, denn die Tage dieser Woche, die schon vorbei sind, sind das Unnützeste, wofür man Spalten ausgeben kann. In der Adresse steht weiterhin `week`. | | **Monat** | Sechs Wochen, beginnend am Montag der Woche, in die der Erste fällt — die Tage, die aus den Nachbarmonaten hereinragen, werden also gezeigt, wie ein Monatsraster das immer tut. | | **Agenda** | Eine fortlaufende Liste der nächsten 30 Tage, die die leere Zeit zwischen den Einträgen überspringt. | Die Werkzeugleiste über dem Raster trägt **Zurück**, **Heute** und **Weiter**, das Datum oder den Zeitraum, den du gerade ansiehst, den Ansichtsumschalter und eine Schaltfläche **Neuer Termin**. -Zurück und Weiter springen in der Monatsansicht um einen Monat, in der Wochenansicht um sieben Tage +Zurück und Weiter springen in der Monatsansicht um einen Monat, in der 7-Tage-Ansicht um sieben Tage und überall sonst um einen Tag — die Agenda eingeschlossen, denn sie ist eine fortlaufende Liste und keine Seite. -Die volle Seite öffnet mit **Woche**. Die angedockte Fläche öffnet mit **Agenda** — sie ist 380 -Pixel einer geteilten Zeile, und ein Monatsraster in dieser Breite besteht überwiegend aus leeren -Zellen. Die Fläche bietet trotzdem alle vier Ansichten an, als Symbole statt als Wörter, denn die -Fassung, die den Umschalter ganz weggelassen hatte, ließ die Fläche nichts als ihre Agenda zeigen. +Die volle Seite öffnet mit der Ansicht **7 Tage**. Die angedockte Fläche öffnet mit **Agenda** — sie +ist 380 Pixel einer geteilten Zeile, und ein Monatsraster in dieser Breite besteht überwiegend aus +leeren Zellen. Die Fläche bietet trotzdem alle vier Ansichten an, als Symbole statt als Wörter, denn +die Fassung, die den Umschalter ganz weggelassen hatte, ließ die Fläche nichts als ihre Agenda +zeigen. In der Monatsansicht zeichnet eine Zelle so viele Einträge ihres Tages, wie hineinpassen, und blendet den letzten dort aus, wo der Platz endet — statt sie zu zählen. Früher stand dort **N weitere**, und @@ -89,9 +90,9 @@ anzufangen, wo die Zeit gerade aufgehört hat. ### Das Zeitraster -Tag und Woche werden als Zeitraster gezeichnet: die Stunden links untereinander, und jeder Termin -dort, wo er tatsächlich beginnt, und so lang, wie er tatsächlich dauert. Termine, die sich -überschneiden, werden in Spuren gelegt, sodass drei gleichzeitige Dinge drei schmalere Blöcke +Die Ansichten Tag und 7 Tage werden als Zeitraster gezeichnet: die Stunden links untereinander, und +jeder Termin dort, wo er tatsächlich beginnt, und so lang, wie er tatsächlich dauert. Termine, die +sich überschneiden, werden in Spuren gelegt, sodass drei gleichzeitige Dinge drei schmalere Blöcke nebeneinander sind — und die Zahl der Spuren bleibt über eine ununterbrochene Kette von Überschneidungen hinweg gleich, statt sich von Block zu Block zu ändern. diff --git a/docs/features/calendar.md b/docs/features/calendar.md index d9f5cfa2..757167bb 100644 --- a/docs/features/calendar.md +++ b/docs/features/calendar.md @@ -37,23 +37,23 @@ anyone gets who navigates there directly or follows a link. ## The four views -Day, Week, Month and Agenda. A view is part of the URL — `/calendar/week/2026-08-05` — rather than +Day, 7 days, Month and Agenda. A view is part of the URL — `/calendar/week/2026-08-05` — rather than something the browser remembers, which means every view of every date is bookmarkable, the browser's back button does the obvious thing, and the range behind it stays one indexed query. | View | What it covers | |---|---| | **Day** | The one day. | -| **Week** | Monday to Sunday. | +| **7 days** | The seven days from today — or from the day you moved to. Today comes first, because the days of this week that are already over are the least useful thing to spend columns on. The address still says `week`. | | **Month** | Six weeks, starting on the Monday of the week the 1st falls in — so the days spilling in from the neighbouring months are shown, as a month grid always does. | | **Agenda** | A rolling list of the next 30 days, skipping the empty time between entries. | The toolbar above the grid holds **Previous**, **Today** and **Next**, the date or range you are looking at, the view switcher, and a **New event** button. Previous and Next step by a month in -month view, by seven days in week view, and by a day everywhere else — agenda included, because it +month view, by seven days in the 7-day view, and by a day everywhere else — agenda included, because it is a rolling list rather than a page. -The full page opens on **Week**. The docked pane opens on **Agenda** — it is 380 pixels of a shared +The full page opens on **7 days**. The docked pane opens on **Agenda** — it is 380 pixels of a shared row, and a month grid in that width is a lot of empty cells. The pane still offers all four views, as icons rather than words, because the version that dropped the switcher entirely left the pane able to show nothing but its agenda. @@ -81,7 +81,7 @@ end. ### The time grid -Day and Week are drawn as a time grid: hours down the left, and every event drawn where it actually +Day and 7 days are drawn as a time grid: hours down the left, and every event drawn where it actually starts and as long as it actually lasts. Overlapping events are placed in lanes, so three things happening at once are three narrower blocks side by side, and the lane count holds steady across an unbroken run of overlaps rather than changing block by block. diff --git a/src/Command/Test/SeedGridEventsCommand.php b/src/Command/Test/SeedGridEventsCommand.php index b412a02c..e7cb1cd9 100644 --- a/src/Command/Test/SeedGridEventsCommand.php +++ b/src/Command/Test/SeedGridEventsCommand.php @@ -150,20 +150,17 @@ final class SeedGridEventsCommand extends Command $zone = $this->zoneOf($calendar); $timed = new DateTimeImmutable('today ' . self::TIMED_AT, $zone); - // Monday of the current week, not today. + // Today, because the week view is the seven days from today. // - // A daily series starting today has occurrences only on the days the - // week has LEFT — five of them on a Monday and exactly one on a Sunday - // — so every spec that needs two visible blocks passed six days out of - // seven and failed on the seventh. That is the worst shape a test can - // have: it looks like whatever was committed that day broke the - // calendar, which is how an afternoon gets spent. - // - // Anchored to the start of the displayed week instead, the same five - // occurrences are in view whichever day the suite runs. `first()` is + // Anchored to the first day the grid shows, the five occurrences are + // all in view whichever day the suite runs. That is the whole + // requirement, and the anchor has to follow the view: while the week + // ran Monday to Sunday this had to be Monday, and a series started + // today had only the days the week had LEFT — one on a Sunday — so the + // specs that need two blocks failed one day in seven. `first()` is // still the first block in the grid, which is what the drag specs // actually mean by it. - $daily = new DateTimeImmutable('monday this week ' . self::DAILY_AT, $zone); + $daily = new DateTimeImmutable('today ' . self::DAILY_AT, $zone); $this->write($user, $calendar, self::TIMED, $timed, $timed->modify('+1 hour'), $zone); diff --git a/src/Domain/Enum/Calendar/CalendarView.php b/src/Domain/Enum/Calendar/CalendarView.php index ad0ac7c7..67286657 100644 --- a/src/Domain/Enum/Calendar/CalendarView.php +++ b/src/Domain/Enum/Calendar/CalendarView.php @@ -80,6 +80,15 @@ enum CalendarView: string * How far either side of the anchor date this view reaches, before the * timezone padding the reader adds. Month is asked for six weeks because a * month grid always shows the days spilling in from its neighbours. + * + * The week is the seven days FROM the anchor, not the Monday-to-Sunday + * around it. The anchor is today unless somebody has navigated, and the + * days of this week that have already happened are the least useful thing + * a week view can spend its columns on — in the docked pane, where seven + * columns do not fit, they pushed today off to the right. It is labelled + * "7 days" for that reason. Month keeps its Monday: a grid of weeks is + * what a month view is. The public shared page builds its own range and + * keeps a real week (SharedCalendarRangeBuilder). */ public function range(\DateTimeImmutable $anchor): array { @@ -89,8 +98,8 @@ enum CalendarView: string $anchor->modify('+1 day')->setTime(0, 0), ], self::Week => [ - $anchor->modify('monday this week')->setTime(0, 0), - $anchor->modify('monday this week')->modify('+7 days')->setTime(0, 0), + $anchor->setTime(0, 0), + $anchor->modify('+7 days')->setTime(0, 0), ], self::Month => [ $anchor->modify('first day of this month')->modify('monday this week')->setTime(0, 0), diff --git a/src/Service/Calendar/CalendarRangeReader.php b/src/Service/Calendar/CalendarRangeReader.php index fd6c2035..33463721 100644 --- a/src/Service/Calendar/CalendarRangeReader.php +++ b/src/Service/Calendar/CalendarRangeReader.php @@ -147,8 +147,8 @@ final readonly class CalendarRangeReader $end = $isFloating ? $cluster->primary->endsAt : $cluster->primary->endsAt->setTimezone($zone); // A multi-day event belongs to every day it touches, not only the - // one it started on — otherwise it vanishes from the week whose - // Monday it began before. + // one it started on — otherwise it vanishes from any range that + // starts after the day it began. for ($day = $start->setTime(0, 0); $day < $end; $day = $day->modify('+1 day')) { $key = $day->format('Y-m-d'); diff --git a/templates/calendar/_toolbar_shell.html.twig b/templates/calendar/_toolbar_shell.html.twig index 6f61ac21..86a8d0b6 100644 --- a/templates/calendar/_toolbar_shell.html.twig +++ b/templates/calendar/_toolbar_shell.html.twig @@ -53,6 +53,11 @@ Variables: passes true — it is a bounded page of the published window rather than the authenticated agenda's rolling list from a date, so its two ends are the honest label + labelKeys map optional, view value => translation key, for a caller + whose view is not the one `calendar.view.*` names. + The shared page passes week => monday_week: its week + is still Monday to Sunday, while the authenticated + one is the seven days from its anchor ("7 days") Blocks: toolbar_actions the right-hand end, after the switcher @@ -60,6 +65,7 @@ Blocks: {% set compact = compact|default(false) %} {% set frame = frame|default(null) %} +{% set labelKeys = labelKeys|default({}) %} {% set spanLabel = spanLabel|default(view.value == 'week') %} {% set viewIcons = { @@ -185,7 +191,7 @@ Blocks: