feat(calendar): Wiederholungen, Tagesansicht, Terminfarben, Farbpunkt als Schalter
Fünf Wünsche aus dem Durchtesten: 1. Wiederholungen einstellbar (täglich/wöchentlich/monatlich/jährlich, alle N, Ende nie/nach Anzahl/an einem Datum). Der eigentliche Aufwand lag nicht im Formular, sondern im Aufklappen: eine wöchentliche Reihe erschien sonst als *ein* Eintrag. Der Server klappt sie jetzt im angefragten Zeitfenster auf (?from=&to=, rrule-go über go-icals RecurrenceSet), die Ansichten fragen ihren sichtbaren Ausschnitt an. Geprüft: 5 Termine wöchentlich, nach Umstellung auf 14-tägig korrekt neu gerechnet, Fenster einer Woche liefert genau einen. Regeln, die das Formular nicht abbildet (etwa jeder zweite Dienstag im Monat), werden weiterhin korrekt *angezeigt* -- geprüft, die vier Termine stimmen -- aber nicht zum Bearbeiten angeboten (409). Ein halb verstandenes Speichern würde die Regel sonst still beschneiden. 2. Tag wird erst geöffnet, statt sofort einen Termin anzulegen: Klick auf einen Tag zeigt dessen Termine als Liste, dort wählt man einen aus oder legt bewusst einen neuen an. 3. Eigene Farbe je Termin (COLOR nach RFC 7986), leer = Kalenderfarbe. 4. Kalenderliste ohne Kästchen: der Farbpunkt selbst ist der Schalter -- gefüllt heißt sichtbar, leerer Ring ausgeblendet. 5. Ganztägig als Schiebeschalter statt Kästchen -- es stellt das Formular um, das ist keine Nebenangabe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
105ce8de4a
commit
79a7cc6a3d
8 files changed
+795
-218
No files matched your search
@@ -902,20 +902,40 @@ export interface CalendarItem {
|
||||
created_at: string
|
||||
}
|
||||
|
||||
/** Die Wiederholung, die das Formular anbietet: alle N Tage/Wochen/Monate/
|
||||
* Jahre, wahlweise mit Ende. Verwickeltere Regeln aus fremden Clients
|
||||
* bleiben erhalten, kommen hier aber als `recurrence: undefined` an und
|
||||
* sind dann nur lesbar (siehe events_api.go). */
|
||||
export interface Recurrence {
|
||||
freq: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY'
|
||||
interval: number
|
||||
count?: number
|
||||
/** ISO 8601. Der Tag, an dem die Reihe endet (einschließlich). */
|
||||
until?: string
|
||||
}
|
||||
|
||||
export interface CalendarEvent {
|
||||
uid: string
|
||||
summary: string
|
||||
description: string
|
||||
location: string
|
||||
/** ISO 8601, immer UTC ("...Z") – der Server rechnet nicht um, das
|
||||
* übernimmt der Browser beim Anzeigen (new Date(...) kennt die lokale
|
||||
* Zeitzone bereits). */
|
||||
/** ISO 8601, immer UTC ("...Z"). Bei ganztägigen Terminen Mitternacht UTC
|
||||
* als reine Datumsangabe – nie über new Date(...) in Ortszeit umrechnen,
|
||||
* sondern über eventDay() aus components/calendar/dates.ts. */
|
||||
start: string
|
||||
end?: string
|
||||
all_day: boolean
|
||||
/** Über einen echten CalDAV-Client mit Wiederholung angelegt – hier nur
|
||||
* sichtbar, nicht bearbeitbar (siehe events_api.go, UpdateEvent). */
|
||||
/** Leer = Farbe des Kalenders. */
|
||||
color?: string
|
||||
/** Es hängt überhaupt eine Wiederholung dran. */
|
||||
recurring: boolean
|
||||
/** Die Regel – nur gesetzt, wenn sie sich im Formular abbilden lässt. */
|
||||
recurrence?: Recurrence
|
||||
/** Bei aufgeklappten Wiederholungen: Anfang/Ende der **Reihe**, während
|
||||
* start/end den einzelnen Termin tragen. Das Formular bearbeitet immer
|
||||
* die Reihe. */
|
||||
series_start?: string
|
||||
series_end?: string
|
||||
etag: string
|
||||
}
|
||||
|
||||
@@ -926,6 +946,8 @@ export interface EventInput {
|
||||
start: string
|
||||
end?: string
|
||||
all_day: boolean
|
||||
color?: string
|
||||
recurrence?: Recurrence | null
|
||||
}
|
||||
|
||||
export const calendarApi = {
|
||||
@@ -949,7 +971,13 @@ export const calendarApi = {
|
||||
return json.data
|
||||
},
|
||||
|
||||
listEvents: (id: string) => request<CalendarEvent[]>('GET', `/calendars/${id}/events`),
|
||||
/** Termine im Zeitfenster. Wiederholungen kommen vom Server bereits in
|
||||
* einzelne Termine aufgeklappt zurück – deshalb braucht es die Grenzen:
|
||||
* eine tägliche Reihe ohne Ende hat sonst kein natürliches Ende. */
|
||||
listEvents: (id: string, from?: Date, to?: Date) => {
|
||||
const qs = from && to ? `?from=${from.toISOString()}&to=${to.toISOString()}` : ''
|
||||
return request<CalendarEvent[]>('GET', `/calendars/${id}/events${qs}`)
|
||||
},
|
||||
createEvent: (id: string, input: EventInput) =>
|
||||
request<CalendarEvent>('POST', `/calendars/${id}/events`, input),
|
||||
updateEvent: (id: string, uid: string, input: EventInput) =>
|
||||
|
||||
Reference in new issue
Block a user