Aufgaben: die Bedienung, nicht die Kacheln

Filipe: "ich will dass du dass system jetzt wie die vier kategorien
bedient werden, perfektionnierst ... ich red von den aufgaben. das
system von den aufgaben, die bedienung ... die hauptkachel von der
kategorie nicht veraendern oder anfassen, die bleiben so."

Die vier Kacheln sind unberuehrt. Geaendert ist, was danach kommt.

--- 1. DAS VORLAGENBRETT WAR IM WEG ---

Gemessen am Handy: Der Vorlagenblock fuellte ANDERTHALB BILDSCHIRME,
bevor die erste eigene Aufgabe kam. Und mein eigener Ausbau von Profi
und Meister ein paar Stunden vorher hat ihn noch laenger gemacht --
aus 48 Vorlagen wurden 80.

Das ist die falsche Reihenfolge: Vorlagen holt man selten, das Brett
benutzt man jeden Tag. Der Block bleibt an seiner Stelle (dort gehoert
er hin, weil daraus Aufgaben auf das Brett darunter wandern), ist aber
zugeklappt. Zugeklappt steht dort, WIE VIEL darin liegt -- sonst sieht
er aus wie eine Ueberschrift ohne Inhalt und niemand macht ihn auf.

Wer ihn aufmacht, findet ihn beim naechsten Mal offen: Wer Vorlagen
holt, holt meistens mehrere. Und zugeklappt werden die achtzig Karten
GAR NICHT ERST GEBAUT, nicht nur versteckt.

--- 2. MAN SAH NICHT, WAS MAN SCHON GEHOLT HATTE ---

Dieselbe Vorlage liess sich zweimal uebernehmen, und die Aufgabe stand
dann zweimal auf dem Brett -- ohne jeden Hinweis. Bei achtzig Vorlagen
ueber vier Stufen weiss niemand auswendig, was er letzten Monat schon
geholt hat.

Die Kennung der Vorlage steht jetzt an der Aufgabe (neue Spalte
`vorlage`). Ueber den TITEL zu vergleichen waere die naheliegende
Abkuerzung gewesen -- und faellt in dem Moment um, in dem jemand den
Titel einer uebernommenen Aufgabe aendert.

Uebernommene Karten treten zurueck (nicht: verschwinden -- wer sie
ausblendet, nimmt die Moeglichkeit, sie bewusst noch einmal zu holen),
tragen "schon uebernommen" MIT ZUSTAND, und ihr Knopf heisst
"Nochmal". Darunter steht der Stand: "5 von 7 noch nicht uebernommen."
Es braucht dafuer keine zweite Abfrage -- die Aufgaben liegen ohnehin
im Browser.

--- 3. DRINGEND SCHLAEGT WICHTIG ---

Die Liste war nach PRIORITAET sortiert, dann nach Frist. Auf dem Brett
stand damit eine seit vier Tagen ueberfaellige Aufgabe mit Prioritaet
"niedrig" UNTER einer, die als "hoch" eingetragen ist und erst in
dreissig Tagen faellig wird. Wer die Spalte von oben liest, faengt
dann mit dem Falschen an.

Eine Prioritaet ist eine Einschaetzung von damals, eine
ueberschrittene Frist eine Tatsache von heute. Jetzt: erst was
faellig ist, dann nach Datum, und die Prioritaet entscheidet nur noch
bei gleichem Datum. Die Sortierung steht im SERVER -- Startseite und
Uebersicht lesen dieselbe Liste, und zwei Sortierungen fuer dieselbe
Frage laufen auseinander.

--- 4. "WICHTIG" STEHT JETZT DA ---

Die Prioritaet war ein 3 px breiter Rand links -- direkt neben der
farbigen Kante der Spalte und damit praktisch unsichtbar. Als Wort
steht sie dort, wo man sie liest. NUR bei "hoch" und nur solange
nicht erledigt: Eine Marke an jeder Karte waere keine Marke mehr.

--- Pruefung ---

pruef-aufgaben-vorlagen: zugeklappt als Vorgabe (gemessen wird, dass
die Karten gar nicht gebaut werden), Aufklappen, uebernommene Vorlage
markiert samt Zustand und "Nochmal"-Knopf, Stand darunter, Zustand
ueberlebt das Neuladen -- mit Gegenprobe, dass die uebrigen NICHT
markiert sind.

Dabei fiel eine eigene Nachlaessigkeit auf: Die Pruefung "die Karten
sind gestaltet" mass zu einem Zeitpunkt, an dem es zugeklappt gar
keine Karte gab -- getComputedStyle auf null liefert nichts, und der
Haken wurde rot, ohne dass etwas kaputt war. Sie misst jetzt nach dem
Aufklappen.

pruef-aufgabenbrett: die Sortierung an zwei absichtlich unguenstig
angelegten Aufgaben (ueberfaellig+niedrig gegen fern+hoch), plus die
Gegenprobe, dass bei GLEICHER Frist weiterhin die Prioritaet
entscheidet -- sonst waere die Prioritaet wirkungslos geworden, und
das waere die andere Uebertreibung.

Ausserdem gruen: pruef-css-klassen, pruef-start-ansicht, pruef-uebersicht.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-09 14:56:40 +02:00
co-authored by Claude Opus 5
parent 38416962b3
commit f3acfab10a
26 changed files with 594 additions and 208 deletions
+119 -12
View File
@@ -183,6 +183,17 @@
if (a.beschreibung) k.append(el('p', 'karte__text', a.beschreibung));
const zeile = el('div', 'karte__zeile');
/* WICHTIG STEHT DA, statt nur eine Kante einzufaerben.
Die Prioritaet gab es als 3 px breiten Rand links -- direkt neben
der farbigen Kante der Spalte, und damit praktisch unsichtbar.
Als Wort steht sie da, wo man sie liest.
NUR bei "hoch". Eine Marke an jeder Karte waere keine Marke mehr:
Was immer da steht, sieht man nach zwei Tagen nicht mehr. */
if (a.prioritaet === 'hoch' && a.status !== 'erledigt') {
zeile.append(el('span', 'karte__wichtig', 'wichtig'));
}
if (a.frist) {
const faellig = a.status !== 'erledigt' && a.frist < heute;
const f = el('span', 'karte__frist' + (faellig ? ' karte__frist--faellig' : ''),
@@ -882,6 +893,25 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
let vBereich = 'live';
let vStufe = 'anfaenger';
/* ---------- DAS VORLAGENBRETT IST ZUGEKLAPPT (09.09.2026) ------------
Filipe: "ich will nur dass du dich informierst und schaust was man
vielleicht noch besser machen koennte von der benutzung ... ich red
von den aufgaben. das system von den aufgaben, die bedienung."
Gemessen auf dem Handy: Der Vorlagenblock fuellte anderthalb
Bildschirme, BEVOR die erste eigene Aufgabe kam. Nach dem Ausbau
von Profi und Meister am selben Tag ist er noch laenger geworden.
Das ist die falsche Reihenfolge: Vorlagen holt man selten, das
Brett benutzt man jeden Tag. Der Block bleibt an seiner Stelle --
dort gehoert er hin, weil daraus Aufgaben auf das Brett darunter
wandern --, aber er ist jetzt zu. Wer ihn aufmacht, findet ihn
beim naechsten Mal wieder offen: Wer Vorlagen holt, holt meistens
mehrere. */
const VORLAGEN_OFFEN = 'dfw_vorlagenbrett_offen';
let vOffen = false;
try { vOffen = localStorage.getItem(VORLAGEN_OFFEN) === 'ja'; } catch { vOffen = false; }
async function vorlagenbrettZeigen() {
const ziel = $('vorlagenbrett');
if (!ziel || !ich) return;
@@ -896,12 +926,48 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
ziel.hidden = false;
ziel.textContent = '';
const kopf = el('div', 'vorlagenbrett__kopf');
kopf.append(el('h2', 'feldschild', 'Aufgaben aus der Vorlage'));
kopf.append(el('p', 'vorlagenbrett__unter',
'Vier Bereiche, vier Stufen. Übernommen wird als ganz normale Aufgabe '
+ '– mit Frist, veränderbar, auf dem Brett darunter.'));
/* DER KOPF IST DER KNOPF. Ein eigener kleiner Schalter daneben waere
ein zweites Ziel fuer dieselbe Absicht -- und ein kleineres. */
const kopf = el('button', 'vorlagenbrett__kopf');
kopf.type = 'button';
kopf.setAttribute('aria-expanded', String(vOffen));
kopf.setAttribute('aria-controls', 'vorlagenbrett-koerper');
const kText = el('span', 'vorlagenbrett__kopftext');
kText.append(el('span', 'feldschild', 'Aufgaben aus der Vorlage'));
/* Zugeklappt zaehlt nicht die Erklaerung, sondern WIE VIEL darin
liegt -- sonst sieht der Block aus wie eine Ueberschrift ohne
Inhalt und niemand macht ihn je auf. */
const gesamt = Object.values(vorlagen)
.reduce((n, b) => n + Object.values(b).reduce((m, l) => m + l.length, 0), 0);
kText.append(el('span', 'vorlagenbrett__unter', vOffen
? 'Vier Bereiche, vier Stufen. Übernommen wird als ganz normale Aufgabe '
+ '– mit Frist, veränderbar, auf dem Brett darunter.'
: `${gesamt} fertige Aufgaben in vier Bereichen und vier Stufen – zum Übernehmen.`));
kopf.append(kText);
const pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
pfeil.setAttribute('viewBox', '0 0 24 24');
pfeil.setAttribute('class', 'klapp-pfeil');
pfeil.setAttribute('aria-hidden', 'true');
const pfad = document.createElementNS('http://www.w3.org/2000/svg', 'path');
pfad.setAttribute('d', 'm6 9.5 6 6 6-6');
pfeil.append(pfad);
kopf.append(pfeil);
kopf.addEventListener('click', () => {
vOffen = !vOffen;
try { localStorage.setItem(VORLAGEN_OFFEN, vOffen ? 'ja' : 'nein'); } catch { /* egal */ }
vorlagenbrettZeigen();
});
ziel.append(kopf);
ziel.dataset.auf = vOffen ? 'ja' : 'nein';
/* Zugeklappt wird der Rest gar nicht erst gebaut. Ihn nur zu
verstecken hiesse, bei jedem Neuzeichnen achtzig Karten
anzulegen, die niemand sieht. */
if (!vOffen) return;
const koerper = el('div', 'vorlagenbrett__koerper');
koerper.id = 'vorlagenbrett-koerper';
ziel.append(koerper);
/* Reihe 1: der Bereich. */
const r1 = el('div', 'stufenleiter');
@@ -916,7 +982,7 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
k.addEventListener('click', () => { vBereich = b.schluessel; vorlagenbrettZeigen(); });
r1.append(k);
}
ziel.append(r1);
koerper.append(r1);
/* Reihe 2: die Stufe, mit der Zahl der Aufgaben darin. */
const r2 = el('div', 'stufenleiter');
@@ -935,43 +1001,84 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
k.addEventListener('click', () => { vStufe = st.schluessel; vorlagenbrettZeigen(); });
r2.append(k);
}
ziel.append(r2);
koerper.append(r2);
const hilfe = STUFEN_VORLAGE.find((x) => x.schluessel === vStufe)?.hilfe;
if (hilfe) ziel.append(el('p', 'stufenleiter__hilfe', hilfe));
if (hilfe) koerper.append(el('p', 'stufenleiter__hilfe', hilfe));
/* Für wen? */
const fuer = ich.rolle === 'creator' ? ich.id : nurCreator;
if (!fuer) {
ziel.append(el('p', 'vorlagenbrett__hinweis',
koerper.append(el('p', 'vorlagenbrett__hinweis',
'Wähle oben einen Creator, dann lassen sich diese Aufgaben übernehmen.'));
}
/* WAS SCHON GEHOLT WURDE, STEHT DA (09.09.2026).
Vorher konnte man dieselbe Vorlage zweimal uebernehmen und
bekam die Aufgabe zweimal auf das Brett -- ohne jeden Hinweis.
Bei achtzig Vorlagen ueber vier Stufen weiss niemand auswendig,
was er letzten Monat schon geholt hat.
Verglichen wird ueber die KENNUNG der Vorlage, nicht ueber den
Titel: Ein Titel darf geaendert werden, und dann waere der
Vergleich still falsch. Die Kennung liegt seit heute an der
Aufgabe (Spalte `vorlage`).
Es braucht dafuer keine zusaetzliche Abfrage -- die Aufgaben
liegen ohnehin schon im Browser. */
const schonDa = new Map();
for (const a of alleAufgaben) {
if (!a.vorlage) continue;
if (fuer && a.creator_id !== fuer) continue;
schonDa.set(a.vorlage, a);
}
const liste = (vorlagen[vBereich] || {})[vStufe] || [];
const box = el('div', 'vorlagenbrett__liste');
for (const [nr, v] of liste.entries()) {
const karte = el('div', 'vorlagenbrett__karte');
const schon = schonDa.get(v.schluessel);
if (schon) karte.dataset.schon = 'ja';
karte.append(el('h3', 'vorlagenbrett__titel', v.titel));
karte.append(el('p', 'vorlagenbrett__text', v.text));
const fuss = el('div', 'vorlagenbrett__fuss');
fuss.append(el('span', 'vorlagenbrett__frist',
v.tage === 1 ? 'Frist: morgen' : `Frist: in ${v.tage} Tagen`));
if (schon) {
/* Der Zustand steht dabei, nicht nur die Tatsache. "Schon
uebernommen" allein liesse offen, ob sie noch offen ist oder
laengst abgehakt -- und danach entscheidet man, ob man sie
ein zweites Mal holt. */
fuss.append(el('span', 'vorlagenbrett__schon',
`schon übernommen · ${STATUS_NAME[schon.status] || schon.status}`));
}
if (fuer) {
const k = el('button', 'knopf knopf--klein', 'Übernehmen');
const k = el('button', 'knopf knopf--klein', schon ? 'Nochmal' : 'Übernehmen');
k.type = 'button';
if (schon) k.title = 'Diese Vorlage liegt schon auf dem Brett – noch einmal übernehmen?';
k.addEventListener('click', () => uebernehmen(k, { art: 'aufgabe', nr }, fuer));
fuss.append(k);
}
karte.append(fuss);
box.append(karte);
}
ziel.append(box);
/* Und wie viele der Stufe noch offen sind -- die Zahl, nach der man
eigentlich sucht, wenn man den Block aufmacht. */
if (liste.length) {
const offen = liste.filter((v) => !schonDa.has(v.schluessel)).length;
koerper.append(el('p', 'vorlagenbrett__stand', offen
? `${offen} von ${liste.length} noch nicht übernommen.`
: `Alle ${liste.length} dieser Stufe sind übernommen.`));
}
koerper.append(box);
if (fuer && liste.length > 1) {
const alle = el('button', 'abmelden', `Alle ${liste.length} übernehmen`);
alle.title = 'Legt alle Aufgaben dieser Stufe an – auch die, die schon auf dem Brett liegen.';
alle.type = 'button';
alle.style.marginTop = '12px';
alle.addEventListener('click', () => uebernehmen(alle, { art: 'aufgaben_alle' }, fuer));
ziel.append(alle);
koerper.append(alle);
}
}