Ein Termin von-bis belegt jeden Tag dazwischen
Zwei Fehler, nicht einer. Der sichtbare: Die Kachel stand nur am Anfangstag. Wer im Monatsraster auf den Mittwoch sah, sah nichts -- obwohl die Aktion von Montag bis Freitag lief. Der unsichtbare, und der ist der schlimmere: Der SERVER suchte Eintraege, deren ANFANG im sichtbaren Fenster liegt. Eine Aktion vom 28.09. bis zum 05.10. kam im Oktober deshalb ueberhaupt nicht an -- nicht "nur am ersten Tag markiert", sondern gar nicht da. Wer im Oktober plante, sah eine freie Woche, die belegt war. Jetzt entscheidet die UEBERSCHNEIDUNG, nicht der Anfang. Gebaut wurde es in nachTag() -- der einzigen Stelle, an der Eintraege auf Tage verteilt werden. Monat, Woche, Liste und Zeitstrahl holen sich alle dort; vier Ansichten einzeln nachzuruesten waeren vier Stellen, an denen die fuenfte vergessen wird. Das Ende wird abgeleitet, nicht gepflegt: aus event_ende ODER aus Uhrzeit plus Dauer. Ein Live von 22:00 ueber vier Stunden endet um 02:00 am naechsten Tag -- das stand bisher nirgends, obwohl die Zahlen da waren. Der Tagesdialog filterte selbst auf den Anfangstag. Im Raster war der Mittwoch markiert, tippte man ihn an, stand da "An diesem Tag steht nichts." Jetzt fragt er dieselbe Stelle wie das Raster. pruef-zeitraum.mjs: 16 Pruefungen, beide Fehler einzeln, mit drei Gegenproben (vor dem Anfang, nach dem Ende, Punkttermin). pruef-terminregel.mjs weiterhin 35/0. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -355,6 +355,75 @@
|
||||
Kontrastmodus nicht zu erkennen. */
|
||||
.k-pille.erledigt { opacity: .5; text-decoration: line-through; }
|
||||
|
||||
/* =====================================================================
|
||||
EIN TERMIN, DER MEHRERE TAGE LAEUFT (20.09.2026)
|
||||
|
||||
Filipe: „wenn ich termine eintrage mit von bis, will ich dass die
|
||||
ganze zeit markiert ist und nicht nur der anfang."
|
||||
|
||||
Die Kachel steht jetzt in jeder Tageszelle dazwischen. Damit man
|
||||
sieht, dass es EIN Termin ist und nicht vier gleichnamige, wird sie
|
||||
an den Seiten angeschnitten, an denen es weitergeht:
|
||||
|
||||
Mo [ 20:00 Aktion ━
|
||||
Di ━ Tag 2/4 ━
|
||||
Mi ━ Tag 3/4 ━
|
||||
Do ━ Tag 4/4 ]
|
||||
|
||||
DIE FORM MACHT DIE AUSSAGE, nicht die Farbe -- an einer eckigen
|
||||
Kante sieht man „geht weiter" auch dann, wenn man Farben schlecht
|
||||
unterscheidet oder der Kontrastmodus alles einfaerbt.
|
||||
|
||||
WARUM KEIN ECHTER BALKEN UEBER DIE ZELLEN: Ein Element, das sich
|
||||
ueber mehrere Rasterzellen legt, muesste wissen, wo die Woche
|
||||
umbricht, wie hoch die Zeile gerade ist und was darunter noch steht.
|
||||
Das ist bei jeder Fensterbreite eine andere Rechnung -- und eine
|
||||
Rechnung, die irgendwann danebenliegt, schiebt Kacheln uebereinander.
|
||||
Die angeschnittene Kante kostet nichts und kann nicht verrutschen. */
|
||||
|
||||
/* Laeuft gestern schon: links glatt abgeschnitten, kein Randstrich. */
|
||||
.k-pille[data-spanne="mitte"],
|
||||
.k-pille[data-spanne="ende"] {
|
||||
border-left: 0;
|
||||
border-top-left-radius: 0; border-bottom-left-radius: 0;
|
||||
/* Der Strich am linken Rand wird zum FORTSETZUNGSZEICHEN: ein
|
||||
schmaler, waagerechter Balken in der Farbe, auf halber Hoehe. */
|
||||
padding-left: 12px;
|
||||
background-image: linear-gradient(90deg,
|
||||
var(--pfarbe) 0 4px, transparent 4px);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50%;
|
||||
background-size: 100% 2px;
|
||||
}
|
||||
/* Geht morgen weiter: rechts glatt abgeschnitten. */
|
||||
.k-pille[data-spanne="start"],
|
||||
.k-pille[data-spanne="mitte"] {
|
||||
border-top-right-radius: 0; border-bottom-right-radius: 0;
|
||||
/* Eine Kante, die zeigt, dass hier nichts endet. */
|
||||
box-shadow: inset -3px 0 0 -1px color-mix(in srgb, var(--pfarbe) 70%, transparent);
|
||||
}
|
||||
/* Der ganze Zeitraum liegt etwas satter als ein Punkttermin -- er
|
||||
BELEGT die Tage, und das soll man beim Ueberfliegen sehen. */
|
||||
.k-pille[data-spanne] {
|
||||
background-color: color-mix(in srgb, var(--pfarbe) 22%, transparent);
|
||||
}
|
||||
.k-pille[data-spanne]:hover {
|
||||
background-color: color-mix(in srgb, var(--pfarbe) 32%, transparent);
|
||||
}
|
||||
/* „Tag 2/4" ist eine Angabe zur Lage, keine Uhrzeit -- deshalb ruhiger
|
||||
als die fette Startzeit daneben. */
|
||||
.k-pille__lauf { font-weight: 550; opacity: .82; }
|
||||
|
||||
@media (forced-colors: active) {
|
||||
/* Im Kontrastmodus verschwinden Farbflaechen und Schatten. Dann muss
|
||||
die Kante als echter Rahmen dastehen, sonst sieht die Kachel am
|
||||
Mittwoch genauso aus wie ein eigener Termin. */
|
||||
.k-pille[data-spanne="start"],
|
||||
.k-pille[data-spanne="mitte"] { border-right: 2px dashed CanvasText; }
|
||||
.k-pille[data-spanne="mitte"],
|
||||
.k-pille[data-spanne="ende"] { border-left: 2px dashed CanvasText; }
|
||||
}
|
||||
|
||||
/* ---------- Wochenansicht ----------------------------------------------- */
|
||||
.k-woche {
|
||||
display: grid; gap: 1px;
|
||||
|
||||
@@ -601,11 +601,93 @@
|
||||
statt verschluckt. */
|
||||
const sichtbare = () => (daten ? daten.eintraege.filter((e) => zeigen[e.art] !== false) : []);
|
||||
|
||||
/* =====================================================================
|
||||
EIN TERMIN VON--BIS STEHT AN JEDEM TAG DAZWISCHEN (20.09.2026)
|
||||
|
||||
Filipe: „wenn ich termine eintrage mit von bis, will ich dass die
|
||||
ganze zeit markiert ist und nicht nur der anfang."
|
||||
|
||||
BISHER stand er nur am Anfangstag. Wer im Monatsraster auf den
|
||||
Mittwoch sah, sah nichts -- obwohl die Aktion von Montag bis
|
||||
Freitag lief. Genau in der Ansicht, in der man plant, war der
|
||||
belegte Zeitraum unsichtbar, und man legte etwas mitten hinein.
|
||||
|
||||
WARUM GENAU HIER: `nachTag()` ist die EINZIGE Stelle, an der
|
||||
Eintraege auf Tage verteilt werden -- Monat, Woche, Liste und
|
||||
Zeitstrahl holen sich alle `karte.get(tag)`. Vier Ansichten
|
||||
einzeln nachzuruesten waere vier Stellen, an denen die naechste
|
||||
Ansicht vergessen wird.
|
||||
|
||||
DAS ENDE WIRD ABGELEITET, NICHT GEPFLEGT:
|
||||
* `bis` -- Brettkarten mit event_ende
|
||||
* Uhr + Dauer -- ein Live von 22:00 ueber 240 Minuten endet um
|
||||
02:00 am naechsten Tag. Das stand bisher
|
||||
NIRGENDS, obwohl die Zahlen da waren.
|
||||
Eine Liste „diese Arten haben ein Ende" waere die Liste, die beim
|
||||
naechsten Termintyp veraltet.
|
||||
|
||||
DIE KOPIEN AENDERN `tag` NICHT. Wer auf eine Kachel am Mittwoch
|
||||
tippt, will den Termin bearbeiten -- und der faengt am Montag an.
|
||||
Wuerde die Kopie `tag` auf den Mittwoch setzen, verschoebe ein
|
||||
Speichern den Termin auf den Tag, an dem man zufaellig
|
||||
hingetippt hat. Der Anzeigetag steht deshalb getrennt daneben. */
|
||||
|
||||
/** Der letzte Tag, an dem dieser Eintrag noch laeuft. */
|
||||
function endTagVon(e) {
|
||||
if (e.bis) return String(e.bis).slice(0, 10);
|
||||
if (e.uhr && Number(e.dauer_min) > 0) {
|
||||
const [st, mi] = e.uhr.split(':').map(Number);
|
||||
const start = ausText(e.tag);
|
||||
if (Number.isNaN(st) || Number.isNaN(start.getTime())) return e.tag;
|
||||
/* AB MITTERNACHT RECHNEN, NICHT AB `ausText`. `ausText` legt den
|
||||
Tag bewusst auf 12:00 UTC (damit Zeitzonen ihn nicht um einen
|
||||
Tag verschieben) -- wer darauf die Uhrzeit ADDIERT, rechnet
|
||||
zwoelf Stunden zu viel. Erster Anlauf ergab damit fuer
|
||||
„13:00, 60 Minuten" den FOLGETAG. */
|
||||
const mitternacht = Date.UTC(
|
||||
start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate());
|
||||
/* Minus eine Millisekunde: Ein Stream von 22:00 ueber genau zwei
|
||||
Stunden endet um 00:00 -- er laeuft am naechsten Tag NICHT
|
||||
mehr, auch wenn die Zahl dort steht. */
|
||||
const endeMs = mitternacht
|
||||
+ ((st * 60 + mi + Number(e.dauer_min)) * 60000) - 1;
|
||||
return alsText(new Date(Math.max(endeMs, mitternacht)));
|
||||
}
|
||||
return e.tag;
|
||||
}
|
||||
|
||||
/* Eine Obergrenze, die nicht schoen ist, aber ehrlich: Ein Eintrag
|
||||
mit kaputtem Enddatum (Jahr 9999) wuerde sonst Millionen Kopien
|
||||
bauen und den Browser anhalten. 400 Tage sind mehr als jede
|
||||
Ansicht je zeigt -- die Grenze ist also nie im Weg und faengt nur
|
||||
den Unfall ab. */
|
||||
const SPANNE_MAX = 400;
|
||||
|
||||
function nachTag() {
|
||||
const karte = new Map();
|
||||
const lege = (tag, e) => {
|
||||
if (!karte.has(tag)) karte.set(tag, []);
|
||||
karte.get(tag).push(e);
|
||||
};
|
||||
for (const e of sichtbare()) {
|
||||
if (!karte.has(e.tag)) karte.set(e.tag, []);
|
||||
karte.get(e.tag).push(e);
|
||||
const ende = endTagVon(e);
|
||||
if (!ende || ende <= e.tag) { lege(e.tag, e); continue; }
|
||||
|
||||
const tage = Math.min(SPANNE_MAX,
|
||||
Math.round((ausText(ende) - ausText(e.tag)) / 86400000) + 1);
|
||||
let d = ausText(e.tag);
|
||||
for (let i = 0; i < tage; i++) {
|
||||
lege(alsText(d), {
|
||||
...e,
|
||||
/* Der Tag, an dem die Kachel steht -- NICHT `tag`. */
|
||||
spann_tag: alsText(d),
|
||||
spann_nr: i + 1,
|
||||
spann_tage: tage,
|
||||
spann_bis: ende,
|
||||
spann_pos: i === 0 ? 'start' : (i === tage - 1 ? 'ende' : 'mitte'),
|
||||
});
|
||||
d = plus(d, 1);
|
||||
}
|
||||
}
|
||||
return karte;
|
||||
}
|
||||
@@ -629,8 +711,38 @@
|
||||
if (e.ziel) k.href = e.ziel;
|
||||
k.style.setProperty('--pfarbe', e.farbe);
|
||||
k.title = `${e.titel}${e.zusatz ? ' — ' + e.zusatz : ''}`
|
||||
+ (e.serie_id ? ' — wiederholt sich' : '');
|
||||
if (e.uhr) k.append(el('span', 'k-pille__zeit', e.uhr));
|
||||
+ (e.serie_id ? ' — wiederholt sich' : '')
|
||||
/* Der ganze Zeitraum, nicht nur „Tag 2/4": Wer am Mittwoch
|
||||
draufzeigt, will wissen, WANN es anfing und aufhoert -- sonst
|
||||
muss er selbst zurueckblaettern und zaehlen. */
|
||||
+ (e.spann_tage > 1
|
||||
? ` — läuft vom ${tagLang(e.tag)} bis ${tagLang(e.spann_bis)}`
|
||||
+ ` (Tag ${e.spann_nr} von ${e.spann_tage})`
|
||||
: '');
|
||||
/* ---- LAEUFT UEBER MEHRERE TAGE (20.09.2026) --------------------
|
||||
|
||||
Drei Dinge unterscheiden die Kachel eines Zeitraums von der eines
|
||||
Punkttermins, und alle drei sind noetig:
|
||||
|
||||
1. `data-spanne` -- daraus macht das Stilblatt einen
|
||||
durchgehenden Balken: links angeschnitten, wo er gestern
|
||||
schon lief, rechts angeschnitten, wo er morgen weiterlaeuft.
|
||||
Man sieht an der FORM, dass es weitergeht, ohne ein Wort.
|
||||
2. „Tag 2/4" statt der Uhrzeit auf den Folgetagen. Die Uhrzeit
|
||||
gehoert zum Anfang; sie am Mittwoch zu wiederholen behauptet,
|
||||
es ginge am Mittwoch um 20:00 wieder los.
|
||||
3. Der ganze Zeitraum im Titel -- fuer Maus und Vorleseprogramm.
|
||||
|
||||
AUF DEM ANFANGSTAG BLEIBT ALLES WIE VORHER. Wer den Termin
|
||||
eintraegt, sieht dort die Uhrzeit, die er eingetragen hat. */
|
||||
if (e.spann_tage > 1) {
|
||||
k.dataset.spanne = e.spann_pos;
|
||||
k.style.setProperty('--spann-tage', String(e.spann_tage));
|
||||
}
|
||||
if (e.spann_tage > 1 && e.spann_pos !== 'start') {
|
||||
k.append(el('span', 'k-pille__zeit k-pille__lauf',
|
||||
`Tag ${e.spann_nr}/${e.spann_tage}`));
|
||||
} else if (e.uhr) k.append(el('span', 'k-pille__zeit', e.uhr));
|
||||
/* Das Zeichen steht im Raster VOR dem Titel, nicht dahinter: Eine
|
||||
Zelle im Monatsraster ist gut 150 px breit, der Titel wird dort
|
||||
abgeschnitten -- ein Zeichen am Ende wäre genau in der Ansicht
|
||||
@@ -1355,7 +1467,16 @@
|
||||
|
||||
const liste = $('tagdialog-liste');
|
||||
liste.replaceChildren();
|
||||
const eintraege = sichtbare().filter((e) => e.tag === tag);
|
||||
/* UEBER `nachTag()`, NICHT UEBER `e.tag` (20.09.2026).
|
||||
|
||||
Vorher stand hier ein eigener Filter auf den Anfangstag. Folge:
|
||||
Im Monatsraster war die Aktion am Mittwoch markiert -- tippte man
|
||||
die Zelle an, sagte der Tagesdialog „An diesem Tag steht
|
||||
nichts." Zwei Antworten auf dieselbe Frage, und die zweite
|
||||
widerspricht dem, was man gerade gesehen hat.
|
||||
|
||||
`nachTag()` ist die eine Stelle, die das entscheidet. */
|
||||
const eintraege = nachTag().get(tag) || [];
|
||||
if (!eintraege.length) {
|
||||
liste.append(el('p', 'leise', 'An diesem Tag steht nichts.'));
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user