Kalender: was auf den Brettern steht und einen Termin hat
Filipe, zu einer Clip-Karte: "ich will dass die auch in einer kalender
drin sind, aber ich will dass es richtig geil ist und perfektionier das
bitte."
Gemessen vor dem Bau: /workspace/api/termine lieferte `termine` und
`fristen`. Die Zettel von den achtzehn Brettern kamen nirgends vor --
obwohl `eintraege` seit langem VIER Zeitfelder hat: datum, uhrzeit,
geplant, event_ende.
WELCHE HINEINGEHOEREN, IST DIE GANZE FRAGE -- und sie laesst sich
messen statt raten. `datum` ist ein Pflichtfeld und faellt auf HEUTE
zurueck, wenn niemand eins waehlt. Alle Eintraege hineinzukippen hiesse
also: jeder je getippte Zettel steht an dem Tag, an dem ihn jemand
getippt hat. Nach einem Monat waere der Kalender ein Protokoll und kein
Plan -- und ein Kalender, in dem alles steht, sagt nichts mehr.
GEZEIGT WIRD NUR, WOFUER JEMAND EINE ZEIT BESTIMMT HAT:
geplant eine Zusage ("Wird gemacht -- am 24.09.")
event_ende ein Zeitraum
uhrzeit niemand tippt aus Versehen 20:00
datum > heute der Rueckfall ist IMMER heute oder frueher
Erledigtes bleibt draussen. Der vierte Fall ist der wichtigste und der
unauffaelligste: kein neues Feld, keine Umgewoehnung.
RECHTE: dieselbe Funktion wie die Bretter selbst (`sichtbarEintrag`),
nicht eine zweite Meinung. Im Kalender steht nur eine kleine Pille mit
einem Titel -- dass darin ein vertrauliches Vorhaben steckt, faellt
niemandem auf, der nicht danach sucht. Genau so kam am 03.09. eine
Managerin an fremde Aufgabenfristen.
DREI FEHLER AM BILDSCHIRMFOTO GEFUNDEN, nicht an einer Zahl:
1. Der Brettname stand VOR dem Titel -- aus "Clip am Wochenende"
wurde "Cli...". Das Etikett verdraengte, was es einordnen sollte.
Jetzt zweite Zeile: Hoehe ist im Monatsraster der billigere Platz.
2. Am Handy (45px Zellbreite) wurde daraus ein "Co..." -- Hoehe ohne
Information. Jetzt eine CONTAINER-Abfrage: entschieden wird nach
der Breite der ZELLE, nicht des Fensters. Eine Fensterschwelle
waere wieder die Rechnung von gestern (September, Kopfleiste,
zweimal).
3. .64rem = 10,24px -- unter der Hausgrenze 11,5px, gefunden von
pruef-css-klassen. Gedaempft wird jetzt ueber Farbe und Gewicht,
nicht ueber Groesse.
EIN ECHTER FEHLER VERHINDERT: In der Listenansicht waeren die Zettel im
Termin-Zweig gelandet -- mit Wecker, "erledigt" und "loeschen". Der
Knopf haette PATCH /api/termine/b12 geschickt: eine Nummer, die es dort
nicht gibt, an eine Schnittstelle, die davon nichts weiss. Still, ohne
Wirkung, ohne Meldung.
DER WEG FUEHRT AUF DEN ZETTEL, nicht nur auf das Brett -- ueber
`?zeigen=` (kopf.js), den Weg, den das Haus dafuer schon hat. Zwischen
zwanzig Eintraegen waere der gesuchte sonst von Hand zu suchen.
pruef-kalender: +25 Pruefungen. Sieben Gegenproben, jede zielgenau:
Schnitt weg -> 6 rot Erledigtes rein -> 6 rot
Rechteregel ausgehebelt-> 1 rot COALESCE weg -> 1 rot
Termin-Knoepfe an -> 2 rot Container-Regel weg -> 1 rot
Sprung-Zweig weg -> 3 rot
UND SIEBEN FESTE ZAHLEN ABGELEITET. Die alten Pruefungen zaehlten
"alle fünf Einträge", "vier Arten", "vier Filter" -- mit den neuen
Testdaten wurden daraus zehn, und sieben Pruefungen je Bildschirmgroesse
wurden rot, ohne dass am Kalender etwas kaputt war. Mit `git stash`
nachgemessen (ohne meine Aenderung: 0 Fehler), also nicht angepasst,
sondern gerechnet: jede Zahl kommt jetzt aus den Testdaten darueber.
Zwei eigene Pruefungsfehler dabei behoben: ein falscher Umschalter-
Selektor liess `every()` auf einem leeren Feld laufen (gruen ohne
Daten), und die Sichtbarkeit der zweiten Zeile wurde ueber
`textContent` gemessen -- das liefert auch, was `display: none`
ausblendet.
Gruen: kalender, sprung, namen, css-klassen, struktur.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -60,6 +60,19 @@
|
||||
call: 'Call', termin: 'Termin', review: 'Review', frist: 'Frist',
|
||||
bigmatch: 'BigMatch', turnier: 'Turnier', special: 'Special-Live',
|
||||
collab: 'Collab', raid: 'Raid-Train', charity: 'Charity',
|
||||
/* WAS AUF DEN BRETTERN STEHT UND EINEN TERMIN HAT (17.09.2026).
|
||||
|
||||
Eine EINZIGE Art, nicht eine je Brett. Der Filter haette sonst
|
||||
achtzehn Schalter, und eine Leiste mit achtzehn Schaltern liest
|
||||
niemand mehr -- derselbe Grund, aus dem die sechs Auftritts-Arten
|
||||
nur bei Bedarf erscheinen.
|
||||
|
||||
UNTERSCHIEDEN WIRD UEBER DAS WORT, NICHT UEBER DIE FARBE: In der
|
||||
Pille steht der Name des Bretts. Eine Farbe je Brett waere eine
|
||||
von Hand gepflegte Liste -- und die waere beim naechsten neuen
|
||||
Brett vergessen, genau wie die Filterliste, die hier schon
|
||||
einmal stehengeblieben ist (siehe unten bei `zeigen`). */
|
||||
brett: 'Vom Brett',
|
||||
};
|
||||
/* Jede Art trägt ihre eigene Farbe -- dieselbe Idee wie bei den Kacheln
|
||||
auf der Startseite: Die Farbe gehört zur Sache, nicht zum Rang. */
|
||||
@@ -92,7 +105,25 @@
|
||||
collab: '#2fd6c4',
|
||||
raid: '#ff9040',
|
||||
charity: '#a7d64a',
|
||||
/* BEWUSST RUHIGER ALS DIE AUFTRITTE. Ein Zettel vom Brett ist
|
||||
keine Sendung -- er soll im Monatsraster sichtbar sein, aber
|
||||
einem BigMatch nicht die Aufmerksamkeit wegnehmen. Stahlblau ist
|
||||
ausserdem der letzte Ton, der sich von allen neun anderen klar
|
||||
unterscheidet: nicht das helle Blau der Calls, nicht das Violett
|
||||
der Termine, nicht das Tuerkis der Collabs. */
|
||||
brett: '#7f9cc0',
|
||||
};
|
||||
/* Warum ein Zettel vom Brett im Kalender steht -- in Worten, die man
|
||||
ohne Erklaerung versteht. Die Schluessel kommen vom Server; steht
|
||||
ein unbekannter dabei, bleibt die Zeile einfach ohne dieses Stueck
|
||||
statt einen Rohwert zu zeigen. */
|
||||
const GRUNDWORT = {
|
||||
zugesagt: 'zugesagt',
|
||||
zeitraum: 'laeuft ueber mehrere Tage',
|
||||
uhrzeit: null,
|
||||
termin: 'geplant',
|
||||
};
|
||||
|
||||
const FEIERTAG_FARBE = '#ff9aa2';
|
||||
const ANLASS_FARBE = '#d8a13a';
|
||||
|
||||
@@ -335,6 +366,10 @@
|
||||
const fmt = (o) => new Intl.DateTimeFormat('de-DE', { timeZone: 'UTC', ...o });
|
||||
const tagLang = (t) =>
|
||||
fmt({ weekday: 'long', day: '2-digit', month: 'long' }).format(ausText(t));
|
||||
/* Kurzfassung fuer eine Pille: „24.09." -- ohne Jahr und ohne
|
||||
Wochentag. In einer Zelle von 150 px ist jedes weitere Zeichen
|
||||
eines, das den Titel abschneidet. */
|
||||
const kurz = (t) => fmt({ day: '2-digit', month: '2-digit' }).format(ausText(t));
|
||||
|
||||
/* ---------- Anlässe ------------------------------------------------------ */
|
||||
|
||||
@@ -515,6 +550,46 @@
|
||||
ziel: 'aufgaben.html',
|
||||
});
|
||||
}
|
||||
/* ---- Was auf den Brettern steht (17.09.2026) --------------------
|
||||
|
||||
Filipe, zu einer Clip-Karte: „ich will dass die auch in einer
|
||||
kalender drin sind."
|
||||
|
||||
WELCHE hier ankommen, entscheidet der Server (workspace-
|
||||
kalender.js) -- und zwar nach der Regel „nur, wofuer jemand eine
|
||||
Zeit bestimmt hat". Der Browser rechnet das NICHT nach: Eine
|
||||
zweite Fassung derselben Regel ist die, die beim naechsten
|
||||
Nachschaerfen auseinanderlaeuft. Er zeigt, was kommt. */
|
||||
for (const b of roh.brettsachen || []) {
|
||||
raus.push({
|
||||
art: 'brett', tag: b.wann, uhr: b.uhrzeit || null,
|
||||
titel: b.titel, erledigt: false, id: 'b' + b.id,
|
||||
farbe: ARTFARBE.brett,
|
||||
brett_name: b.brett_name,
|
||||
/* DER GRUND STEHT DABEI. „Zugesagt am 24." ist etwas anderes
|
||||
als „liegt auf dem 24." -- das erste ist ein Versprechen an
|
||||
jemanden, das zweite eine Notiz an sich selbst. Wer das nicht
|
||||
unterscheiden kann, behandelt beides gleich, und dann zaehlt
|
||||
die Zusage so wenig wie die Notiz. */
|
||||
grund: b.grund,
|
||||
bis: b.event_ende || null,
|
||||
zusatz: [b.brett_name, GRUNDWORT[b.grund] || null,
|
||||
b.event_ende && b.event_ende !== b.wann
|
||||
? 'bis ' + kurz(b.event_ende) : null,
|
||||
b.von_name ? 'von ' + b.von_name : null].filter(Boolean).join(' · '),
|
||||
beschreibung: b.text || null,
|
||||
/* Der Weg zurueck zum Brett. Ein Kalendereintrag, den man nur
|
||||
ansehen und nicht oeffnen kann, ist eine Sackgasse -- und der
|
||||
ganze Vorgang (kommentieren, erledigen, verschieben) steht
|
||||
dort, nicht hier. */
|
||||
/* Auf den ZETTEL, nicht nur auf das Brett. Zwischen zwanzig
|
||||
anderen ist der gesuchte sonst wieder von Hand zu suchen --
|
||||
und dann hat der Link nichts gebracht. `?zeigen=` ist der
|
||||
Weg, den das Haus dafuer schon hat (kopf.js). */
|
||||
ziel: 'bereich.html?b=' + encodeURIComponent(b.bereich)
|
||||
+ '&zeigen=eintrag-' + b.id,
|
||||
});
|
||||
}
|
||||
/* Erst nach Tag, dann nach Uhrzeit. Fristen haben keine Uhrzeit und
|
||||
stehen deshalb ans Ende des Tages -- sie blockieren keinen Slot. */
|
||||
return raus.sort((a, b) =>
|
||||
@@ -563,7 +638,41 @@
|
||||
(siehe zeile()) ist Platz, dort steht es hinter dem Titel und
|
||||
liest sich natürlicher. */
|
||||
if (e.serie_id) k.append(wiederholZeichen());
|
||||
/* WOHER ER KOMMT, STEHT VOR DEM TITEL (17.09.2026).
|
||||
|
||||
„Wer ist euer Komet?!" allein sagt im Kalender nichts -- man
|
||||
weiss nicht, ob das ein Stream, eine Aufgabe oder ein Zettel
|
||||
ist. „Content · Wer ist euer Komet?!" beantwortet das in einem
|
||||
Wort, und zwar VOR dem Titel: Eine Zelle im Monatsraster ist gut
|
||||
150 px breit und schneidet hinten ab. Dieselbe Ueberlegung wie
|
||||
beim Wiederhol-Zeichen eine Zeile darueber.
|
||||
|
||||
UND ES IST EINE ZUSAGE ERKENNBAR. Was jemandem versprochen
|
||||
wurde, traegt ein eigenes Zeichen -- ein Versprechen, das
|
||||
aussieht wie eine Notiz, wird auch wie eine behandelt. */
|
||||
/* EINE ZUSAGE TRAEGT EIN HAKEN, und der steht VOR dem Titel.
|
||||
|
||||
„Wird gemacht -- am 24.09." ist ein Versprechen an jemanden;
|
||||
ein selbstgesetztes Datum ist eine Notiz an sich selbst. Wer das
|
||||
nicht unterscheiden kann, behandelt beides gleich -- und dann
|
||||
zaehlt die Zusage so wenig wie die Notiz.
|
||||
|
||||
Zwei Zeichen statt eines Wortes: Im Monatsraster ist jede
|
||||
Buchstabenbreite eine, die dem Titel fehlt. */
|
||||
if (e.grund === 'zugesagt') k.append(el('span', 'k-pille__zusage', '\u2713'));
|
||||
k.append(document.createTextNode(e.titel));
|
||||
/* WOHER ER KOMMT, STEHT DARUNTER -- nicht davor (17.09.2026).
|
||||
|
||||
Der erste Anlauf setzte den Brettnamen VOR den Titel. Am
|
||||
Bildschirmfoto war sofort zu sehen, warum das nicht geht: In
|
||||
einer Monatszelle von rund 150 px blieb von „Clip am Wochenende"
|
||||
genau „Cli…" uebrig. Das Etikett hat die Information verdraengt,
|
||||
die es einordnen sollte.
|
||||
|
||||
In der zweiten Zeile kostet es KEINE Breite. Hoehe ist im
|
||||
Monatsraster der billigere Platz: Eine Zelle ist gut 110 px hoch
|
||||
und traegt meist ein bis zwei Eintraege. */
|
||||
if (e.brett_name) k.append(el('span', 'k-pille__brett', e.brett_name));
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -1023,13 +1132,29 @@
|
||||
ANGABE ueber den Termin ("das ist ein Termin, kein Call"), genau
|
||||
wie Uhrzeit und Titel. Jetzt steht sie neben dem Titel, und die
|
||||
Knopfreihe enthaelt nur noch Dinge, die etwas tun. */
|
||||
titel.append(el('span', 'k-zeile__art', ARTNAME[e.art] || e.art));
|
||||
/* Bei einem Zettel vom Brett steht dort das BRETT und nicht „Vom
|
||||
Brett" -- in der Liste ist Platz fuer das Wort, das wirklich
|
||||
etwas sagt. In der Filterleiste bleibt es eine Art; dort waeren
|
||||
achtzehn Schalter unbrauchbar. */
|
||||
titel.append(el('span', 'k-zeile__art',
|
||||
e.brett_name || ARTNAME[e.art] || e.art));
|
||||
|
||||
const rechts = el('div', 'k-zeile__knoepfe');
|
||||
|
||||
if (e.art === 'frist') {
|
||||
const a = el('a', 'schritt', 'zur Aufgabe');
|
||||
a.href = 'aufgaben.html';
|
||||
/* WAS NICHT AUS DEM KALENDER STAMMT, BEKOMMT KEINE KALENDER-KNOEPFE.
|
||||
|
||||
Ohne diese Zeile waere der Zettel vom Brett im `else`-Zweig
|
||||
gelandet -- mit Wecker, „erledigt" und „loeschen". Und „erledigt"
|
||||
haette `PATCH /workspace/api/termine/b12` geschickt: eine Nummer,
|
||||
die es dort nicht gibt, an eine Schnittstelle, die davon nichts
|
||||
weiss. Der Fehler waere still gewesen (eine 404 im Hintergrund),
|
||||
und der Knopf haette einfach nichts getan.
|
||||
|
||||
Dasselbe gilt seit jeher fuer die Frist -- deshalb steht beides
|
||||
in EINER Bedingung und nicht in zwei: Es ist dieselbe Regel. */
|
||||
if (e.art === 'frist' || e.art === 'brett') {
|
||||
const a = el('a', 'schritt', e.art === 'brett' ? 'zum Brett' : 'zur Aufgabe');
|
||||
a.href = e.ziel || 'aufgaben.html';
|
||||
rechts.append(a);
|
||||
} else {
|
||||
/* DER WECKER (07.09.2026). Er steht bei JEDEM Termin, den man
|
||||
|
||||
Reference in New Issue
Block a user