Im Code stand die Begruendung selbst: "«Review» allein sagt einem Neuen nichts." Das Wort ist englisch, ein Hauptwort ohne Handlung, und es verraet nicht, WER jetzt dran ist. "Zur Freigabe" sagt beides: fertig von mir, wartet auf jemanden. Geaendert wurde nur, was ein Mensch LIEST -- der Zustandsschluessel bleibt `review`, der gehoert der Datenbank. Betroffen: Spalte und Weiterknopf im Aufgabenbrett, Dateien-Filter, Startseiten-Zaehler, Kachel-Unterzeile, Hinweis "Datei wartet auf Freigabe", Report. NICHT geaendert: der Kalender. Dort ist `review` eine TERMINART (ein Gespraech, in dem man zurueckschaut), kein Zustand. Ich hatte das beim Umbenennen selbst verwechselt und wieder zurueckgenommen -- ein Kommentar an der Stelle haelt die zwei Bedeutungen jetzt auseinander. pruef-sprung hing an der Wortwahl (`/review/i` auf der Beschriftung) und wurde rot, obwohl der Filter richtig stand. Sie prueft jetzt `data-status` -- den Schluessel, der sich nicht mit der Sprache aendert. DAZU, unabhaengig gefunden: Datumsfelder waren 48 px hoch, alle anderen Felder 44. Gemessen auf drei Seiten bei 390 px. Alle liegen auf dem 44-px-Beruehrziel -- nur das Datumsfeld drueckte sich darueber, weil Chromium in `::-webkit-datetime-edit` eine eigene Innenpolsterung setzt, die sogar ein gesetztes `height: 44px` ueberstimmt. Zwei Anteile, einzeln nachgemessen (jeder allein 48->46, erst beide zusammen 48->44): 1 px Polsterung oben und unten im Feldkasten, und eine Zeilenhoehe von 24 statt 22. Keine feste Hoehe gesetzt -- die Zeilenhoehe wird aus Beruehrziel und Polsterung gerechnet, damit sie mitwandert, wenn sich eines davon aendert. Geprueft: pruef-formulare 19/0 (war 16 mit 3 Fehlern), pruef-sprung 43/0, pruef-start-ansicht 151/0, pruef-aufgabenbrett 49/0, pruef-uebersicht 35/0, pruef-uebersicht-browser 20/0, pruef-deutsche-texte, pruef-css-klassen. Ausserdem: vorlagen.js geloescht (8,2 KB). `vorlagenBlock(` wurde inca104799eingebaut und in9267797dwieder ausgebaut -- seither laedt die Datei auf zwei Seiten, ohne dass jemand sie aufruft. Co-Authored-By: Claude Opus 5 <[email protected]>
1106 lines
53 KiB
JavaScript
1106 lines
53 KiB
JavaScript
/* ===================================================================
|
||
Die Bereiche -- EINE Quelle für die ganze Anwendung.
|
||
|
||
Zeichen, Farbton, Rolle und Ziel jedes Bereichs standen bis zum
|
||
01.09.2026 nur in start.js. Seit jede Unterseite Zeichen und Farbe
|
||
ihrer Kachel trägt, brauchen sie auch die Kopfleisten -- und eine
|
||
zweite, abgeschriebene Liste wäre der sichere Weg, dass "Aufgaben"
|
||
irgendwann auf der Startseite gelb und auf der Aufgabenseite grün ist.
|
||
|
||
Deshalb liegt beides jetzt hier und wird von start.js UND kopf.js
|
||
benutzt. Wer eine Kachel ändert, ändert damit automatisch auch den
|
||
Kopf der zugehörigen Seite.
|
||
=================================================================== */
|
||
(() => {
|
||
'use strict';
|
||
|
||
/* ---------- Zeichen ------------------------------------------------------
|
||
|
||
Alle im selben Raster (24×24). Seit dem 03.09.2026 besteht jedes
|
||
Zeichen aus ZWEI Teilen:
|
||
|
||
fuellung eine gefüllte Grundform -- der Gegenstand selbst,
|
||
gedeckt hinterlegt
|
||
linien die scharfe Zeichnung darüber
|
||
|
||
Das ist der Unterschied zwischen einem Symbol und einem Piktogramm.
|
||
Eine reine Kontur ist neutral; sobald ein Teil FLÄCHE hat, bekommt
|
||
das Zeichen ein Vorn und ein Hinten, und das Auge erkennt es, ohne
|
||
es zu lesen. Gefüllt wird immer das, worum es geht: beim Kalender
|
||
der Kopf, beim Ordner der Korpus, bei einer Person der Kopf, beim
|
||
Regler die Griffe.
|
||
|
||
WARUM NICHT EINFACH DICKER: Ein früherer Versuch legte eine dicke,
|
||
weichgezeichnete Kopie der LINIE darunter. Das hat die feinen
|
||
Lücken zugeschmiert -- aus dem Kalender wurde ein leerer Kasten
|
||
(siehe start.css). Eine Fläche ist etwas anderes als ein
|
||
aufgeblasener Strich: Sie liegt INNERHALB der Kontur und lässt die
|
||
Zwischenräume unberührt.
|
||
|
||
Eigene Pfade statt einer Fremdbibliothek: siebzehn Zeichen sind
|
||
kleiner als jede Schriftart und kosten keine Lieferkette. */
|
||
|
||
/* ---------- Die Silhouetten -------------------------------------------
|
||
|
||
Der UMRISS jedes Gegenstands als geschlossene Form. Aus ihm entsteht
|
||
die Tiefe: Er wird dreimal übereinander gezeichnet, jedes Mal ein
|
||
Stück versetzt und dunkler -- unten die Grundfläche, darüber die
|
||
Seitenwand, oben die Deckfläche. Das ist dasselbe Verfahren, mit dem
|
||
man einen Körper von Hand zeichnet, und es ist der Grund, warum die
|
||
Zeichen jetzt eine Höhe haben statt nur einen Umriss.
|
||
|
||
Getrennt von den Linien gehalten: Die Linien sind die DETAILS auf der
|
||
Oberfläche (Querstriche, Haken, Wellen). Sie bekommen keine Tiefe --
|
||
ein aufgedruckter Strich steht nicht hervor. */
|
||
const KOERPER = {
|
||
dashboard: [
|
||
'M4 4.5h6.4v6.4H4z',
|
||
'M13.6 4.5h6.4v4.2h-6.4z',
|
||
'M13.6 11.6h6.4v7.9h-6.4z',
|
||
'M4 13.7h6.4v5.8H4z'
|
||
],
|
||
aufgaben: [
|
||
'M4.5 5h4v14h-4z',
|
||
'M10 5h4v9h-4z',
|
||
'M15.5 5h4v11.5h-4z'
|
||
],
|
||
kalender: [
|
||
'M3.5 7h17v12.5h-17z'
|
||
],
|
||
calls: [
|
||
'M3.5 7h11v10h-11z',
|
||
'M14.5 11l6-3.5v9l-6-3.5z'
|
||
],
|
||
dateien: [
|
||
'M3.5 6.5h5.5l2 2h9.5v11h-17z'
|
||
],
|
||
/* Chat (06.09.2026): eine Sprechblase mit Schweif nach links
|
||
unten. Bewusst OHNE die drei Punkte darin -- bei 20 Pixeln
|
||
werden die zu Matsch, und die Blase allein ist eindeutig. */
|
||
chat: [
|
||
'M4 5.5h16v11H9.5L5 20.5V16.5H4z'
|
||
],
|
||
steckbrief: [
|
||
'M3.5 5.5h17v13h-17z'
|
||
],
|
||
profil: [
|
||
'M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z',
|
||
'M5.5 20c.7-3.3 3.3-5.3 6.5-5.3s5.8 2 6.5 5.3z'
|
||
],
|
||
startcheck: [
|
||
'M6 4.5h12v15H6z'
|
||
],
|
||
live: [
|
||
'M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z'
|
||
],
|
||
content: [
|
||
'M3.5 6h17v13h-17z'
|
||
],
|
||
technik: [
|
||
'M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'
|
||
],
|
||
community: [
|
||
'M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z',
|
||
'M3.5 19.5c.6-2.8 2.8-4.5 5.5-4.5s4.9 1.7 5.5 4.5z'
|
||
],
|
||
schutz: [
|
||
'M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z'
|
||
],
|
||
reports: [
|
||
'M6.6 9.5h1.8v7h-1.8z',
|
||
'M11.1 5.5h1.8v11h-1.8z',
|
||
'M15.6 11.5h1.8v5h-1.8z'
|
||
],
|
||
personen: [
|
||
'M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z'
|
||
],
|
||
scouting: [
|
||
'M3.5 5.5h17l-6.6 7.6v6.4l-3.8-2.1v-4.3z'
|
||
],
|
||
wissen: [
|
||
'M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'
|
||
],
|
||
automation: [
|
||
'M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'
|
||
],
|
||
/* Zahlen (06.09.2026): die Flaeche UNTER einem steigenden
|
||
Linienzug. Bewusst kein zweites Balkendiagramm -- "Reports &
|
||
Review" hat schon eins, und zwei Kacheln mit demselben Zeichen
|
||
sind schlimmer als eine ohne: Man klickt zweimal falsch, bevor
|
||
man merkt, dass es zwei verschiedene Sachen sind. Eine Linie
|
||
ist auch die richtige Aussage: Es geht hier nicht um einen
|
||
Bericht, sondern um einen VERLAUF. */
|
||
zahlen: [
|
||
'M4 16 9.5 11.5 13 14 20 6.5 20 19.5 4 19.5z'
|
||
],
|
||
/* Agentur (06.09.2026): ein Aktenkoffer. Bewusst kein
|
||
Haendedruck und kein Gebaeude -- beides wird bei 20 Pixeln zu
|
||
Matsch. Der Koffer ist die einzige Form, die man bei dieser
|
||
Groesse noch als "offizielle Seite" liest. */
|
||
agentur: [
|
||
'M3.5 8h17v11h-17z'
|
||
]
|
||
};
|
||
|
||
const ZEICHEN = {
|
||
dashboard: {
|
||
/* Zwei der vier Felder gefüllt, über Eck -- das gibt dem Zeichen
|
||
einen Rhythmus. Alle vier zu füllen wäre ein Klotz. */
|
||
fuellung: ['M4 4.5h6.4v6.4H4z', 'M13.6 11.6h6.4v7.9h-6.4z'],
|
||
linien: ['M4 4.5h6.4v6.4H4z', 'M13.6 4.5h6.4v4.2h-6.4z',
|
||
'M13.6 11.6h6.4v7.9h-6.4z', 'M4 13.7h6.4v5.8H4z'],
|
||
},
|
||
aufgaben: {
|
||
/* Die mittlere Spalte -- "in Arbeit". Das Brett hat drei Spalten,
|
||
und die mittlere ist die, in der gerade etwas passiert. */
|
||
fuellung: ['M10 5h4v9h-4z'],
|
||
linien: ['M4.5 5h4v14h-4z', 'M10 5h4v9h-4z', 'M15.5 5h4v11.5h-4z'],
|
||
},
|
||
kalender: {
|
||
/* Der Kopf des Blattes. Genau der Streifen, an dem man einen
|
||
Kalender auch aus drei Metern erkennt. */
|
||
fuellung: ['M3.5 7h17v4.5h-17z'],
|
||
linien: ['M3.5 7h17v12.5h-17z', 'M3.5 11.5h17', 'M7.5 4v4.6', 'M16.5 4v4.6'],
|
||
},
|
||
calls: {
|
||
/* Das Objektiv. Der Kasten bleibt offen, sonst wird das Zeichen
|
||
schwer. */
|
||
fuellung: ['M14.5 11l6-3.5v9l-6-3.5z'],
|
||
linien: ['M3.5 7h11v10h-11z', 'M14.5 11l6-3.5v9l-6-3.5z'],
|
||
},
|
||
dateien: {
|
||
/* Der Korpus ohne die Lasche -- so bleibt die Stufe oben sichtbar,
|
||
die den Ordner ausmacht. */
|
||
fuellung: ['M3.5 10h17v9.5h-17z'],
|
||
linien: ['M3.5 6.5h5.5l2 2h9.5v11h-17z', 'M3.5 10h17'],
|
||
},
|
||
steckbrief: {
|
||
/* Kopf und Schultern der Person IN der Karte -- unterscheidbar vom
|
||
Profil-Zeichen (nur die Person), damit die beiden Kacheln nicht
|
||
gleich aussehen. */
|
||
fuellung: ['M8.5 11.2a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8z'],
|
||
linien: ['M3.5 5.5h17v13h-17z', 'M8.5 11.2a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8z',
|
||
'M5.6 16.2c0-1.7 1.3-3 2.9-3s2.9 1.3 2.9 3', 'M14.5 9.5h4', 'M14.5 13h4'],
|
||
},
|
||
profil: {
|
||
fuellung: ['M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z'],
|
||
linien: ['M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z',
|
||
'M5.5 20c.7-3.3 3.3-5.3 6.5-5.3s5.8 2 6.5 5.3'],
|
||
},
|
||
startcheck: {
|
||
/* Nur der Haken ist gefüllt -- er ist die Aussage des Zeichens.
|
||
Ein gefülltes Klemmbrett wäre ein Kasten. */
|
||
fuellung: ['M9.2 9.6l1.7 1.7 3.6-3.7 1 1-4.6 4.7-2.7-2.7z'],
|
||
linien: ['M6 4.5h12v15H6z', 'M9.2 9.6l1.7 1.7 3.6-3.7', 'M9.2 15.2h5.6'],
|
||
},
|
||
live: {
|
||
/* Der Sender in der Mitte. Die Wellen bleiben Linien -- gefüllte
|
||
Wellen sähen aus wie ein Auge. */
|
||
fuellung: ['M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z'],
|
||
linien: ['M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z',
|
||
'M8.2 8.2a5.4 5.4 0 0 0 0 7.6', 'M15.8 15.8a5.4 5.4 0 0 0 0-7.6',
|
||
'M5.4 5.4a9.4 9.4 0 0 0 0 13.2', 'M18.6 18.6a9.4 9.4 0 0 0 0-13.2'],
|
||
},
|
||
content: {
|
||
/* Die Klappe der Filmklappe. */
|
||
fuellung: ['M3.5 6h17v4h-17z'],
|
||
linien: ['M3.5 6h17v13h-17z', 'M3.5 10h17', 'M8 6l-1.4 4', 'M13 6l-1.4 4', 'M18 6l-1.4 4'],
|
||
},
|
||
technik: {
|
||
/* Die drei Griffe. Sie waren bis zum 03.09.2026 Bögen der Länge
|
||
null und wurden nie gezeichnet -- übrig blieben drei nackte
|
||
Striche, die aussahen wie ein Menü-Symbol. */
|
||
fuellung: ['M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'],
|
||
linien: ['M4 7.5h16', 'M4 12h16', 'M4 16.5h16',
|
||
'M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'],
|
||
},
|
||
community: {
|
||
/* Der vordere Kopf. Der hintere bleibt Kontur -- dadurch entsteht
|
||
die Tiefe, um die es bei zwei Personen geht. */
|
||
fuellung: ['M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z'],
|
||
linien: ['M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z',
|
||
'M3.5 19.5c.6-2.8 2.8-4.5 5.5-4.5s4.9 1.7 5.5 4.5',
|
||
'M16 8.8a2.4 2.4 0 1 1 1.6 4.3', 'M17 15.2c2 .5 3.3 2 3.7 4.3'],
|
||
},
|
||
schutz: {
|
||
fuellung: ['M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z'],
|
||
linien: ['M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z',
|
||
'M9.4 11.8l1.9 1.9 3.4-3.6'],
|
||
},
|
||
reports: {
|
||
/* Aus drei Strichen werden drei Säulen -- ein Balkendiagramm hat
|
||
Balken, keine Striche. */
|
||
fuellung: ['M6.6 9.5h1.8v7h-1.8z', 'M11.1 5.5h1.8v11h-1.8z', 'M15.6 11.5h1.8v5h-1.8z'],
|
||
linien: ['M4 19.5h16', 'M6.6 9.5h1.8v7h-1.8z', 'M11.1 5.5h1.8v11h-1.8z',
|
||
'M15.6 11.5h1.8v5h-1.8z'],
|
||
},
|
||
teamlage: {
|
||
/* Zwei Koepfe und eine steigende Linie darunter: Es geht um
|
||
Menschen UND um ihren Verlauf. Gefuellt ist nur der vordere
|
||
Kopf -- zwei gefuellte Kreise nebeneinander lesen sich als
|
||
Brille, nicht als Team. */
|
||
fuellung: ['M8.6 4.6a2.9 2.9 0 1 0 0 5.8 2.9 2.9 0 0 0 0-5.8z'],
|
||
linien: ['M8.6 4.6a2.9 2.9 0 1 0 0 5.8 2.9 2.9 0 0 0 0-5.8z',
|
||
'M15.6 5.4a2.4 2.4 0 1 0 0 4.8 2.4 2.4 0 0 0 0-4.8z',
|
||
'M4 20v-2.2', 'M9 20v-4.6', 'M14 20v-3.2', 'M19 20v-6.4'],
|
||
},
|
||
personen: {
|
||
/* Der Bart des Schlüssels bleibt Linie, der Kopf wird Fläche. */
|
||
fuellung: ['M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z'],
|
||
linien: ['M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z', 'M11.6 12.2 4 19.8',
|
||
'M6.4 17.4l2 2', 'M8.6 15.2l2 2'],
|
||
},
|
||
scouting: {
|
||
/* Der Trichter, aber nur der obere Teil -- der Stiel bleibt offen,
|
||
sonst kippt das Zeichen optisch nach unten. */
|
||
fuellung: ['M3.5 5.5h17l-6.6 7.6h-3.8z'],
|
||
linien: ['M3.5 5.5h17l-6.6 7.6v6.4l-3.8-2.1v-4.3z'],
|
||
},
|
||
werdegang: {
|
||
/* EIN Mensch und sein Weg -- nicht zwei Koepfe wie bei
|
||
"teamlage", nicht eine Messkurve wie bei "zahlen". Der
|
||
Unterschied ist der ganze Punkt dieser Kachel: Hier wird
|
||
niemand mit jemandem verglichen.
|
||
|
||
Drei Stufen, die ansteigen, und ein gefuellter Punkt auf der
|
||
obersten -- das Jetzt. Gefuellt ist NUR der Punkt: Wuerden die
|
||
Stufen mitgefuellt, saehe es aus wie ein Balkendiagramm, und
|
||
genau das ist es ausdruecklich nicht. */
|
||
fuellung: ['M17.8 6.6a1.7 1.7 0 1 0 0 3.4 1.7 1.7 0 0 0 0-3.4z'],
|
||
linien: ['M3.4 19.6h4.2v-3.4H3.4z', 'M9.9 19.6h4.2v-6.6H9.9z',
|
||
'M16.4 19.6h4.2v-6.2h-4.2z',
|
||
'M17.8 6.6a1.7 1.7 0 1 0 0 3.4 1.7 1.7 0 0 0 0-3.4z',
|
||
'M5.5 16.2 12 13l5.8-2.7'],
|
||
},
|
||
wissen: {
|
||
/* Die linke Seite gefüllt: ein aufgeschlagenes Buch hat eine
|
||
Seite im Licht und eine im Schatten. */
|
||
fuellung: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z'],
|
||
linien: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'],
|
||
},
|
||
automation: {
|
||
fuellung: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||
linien: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||
},
|
||
agentur: {
|
||
/* Der Deckel als Flaeche -- daran erkennt man einen Koffer, so wie
|
||
man einen Kalender an seinem Kopf erkennt. */
|
||
fuellung: ['M3.5 8h17v4.6h-17z'],
|
||
linien: ['M3.5 8h17v11h-17z',
|
||
'M9 8V6.4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1V8',
|
||
'M3.5 12.6h17',
|
||
'M10.9 11.6h2.2v2h-2.2z'],
|
||
},
|
||
/* HINAUS (19.09.2026) -- fuer "Unsere Seiten".
|
||
Jedes andere Zeichen im Haus zeigt auf etwas INNERHALB des
|
||
Workspace. Dieses eine muss sagen: hier geht es hinaus. Das
|
||
Sinnbild dafuer ist ueberall dasselbe -- ein angefangener Rahmen
|
||
mit einem Pfeil, der ihn nach oben rechts verlaesst. Es zu
|
||
erfinden waere ein Fehler; wer es kennt, weiss sofort, dass sich
|
||
ein neues Fenster oeffnet. */
|
||
hinaus: {
|
||
/* Nur der Pfeilkopf ist Flaeche -- er ist die Aussage. */
|
||
fuellung: ['M13.8 4H20v6.2z'],
|
||
linien: ['M11 4.8H5.4A1.4 1.4 0 0 0 4 6.2v12.4a1.4 1.4 0 0 0 1.4 1.4h12.4a1.4 1.4 0 0 0 1.4-1.4V13',
|
||
'M13.8 4H20v6.2',
|
||
'M19.4 4.6 12 12'],
|
||
},
|
||
zahlen: {
|
||
fuellung: ['M4 16 9.5 11.5 13 14 20 6.5 20 19.5 4 19.5z'],
|
||
/* Der Linienzug selbst, die Grundlinie darunter und ein Punkt am
|
||
oberen Ende -- der letzte Messwert, das Jetzt. Genau dieselbe
|
||
Bildsprache wie die kleine Linie in jeder Zahlkarte: Wer die
|
||
Kachel gesehen hat, erkennt die Karten wieder. */
|
||
linien: ['M4 16 9.5 11.5 13 14 20 6.5', 'M3.6 19.8h16.8',
|
||
'M20 5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z'],
|
||
},
|
||
};
|
||
|
||
/* ---------- Die Bereiche -------------------------------------------------
|
||
|
||
`rollen` steuert, wem ein Bereich überhaupt erscheint -- serverseitig
|
||
wird es ohnehin noch einmal geprüft, das hier ist nur Höflichkeit.
|
||
|
||
`ton` ist der Farbplatz 1..17 -- JEDE Kachel hat ihre eigene Farbe.
|
||
|
||
Ein erster Versuch mit frei gewählten Farben ergab Paare mit einem
|
||
Abstand von 1,4: praktisch dieselbe Farbe, das sieht nach Zufall aus
|
||
statt nach Absicht. Deshalb sind Farben UND Zuordnung gerechnet, von
|
||
tools/kachel-farben.mjs. Die Überlegung dahinter: Das Auge vergleicht
|
||
nur, was nebeneinander liegt. Siebzehn Farben müssen sich also nicht
|
||
alle voneinander unterscheiden, sondern nur von ihren Nachbarn im
|
||
Raster -- und da sind es jetzt mindestens 105,9 Grad.
|
||
|
||
Wer hier Kacheln umsortiert oder eine hinzufügt, ändert damit die
|
||
Nachbarschaften. Dann gehört tools/kachel-farben.mjs neu gelaufen
|
||
(dort die Liste NACHBARN anpassen), sonst stimmt der Abstand nicht
|
||
mehr und niemand merkt es. */
|
||
|
||
const GRUPPEN = [
|
||
/* =============================================================
|
||
RUND UM DAS TEAM (09.09.2026)
|
||
|
||
Filipe: "so eine kategorie wie ueber die creator will ich dass
|
||
nur fuer die spicy und dogfather rolle auch ueber manager und
|
||
scouts gibt ... ich will dass die spicy und dogfather rolle
|
||
einen kompletten teil haben mit daten ueber die arbeit von den
|
||
manager und scout."
|
||
|
||
WARUM SIE GANZ OBEN STEHT (11.09.2026).
|
||
|
||
Bis dahin stand sie hinter "Rund um den Creator" -- dieselbe
|
||
Frage, eine Ebene hoeher. Filipe wollte sie nach vorn: "ich will
|
||
dass die kategorie ... ueber der kategorie ist [Taeglich]."
|
||
|
||
Das ist auch sachlich die bessere Stelle. Wer die Leitung hat,
|
||
fragt zuerst "wo klemmt es im Team" und erst danach "was mache
|
||
ich heute". Die taeglichen Werkzeuge findet man ohnehin; eine
|
||
Luecke in der Betreuung findet man nur, wenn sie einem
|
||
entgegenkommt.
|
||
|
||
Fuer alle ausser Spicy Media und DogFather aendert sich nichts:
|
||
Die Gruppe hat genau eine Kachel, und die tragen nur diese zwei
|
||
Rollen. Bei allen anderen faellt die ganze Gruppe weg, und
|
||
"Taeglich" steht wie bisher oben.
|
||
|
||
NUR ZWEI ROLLEN. Ein Manager sieht die Gruppe nicht -- eine
|
||
Uebersicht ueber die Arbeit der Kollegen gehoert der Leitung.
|
||
Die Kachel wegzunehmen reicht dafuer nicht: Die Seite selbst
|
||
ist in workspace.js auf ['spicy','admin'] gesetzt, und die
|
||
Schnittstelle antwortet allen anderen mit 404. Eine
|
||
ausgeblendete Kachel hat noch nie etwas geschuetzt. */
|
||
{
|
||
name: 'Rund um das Team',
|
||
unter: 'Manager und Scouts – Auslastung, Lücken, Wirkung',
|
||
bereiche: [
|
||
{ name: 'Team-Lage', unter: 'Wer betreut wen, wo staut sich etwas',
|
||
zeichen: 'teamlage', ton: 22,
|
||
rollen: ['spicy', 'admin'], ziel: 'team.html', szene: 'halle' },
|
||
],
|
||
},
|
||
{
|
||
name: 'Täglich',
|
||
unter: 'Was du sowieso jeden Tag aufmachst',
|
||
bereiche: [
|
||
{ name: 'Dashboard', unter: 'Alle Creator auf einen Blick', zeichen: 'dashboard', ton: 1,
|
||
gross: true, rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'uebersicht.html', szene: 'showbuehne' },
|
||
{ name: 'Aufgaben', unter: 'Offen, in Arbeit, zur Freigabe', zeichen: 'aufgaben', ton: 13,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html', szene: 'garage' },
|
||
/* REIHENFOLGE: CHAT, KALENDER, CALLS (08.09.2026).
|
||
|
||
Filipe, screen31: "die reihenfolge von denen, links der chat,
|
||
mitte den kalender und rechts calls & protokolle".
|
||
|
||
Vorher stand der Chat hinter "Calls & Protokolle", mit der
|
||
Begruendung, dass beides Gespraech ist. Die neue Ordnung ist
|
||
die nach VERBINDLICHKEIT, und sie liest sich von links nach
|
||
rechts: Der Chat laeuft nebenher, der Kalender bindet an eine
|
||
Uhrzeit, das Protokoll haelt fest, was verabredet wurde.
|
||
|
||
Die Toene bleiben an ihren Kacheln (Chat 4, Kalender 8, Calls
|
||
15) -- sie kennzeichnen die Kachel, nicht ihren Platz. Wer sie
|
||
beim Umsortieren mitwandern liesse, haette am naechsten Tag
|
||
zwei Kacheln in derselben Farbe. */
|
||
{ name: 'Chat', unter: 'Nachrichten mit deinem Team', zeichen: 'chat', ton: 4,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'chat.html', szene: 'lounge' },
|
||
{ name: 'Kalender', unter: 'Termine und Calls', zeichen: 'kalender', ton: 8,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'kalender.html', szene: 'skyline' },
|
||
{ name: 'Calls & Protokolle', unter: 'Gespräche mit To-dos', zeichen: 'calls', ton: 15,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'calls.html', szene: 'lounge' },
|
||
{ name: 'Dateien', unter: 'Ablage und Freigaben', zeichen: 'dateien', ton: 19,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'dateien.html', szene: 'arena' },
|
||
/* HIER STAND DAS IDEEN-BOARD, und es ist am 10.09.2026 in den
|
||
Server gezogen (workspace.js, ZUSATZ_BEREICHE).
|
||
|
||
Zwei Gruende, und der zweite wiegt schwerer:
|
||
1. Es gehoert in dieselbe Gruppe wie der Eingang, und die
|
||
entsteht dort.
|
||
2. Es stand hier mit `rollen: ['admin']` -- in einer Datei,
|
||
die JEDER herunterlaedt. Eine Kachel, die nur eine
|
||
einzige Rolle sieht, wirft beim Lesen die Frage auf,
|
||
wofuer sie ist. Genau die soll niemand stellen.
|
||
|
||
Die Kachel ist nicht weg; sie kommt jetzt nur an die, die
|
||
sie auch bekommen. */
|
||
],
|
||
},
|
||
{
|
||
name: 'Rund um den Creator',
|
||
unter: 'Die Betreuungsakte – Stand, Zahlen, Verlauf',
|
||
bereiche: [
|
||
/* ZWEI VERSCHIEDENE DINGE, zwei Kacheln (01.09.2026).
|
||
|
||
Vorher war beides dieselbe Seite, und das war verwirrend:
|
||
Oben stand "Profil: SpongBobSchwammKopf" und mitten darin
|
||
"MEIN PROFIL - Dogfather". Zwei Personen auf einem Bildschirm,
|
||
ohne dass klar war, welche gerade gemeint ist.
|
||
|
||
Es sind auch wirklich zwei Sachen:
|
||
MEIN STECKBRIEF gehoert MIR -- Bild, ein Satz ueber mich,
|
||
meine Kanaele. Fuehre ich selbst, hat
|
||
jeder (auch Scouts und Manager).
|
||
CREATOR-PROFILE die BETREUUNGSAKTE eines Creators --
|
||
Ziele, 90-Tage-Plan, interne Notizen.
|
||
Fuehren die Betreuer.
|
||
|
||
Ein Creator sieht nur seine eigene Akte (dort steht auch sein
|
||
Steckbrief mit drin, er hat ja nur eine Seite). Alle anderen
|
||
bekommen beide Kacheln getrennt. */
|
||
/* ZAHLEN STEHT VORN (06.09.2026).
|
||
Der Workspace organisierte bis dahin ARBEIT hervorragend und
|
||
wusste über das GESCHÄFT nichts -- keine Diamanten, keine
|
||
LIVE-Tage, keine Verweildauer. Damit hing die ganze Gruppe
|
||
hier in der Luft: Der Start-Check bewertet, ohne zu messen,
|
||
der Report fragt "was hat funktioniert?" ohne Beleg, und das
|
||
90-Tage-Ziel war ein Satz statt eines Fortschritts. Deshalb
|
||
die erste Kachel der Gruppe, nicht die letzte.
|
||
|
||
Ton 4 (Violett) ist von Hand gewählt und nicht gerechnet: Er
|
||
liegt weit von seinem Nachbarn 15 (Blaugrün) und von 8
|
||
(Orangerot) darunter. Wer diese Gruppe umsortiert, lässt
|
||
tools/kachel-farben.mjs neu laufen -- die Nachbarschaften
|
||
haben sich durch diese Kachel geändert. */
|
||
/* REIHENFOLGE: STECKBRIEF, PROFILE, ZAHLEN (Wunsch Filipe,
|
||
07.09.2026: "zuerst steckbrief, dan, profile, und dan erst
|
||
zahlen"). Das ist auch die Reihenfolge, in der man arbeitet:
|
||
erst wer jemand IST, dann was er vorhat, dann was dabei
|
||
herauskommt. Die Zahlen zuerst zu zeigen dreht das um. */
|
||
{ name: 'Mein Steckbrief', unter: 'Dein Bild und deine Kanäle', zeichen: 'steckbrief', ton: 10,
|
||
rollen: ['spicy', 'admin', 'manager', 'scout'], ziel: 'steckbrief.html', szene: 'halle' },
|
||
{ name: 'Creator-Profile', unter: 'Ziele und 90-Tage-Plan', zeichen: 'profil', ton: 20,
|
||
rollen: ['spicy', 'admin', 'manager', 'scout'], ziel: 'profil.html', szene: 'halle' },
|
||
/* KEINE eigene Steckbrief-Kachel fuer Creator, und das ist
|
||
Absicht: Ihr Steckbrief samt Profilbild steht bereits auf
|
||
`profil.html` (der Block mit `data-nur-creator="ja"`). Eine
|
||
zweite Kachel fuehrte auf dieselbe Sache unter anderem Namen
|
||
-- und wer zwei Wege zu einer Einstellung anbietet, bekommt
|
||
die Frage, welcher der richtige ist. */
|
||
{ name: 'Mein Profil', unter: 'Dein Bild, deine Ziele und Pläne', zeichen: 'profil', ton: 20,
|
||
rollen: ['creator'], ziel: 'profil.html', szene: 'halle' },
|
||
/* WIEDER FUER ALLE FUENF (11.09.2026). Filipe: "jetzt soll jede
|
||
rolle diese kachel sehen. spicy, dogfather, manager, scout
|
||
und creator." Damit ist die Sperre vom 07.09. aufgehoben.
|
||
|
||
Die Kachel sieht fuer alle gleich aus, dahinter ist sie es
|
||
nicht: Ein Creator findet dort NUR seine eigenen Zahlen und
|
||
keinen einzigen Knopf zum Eintragen -- das entscheidet nicht
|
||
diese Zeile, sondern sichtbareCreatorIds() und
|
||
darfEintragen() auf dem Server.
|
||
|
||
Kachel und Tuer gehoeren zusammen: Diese Zeile ist der Weg,
|
||
die Rechteliste in workspace.js ist die Schranke. Nur eines
|
||
von beiden zu aendern ergibt entweder eine Kachel, die in
|
||
eine Absage fuehrt, oder einen Weg, den man nur kennen
|
||
muss. */
|
||
{ name: 'Zahlen', unter: 'Diamanten, LIVE-Tage, Verweildauer', zeichen: 'zahlen', ton: 2,
|
||
rollen: ['spicy', 'admin', 'manager', 'scout', 'creator'], ziel: 'leistung.html', szene: 'arena' },
|
||
{ name: 'Start-Check', unter: 'Erstanalyse, 16 Punkte', zeichen: 'startcheck', ton: 16,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'startcheck.html', szene: 'wald' },
|
||
{ name: 'LIVE-Analyse', unter: 'Vorher, während, danach', zeichen: 'live', ton: 3,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=live', szene: 'portal' },
|
||
{ name: 'Content-Ideen', unter: 'Idee bis Upload', zeichen: 'content', ton: 12,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'content.html', szene: 'portal' },
|
||
{ name: 'Community', unter: 'Moderation und Konflikte', zeichen: 'community', ton: 6,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=community', szene: 'lounge' },
|
||
{ name: 'Technik', unter: 'Setup, Fehler, Lösungen', zeichen: 'technik', ton: 14,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=technik', szene: 'garage' },
|
||
{ name: 'Schutz & Regeln', unter: 'Richtlinien und Vorfälle', zeichen: 'schutz', ton: 5,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=schutz', szene: 'halle' },
|
||
/* DER SECHSTE BEREICH (06.09.2026). Kernprinzip 04 des Konzepts
|
||
lautet "Die Agentur bleibt angebunden" -- und dafuer gab es
|
||
bis heute nichts. Fuenf Bereiche standen, dieser fehlte.
|
||
Steht bei den anderen fuenf und nicht unter "Team & System":
|
||
Es ist ein Bereich wie LIVE, Technik oder Schutz, nur dass
|
||
die andere Seite des Tisches die Agentur ist.
|
||
Ton 9 (Orange) -- deutlich von seinen Nachbarn 1 (Blau) und
|
||
14 (Gruen) entfernt. */
|
||
/* Untertitel gekuerzt (06.09.2026): "Kampagnen, Schulungen,
|
||
offizieller Weg" wurde auf dem Handy abgeschnitten -- gemessen
|
||
von pruef-start-ansicht. Ein Untertitel, der mitten im Wort
|
||
endet, ist schlechter als ein kuerzerer. */
|
||
{ name: 'Agentur', unter: 'Kampagnen und offizielle Wege', zeichen: 'agentur', ton: 17,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=agentur', szene: 'halle' },
|
||
{ name: 'Reports & Review', unter: 'Woche und Entscheidung', zeichen: 'reports', ton: 7,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'report.html', szene: 'showbuehne' },
|
||
],
|
||
},
|
||
{
|
||
name: 'Team & System',
|
||
unter: 'Was den Laden am Laufen hält',
|
||
/* Für einen Creator bleibt von dieser Gruppe genau eine Kachel übrig:
|
||
die Wissens-Bibliothek. "Team & System" wäre dann eine Überschrift,
|
||
die etwas verspricht, was gar nicht da ist -- und die klingt, als
|
||
gäbe es dahinter noch einen Bereich, den er nicht sehen darf. Er
|
||
liest stattdessen "Wissen", und das beschreibt genau, was dort
|
||
steht. Der Untertitel wechselt mit. */
|
||
nameCreator: 'Wissen',
|
||
unterCreator: 'Nachschlagen, wenn du etwas brauchst',
|
||
bereiche: [
|
||
/* NUR DogFather (02.09.2026, Wunsch: "die manager sollen diese
|
||
kategorien garnicht sehen").
|
||
|
||
Es war ohnehin ein Widerspruch: In der Rollenauswahl steht seit
|
||
jeher "Manager -- dieselben Rechte wie DogFather, AUSSER der
|
||
Personenverwaltung". Die Kachel stand trotzdem bei ihm, und die
|
||
Seite liess ihn auch hinein. Eine Beschreibung, die etwas
|
||
anderes sagt als die Software, ist schlimmer als beides
|
||
einzeln: Man weiss danach nicht mehr, welcher von beiden man
|
||
glauben soll. */
|
||
{ name: 'Personen & Zugänge', unter: 'Rollen und Codes', zeichen: 'personen', ton: 11,
|
||
/* MANAGER SEHEN DIESE KACHEL JETZT AUCH (07.09.2026).
|
||
Filipe: "die manager sehen immer noch nicht die kachel
|
||
personen & zugangscode, wo sie dan die neuen creator
|
||
hinzufuegen koennen." Die SEITE zeigt ihnen nur das
|
||
Anlegen -- Codes, Sperren, Loeschen und das Protokoll
|
||
haengen weiterhin an DogFather (siehe personen.js). */
|
||
rollen: ['spicy', 'admin', 'manager'], ziel: 'personen.html', szene: 'halle' },
|
||
{ name: 'Scout-Pipeline', unter: 'Entdeckt bis übergeben', zeichen: 'scouting', ton: 21,
|
||
rollen: ['spicy', 'admin', 'manager', 'scout'], ziel: 'scouting.html', szene: 'wald' },
|
||
{ name: 'Wissens-Bibliothek', unter: 'Anleitungen und PDFs', zeichen: 'wissen', ton: 9,
|
||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'wissen.html', szene: 'arena' },
|
||
/* Ebenfalls nur DogFather (02.09.2026). Was von allein passiert,
|
||
legt fest, was ALLEN anderen automatisch zugeschoben wird --
|
||
das gehört in dieselbe Hand wie die Rollenvergabe. */
|
||
{ name: 'Automationen', unter: 'Was von allein passiert', zeichen: 'automation', ton: 18,
|
||
rollen: ['admin'], ziel: 'automation.html', szene: 'garage' },
|
||
],
|
||
},
|
||
];
|
||
|
||
/* Ein Bereich anhand des Dateinamens finden. Die Bereichsseite
|
||
(bereich.html?b=live) trägt ihren Bereich in der Adresse -- deshalb
|
||
wird auch die Abfrage verglichen, nicht nur der Dateiname. */
|
||
function zuSeite(pfad, abfrage) {
|
||
const datei = String(pfad).split('/').pop() || 'start.html';
|
||
const gesucht = datei + (abfrage || '');
|
||
let treffer = null;
|
||
for (const g of GRUPPEN) {
|
||
for (const b of g.bereiche) {
|
||
if (b.ziel === gesucht) return b;
|
||
/* Ohne Abfrage: der erste Bereich mit passendem Dateinamen.
|
||
"Mein Profil" und "Creator-Profile" zeigen auf dieselbe Datei
|
||
und teilen sich Zeichen und Ton -- da ist beides richtig. */
|
||
if (!treffer && b.ziel.split('?')[0] === datei) treffer = b;
|
||
}
|
||
}
|
||
return treffer;
|
||
}
|
||
|
||
/* Ein SVG mit dem Zeichen eines Bereichs. Klasse frei wählbar, damit
|
||
Kachel, Hinweiszeile und Seitenkopf dieselbe Form in
|
||
unterschiedlicher Größe benutzen können. */
|
||
/* ---------- Die Zeichen (überarbeitet 03.09.2026) ------------------------
|
||
|
||
Wunsch: "ich will dass du die symbole perfektionnierst, ich will
|
||
wirklich dass jeder sich denkt woooow."
|
||
|
||
Vorher war jedes Zeichen eine flache Linie in einer Farbe. Sauber,
|
||
aber leblos -- siebzehn gleich starke Striche nebeneinander.
|
||
|
||
Jetzt besteht jedes Zeichen aus ZWEI übereinanderliegenden Lagen
|
||
derselben Form:
|
||
|
||
SCHEIN dick, weich, halbdurchsichtig -- das Licht, das die
|
||
Linie wirft. Sie liegt darunter und wird nie gelesen,
|
||
aber ohne sie sitzt das Zeichen flach auf der Fläche
|
||
statt darüber zu schweben.
|
||
LINIE die eigentliche Zeichnung, mit einem VERLAUF von oben
|
||
hell nach unten gedämpft.
|
||
|
||
Der Verlauf ist der eigentliche Kniff. Er ist EINMAL im Dokument
|
||
definiert und benutzt `currentColor` -- dadurch passt er sich jeder
|
||
der siebzehn Kachelfarben von selbst an, ohne siebzehn Verläufe.
|
||
Eine Lichtquelle oben, wie in der echten Welt: Genau das lässt eine
|
||
Linie geprägt statt gemalt wirken.
|
||
|
||
Kein zusätzliches Bild, keine Schriftart, kein Nachladen -- alles
|
||
entsteht aus den Pfaden, die ohnehin schon da waren. */
|
||
|
||
const NS = 'http://www.w3.org/2000/svg';
|
||
const VERLAUF_ID = 'zeichen-verlaeufe';
|
||
|
||
/* ---------- Die drei Verläufe ------------------------------------------
|
||
|
||
Ein Zeichen wird aus drei Lagen aufgebaut, und jede hat ihren
|
||
eigenen Verlauf. Alle drei stehen EINMAL im Dokument und arbeiten
|
||
mit currentColor -- dadurch nehmen sie den Ton jeder der siebzehn
|
||
Kacheln an, ohne dass es einundfünfzig Verläufe braucht.
|
||
|
||
flaeche die gefüllte Grundform: oben kräftig, unten fast weg.
|
||
Das ist der Körper des Gegenstands.
|
||
linie die Kontur: oben fast WEISS, unten im Farbton. Genau so
|
||
sieht Metall aus, auf das Licht von oben fällt -- und
|
||
genau das lässt ein Zeichen plastisch wirken statt
|
||
gezeichnet.
|
||
glanz ein schmaler heller Streifen quer über die obere Hälfte.
|
||
Die Spiegelung. Sie ist der Unterschied zwischen "gut
|
||
gemacht" und "das will ich anfassen".
|
||
|
||
ALLE in Benutzerkoordinaten (userSpaceOnUse) über die festen 24
|
||
Einheiten des Rasters. In Objektkoordinaten -- der Vorgabe -- würde
|
||
der Verlauf auf den Umriss JEDES einzelnen Pfades gerechnet, und
|
||
eine waagerechte Linie hat die Höhe null: Der Verlauf wäre entartet
|
||
und der Browser zeichnete den Pfad gar nicht. Genau daran sind am
|
||
03.09.2026 die Querlinie im Kalender, die Regler in Technik und die
|
||
Grundlinie der Berichte verschwunden. */
|
||
/* =====================================================================
|
||
WARUM JEDES ZEICHEN SEINE VERLAEUFE SELBST TRAEGT (07.09.2026)
|
||
|
||
Sie lagen bis heute in EINEM versteckten SVG am Ende der Seite, und
|
||
alle Zeichen verwiesen darauf. Das ist die uebliche Bauart, spart
|
||
Platz -- und sie hat hier ein Jahr lang das Gegenteil von dem
|
||
bewirkt, was danebenstand.
|
||
|
||
Die Verlaeufe arbeiten mit `currentColor`, damit jedes Zeichen die
|
||
Farbe SEINER Kachel annimmt. `currentColor` in einem Verlaufsstopp
|
||
wird aber an dem Element aufgeloest, das den STOPP enthaelt -- also
|
||
im versteckten SVG am Seitenende, nicht an der Kachel. Dort ist die
|
||
Textfarbe das helle Grau der Seite. Jedes Zeichen im ganzen Haus war
|
||
deshalb grau, egal welche Farbe seine Kachel hatte.
|
||
|
||
GEMESSEN, NICHT VERMUTET: Faerbt man das versteckte SVG rot, werden
|
||
die Zeichen rot (hellster Bildpunkt 43/49/61 -> 46/29/40). Faerbt
|
||
man das ZEICHEN rot, passiert nichts. Damit war klar, wo die Farbe
|
||
wirklich herkam.
|
||
|
||
Das Tueckische: Es sah nie kaputt aus. Graue Zeichen auf dunklem
|
||
Grund wirken sauber und zurueckhaltend -- man haelt es fuer die
|
||
Gestaltung. Filipe hat es als Erster benannt: "ich will dass die
|
||
symbole viel krasser, realistischer, farbiger und spezieller sind."
|
||
|
||
Jetzt bekommt jedes Zeichen seine eigenen Verlaeufe MIT, in seinem
|
||
eigenen SVG und mit eigener Kennung. Damit steht `currentColor` dort,
|
||
wo es hingehoert -- im Zeichen selbst, das die Farbe seiner Kachel
|
||
erbt. Zwanzig Zeichen je Seite ergeben zwanzig kleine
|
||
Verlaufsbloecke; das ist nichts gegen ein Farbsystem, das nicht
|
||
wirkt. */
|
||
let zeichenZaehler = 0;
|
||
|
||
function verlaufSicherstellen(ziel, endung) {
|
||
const defs = document.createElementNS(NS, 'defs');
|
||
|
||
/* AN DER FORM AUSGERICHTET, NICHT AM RASTER (07.09.2026).
|
||
|
||
Die Verlaeufe spannten ueber das ganze 24er-Raster (y von 2 bis
|
||
22). Ein Zeichen fuellt das aber nie aus: Die Sprechblase des
|
||
Chats reicht von y 5,5 bis 20,5. Das warme Streulicht sass bei
|
||
y 22 -- also UNTER der Form, und war nie zu sehen. Bei hoher
|
||
Vergroesserung nachgemessen; von den drei Lichtern kam nur eines
|
||
an.
|
||
|
||
`objectBoundingBox` spannt den Verlauf ueber JEDES Teil einzeln:
|
||
Der Kalenderkorpus bekommt sein volles Licht, seine Fuesse
|
||
ebenfalls. Genau so verhaelt sich ein echter Aufbau -- jedes Teil
|
||
liegt im selben Licht, nicht im selben Ausschnitt. */
|
||
const bauen = (id, stops, x2 = '0', y1 = '0', y2 = '1', raum = 'objectBoundingBox') => {
|
||
const lg = document.createElementNS(NS, 'linearGradient');
|
||
lg.setAttribute('id', id + endung);
|
||
lg.setAttribute('gradientUnits', raum);
|
||
lg.setAttribute('x1', '0'); lg.setAttribute('y1', y1);
|
||
lg.setAttribute('x2', x2); lg.setAttribute('y2', y2);
|
||
for (const [pos, farbe, deck] of stops) {
|
||
const st = document.createElementNS(NS, 'stop');
|
||
st.setAttribute('offset', pos);
|
||
st.setAttribute('stop-color', farbe);
|
||
st.setAttribute('stop-opacity', deck);
|
||
lg.append(st);
|
||
}
|
||
defs.append(lg);
|
||
};
|
||
|
||
/* Die Deckfläche: oben fast weiss, unten im Farbton. Das ist die
|
||
Seite, auf die das Licht fällt. */
|
||
/* AM 07.09.2026 AUF FARBE UMGESTELLT.
|
||
|
||
Filipe: "ich will dass die symbole viel krasser, realistischer,
|
||
farbiger und spezieller sind."
|
||
|
||
Der Farbton kam die ganze Zeit richtig an -- gemessen, das Zeichen
|
||
der Dashboard-Kachel bekam sauber rgb(62,149,231). Er war nur
|
||
nicht zu SEHEN, weil die Verlaeufe fast ueberall Weiss zeigten:
|
||
Die Deckflaeche begann mit 92 % Weiss, die Kontur war bis 38 %
|
||
weiss und bei 100 % wieder. Uebrig blieb ein graues Zeichen mit
|
||
einem Hauch Farbe in der Mitte.
|
||
|
||
Weiss ist jetzt nur noch da, wo bei einem echten Gegenstand das
|
||
SPITZLICHT sitzt: ein schmaler Streifen ganz oben. Darunter
|
||
traegt die Eigenfarbe, unten kommt Streulicht in einer HELLEREN
|
||
Tonung statt in Weiss -- Licht, das vom Untergrund zurueckkommt,
|
||
nimmt die Farbe des Gegenstands mit, es bleicht ihn nicht aus. */
|
||
/* =====================================================================
|
||
DREI LICHTER, DREI FARBEN (07.09.2026)
|
||
|
||
Filipe: "die symbole sollen auch 2-3 farben haben ... sollen mehr
|
||
leben haben, auch viel realistischere effekte."
|
||
|
||
Nicht drei ausgedachte Farben, sondern die drei, die ein
|
||
Gegenstand in einem echten Aufbau bekommt -- so wird jedes
|
||
Produktfoto ausgeleuchtet, und aus demselben Grund sieht es
|
||
plastisch aus:
|
||
|
||
1 FUEHRUNGSLICHT, kalt, von oben links. Ein Spitzlicht ist nie
|
||
reinweiss; es traegt die Farbe der Lampe, und die ist kuehl.
|
||
Hier ein Hauch Babyblau darin.
|
||
2 EIGENFARBE des Gegenstands -- der Ton seiner Kachel.
|
||
3 STREULICHT, warm, von unten. Licht, das vom Untergrund
|
||
zurueckkommt, ist waermer als das Hauptlicht. Genau dieser
|
||
warme Saum unten ist der Grund, warum ein Gegenstand im Bild
|
||
"steht" statt zu schweben.
|
||
|
||
Und die Schatten sind KUEHL: Warmes Licht, kuehle Schatten -- das
|
||
ist die aelteste Regel der Malerei und der schnellste Weg von
|
||
"Farbflaeche" zu "Koerper". Sie steckt unten in `zeichen-wand`. */
|
||
bauen('zeichen-deck', [
|
||
['0', '#eaf4ff', '0.95'],
|
||
['0.12', 'currentColor', '1'],
|
||
['0.55', 'currentColor', '0.97'],
|
||
['0.82', '#ff9c5a', '0.42'],
|
||
['1', '#ffb46a', '0.66'],
|
||
]);
|
||
/* Die Seitenwand: derselbe Ton, deutlich dunkler -- eine Wand, die
|
||
vom Licht abgewandt ist. */
|
||
/* Die Seitenwand -- kuehl und dunkel. Ein Schatten ist nicht
|
||
"dieselbe Farbe, nur dunkler": Ihm fehlt das warme Hauptlicht,
|
||
also kippt er ins Blaue. */
|
||
bauen('zeichen-wand', [
|
||
['0', 'currentColor', '0.52'],
|
||
['0.6', '#1b2b45', '0.62'],
|
||
['1', '#0d1626', '0.72'],
|
||
]);
|
||
|
||
/* Der Körper: oben satt, unten fast durchsichtig. */
|
||
bauen('zeichen-flaeche', [
|
||
['0', 'currentColor', '0.68'],
|
||
['0.45', 'currentColor', '0.38'],
|
||
['1', 'currentColor', '0.12'],
|
||
]);
|
||
/* Der Eigenschatten: eine zweite Fuellung, die von unten dunkel
|
||
hereinkriecht. Ein Koerper ist unten dunkler als oben -- ohne das
|
||
bleibt jede Flaeche eine Farbflaeche. */
|
||
bauen('zeichen-schatten', [
|
||
['0', '#000000', '0'],
|
||
['0.55', '#000000', '0'],
|
||
['1', '#000000', '0.45'],
|
||
]);
|
||
|
||
/* Die Kontur: Licht von oben. Oben fast weiss, unten im Farbton --
|
||
das ist der Trick, der die Zeichen aus der Fläche hebt. */
|
||
/* Die Kontur bekommt ZWEI Lichtquellen -- so wie ein echter
|
||
Gegenstand auf einem Tisch:
|
||
|
||
oben das Hauptlicht, fast weiss
|
||
Mitte der Eigenton des Gegenstands
|
||
unten STREULICHT, das vom Untergrund zurueckgeworfen wird
|
||
|
||
Der letzte Stopp ist der Unterschied zwischen "Zeichnung" und
|
||
"Ding". Ohne ihn laeuft jede Form nach unten ins Dunkle aus und
|
||
sieht aus wie gemalt; mit ihm bekommt sie unten eine Kante, und
|
||
das Auge liest sie als Koerper im Raum. */
|
||
bauen('zeichen-linie', [
|
||
['0', '#f2f9ff', '0.99'],
|
||
['0.1', '#bfe0ff', '0.78'],
|
||
['0.3', 'currentColor', '1'],
|
||
['0.74', 'currentColor', '1'],
|
||
['1', '#ffc389', '0.85'],
|
||
]);
|
||
|
||
/* DAS RANDLICHT. Eine kuehle Kante auf der Lichtseite -- der
|
||
schmale Streifen, in dem das Fuehrungslicht die Kante des
|
||
Gegenstands streift. Er wird als zweite Lage der Kontur
|
||
gezeichnet, ein Drittel Rasterpunkt nach oben links versetzt.
|
||
Ein Gegenstand ohne diese Kante sieht immer ein wenig flach aus,
|
||
und man kann meist nicht sagen, warum. */
|
||
bauen('zeichen-rand', [
|
||
['0', '#dff0ff', '0.85'],
|
||
['0.5', '#9fd4ff', '0.45'],
|
||
['1', '#9fd4ff', '0'],
|
||
]);
|
||
|
||
/* Die Spiegelung, diagonal von links oben nach rechts unten. */
|
||
/* DAS SPITZLICHT WIRD SCHMAL UND HART.
|
||
|
||
Vorher lief es ueber zwei Drittel der Flaeche aus -- das ist kein
|
||
Spitzlicht, sondern ein Schleier, und Schleier machen jede Farbe
|
||
blass. Ein Spitzlicht auf einer gewoelbten Flaeche ist KLEIN und
|
||
hat eine Kante; genau daran erkennt das Auge die Woelbung. */
|
||
bauen('zeichen-glanz', [
|
||
['0', '#ffffff', '0.72'],
|
||
['0.16', '#ffffff', '0.3'],
|
||
['0.3', '#ffffff', '0'],
|
||
], '18', '0', '20', 'userSpaceOnUse');
|
||
|
||
ziel.append(defs);
|
||
}
|
||
|
||
function zeichenBauen(name, klasse = 'kachel__svg') {
|
||
const svg = document.createElementNS(NS, 'svg');
|
||
svg.setAttribute('viewBox', '0 0 24 24');
|
||
svg.setAttribute('aria-hidden', 'true');
|
||
svg.setAttribute('class', klasse);
|
||
/* Eine eigene Kennung je Zeichen -- zwei gleiche Kennungen in einem
|
||
Dokument sind ein Verweis ins Nichts fuer das zweite. */
|
||
const endung = '-' + (++zeichenZaehler);
|
||
verlaufSicherstellen(svg, endung);
|
||
|
||
/* Erst die Fläche, dann die Linie -- in dieser Reihenfolge liegt
|
||
die Zeichnung oben. Ein Zeichen ohne Füllung (ältere Einträge,
|
||
die noch ein reines Feld sind) bekommt einfach keine. */
|
||
const eintrag = ZEICHEN[name] || {};
|
||
const umriss = KOERPER[name] || eintrag.fuellung || [];
|
||
const linien = Array.isArray(eintrag) ? eintrag : (eintrag.linien || []);
|
||
|
||
/* ---- Die Tiefe ----------------------------------------------------
|
||
|
||
Dieselbe Silhouette, dreimal, jedes Mal um einen halben
|
||
Rasterpunkt nach rechts unten versetzt. Von hinten nach vorn wird
|
||
sie heller. Das Auge liest die drei versetzten Kanten als EINE
|
||
schräge Seitenwand -- genau so, wie man einen Quader zeichnet.
|
||
|
||
Drei Lagen sind gemessen: bei zwei wirkt es wie ein
|
||
Druckfehler, ab fünf wie ein Schlagschatten. */
|
||
const tiefen = [
|
||
['zeichen__tiefe3', 'translate(1.5 1.5)'],
|
||
['zeichen__tiefe2', 'translate(1 1)'],
|
||
['zeichen__tiefe1', 'translate(0.5 0.5)'],
|
||
];
|
||
/* WOHIN DIE VERWEISE GEHOEREN: in den Inline-Stil.
|
||
|
||
Eine Klassenregel in start.css (`.zeichen__deck { fill: url(...) }`)
|
||
wuerde einen Praesentations-Attributwert schlagen, aber nicht den
|
||
Inline-Stil. Und sie kann die Kennung nicht kennen, weil die je
|
||
Zeichen anders ist. Die Farbe des Wasserzeichens setzt weiterhin
|
||
das CSS -- dort steht ausdruecklich `stroke: var(--ton)`, und
|
||
darum bekommt es hier keinen Verweis. */
|
||
const wasserzeichen = /wasserzeichen/.test(klasse);
|
||
const verweis = (el, eigenschaft, id) => {
|
||
if (!wasserzeichen) el.style.setProperty(eigenschaft, `url(#${id}${endung})`);
|
||
};
|
||
|
||
for (const [klasse, versatz] of tiefen) {
|
||
if (!umriss.length) break;
|
||
const g = document.createElementNS(NS, 'g');
|
||
g.setAttribute('class', klasse);
|
||
g.setAttribute('transform', versatz);
|
||
if (klasse !== 'zeichen__tiefe3') verweis(g, 'fill', 'zeichen-wand');
|
||
for (const d of umriss) {
|
||
const pfad = document.createElementNS(NS, 'path');
|
||
pfad.setAttribute('d', d);
|
||
g.append(pfad);
|
||
}
|
||
svg.append(g);
|
||
}
|
||
|
||
/* ---- Die Deckfläche und was darauf liegt --------------------------- */
|
||
const lagen = [
|
||
['zeichen__deck', umriss], // die Oberseite, hell
|
||
['zeichen__glanz', umriss], // die Spiegelung darauf
|
||
/* Die Details ZWEIMAL: erst ein dunkler Saum, dann die helle
|
||
Linie darauf.
|
||
|
||
Der Grund ist, dass dieselbe Linie über ZWEI Untergründen
|
||
liegt. Ein Querstrich im Kalender liegt auf der hellen
|
||
Deckfläche, die Wellen der LIVE-Analyse dagegen frei auf der
|
||
dunklen Plakette. Eine dunkle Linie verschwindet dort, eine
|
||
helle auf dem Deck -- was immer man wählt, die Hälfte ist weg.
|
||
|
||
Dunkler Saum plus helle Linie löst beides auf einmal: Auf dem
|
||
hellen Deck sieht man den Saum und liest eine eingravierte
|
||
Rille, auf der dunklen Plakette verschwindet er und die helle
|
||
Linie trägt. Ein Zeichen, zwei Untergründe, eine Lösung. */
|
||
['zeichen__saum', linien],
|
||
['zeichen__rand', linien], // die kuehle Lichtkante darunter
|
||
['zeichen__linie', linien],
|
||
];
|
||
const verlaufZu = {
|
||
zeichen__deck: ['fill', 'zeichen-deck'],
|
||
zeichen__glanz: ['fill', 'zeichen-glanz'],
|
||
zeichen__rand: ['stroke', 'zeichen-rand'],
|
||
zeichen__linie: ['stroke', 'zeichen-linie'],
|
||
};
|
||
for (const [klasse, pfade] of lagen) {
|
||
if (!pfade.length) continue;
|
||
const g = document.createElementNS(NS, 'g');
|
||
g.setAttribute('class', klasse);
|
||
if (klasse === 'zeichen__rand') g.setAttribute('transform', 'translate(-0.34 -0.34)');
|
||
if (verlaufZu[klasse]) verweis(g, verlaufZu[klasse][0], verlaufZu[klasse][1]);
|
||
for (const d of pfade) {
|
||
const pfad = document.createElementNS(NS, 'path');
|
||
pfad.setAttribute('d', d);
|
||
g.append(pfad);
|
||
}
|
||
svg.append(g);
|
||
}
|
||
return svg;
|
||
}
|
||
|
||
/* ---------- Das Merkzeichen ----------------------------------------------
|
||
|
||
Wunsch vom 01.09.2026: "wenn die Ansprechpartner was markieren, sollen
|
||
die da so ein Zeichen/Symbol haben, so dass die sehen, da ist was --
|
||
und es soll auch oben in der Kachel angezeigt werden."
|
||
|
||
Es ist bewusst das EINZIGE Zeichen der ganzen Anwendung, das eine
|
||
eigene Form hat statt der 24×24-Linienzeichen oben: eine Raute mit
|
||
Ausrufestrich. Der Grund ist nicht Geschmack, sondern Erkennbarkeit --
|
||
alle anderen Zeichen sind Rechtecke und Kreise; eine Raute ist die
|
||
einzige Form auf dem Bildschirm, die spitz nach oben zeigt, und
|
||
genau deshalb findet das Auge sie zwischen zwanzig Kacheln sofort.
|
||
|
||
Und es ist immer DIESELBE Farbe (Bernstein), egal auf welcher Kachel
|
||
es sitzt. Ein Zeichen, das seine Farbe wechselt, muss gelesen werden;
|
||
eines, das immer gleich aussieht, wird erkannt. Rot wäre falsch --
|
||
"verbessern" ist kein Fehler, sondern ein Auftrag.
|
||
|
||
anzahl > 1 schreibt die Zahl daneben, sonst steht nur das Zeichen.
|
||
Der Satz für Vorleseprogramme wird immer gesetzt: Ein Symbol ohne
|
||
Text ist für sie nicht vorhanden. */
|
||
function merkzeichenBauen(anzahl = 0, klasse = 'merk') {
|
||
const s = document.createElement('span');
|
||
s.className = klasse;
|
||
s.setAttribute('role', 'img');
|
||
s.setAttribute('aria-label', anzahl > 0
|
||
? `${anzahl} ${anzahl === 1 ? 'Punkt ist' : 'Punkte sind'} zum Verbessern markiert`
|
||
: 'Zum Verbessern markiert');
|
||
|
||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||
svg.setAttribute('viewBox', '0 0 24 24');
|
||
svg.setAttribute('aria-hidden', 'true');
|
||
svg.setAttribute('class', klasse + '__svg');
|
||
/* Drei Pfade: die gefüllte Raute, der Strich, der Punkt. Getrennt,
|
||
damit die Fläche eine andere Deckkraft bekommen kann als die
|
||
Linie -- eine durchgehend volle Raute wäre auf dunklem Grund ein
|
||
Klecks. */
|
||
const teile = [
|
||
['M12 1.9 22.1 12 12 22.1 1.9 12z', 'flaeche'],
|
||
['M12 7.5v5.6', 'strich'],
|
||
['M12 16.9h.01', 'punkt'],
|
||
];
|
||
for (const [d, art] of teile) {
|
||
const p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||
p.setAttribute('d', d);
|
||
p.setAttribute('class', `${klasse}__${art}`);
|
||
svg.append(p);
|
||
}
|
||
s.append(svg);
|
||
if (anzahl > 1) {
|
||
const n = document.createElement('span');
|
||
n.className = klasse + '__n';
|
||
n.textContent = String(anzahl);
|
||
n.setAttribute('aria-hidden', 'true');
|
||
s.append(n);
|
||
}
|
||
return s;
|
||
}
|
||
|
||
/* ===================================================================
|
||
WER GEHÖRT ZUR LEITUNG? EINE ANTWORT, NICHT NEUN (07.09.2026)
|
||
|
||
Filipe hat gemeldet, dass die Seite „Creator-Profile" bei Spicy
|
||
Media mit „Profil konnte nicht geladen werden" abbricht. Die
|
||
Ursache war nicht diese eine Seite: In NEUN Skripten stand
|
||
dieselbe Zeile
|
||
|
||
const LEITUNG = new Set(['admin', 'manager']); // <- ohne spicy
|
||
|
||
und in keinem davon stand `spicy`. profil.js hat deshalb den
|
||
Zweig für Creator genommen und das EIGENE Profil geladen -- und
|
||
ein Spicy-Media-Zugang ist kein Creator, also 404.
|
||
|
||
Das ist die Bauart, die von selbst auseinanderläuft: Wer eine
|
||
Rolle hinzufügt, müsste an neun Stellen daran denken, und die
|
||
acht, an die er nicht gedacht hat, gehen nicht kaputt -- sie
|
||
verhalten sich nur still falsch. Deshalb steht die Antwort jetzt
|
||
hier, an EINER Stelle, in einer Datei, die jede dieser Seiten vor
|
||
ihrem eigenen Skript lädt.
|
||
|
||
`pruef-css-klassen.mjs` verlangt, dass kein Workspace-Skript sich
|
||
wieder eine eigene Leitungsliste baut. */
|
||
const LEITUNG = new Set(['spicy', 'admin', 'manager']);
|
||
|
||
/* Die Reihenfolge, in der Rollen überall erscheinen -- gleiche
|
||
Begründung, dieselbe Falle: kalender.js hatte seine eigene, ohne
|
||
Spicy Media, und sortierte sie damit ans Ende. */
|
||
/* ROLLENFOLGE sagt, welche Rollen diese Datei NENNEN darf -- nicht
|
||
mehr, in welcher Reihenfolge Menschen erscheinen. Die kommt seit
|
||
dem 11.09.2026 vom Server (siehe gruppieren weiter unten). */
|
||
const ROLLENFOLGE = ['spicy', 'admin', 'manager', 'scout', 'creator'];
|
||
|
||
/* DIE NAMEN DER ROLLEN -- ebenfalls an EINER Stelle (07.09.2026).
|
||
|
||
Sie standen als Objekt in fuenf Skripten: chat.js zweimal,
|
||
dateien.js, kalender.js zweimal. In keinem davon 'spicy'. Im Chat
|
||
stand ueber Cigdems Namen deshalb woertlich "UNDEFINED" -- Filipe
|
||
hat es im Bildschirmfoto geschickt.
|
||
|
||
Es ist derselbe Fehler wie bei der Leitungsliste heute Frueh, nur
|
||
in anderer Form: damals ein Set, hier ein Objekt. Deshalb sucht
|
||
`pruef-css-klassen.mjs` jetzt auch nach Rollen-OBJEKTEN.
|
||
|
||
Zwei Schreibweisen, weil beide gebraucht werden: die kurze fuer
|
||
Namensschilder ("Scout"), die Gruppenform fuer Ueberschriften
|
||
ueber Listen ("Scouts"). */
|
||
const ROLLEN_NAME = {
|
||
spicy: 'Spicy Media', admin: 'DogFather', manager: 'Manager',
|
||
scout: 'Scout', creator: 'Creator',
|
||
};
|
||
const ROLLEN_GRUPPE = {
|
||
spicy: 'Spicy Media', admin: 'DogFather', manager: 'Manager',
|
||
scout: 'Scouts', creator: 'Creator',
|
||
};
|
||
|
||
/* =====================================================================
|
||
PERSONEN IN GRUPPEN — IN DER REIHENFOLGE, DIE DER SERVER SCHICKT
|
||
(11.09.2026)
|
||
|
||
Filipe, mit Bildschirmfoto: "rechte hand soll immer als erstes
|
||
sein. ueberall. ... ich will dass auch ueberall immer nach der
|
||
hirarchie gearbeitet wird."
|
||
|
||
WARUM DAS NICHT EINE ZEILE IM SERVER WAR: Der Server sortierte
|
||
schon richtig. Drei Auswahllisten im Browser (Chat, Kalender,
|
||
Sicht-Umschalter) haben seine Reihenfolge aber wieder verworfen
|
||
und nach ROLLENFOLGE neu gezeichnet — einer Liste mit fuenf
|
||
Agentur-Rollen. Team Dogi kommt darin nicht vor und DARF es nicht
|
||
(diese Datei laedt jeder herunter). Folge: die rechte Hand stand
|
||
unten, in einem Nachzuegler-Block, oder — im Kalender — gar nicht.
|
||
|
||
DAS IST DERSELBE FEHLER ZUM VIERTEN MAL. Chat (10.09.), Personen-
|
||
liste (10.09.), Sicht-Umschalter (11.09.) und jetzt der Kalender:
|
||
jedes Mal eine zweite Reihenfolge neben der des Servers, jedes Mal
|
||
verschwindet jemand lautlos. Deshalb hier keine vierte Reparatur,
|
||
sondern eine Stelle: Wer Menschen gruppiert, nimmt diese Funktion.
|
||
|
||
Eine Map behaelt die Einfuegereihenfolge — die Gruppen erscheinen
|
||
also in der Reihenfolge ihres ranghoechsten Mitglieds, ohne dass
|
||
diese Datei einen einzigen Rang kennen muss.
|
||
|
||
@param {Array} personen wie vom Server geliefert, bereits sortiert
|
||
@returns {Array<{titel: string, rolle: string, leute: Array}>} */
|
||
function gruppieren(personen) {
|
||
const nach = new Map();
|
||
for (const p of personen || []) {
|
||
/* Der Server schickt die Ueberschrift mit. Der Rueckfall auf
|
||
ROLLEN_GRUPPE gilt den Wegen, die das noch nicht tun; "Weitere"
|
||
ist die letzte Reissleine — lieber eine blasse Ueberschrift als
|
||
ein Mensch, der nicht gezeichnet wird. */
|
||
const titel = p.gruppe || ROLLEN_GRUPPE[p.rolle] || 'Weitere';
|
||
if (!nach.has(titel)) nach.set(titel, []);
|
||
nach.get(titel).push(p);
|
||
}
|
||
return [...nach].map(([titel, leute]) => ({ titel, rolle: leute[0].rolle, leute }));
|
||
}
|
||
|
||
window.Bereiche = {
|
||
ZEICHEN, GRUPPEN, zuSeite, zeichenBauen, merkzeichenBauen,
|
||
LEITUNG, ROLLENFOLGE, ROLLEN_NAME, ROLLEN_GRUPPE, gruppieren,
|
||
};
|
||
})();
|