From 76fa8b95fc86b20090ac061bfe85e59f587be138 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Wed, 16 Sep 2026 19:21:38 +0200 Subject: [PATCH] Beim Verteilen sehen, wer schon wie viel hat Weiter an derselben Sache: die Kategorien, aus denen Aufgaben an das Team gehen. ZWEI DINGE WAREN UNBEQUEM: Die Person kam aus dem Formular GANZ OBEN auf der Seite. Man waehlt sie dort, scrollt herunter zum Vorlagenbrett und drueckt "Uebernehmen" -- und wer das nicht weiss, bekommt "Bitte zuerst eine Person waehlen" und sucht, wo. Und beim Vergeben sah man nicht, wer schon wie viel offen hat. Das ist die wichtigere Haelfte: Zu wenig Zeit ist in den Untersuchungen zu Moderatoren der meistgenannte Grund fuers Aufhoeren, und die Person, die verteilt, ist die einzige, die das verhindern kann. Dafuer muss die Zahl dort stehen, wo entschieden wird -- nicht auf einer Auswertung, die man hinterher aufruft. Jetzt steht ueber den Aufgaben eine Reihe mit den Namen des Teams und der Zahl daneben. Ein Klick, und die uebernommenen Aufgaben gehen dorthin; das Formular oben bleibt als Rueckfall, damit der bisherige Weg weiter funktioniert. KEINE SCHWELLE, KEINE WARNFARBE AUF DER ZAHL. Was "zu viel" ist, haengt vom Menschen ab -- eine feste Grenze waere geraten, und geraten ist bei dieser Frage schlimmer als nichts. Was NICHT geraten ist: dass etwas ueberfaellig liegt. Nur das wird markiert, und zwar gedeckt. Ein Warnton an einem Namen liest sich sonst wie ein Vorwurf gegen die Person, dabei ist es eine Auskunft ueber die Verteilung. Ohne eine einzige neue Abfrage: Die Personen und ihre Aufgaben liegen im Browser ohnehin schon. Ein zweiter Abruf waere ein zweiter Weg, auf dem eine andere Liste herauskommen kann. server/pruef-modi-katalog.mjs 45 Pruefungen (vorher 36), 0 Fehler Der neue Abschnitt meldet sich als DogFather an -- der bisherige Browserteil ist ein Modi, und der sieht diese Auswahl gar nicht. Er drueckt wirklich: Marina waehlen (9 offen), eine Aufgabe uebernehmen, nachsehen ob sie bei ihr liegt (9 -> 10). Ein Knopf, den niemand betaetigt hat, ist kein geprueter Knopf. Und er prueft die Gegenrichtung mit: Ein Creator und eine Managerin stehen NICHT zur Auswahl -- sie arbeiten im anderen Haus. pruef-aufgabenbrett, pruef-sicht, pruef-womit 41, pruef-css-klassen -- alle 0 Fehler Co-Authored-By: Claude Opus 5 --- server/pruef-modi-katalog.mjs | 107 ++++++++++++++++++++++++++++++++ workspace/app.webmanifest | 8 +-- workspace/assets/css/start.css | 16 +++++ workspace/assets/js/aufgaben.js | 64 ++++++++++++++++++- workspace/aufgaben.html | 24 +++---- workspace/automation.html | 26 ++++---- workspace/befinden.html | 24 +++---- workspace/bereich.html | 34 +++++----- workspace/calls.html | 28 ++++----- workspace/chat.html | 26 ++++---- workspace/content.html | 30 ++++----- workspace/crew-index.html | 10 +-- workspace/crew.webmanifest | 8 +-- workspace/dateien.html | 26 ++++---- workspace/entwicklung.html | 24 +++---- workspace/index.html | 8 +-- workspace/kalender.html | 28 ++++----- workspace/leistung.html | 26 ++++---- workspace/personen.html | 26 ++++---- workspace/profil.html | 28 ++++----- workspace/rechte.html | 24 +++---- workspace/report.html | 28 ++++----- workspace/scouting.html | 26 ++++---- workspace/start.html | 24 +++---- workspace/startcheck.html | 28 ++++----- workspace/steckbrief.html | 28 ++++----- workspace/talente.html | 24 +++---- workspace/team.html | 26 ++++---- workspace/teamlage.html | 24 +++---- workspace/treff-moderation.html | 24 +++---- workspace/treff-regeln.html | 26 ++++---- workspace/uebersicht.html | 26 ++++---- workspace/wissen.html | 26 ++++---- 33 files changed, 545 insertions(+), 360 deletions(-) diff --git a/server/pruef-modi-katalog.mjs b/server/pruef-modi-katalog.mjs index fd34129a..86f7a449 100644 --- a/server/pruef-modi-katalog.mjs +++ b/server/pruef-modi-katalog.mjs @@ -344,6 +344,113 @@ console.log("\n=== 6. Das Brett im echten Browser ===\n"); } } +/* ======================================================================= + 6b. AN WEN? — die Auswahl steht dort, wo entschieden wird (16.09.2026) + + Filipe: „perfektionniere die kategorien wo ich aufgaben an die modis + verteile und so." + + Bis heute kam die Person aus dem Formular GANZ OBEN auf der Seite: + dort wählen, herunterscrollen, „Übernehmen" drücken. Wer das nicht + weiß, bekommt „Bitte zuerst eine Person wählen" und sucht. + + Und man sah beim Vergeben nicht, wer schon wie viel offen hat. Zu + wenig Zeit ist der meistgenannte Grund, warum Moderatoren aufhören; + die Person, die verteilt, ist die einzige, die das verhindern kann. + Dafür muss die Zahl dort stehen, wo entschieden wird — nicht auf + einer Auswertung, die man hinterher aufruft. + ======================================================================= */ +console.log(""); +console.log("=== 6b. An wen die Aufgabe geht ==="); +console.log(""); +{ + const { chromium } = await import( + "file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs"); + const browser = await chromium.launch(); + try { + const kontext = await browser.newContext({ viewport: { width: 1280, height: 1100 } }); + const seite = await kontext.newPage(); + const konsole = []; + seite.on("console", (e) => { if (e.type() === "error") konsole.push(e.text()); }); + seite.on("pageerror", (e) => konsole.push("Absturz: " + e.message)); + await seite.goto(BASIS + "/workspace/", { waitUntil: "domcontentloaded" }); + await seite.click('.rolle[data-rolle="admin"]'); + await seite.fill("#code", "CODE-DOGI-0001"); + await seite.click("button[type=submit]"); + await seite.waitForURL("**/start.html", { timeout: 15000 }); + await seite.goto(BASIS + "/workspace/aufgaben.html", { waitUntil: "networkidle" }); + await seite.waitForTimeout(1400); + const zu = await seite.evaluate(() => + document.getElementById("vorlagenbrett")?.dataset.auf !== "ja"); + if (zu) { + await seite.click(".vorlagenbrett__kopf").catch(() => {}); + await seite.waitForTimeout(800); + } + + const wahl = await seite.evaluate(() => { + const reihen = [...document.querySelectorAll(".stufenleiter--fein")]; + const letzte = reihen[reihen.length - 1]; + const zahl = /^[0-9]+$/; + return { + reihen: reihen.length, + namen: [...(letzte?.querySelectorAll(".stufenleiter__name") || [])] + .map((z) => z.textContent.trim()), + zahlenOk: [...(letzte?.querySelectorAll(".stufenleiter__zahl") || [])] + .every((z) => zahl.test(z.textContent.trim())), + zahlen: [...(letzte?.querySelectorAll(".stufenleiter__zahl") || [])] + .map((z) => z.textContent.trim()), + satz: [...document.querySelectorAll(".vorlagenbrett__stand")] + .map((z) => z.textContent.trim()) + .find((t) => t.includes("Formular oben") || t.includes("gehen an")) || "", + }; + }); + /* ZWEI FEINE REIHEN: die Stufen und die Personen. Eine einzelne + Zahl haette nicht gesagt, welche der beiden fehlt. */ + ok(wahl.reihen === 2, "zwei Auswahlreihen (Stufen und Personen): " + wahl.reihen); + ok(wahl.namen.includes("Marina"), + "der Modi steht zur Auswahl (" + wahl.namen.join(", ") + ")"); + ok(!wahl.namen.includes("Tili") && !wahl.namen.includes("Schulle"), + "ein Creator und eine Managerin nicht — sie arbeiten im anderen Haus"); + ok(wahl.zahlenOk && wahl.zahlen.length === wahl.namen.length, + "neben jedem Namen steht, wie viel offen ist (" + wahl.zahlen.join(", ") + ")"); + ok(wahl.satz.includes("Formular oben"), + "und solange niemand gewählt ist, sagt die Seite es"); + + /* JETZT WIRKLICH DRUECKEN -- und nachsehen, ob die Aufgabe bei + DIESEM Menschen landet. Ein Knopf, den niemand betaetigt hat, + ist kein geprueter Knopf. */ + await seite.evaluate(() => { + const reihen = [...document.querySelectorAll(".stufenleiter--fein")]; + const letzte = reihen[reihen.length - 1]; + [...letzte.querySelectorAll(".stufenleiter__knopf")] + .find((k) => k.textContent.includes("Marina"))?.click(); + }); + await seite.waitForTimeout(600); + const nachWahl = await seite.evaluate(() => + [...document.querySelectorAll(".vorlagenbrett__stand")] + .map((z) => z.textContent.trim()).find((t) => t.includes("gehen an")) || ""); + ok(nachWahl.includes("Marina"), "nach dem Klick steht es da: " + nachWahl); + + const vorher = await seite.evaluate(() => document.querySelectorAll(".karte").length); + await seite.evaluate(() => { + [...document.querySelectorAll(".vorlagenbrett__karte")][0] + ?.querySelector("button")?.click(); + }); + await seite.waitForTimeout(1800); + const danach = await seite.evaluate(() => ({ + karten: document.querySelectorAll(".karte").length, + fuerMarina: [...document.querySelectorAll(".karte")] + .filter((k) => k.textContent.includes("Marina")).length, + })); + ok(danach.karten === vorher + 1, + "die Aufgabe liegt auf dem Brett (" + vorher + " -> " + danach.karten + ")"); + ok(danach.fuerMarina > 0, "und zwar bei Marina (" + danach.fuerMarina + ")"); + ok(konsole.length === 0, + konsole.length ? "Fehler in der Konsole: " + konsole[0].slice(0, 80) + : "keine Fehler in der Konsole"); + } finally { await browser.close(); } +} + /* ---------- 7. Gegenprobe -------------------------------------------- */ console.log("\n=== 7. Gegenprobe: kann das hier ueberhaupt scheitern? ===\n"); { diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index e78c1a95..4ab7838b 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -13,25 +13,25 @@ "theme_color": "#06090f", "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609161903", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609161917", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609161903", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609161917", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609161903", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609161917", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609161903", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609161917", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index 0e70340f..4d204dbc 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -7620,6 +7620,22 @@ body.start .k-leiste .feldschild::after { .stufenleiter--fein { margin: -6px 0 14px; } .stufenleiter--fein .stufenleiter__knopf { padding: 5px 11px; font-size: .76rem; } +/* WER SCHON ETWAS LIEGEN HAT (16.09.2026). + + Beim Vergeben einer Aufgabe steht neben jedem Namen, wie viel offen + ist. Die Zahl allein bekommt KEINE Farbe: Was "zu viel" ist, haengt + vom Menschen ab, und eine feste Grenze waere geraten. + + Was nicht geraten ist: dass etwas ueberfaellig liegt. Nur das wird + markiert -- und zwar gedeckt, nicht grell. Ein Warnton an einem + Namen liest sich sonst wie ein Vorwurf gegen die Person, dabei ist + es eine Auskunft ueber die Verteilung. */ +.stufenleiter__knopf[data-spaet="ja"] { --sf: #cc9451; } +.stufenleiter__spaet { + font-size: .72rem; color: #d8a76a; + font-variant-numeric: tabular-nums; +} + .stufenleiter__knopf:hover { color: var(--text); box-shadow: diff --git a/workspace/assets/js/aufgaben.js b/workspace/assets/js/aufgaben.js index 2291ab19..70c03c1e 100644 --- a/workspace/assets/js/aufgaben.js +++ b/workspace/assets/js/aufgaben.js @@ -969,6 +969,11 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe $('b-feld-verant').hidden = false; try { const { personen } = await (await hole('/workspace/api/personen')).json(); + /* AUCH ALS DATEN BEHALTEN, nicht nur als