Nicht jeder bekommt alle 68 Punkte -- DogFather und die rechte Hand suchen je Person aus
Filipe: "ich will dass die rechte hand und ich diese aufgaben die es da
gibt, individuel aussuchen koennen wer welche aufgabe bekommt. bis
dahin sollen die keine aufgaben sehen. nur die, die die rechte hand
oder dogfather ihnen zutragen."
VORHER GEFRAGT, UND ES WAR NOETIG. Auf entwicklung.html stehen zwei
Listen untereinander -- das Vorlagenbrett (Aufgaben zum Verteilen) und
der Beobachtungskatalog (die 68 Punkte je Person). Sein Text passte auf
das eine, sein Bildschirmfoto zeigte das andere. Am 24.09. habe ich in
genau dieser Lage geraten und an der falschen Stelle gebaut. Seine
Antwort: der 68-Punkte-Katalog, das Vorlagenbrett "nicht anfassen".
BIS HEUTE GALTEN ALLE 68 FUER JEDEN. Das war bequem und in der Sache
falsch: "Clips, Schnitt und Kommentare" gehoert nicht zu jemandem, der
nur im Chat moderiert -- und ein Punkt, der nie zutrifft, steht
trotzdem in der Zaehlung. "0 von 68" bei jemandem, fuer den zwoelf
gelten, ist keine Auskunft, sondern eine Entmutigung.
EINE TABELLE, EINE ZEILE JE PAAR. Eine kommagetrennte Liste in der
Personenzeile waere schneller gebaut und liesse sich nicht abfragen
("wer hat diesen Punkt?"), nicht zaehlen und nicht absichern. Wer und
wann stehen mit drin -- fuer die Frage "seit wann gilt das eigentlich
fuer ihn", die erfahrungsgemaess dann kommt, wenn sie niemand mehr
beantworten kann.
EINE STELLE FUER DIE ANTWORT, drei Aufrufer: die Karte der Leitung, die
Uebersicht mit den Zahlen und der Auswahl-Dialog. Drei Abschriften
waeren drei Gelegenheiten, dass eine nicht mitzieht -- und dann stuende
in der Uebersicht "von 68", waehrend in der Karte zwoelf Punkte stehen.
DIE ZAHLEN ZIEHEN MIT. "X von Y" zaehlt jetzt das Zugeteilte. Auch die
linke Zahl musste nachgezogen werden: Wer frueher zu einem Punkt
gesetzt hat, der ihm inzwischen nicht mehr zugeteilt ist, haette sonst
"13 von 12" bekommen.
GESPEICHERT WIRD DIE GANZE LISTE AUF EINMAL, in einer Transaktion. Wer
zwoelf Haken setzt und dabei die Verbindung verliert, haette sonst
sieben gesetzte und fuenf verlorene -- und saehe nicht, welche.
EINMALIG WIRD UEBERNOMMEN, wozu es schon eine Einschaetzung gibt. Ohne
das waere der Umbau Datenverlust auf dem Bildschirm: Wer zwanzig Punkte
gesetzt hat, saehe am naechsten Morgen eine leere Karte -- die Daten
liegen noch da, man kommt nur nicht mehr hin. Ein Flag verhindert, dass
die Uebernahme wiederkommt, nachdem jemand bewusst abgewaehlt hat; an
einer Wegwerf-Datenbank durchgespielt, beide Laeufe wie erwartet.
NOCH NICHTS AUSGESUCHT HEISST NICHT "KAPUTT". Die Karte sagt es dann
mit einem Satz und einem Knopf. Ein leerer Bildschirm ohne Erklaerung
ist die schlechteste Antwort von allen -- man weiss nicht, ob es laedt,
ob etwas kaputt ist oder ob schlicht noch niemand ausgesucht hat.
Geprueft: pruef-entwicklung 48 -> 61 Punkte. Zuerst das Wichtigste an
seinem Satz ("bis dahin sollen die keine aufgaben sehen"): ohne
Zuteilung ist die Karte leer -- ohne diese Zeile waere alles Folgende
auch dann gruen, wenn weiterhin alles fuer jeden gilt. Dazu vier
Gegenproben: erfundene Schluessel fallen weg, ein Modi sucht nicht aus
(404) und nach seinem Versuch steht der Bestand unveraendert da, und
alles wieder wegzunehmen geht ebenfalls (eine Auswahl, die man nur
erweitern kann, waere eine Falle). pruef-css-klassen und
pruef-tippziele (11) unveraendert gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -2587,3 +2587,82 @@
|
||||
Der Grund ist derselbe geblieben: Bei sechs Leuten wären es sechs
|
||||
Nullen, die aussehen wie Warnungen, und die echte siebte fällt
|
||||
dann nicht mehr auf. */
|
||||
|
||||
/* =====================================================================
|
||||
WELCHE PUNKTE GELTEN FUER DIESEN MENSCHEN (25.09.2026)
|
||||
=====================================================================
|
||||
|
||||
Filipe: „ich will dass die rechte hand und ich diese aufgaben die es
|
||||
da gibt, individuel aussuchen koennen wer welche aufgabe bekommt.
|
||||
bis dahin sollen die keine aufgaben sehen."
|
||||
===================================================================== */
|
||||
|
||||
/* Der Knopf steht neben „Notizen zu dieser Person" -- beides sind
|
||||
Wege, die von der Karte wegfuehren, und beide sehen gleich aus.
|
||||
Ist noch nichts ausgesucht, traegt er die Akzentfarbe: Dann ist er
|
||||
nicht eine Moeglichkeit unter vielen, sondern der naechste Schritt. */
|
||||
.e-karte__waehlen { cursor: pointer; font: inherit; }
|
||||
.e-karte__waehlen[data-leer="ja"] {
|
||||
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
|
||||
color: color-mix(in srgb, var(--akzent) 25%, #ffffff);
|
||||
background: color-mix(in srgb, var(--akzent) 14%, transparent);
|
||||
}
|
||||
|
||||
/* ---- Wenn noch nichts ausgesucht ist ------------------------------
|
||||
Ein leerer Bildschirm ohne Erklaerung ist die schlechteste Antwort
|
||||
von allen: Man weiss nicht, ob es laedt, ob etwas kaputt ist oder
|
||||
ob schlicht noch niemand ausgesucht hat. */
|
||||
.e-leerwahl {
|
||||
margin: 18px 0 0; padding: 22px 20px;
|
||||
border: 1px dashed color-mix(in srgb, var(--rand-hell) 80%, transparent);
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, .02);
|
||||
text-align: center;
|
||||
}
|
||||
.e-leerwahl__titel { margin: 0; font-size: 1.02rem; font-weight: 700; color: var(--text); }
|
||||
.e-leerwahl__satz {
|
||||
margin: 8px auto 16px; max-width: 46ch;
|
||||
font-size: .9rem; line-height: 1.5; color: var(--text-leise);
|
||||
}
|
||||
.e-leerwahl__knopf { cursor: pointer; }
|
||||
|
||||
/* ---- Der Auswahl-Dialog -------------------------------------------- */
|
||||
.e-punktwahl__satz {
|
||||
margin: 0 0 10px; font-size: .9rem; line-height: 1.5; color: var(--text-leise);
|
||||
}
|
||||
/* Die laufende Zahl steht OBEN und nicht bei den Knoepfen: Man liest
|
||||
sie waehrend des Auswaehlens, nicht danach. */
|
||||
.e-punktwahl__zahl {
|
||||
margin: 0 0 14px; padding: 7px 12px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, .04);
|
||||
font-size: .86rem; font-weight: 650; color: var(--text-leise);
|
||||
}
|
||||
.e-punktwahl__zahl[data-leer="ja"] {
|
||||
color: color-mix(in srgb, var(--warn) 30%, #ffffff);
|
||||
background: color-mix(in srgb, var(--warn) 12%, transparent);
|
||||
}
|
||||
.e-punktwahl__block { margin: 0 0 16px; }
|
||||
.e-punktwahl__kopf {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 8px 10px; margin: 0 0 6px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, .035);
|
||||
}
|
||||
.e-punktwahl__blockname {
|
||||
font-size: .95rem; font-weight: 750; color: var(--text); cursor: pointer;
|
||||
}
|
||||
.e-punktwahl__alle { width: 18px; height: 18px; cursor: pointer; }
|
||||
.e-punktwahl__liste { display: grid; gap: 2px; padding-left: 4px; }
|
||||
/* 44 px hoch, auch wenn der Text nur eine Zeile braucht -- hier werden
|
||||
68 Haken gesetzt, und zwar oft am Handy. */
|
||||
.e-punktwahl__punkt {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
min-height: 44px; padding: 4px 10px;
|
||||
border-radius: 9px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.e-punktwahl__punkt:hover { background: rgba(255, 255, 255, .045); }
|
||||
.e-punktwahl__punkt input { width: 17px; height: 17px; flex: none; cursor: pointer; }
|
||||
.e-punktwahl__titel { font-size: .9rem; line-height: 1.4; color: var(--text-leise); }
|
||||
.e-punktwahl__punkt:hover .e-punktwahl__titel { color: var(--text); }
|
||||
|
||||
@@ -1287,6 +1287,130 @@
|
||||
if (ziel) { ziel.hidden = true; ziel.textContent = ''; }
|
||||
}
|
||||
|
||||
/* ==== DIE AUSWAHL (25.09.2026) ===================================
|
||||
|
||||
Ein Dialog mit dem GANZEN Katalog und einem Haken an dem, was
|
||||
gilt. Man waehlt nur aus, was man sieht -- eine Liste, die nur das
|
||||
Ausgewaehlte zeigt, koennte man nie erweitern.
|
||||
|
||||
JE BLOCK EIN „ALLE"-SCHALTER: Wer einen Chat-Moderator einrichtet,
|
||||
will die vierzehn Chat-Punkte am Stueck, nicht vierzehn Klicks.
|
||||
Und er zeigt den Stand mit an (`indeterminate`), wenn nur ein Teil
|
||||
gesetzt ist -- sonst muesste man zaehlen.
|
||||
|
||||
GESPEICHERT WIRD ALLES AUF EINMAL. Punkt fuer Punkt zu schicken
|
||||
waere bequemer zu bauen und im Fehlerfall schlimmer: Bei einem
|
||||
Abbruch mitten drin haette die Person eine halb gesetzte Liste,
|
||||
und niemand saehe, welche Haelfte. */
|
||||
async function punkteWaehlen(id, name) {
|
||||
const a = await hole(`/workspace/api/entwicklung/person/${id}/punkte`);
|
||||
if (!a || !a.ok) { melde('Die Punkte ließen sich nicht laden.'); return; }
|
||||
const daten = await a.json();
|
||||
|
||||
const dlg = document.createElement('dialog');
|
||||
dlg.className = 'dialog e-punktwahl';
|
||||
const form = document.createElement('form');
|
||||
form.method = 'dialog';
|
||||
|
||||
const titel = el('h2', 'dialog__titel', `Welche Punkte gelten für ${name}?`);
|
||||
form.append(titel);
|
||||
form.append(el('p', 'e-punktwahl__satz',
|
||||
'Nur das Ausgewählte steht danach auf der Karte – und nur daran '
|
||||
+ 'wird gemessen. Was hier keinen Haken hat, taucht bei ihr oder '
|
||||
+ 'ihm gar nicht erst auf.'));
|
||||
|
||||
const zaehler = el('p', 'e-punktwahl__zahl');
|
||||
form.append(zaehler);
|
||||
|
||||
const kaesten = [];
|
||||
for (const b of daten.bloecke) {
|
||||
const block = el('section', 'e-punktwahl__block');
|
||||
const kopfZeile = el('div', 'e-punktwahl__kopf');
|
||||
const alleId = `pw-alle-${b.schluessel}`;
|
||||
const alle = document.createElement('input');
|
||||
alle.type = 'checkbox';
|
||||
alle.id = alleId;
|
||||
alle.className = 'e-punktwahl__alle';
|
||||
const alleSchild = document.createElement('label');
|
||||
alleSchild.htmlFor = alleId;
|
||||
alleSchild.className = 'e-punktwahl__blockname';
|
||||
alleSchild.textContent = b.name;
|
||||
kopfZeile.append(alle, alleSchild);
|
||||
block.append(kopfZeile);
|
||||
|
||||
const liste = el('div', 'e-punktwahl__liste');
|
||||
const eigene = [];
|
||||
for (const pt of b.punkte) {
|
||||
const zeile = document.createElement('label');
|
||||
zeile.className = 'e-punktwahl__punkt';
|
||||
const k = document.createElement('input');
|
||||
k.type = 'checkbox';
|
||||
k.value = pt.schluessel;
|
||||
k.checked = pt.dabei;
|
||||
k.addEventListener('change', () => { standZeigen(); });
|
||||
zeile.append(k);
|
||||
zeile.append(el('span', 'e-punktwahl__titel', pt.titel));
|
||||
liste.append(zeile);
|
||||
eigene.push(k);
|
||||
kaesten.push(k);
|
||||
}
|
||||
block.append(liste);
|
||||
alle.addEventListener('change', () => {
|
||||
for (const k of eigene) k.checked = alle.checked;
|
||||
standZeigen();
|
||||
});
|
||||
block.dataset.block = b.schluessel;
|
||||
block._alle = alle;
|
||||
block._eigene = eigene;
|
||||
form.append(block);
|
||||
}
|
||||
|
||||
function standZeigen() {
|
||||
const n = kaesten.filter((k) => k.checked).length;
|
||||
zaehler.textContent = n === 0
|
||||
? 'Noch nichts ausgewählt – die Karte bliebe leer.'
|
||||
: `${n} von ${kaesten.length} ausgewählt`;
|
||||
zaehler.dataset.leer = n === 0 ? 'ja' : 'nein';
|
||||
for (const block of form.querySelectorAll('.e-punktwahl__block')) {
|
||||
const an = block._eigene.filter((k) => k.checked).length;
|
||||
block._alle.checked = an === block._eigene.length && an > 0;
|
||||
/* DER DRITTE ZUSTAND. Ohne ihn saehe „drei von vierzehn" aus
|
||||
wie „keiner" -- und ein Klick auf den Schalter haette dann
|
||||
alle vierzehn gesetzt, statt die drei zu loesen. */
|
||||
block._alle.indeterminate = an > 0 && an < block._eigene.length;
|
||||
}
|
||||
}
|
||||
standZeigen();
|
||||
|
||||
const knoepfe = el('div', 'dialog__knoepfe');
|
||||
const ab = el('button', 'knopf-still', 'Abbrechen');
|
||||
ab.type = 'button';
|
||||
ab.addEventListener('click', () => { dlg.close(); dlg.remove(); });
|
||||
const ok = el('button', 'knopf', 'Speichern');
|
||||
ok.type = 'button';
|
||||
ok.addEventListener('click', async () => {
|
||||
ok.disabled = true;
|
||||
const punkte = kaesten.filter((k) => k.checked).map((k) => k.value);
|
||||
const s = await hole(`/workspace/api/entwicklung/person/${id}/punkte`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ punkte }),
|
||||
});
|
||||
if (!s || !s.ok) { melde('Das ließ sich nicht speichern.'); ok.disabled = false; return; }
|
||||
dlg.close(); dlg.remove();
|
||||
/* DIE KARTE NEU HOLEN und nicht im Browser nachziehen: Welche
|
||||
Punkte danach dastehen, rechnet der Server -- und er weiss
|
||||
auch, was schon gesetzt war. */
|
||||
await karte(id);
|
||||
});
|
||||
knoepfe.append(ab, ok);
|
||||
form.append(knoepfe);
|
||||
dlg.append(form);
|
||||
document.body.append(dlg);
|
||||
dlg.showModal();
|
||||
dlg.addEventListener('close', () => dlg.remove());
|
||||
}
|
||||
|
||||
async function karte(id, springen = false) {
|
||||
offen = id;
|
||||
/* WER IST GERADE OFFEN? Die Antwort gehoert auf die Kacheln, nicht
|
||||
@@ -1379,8 +1503,47 @@
|
||||
const brett = el('a', 'schritt e-karte__brett', 'Notizen zu dieser Person');
|
||||
brett.href = 'bereich.html?b=entwicklung';
|
||||
kopf.append(brett);
|
||||
|
||||
/* ==== WELCHE PUNKTE GELTEN FUER IHN? (25.09.2026) ==============
|
||||
|
||||
Filipe: „ich will dass die rechte hand und ich diese aufgaben
|
||||
die es da gibt, individuel aussuchen koennen wer welche aufgabe
|
||||
bekommt. bis dahin sollen die keine aufgaben sehen."
|
||||
|
||||
DER KNOPF SAGT DIE ZAHL. „Punkte auswaehlen" allein liesse
|
||||
offen, ob schon jemand ausgesucht hat -- und genau das ist die
|
||||
Frage, wenn die Karte leer aussieht. */
|
||||
const waehlen = el('button', 'schritt e-karte__waehlen',
|
||||
r.gesamt
|
||||
? `Punkte auswählen · ${r.gesamt} von ${r.gesamt_katalog}`
|
||||
: 'Punkte auswählen');
|
||||
waehlen.type = 'button';
|
||||
if (!r.gesamt) waehlen.dataset.leer = 'ja';
|
||||
waehlen.addEventListener('click', () => punkteWaehlen(id, r.person.name));
|
||||
kopf.append(waehlen);
|
||||
ziel.append(kopf);
|
||||
|
||||
/* NOCH NICHTS AUSGESUCHT HEISST NICHT „KAPUTT". Ohne diesen Satz
|
||||
stuende die Karte leer da, und niemand wuesste, ob die Seite
|
||||
gerade laedt, ob es einen Fehler gab oder ob schlicht noch
|
||||
niemand ausgesucht hat. Ein leerer Bildschirm ohne Erklaerung
|
||||
ist die schlechteste Antwort von allen. */
|
||||
if (!r.gesamt) {
|
||||
const leer = el('div', 'e-leerwahl');
|
||||
leer.append(el('p', 'e-leerwahl__titel',
|
||||
`Für ${r.person.name} ist noch nichts ausgesucht.`));
|
||||
leer.append(el('p', 'e-leerwahl__satz',
|
||||
'Nicht jeder Punkt passt zu jedem. Such aus, was für sie oder ihn '
|
||||
+ 'wirklich gilt – nur das steht danach hier, und nur daran wird '
|
||||
+ 'gemessen.'));
|
||||
const los = el('button', 'knopf e-leerwahl__knopf', 'Punkte auswählen');
|
||||
los.type = 'button';
|
||||
los.addEventListener('click', () => punkteWaehlen(id, r.person.name));
|
||||
leer.append(los);
|
||||
ziel.append(leer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---- Abweichungen zuerst ------------------------------------------
|
||||
Sie stehen oben, weil sie das Einzige sind, was diese Seite
|
||||
liefert und eine Liste nicht: die Stelle, an der zwei Leute
|
||||
|
||||
Reference in New Issue
Block a user