Personen: jede Rolle einzeln auf- und zuklappbar
Wunsch Filipe: "ich will ueberall die liste zu machen koennen und nur
aufmachen wenn ich sie sehen will."
Jede der vier Rollen klappt jetzt einzeln auf und zu. Das ERSETZT den
Sammelknopf von vorhin ("5 weitere zeigen") -- zwei Mechanismen
nebeneinander, die dasselbe verstecken, waeren eine Einladung zum
Missverstaendnis. Der Knopf oben rechts macht jetzt etwas anderes: alles
auf einmal ("Alle aufklappen" / "Alle zuklappen"), damit man bei vier
Rollen nicht viermal klicken muss.
Der entscheidende Unterschied zum Ausblenden: Die UEBERSCHRIFT mit der
Anzahl bleibt IMMER stehen, auch zugeklappt. Man sieht jederzeit, DASS es
einen Manager gibt -- nur nicht, welchen. Wer eine ganze Rolle spurlos
verschwinden laesst, haelt sie irgendwann fuer leer.
Und zugeklappt zaehlt genau eine Frage: Steckt da etwas Gesperrtes drin,
das ich sehen muesste? Deshalb steht am Manager auch zugeklappt
"1 gesperrt", in Warnfarbe.
Die Ueberschrift IST der Knopf, als echtes <button> -- ein eigener
kleiner Schalter daneben waere ein zweites Ziel fuer dieselbe Absicht,
und ein kleineres. Als Knopf-Element statt div mit Klick-Zuhoerer machen
Tastatur und Vorleseprogramme es ohne Zutun richtig.
Der Zustand wird JE ROLLE gemerkt, nicht als "alles auf/zu": Wer die
Creator zuklappt und die Scouts offen laesst, findet das nach dem Laden
genau so wieder.
30 Pruefungen. Darunter weiterhin der wichtigste: Zuklappen ist eine
ANSICHT, kein Recht -- Tili kann sich anmelden und normal arbeiten,
waehrend ihre Rolle zugeklappt ist, und der Server liefert unveraendert
alle sieben Personen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 324 KiB After Width: | Height: | Size: 326 KiB |
@@ -1,10 +1,16 @@
|
|||||||
/* ===================================================================
|
/* ===================================================================
|
||||||
Pruefung: In der Personenliste steht standardmaessig nur DogFather,
|
Pruefung: Die Personenliste ist je Rolle auf- und zuklappbar.
|
||||||
alle anderen kommen auf Knopfdruck dazu.
|
|
||||||
|
|
||||||
Der wichtigste Punkt ist der letzte: Verstecken ist eine ANSICHT, kein
|
Zwei Dinge sind dabei wichtiger als alles andere:
|
||||||
Recht. Wer eingeklappt ist, hat unveraendert Zugang -- der Server darf
|
|
||||||
davon gar nichts mitbekommen.
|
1. Die UEBERSCHRIFT mit der Anzahl bleibt immer stehen, auch
|
||||||
|
zugeklappt. Das ist der Unterschied zum Ausblenden: Man sieht
|
||||||
|
jederzeit, DASS es einen Manager gibt -- nur nicht, welchen. Wer
|
||||||
|
eine ganze Rolle spurlos verschwinden laesst, haelt sie irgendwann
|
||||||
|
fuer leer.
|
||||||
|
|
||||||
|
2. Zuklappen ist eine ANSICHT, kein Recht. Wer zugeklappt ist, hat
|
||||||
|
unveraendert Zugang -- der Server bekommt davon gar nichts mit.
|
||||||
=================================================================== */
|
=================================================================== */
|
||||||
import { mkdtempSync, rmSync } from "node:fs";
|
import { mkdtempSync, rmSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
@@ -24,7 +30,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(
|
|||||||
await import("./index.js");
|
await import("./index.js");
|
||||||
await new Promise((r) => setTimeout(r, 700));
|
await new Promise((r) => setTimeout(r, 700));
|
||||||
const BASIS = "http://127.0.0.1:4187";
|
const BASIS = "http://127.0.0.1:4187";
|
||||||
setTimeout(() => { console.log("ABBRUCH"); process.exit(1); }, 180_000).unref?.();
|
setTimeout(() => { console.log("ABBRUCH"); process.exit(1); }, 200_000).unref?.();
|
||||||
|
|
||||||
let fehler = 0;
|
let fehler = 0;
|
||||||
const ok = (b, t) => { console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; };
|
const ok = (b, t) => { console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; };
|
||||||
@@ -42,7 +48,6 @@ function anlegen(name, rolle, code, aktiv = 1) {
|
|||||||
const hash = scryptSync(code, salt, 64, { N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex");
|
const hash = scryptSync(code, salt, 64, { N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex");
|
||||||
d.prepare("INSERT INTO personen (name, rolle, code_hash, code_salt, code_n, aktiv, erstellt) VALUES (?,?,?,?,?,?,?)")
|
d.prepare("INSERT INTO personen (name, rolle, code_hash, code_salt, code_n, aktiv, erstellt) VALUES (?,?,?,?,?,?,?)")
|
||||||
.run(name, rolle, hash, salt, 32768, aktiv, jetzt);
|
.run(name, rolle, hash, salt, 32768, aktiv, jetzt);
|
||||||
return d.prepare("SELECT last_insert_rowid() AS id").get().id;
|
|
||||||
}
|
}
|
||||||
/* Genau die Aufstellung aus dem Bild vom 31.08.2026. */
|
/* Genau die Aufstellung aus dem Bild vom 31.08.2026. */
|
||||||
anlegen("Dogfather", "admin", "CODE-DOGI-0001");
|
anlegen("Dogfather", "admin", "CODE-DOGI-0001");
|
||||||
@@ -72,115 +77,136 @@ async function seiteFuer(kontext) {
|
|||||||
|
|
||||||
const lesen = (seite) => seite.evaluate(() => ({
|
const lesen = (seite) => seite.evaluate(() => ({
|
||||||
namen: [...document.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
namen: [...document.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
||||||
/* Die Abschnitte in der Reihenfolge, in der sie tatsächlich stehen --
|
|
||||||
nicht in der, in der sie gemeint waren. */
|
|
||||||
abschnitte: [...document.querySelectorAll(".gruppe")].map((g) => ({
|
abschnitte: [...document.querySelectorAll(".gruppe")].map((g) => ({
|
||||||
name: g.querySelector(".gruppe__name")?.textContent,
|
name: g.querySelector(".gruppe__name")?.textContent,
|
||||||
zahl: g.querySelector(".gruppe__zahl")?.textContent,
|
zahl: g.querySelector(".gruppe__zahl")?.textContent,
|
||||||
unter: g.querySelector(".gruppe__unter")?.textContent,
|
unter: g.querySelector(".gruppe__unter")?.textContent,
|
||||||
|
auf: g.querySelector(".gruppe__kopf")?.getAttribute("aria-expanded"),
|
||||||
|
knopf: g.querySelector(".gruppe__kopf")?.tagName,
|
||||||
personen: [...g.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
personen: [...g.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
||||||
})),
|
})),
|
||||||
knopfDa: !document.getElementById("rest-schalter")?.hidden,
|
knopfDa: !document.getElementById("rest-schalter")?.hidden,
|
||||||
knopfText: document.getElementById("rest-schalter-text")?.textContent,
|
knopfText: document.getElementById("rest-schalter-text")?.textContent,
|
||||||
auf: document.getElementById("rest-schalter")?.getAttribute("aria-expanded"),
|
|
||||||
ueber: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
ueber: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const klick = (seite, rolle) =>
|
||||||
|
seite.locator(".gruppe__kopf", { hasText: new RegExp("^" + rolle) }).first().click();
|
||||||
|
|
||||||
const kontext = await browser.newContext({ viewport: { width: 1440, height: 1100 } });
|
const kontext = await browser.newContext({ viewport: { width: 1440, height: 1100 } });
|
||||||
const konsole = [];
|
const konsole = [];
|
||||||
const seite = await seiteFuer(kontext);
|
const seite = await seiteFuer(kontext);
|
||||||
seite.on("console", (m) => { if (m.type() === "error") konsole.push(m.text()); });
|
seite.on("console", (m) => { if (m.type() === "error") konsole.push(m.text()); });
|
||||||
seite.on("pageerror", (e) => konsole.push("pageerror: " + e.message));
|
seite.on("pageerror", (e) => konsole.push("pageerror: " + e.message));
|
||||||
|
|
||||||
console.log("\n1) Standardmäßig nur DogFather");
|
console.log("\n1) Alle vier Überschriften stehen da – offen ist nur DogFather");
|
||||||
{
|
{
|
||||||
const r = await lesen(seite);
|
const r = await lesen(seite);
|
||||||
console.log(" sichtbar:", r.namen.join(", "));
|
console.log(" ", r.abschnitte.map((a) => `${a.name}(${a.zahl},${a.auf === "true" ? "auf" : "zu"})`).join(" · "));
|
||||||
console.log(" Knopf: ", r.knopfText);
|
|
||||||
ok(r.namen.length === 2, `zwei Personen sichtbar (${r.namen.length})`);
|
ok(r.abschnitte.length === 4, `vier Überschriften, auch zugeklappt (${r.abschnitte.length})`);
|
||||||
ok(r.abschnitte.length === 1 && r.abschnitte[0].name === "DogFather",
|
ok(r.abschnitte.map((a) => a.name).join(",") === "DogFather,Manager,Scout,Creator",
|
||||||
`zugeklappt steht nur der DogFather-Abschnitt da (${r.abschnitte.map((a) => a.name).join(", ") || "keiner"})`);
|
`Reihenfolge wie auf der Zugangsseite (${r.abschnitte.map((a) => a.name).join(", ")})`);
|
||||||
|
ok(r.abschnitte.map((a) => a.zahl).join(",") === "2,1,2,2",
|
||||||
|
`mit den Anzahlen (${r.abschnitte.map((a) => a.zahl).join(", ")})`);
|
||||||
|
|
||||||
|
ok(r.namen.length === 2, `aber nur zwei Personen sichtbar (${r.namen.length})`);
|
||||||
ok(r.namen.includes("Dogfather") && r.namen.includes("VanVan"),
|
ok(r.namen.includes("Dogfather") && r.namen.includes("VanVan"),
|
||||||
`Dogfather und VanVan (${r.namen.join(", ")})`);
|
`Dogfather und VanVan (${r.namen.join(", ")})`);
|
||||||
ok(!r.namen.includes("Tili"), "kein Creator");
|
ok(r.abschnitte[0].auf === "true", `DogFather ist offen (${r.abschnitte[0].auf})`);
|
||||||
ok(!r.namen.includes("Patrick"), "kein Scout");
|
ok(r.abschnitte.slice(1).every((a) => a.auf === "false"), "die anderen drei sind zu");
|
||||||
ok(r.knopfDa, "der Knopf ist da");
|
|
||||||
/* Die ZAHL gehoert auf den Knopf -- "Alle zeigen" sagt nicht, wie
|
/* Als echtes <button>, damit Tastatur und Vorleseprogramme es ohne
|
||||||
viele man gerade nicht sieht. */
|
Zutun richtig machen. */
|
||||||
ok(/5 weitere zeigen/.test(r.knopfText || ""), `mit der Anzahl (${r.knopfText})`);
|
ok(r.abschnitte.every((a) => a.knopf === "BUTTON"), "jede Überschrift ist ein echter Knopf");
|
||||||
ok(/1 gesperrt/.test(r.knopfText || ""), "und dem Hinweis auf die gesperrte Person");
|
|
||||||
ok(r.auf === "false", `aria-expanded=false (${r.auf})`);
|
/* Zugeklappt muss trotzdem auffallen, wenn dort etwas Gesperrtes liegt. */
|
||||||
|
const manager = r.abschnitte.find((a) => a.name === "Manager");
|
||||||
|
ok(/1 gesperrt/.test(manager?.unter || ""),
|
||||||
|
`bei Manager steht die gesperrte Person dran ("${manager?.unter}")`);
|
||||||
|
|
||||||
|
ok(r.knopfDa && /Alle aufklappen/.test(r.knopfText || ""),
|
||||||
|
`der Sammelknopf bietet alles an (${r.knopfText})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("\n2) Auf Knopfdruck kommen alle dazu");
|
console.log("\n2) Jede Rolle einzeln auf und zu");
|
||||||
|
{
|
||||||
|
await klick(seite, "Scout");
|
||||||
|
await seite.waitForTimeout(250);
|
||||||
|
let r = await lesen(seite);
|
||||||
|
console.log(" ", r.abschnitte.map((a) => `${a.name}=${a.auf === "true" ? "auf" : "zu"}`).join(" · "));
|
||||||
|
ok(r.namen.includes("Patrick") && r.namen.includes("BananaStift"), "die Scouts stehen da");
|
||||||
|
ok(!r.namen.includes("Tili"), "die Creator weiterhin nicht");
|
||||||
|
ok(r.abschnitte.find((a) => a.name === "Creator").auf === "false", "Creator bleibt unberührt zu");
|
||||||
|
|
||||||
|
await klick(seite, "Scout");
|
||||||
|
await seite.waitForTimeout(250);
|
||||||
|
r = await lesen(seite);
|
||||||
|
ok(!r.namen.includes("Patrick"), "dieselbe Überschrift klappt wieder zu");
|
||||||
|
|
||||||
|
/* "Überall" heisst überall -- auch DogFather. */
|
||||||
|
await klick(seite, "DogFather");
|
||||||
|
await seite.waitForTimeout(250);
|
||||||
|
r = await lesen(seite);
|
||||||
|
ok(r.namen.length === 0, `alles zu, keine Person sichtbar (${r.namen.length})`);
|
||||||
|
ok(r.abschnitte.length === 4, "die vier Überschriften stehen trotzdem noch da");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n3) Der Sammelknopf klappt alles auf und wieder zu");
|
||||||
{
|
{
|
||||||
await seite.click("#rest-schalter");
|
await seite.click("#rest-schalter");
|
||||||
await seite.waitForTimeout(250);
|
await seite.waitForTimeout(250);
|
||||||
const r = await lesen(seite);
|
const r = await lesen(seite);
|
||||||
console.log(" sichtbar:", r.namen.join(", "));
|
|
||||||
ok(r.namen.length === 7, `alle sieben (${r.namen.length})`);
|
ok(r.namen.length === 7, `alle sieben (${r.namen.length})`);
|
||||||
ok(r.namen.includes("BanaStift"), "auch die gesperrte Person");
|
ok(r.namen.includes("BanaStift"), "auch die gesperrte Person");
|
||||||
ok(/Nur DogFather zeigen/.test(r.knopfText || ""), `Knopf bietet das Zuklappen an (${r.knopfText})`);
|
ok(/Alle zuklappen/.test(r.knopfText || ""), `Knopf bietet jetzt das Zuklappen an (${r.knopfText})`);
|
||||||
ok(r.auf === "true", `aria-expanded=true (${r.auf})`);
|
|
||||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px)`);
|
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px)`);
|
||||||
|
|
||||||
console.log(" Abschnitte:", r.abschnitte.map((a) => `${a.name}(${a.zahl})`).join(" → "));
|
/* Der Fehler von vorher: Der GESPERRTE Manager stand ganz unten unter
|
||||||
ok(r.abschnitte.length === 4, `vier Abschnitte (${r.abschnitte.length})`);
|
den Creators, weil "aktiv" vor der Rolle sortierte. */
|
||||||
ok(r.abschnitte.map((a) => a.name).join(",") === "DogFather,Manager,Scout,Creator",
|
|
||||||
`Reihenfolge wie auf der Zugangsseite (${r.abschnitte.map((a) => a.name).join(", ")})`);
|
|
||||||
ok(r.abschnitte.map((a) => a.zahl).join(",") === "2,1,2,2",
|
|
||||||
`Anzahl je Rolle (${r.abschnitte.map((a) => a.zahl).join(", ")})`);
|
|
||||||
|
|
||||||
/* Der eigentliche Fehler von vorher: Der GESPERRTE Manager stand ganz
|
|
||||||
unten unter den Creators, weil "aktiv" vor der Rolle sortierte. */
|
|
||||||
const manager = r.abschnitte.find((a) => a.name === "Manager");
|
const manager = r.abschnitte.find((a) => a.name === "Manager");
|
||||||
ok(manager?.personen.includes("BanaStift"),
|
ok(manager?.personen.includes("BanaStift"),
|
||||||
`der gesperrte Manager steht bei den Managern (${manager?.personen.join(", ")})`);
|
`der gesperrte Manager steht bei den Managern (${manager?.personen.join(", ")})`);
|
||||||
const creator = r.abschnitte.find((a) => a.name === "Creator");
|
const creator = r.abschnitte.find((a) => a.name === "Creator");
|
||||||
ok(!creator?.personen.includes("BanaStift"), "und nicht mehr bei den Creators");
|
|
||||||
ok(creator?.personen.join(",") === "SpongBobSchwammKopf,Tili",
|
ok(creator?.personen.join(",") === "SpongBobSchwammKopf,Tili",
|
||||||
`innerhalb der Rolle nach Namen (${creator?.personen.join(", ")})`);
|
`innerhalb der Rolle nach Namen (${creator?.personen.join(", ")})`);
|
||||||
|
|
||||||
/* Dieselben Zusatztexte wie auf der Zugangsseite -- wer sich eben
|
|
||||||
angemeldet hat, findet hier dieselbe Sprache wieder. */
|
|
||||||
ok(r.abschnitte[2]?.unter === "Eigene Pipeline & Kontakte",
|
ok(r.abschnitte[2]?.unter === "Eigene Pipeline & Kontakte",
|
||||||
`Zusatztext wörtlich von der Zugangsseite ("${r.abschnitte[2]?.unter}")`);
|
`Zusatztext wörtlich von der Zugangsseite ("${r.abschnitte[2]?.unter}")`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("\n3) Der Zustand überlebt das Neuladen");
|
console.log("\n4) Der Zustand überlebt das Neuladen – je Rolle einzeln");
|
||||||
{
|
{
|
||||||
/* Ein Knopf, den man nach jedem Laden neu druecken muss, ist keine
|
/* Nur die Creator zuklappen. Es muss die EINZELNE Einstellung
|
||||||
Einstellung, sondern eine Zumutung. */
|
überleben, nicht bloss "alles auf" oder "alles zu". */
|
||||||
await seite.reload({ waitUntil: "networkidle" });
|
await klick(seite, "Creator");
|
||||||
await seite.waitForTimeout(600);
|
|
||||||
const r = await lesen(seite);
|
|
||||||
ok(r.namen.length === 7, `nach dem Neuladen weiterhin alle (${r.namen.length})`);
|
|
||||||
|
|
||||||
await seite.click("#rest-schalter");
|
|
||||||
await seite.waitForTimeout(250);
|
await seite.waitForTimeout(250);
|
||||||
await seite.reload({ waitUntil: "networkidle" });
|
await seite.reload({ waitUntil: "networkidle" });
|
||||||
await seite.waitForTimeout(600);
|
await seite.waitForTimeout(700);
|
||||||
const z = await lesen(seite);
|
const r = await lesen(seite);
|
||||||
ok(z.namen.length === 2, `und zugeklappt bleibt zugeklappt (${z.namen.length})`);
|
console.log(" ", r.abschnitte.map((a) => `${a.name}=${a.auf === "true" ? "auf" : "zu"}`).join(" · "));
|
||||||
|
ok(!r.namen.includes("Tili"), "die zugeklappten Creator bleiben zu");
|
||||||
|
ok(r.namen.includes("Patrick"), "die offenen Scouts bleiben offen");
|
||||||
|
ok(r.abschnitte.find((a) => a.name === "Creator").auf === "false",
|
||||||
|
"und der Zustand steht auch im aria-expanded");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("\n4) Verstecken ist eine Ansicht, kein Recht");
|
console.log("\n5) Zuklappen ist eine Ansicht, kein Recht");
|
||||||
{
|
{
|
||||||
/* Der springende Punkt. Wer eingeklappt ist, muss unveraendert
|
/* Der springende Punkt. Wer zugeklappt ist, muss unverändert arbeiten
|
||||||
arbeiten koennen -- sonst waere aus einer Anzeigeeinstellung
|
können -- sonst wäre aus einer Anzeigeeinstellung versehentlich eine
|
||||||
versehentlich eine Sperre geworden. */
|
Sperre geworden. */
|
||||||
const a = await fetch(BASIS + "/workspace/api/anmelden", {
|
const a = await fetch(BASIS + "/workspace/api/anmelden", {
|
||||||
method: "POST", headers: { "Content-Type": "application/json" },
|
method: "POST", headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ rolle: "creator", code: "CODE-TILI-0001" }), redirect: "manual" });
|
body: JSON.stringify({ rolle: "creator", code: "CODE-TILI-0001" }), redirect: "manual" });
|
||||||
ok(a.ok, `Tili kann sich anmelden, obwohl sie ausgeblendet ist (${a.status})`);
|
ok(a.ok, `Tili kann sich anmelden, obwohl zugeklappt (${a.status})`);
|
||||||
|
|
||||||
const keks = (a.headers.getSetCookie?.() || []).map((c) => c.split(";")[0]).join("; ");
|
const keks = (a.headers.getSetCookie?.() || []).map((c) => c.split(";")[0]).join("; ");
|
||||||
const ich = await (await fetch(BASIS + "/workspace/api/ich", { headers: { cookie: keks } })).json();
|
const ich = await (await fetch(BASIS + "/workspace/api/ich", { headers: { cookie: keks } })).json();
|
||||||
ok(ich.name === "Tili", `und ist ganz normal angemeldet (${ich.name})`);
|
ok(ich.name === "Tili", `und ist ganz normal angemeldet (${ich.name})`);
|
||||||
|
|
||||||
/* Und der Server liefert weiterhin ALLE -- das Kuerzen passiert nur
|
/* Und der Server liefert weiterhin ALLE -- das Kürzen passiert nur in
|
||||||
in der Anzeige. Waere es serverseitig, wuerde die naechste
|
der Anzeige. Wäre es serverseitig, würde die nächste Auswertung
|
||||||
Auswertung stillschweigend Personen uebersehen. */
|
stillschweigend Personen übersehen. */
|
||||||
const dogiA = await fetch(BASIS + "/workspace/api/anmelden", {
|
const dogiA = await fetch(BASIS + "/workspace/api/anmelden", {
|
||||||
method: "POST", headers: { "Content-Type": "application/json" },
|
method: "POST", headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ rolle: "admin", code: "CODE-DOGI-0001" }), redirect: "manual" });
|
body: JSON.stringify({ rolle: "admin", code: "CODE-DOGI-0001" }), redirect: "manual" });
|
||||||
@@ -196,13 +222,17 @@ await seite.waitForTimeout(300);
|
|||||||
await seite.screenshot({ path: "pruef-personen.png", fullPage: true });
|
await seite.screenshot({ path: "pruef-personen.png", fullPage: true });
|
||||||
await kontext.close();
|
await kontext.close();
|
||||||
|
|
||||||
console.log("\n5) Auf dem Handy genauso");
|
console.log("\n6) Auf dem Handy genauso");
|
||||||
{
|
{
|
||||||
const k = await browser.newContext({ viewport: { width: 390, height: 844 } });
|
const k = await browser.newContext({ viewport: { width: 390, height: 844 } });
|
||||||
const s = await seiteFuer(k);
|
const s = await seiteFuer(k);
|
||||||
const r = await lesen(s);
|
const r = await lesen(s);
|
||||||
ok(r.knopfDa, "der Knopf ist auch dort da");
|
ok(r.abschnitte.length === 4, `vier Überschriften (${r.abschnitte.length})`);
|
||||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px)`);
|
await klick(s, "Creator");
|
||||||
|
await s.waitForTimeout(250);
|
||||||
|
const n = await lesen(s);
|
||||||
|
ok(n.namen.includes("Tili"), "auch dort lässt sich eine Rolle aufklappen");
|
||||||
|
ok(n.ueber <= 0, `nichts steht über (${n.ueber}px)`);
|
||||||
await k.close();
|
await k.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,3 +194,30 @@
|
|||||||
background: rgba(255, 154, 162, .1);
|
background: rgba(255, 154, 162, .1);
|
||||||
}
|
}
|
||||||
.schritt[data-gefahr="ja"]:focus-visible { outline-color: var(--warn); }
|
.schritt[data-gefahr="ja"]:focus-visible { outline-color: var(--warn); }
|
||||||
|
|
||||||
|
/* Die Rollen-Überschrift ist der Klappknopf. Sie sieht aus wie eine
|
||||||
|
Überschrift und verhält sich wie ein Knopf – deshalb hier nur der
|
||||||
|
Knopf-Rücksetzer und ein Zeiger, kein eigener Entwurf. */
|
||||||
|
.gruppe__kopf--klappbar {
|
||||||
|
width: 100%; text-align: left; cursor: pointer;
|
||||||
|
font: inherit; color: inherit;
|
||||||
|
background: none; border: 0;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
border-image: linear-gradient(90deg, var(--rand-hell), transparent 70%) 1;
|
||||||
|
transition: opacity var(--tempo);
|
||||||
|
}
|
||||||
|
.gruppe__kopf--klappbar:hover { opacity: .82; }
|
||||||
|
.gruppe__kopf--klappbar:focus-visible {
|
||||||
|
outline: 2px solid var(--akzent); outline-offset: 3px; border-radius: 4px;
|
||||||
|
}
|
||||||
|
/* Der Pfeil ganz nach rechts – dort sucht ihn die Hand. */
|
||||||
|
.gruppe__kopf--klappbar .klapp-pfeil { margin-left: auto; color: var(--text-still); }
|
||||||
|
.gruppe__kopf--klappbar:hover .klapp-pfeil { color: var(--akzent); }
|
||||||
|
|
||||||
|
/* Zugeklappt zählt nur eines: Steckt da etwas Gesperrtes drin, das man
|
||||||
|
sehen müsste? Dann fällt der Zusatztext auf. */
|
||||||
|
.gruppe__unter[data-warn="ja"] { color: var(--warn); }
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.gruppe__kopf--klappbar { transition: none; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -319,10 +319,33 @@
|
|||||||
} catch { /* umgeleitet */ }
|
} catch { /* umgeleitet */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
const SPEICHER = 'dfw_personen_alle';
|
/* ---------- Was aufgeklappt ist ------------------------------------------
|
||||||
|
|
||||||
|
Wunsch Filipe, 31.08.2026: "ich will überall die liste zu machen
|
||||||
|
können und nur aufmachen wenn ich sie sehen will."
|
||||||
|
|
||||||
|
Also klappt JEDE Rolle einzeln auf und zu. Das ersetzt den vorherigen
|
||||||
|
Sammelknopf ("5 weitere zeigen") -- zwei Mechanismen nebeneinander,
|
||||||
|
die dasselbe verstecken, wären eine Einladung zum Missverständnis.
|
||||||
|
|
||||||
|
Die Überschrift mit der ANZAHL bleibt immer stehen, auch zugeklappt.
|
||||||
|
Das ist der entscheidende Unterschied zum Ausblenden: Man sieht
|
||||||
|
jederzeit, dass es vier Manager gibt -- man sieht nur nicht, welche.
|
||||||
|
Wer eine ganze Rolle spurlos verschwinden lässt, hält sie irgendwann
|
||||||
|
für leer.
|
||||||
|
|
||||||
|
Voreinstellung: DogFather offen, alles andere zu. */
|
||||||
|
const SPEICHER = 'dfw_personen_offen';
|
||||||
let alle = [];
|
let alle = [];
|
||||||
let alleZeigen = false;
|
let offen = new Set(['admin']);
|
||||||
try { alleZeigen = localStorage.getItem(SPEICHER) === 'ja'; } catch { /* egal */ }
|
try {
|
||||||
|
const g = JSON.parse(localStorage.getItem(SPEICHER) || 'null');
|
||||||
|
if (Array.isArray(g)) offen = new Set(g);
|
||||||
|
} catch { /* kaputt gespeichert = Voreinstellung */ }
|
||||||
|
|
||||||
|
function offenMerken() {
|
||||||
|
try { localStorage.setItem(SPEICHER, JSON.stringify([...offen])); } catch { /* egal */ }
|
||||||
|
}
|
||||||
|
|
||||||
/* Jede Rolle bekommt einen eigenen Abschnitt, in der Reihenfolge der
|
/* Jede Rolle bekommt einen eigenen Abschnitt, in der Reihenfolge der
|
||||||
ZUGANGSSEITE: DogFather, Manager, Scout, Creator. Die Zusatztexte
|
ZUGANGSSEITE: DogFather, Manager, Scout, Creator. Die Zusatztexte
|
||||||
@@ -342,53 +365,77 @@
|
|||||||
const ziel = $('liste');
|
const ziel = $('liste');
|
||||||
ziel.textContent = '';
|
ziel.textContent = '';
|
||||||
|
|
||||||
const oben = alle.filter((p) => p.rolle === 'admin');
|
const vorhanden = ROLLEN_ABSCHNITTE
|
||||||
const rest = alle.filter((p) => p.rolle !== 'admin');
|
.map((a) => ({ ...a, drin: alle.filter((p) => p.rolle === a.rolle) }))
|
||||||
const sichtbar = alleZeigen ? alle : oben;
|
.filter((a) => a.drin.length);
|
||||||
|
|
||||||
for (const abschnitt of ROLLEN_ABSCHNITTE) {
|
|
||||||
const drin = sichtbar.filter((p) => p.rolle === abschnitt.rolle);
|
|
||||||
if (!drin.length) continue;
|
|
||||||
|
|
||||||
|
for (const abschnitt of vorhanden) {
|
||||||
|
const auf = offen.has(abschnitt.rolle);
|
||||||
const block = document.createElement('section');
|
const block = document.createElement('section');
|
||||||
block.className = 'gruppe';
|
block.className = 'gruppe';
|
||||||
const kopf = document.createElement('div');
|
|
||||||
kopf.className = 'gruppe__kopf';
|
/* Die Überschrift IST der Knopf. Ein eigener kleiner Schalter
|
||||||
|
daneben wäre ein zweites Ziel für dieselbe Absicht -- und ein
|
||||||
|
kleineres. Als <button> statt <div> mit Klick-Zuhörer, damit
|
||||||
|
Tastatur und Vorleseprogramme es ohne Zutun richtig machen. */
|
||||||
|
const kopf = document.createElement('button');
|
||||||
|
kopf.type = 'button';
|
||||||
|
kopf.className = 'gruppe__kopf gruppe__kopf--klappbar';
|
||||||
|
kopf.setAttribute('aria-expanded', auf ? 'true' : 'false');
|
||||||
|
|
||||||
const h = document.createElement('h2');
|
const h = document.createElement('h2');
|
||||||
h.className = 'gruppe__name';
|
h.className = 'gruppe__name';
|
||||||
h.textContent = abschnitt.name;
|
h.textContent = abschnitt.name;
|
||||||
|
|
||||||
const zahl = document.createElement('span');
|
const zahl = document.createElement('span');
|
||||||
zahl.className = 'gruppe__zahl';
|
zahl.className = 'gruppe__zahl';
|
||||||
zahl.textContent = String(drin.length);
|
zahl.textContent = String(abschnitt.drin.length);
|
||||||
|
|
||||||
const unter = document.createElement('span');
|
const unter = document.createElement('span');
|
||||||
unter.className = 'gruppe__unter';
|
unter.className = 'gruppe__unter';
|
||||||
unter.textContent = abschnitt.unter;
|
/* Zugeklappt zählt der Zusatztext weniger als die Frage "ist da
|
||||||
kopf.append(h, zahl, unter);
|
etwas Gesperrtes drin, das ich sehen müsste?". */
|
||||||
|
const gesperrt = abschnitt.drin.filter((p) => !p.aktiv).length;
|
||||||
|
unter.textContent = gesperrt
|
||||||
|
? `${abschnitt.unter} · ${gesperrt} gesperrt`
|
||||||
|
: abschnitt.unter;
|
||||||
|
if (gesperrt) unter.dataset.warn = 'ja';
|
||||||
|
|
||||||
|
const pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
|
pfeil.setAttribute('viewBox', '0 0 24 24');
|
||||||
|
pfeil.setAttribute('aria-hidden', 'true');
|
||||||
|
pfeil.setAttribute('class', 'klapp-pfeil');
|
||||||
|
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(h, zahl, unter, pfeil);
|
||||||
|
kopf.addEventListener('click', () => {
|
||||||
|
if (offen.has(abschnitt.rolle)) offen.delete(abschnitt.rolle);
|
||||||
|
else offen.add(abschnitt.rolle);
|
||||||
|
offenMerken();
|
||||||
|
listeZeigen();
|
||||||
|
});
|
||||||
block.append(kopf);
|
block.append(kopf);
|
||||||
|
|
||||||
for (const p of drin) block.append(zeile(p));
|
if (auf) for (const p of abschnitt.drin) block.append(zeile(p));
|
||||||
ziel.append(block);
|
ziel.append(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ein Knopf für alle auf einmal -- bei vier Rollen viermal klicken zu
|
||||||
|
müssen, nur um einmal alles zu sehen, wäre unnötige Arbeit. */
|
||||||
const schalter = $('rest-schalter');
|
const schalter = $('rest-schalter');
|
||||||
schalter.hidden = rest.length === 0;
|
schalter.hidden = vorhanden.length < 2;
|
||||||
if (!rest.length) return;
|
const alleOffen = vorhanden.every((a) => offen.has(a.rolle));
|
||||||
|
$('rest-schalter-text').textContent = alleOffen ? 'Alle zuklappen' : 'Alle aufklappen';
|
||||||
/* Die Zahl gehört auf den Knopf, nicht nur der Zustand. "Alle
|
schalter.setAttribute('aria-expanded', alleOffen ? 'true' : 'false');
|
||||||
zeigen" sagt nicht, wie viele man gerade nicht sieht. */
|
schalter.onclick = () => {
|
||||||
const gesperrt = rest.filter((p) => !p.aktiv).length;
|
if (alleOffen) offen.clear();
|
||||||
$('rest-schalter-text').textContent = alleZeigen
|
else for (const a of vorhanden) offen.add(a.rolle);
|
||||||
? 'Nur DogFather zeigen'
|
offenMerken();
|
||||||
: `${rest.length} weitere zeigen`
|
|
||||||
+ (gesperrt ? ` · ${gesperrt} gesperrt` : '');
|
|
||||||
schalter.setAttribute('aria-expanded', alleZeigen ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
|
|
||||||
$('rest-schalter').addEventListener('click', () => {
|
|
||||||
alleZeigen = !alleZeigen;
|
|
||||||
try { localStorage.setItem(SPEICHER, alleZeigen ? 'ja' : 'nein'); } catch { /* egal */ }
|
|
||||||
listeZeigen();
|
listeZeigen();
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function laden() {
|
async function laden() {
|
||||||
const ziel = $('liste');
|
const ziel = $('liste');
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -134,8 +134,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/aufgaben.js?v=202608312313" defer></script>
|
<script src="assets/js/aufgaben.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/automation.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/automation.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -127,8 +127,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/automation.js?v=202608312313" defer></script>
|
<script src="assets/js/automation.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -98,8 +98,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/bereich.js?v=202608312313" defer></script>
|
<script src="assets/js/bereich.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/calls.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/calls.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -49,9 +49,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/calls.js?v=202608312313" defer></script>
|
<script src="assets/js/calls.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/content.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/content.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -153,8 +153,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/content.js?v=202608312313" defer></script>
|
<script src="assets/js/content.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/dateien.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -88,8 +88,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/dateien.js?v=202608312313" defer></script>
|
<script src="assets/js/dateien.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
type="image/webp" media="(max-width: 899px)" />
|
type="image/webp" media="(max-width: 899px)" />
|
||||||
|
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate">
|
<body class="gate">
|
||||||
@@ -143,6 +143,6 @@
|
|||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202608312313" defer></script>
|
<script src="assets/js/gate.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/kalender.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -94,8 +94,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kalender.js?v=202608312313" defer></script>
|
<script src="assets/js/kalender.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/personen.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/personen.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -116,8 +116,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/personen.js?v=202608312313" defer></script>
|
<script src="assets/js/personen.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -127,8 +127,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/profil.js?v=202608312313" defer></script>
|
<script src="assets/js/profil.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/report.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/report.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -86,9 +86,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/report.js?v=202608312313" defer></script>
|
<script src="assets/js/report.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/scouting.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -124,8 +124,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/scouting.js?v=202608312313" defer></script>
|
<script src="assets/js/scouting.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -68,8 +68,8 @@
|
|||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/start.js?v=202608312313" defer></script>
|
<script src="assets/js/start.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/startcheck.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -65,9 +65,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/startcheck.js?v=202608312313" defer></script>
|
<script src="assets/js/startcheck.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/uebersicht.js?v=202608312313" defer></script>
|
<script src="assets/js/uebersicht.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<meta name="theme-color" content="#05070d" />
|
<meta name="theme-color" content="#05070d" />
|
||||||
<link rel="icon" href="assets/img/favicon.png" />
|
<link rel="icon" href="assets/img/favicon.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202608312313" />
|
<link rel="stylesheet" href="assets/css/wissen.css?v=202608312317" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -170,8 +170,8 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||||
<script src="assets/js/wissen.js?v=202608312313" defer></script>
|
<script src="assets/js/wissen.js?v=202608312317" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user