Spicy sieht DogFathers Sachen nicht mehr -- und sechs Fehler dazu
VIER DINGE AUS DEN BILDSCHIRMFOTOS, jedes ein echter Fehler:
1. SPICY MEDIA SAH DOGFATHERS DATEN. Beim ersten Anlauf bekam die Rolle
dieselbe Regel wie DogFather (`1=1`) -- damit stimmte der Ueberblick
ueber Manager, Scouts und Creator, und nebenbei standen seine eigenen
Termine, Aufgaben, Dateien und Eintraege mit drin. Jetzt gibt es
ohneDogFather() als EINE Stelle dafuer: Zwei Spalten werden geprueft,
`creator_id` (um wen geht es) und `erstellt_von` (wer hat es
geschrieben) -- ein Termin, den er sich selbst anlegt, haengt nur an
der zweiten. `IS NULL OR NOT IN` und nicht bloss `NOT IN`: In SQL ist
`NULL NOT IN (...)` weder wahr noch falsch, die Zeile fiele
stillschweigend heraus.
2. "PERSOENLICHER ZUGANGSCODE · undefined" auf der Anmeldeseite. Eine
zweite Namensliste im Browser, die beim Hinzufuegen der Rolle
niemand gepflegt hat. Ein unbekannter Schluessel faellt jetzt auf
sich selbst zurueck statt auf `undefined` -- haesslich, aber
sichtbar.
3. SPICY KAM NICHT IN DIE PERSONENVERWALTUNG. Der Server liess sie
herein, das Skript warf sie wieder hinaus: zwei Listen fuer dieselbe
Frage, gepflegt wurde nur die erste.
4. DIE ANMELDEKARTE WAR ZU KLEIN FUER FUENF ROLLEN. Der Kommentar an
genau dieser Stelle warnt woertlich davor -- und ich habe getan,
wovor er warnt: eine Rolle eingefuegt und die Zahl daneben nicht
angefasst. Gemessen: Inhalt 573 px in einer 526 px hohen Tafel, die
Fusszeile stand unter dem Rahmen. Schrift kleiner half nicht (sie lag
schon auf dem Anschlag), also sind die Abstaende an neun Stellen
enger. Nachgemessen auf fuenf Groessen: passt ueberall.
DIE ZEIT WAR WIRKLICH FALSCH. Nicht nur in meinem Satz: `datum()` in
personen.js schnitt die ISO-Zeichenkette ab -- und die ist UTC. Im
Protokoll stand 03:00, wo 05:00 war. Das Tueckische daran ist, dass es
nie kaputt aussieht: Eine Uhrzeit ist immer plausibel.
PROFILBILDER WERDEN JETZT GEZEICHNET. Der Server lieferte sie seit
gestern mit, gezeichnet wurden sie nirgends -- deshalb aenderte sich
nichts. Jetzt in der Personenauswahl (Aufgaben, Termine, Dateien,
Bereiche), in der Gespraechsliste und an jeder Nachricht. Der
Anfangsbuchstabe bleibt als Unterlage LIEGEN: Faellt das Bild aus, steht
dort weiter etwas Sinnvolles.
DER CHAT: Gesichter mit Rollenfarbe, Blasen mit Richtung (die erste
einer Folge eckig, die naechsten rund -- so sieht man, wo ein Gedanke
anfaengt), das offene Gespraech mit Schiene, Ungelesenes hervorgehoben,
und das Eingabefeld in einer eigenen Leiste, die sich beim Schreiben
hebt.
ZWEI EIGENE PATZER, beide von Pruefungen gefunden:
- `o is not defined`: Mein Suchmuster hat die zwei Zeilen fuer das
Bild ans DATEIENDE gesetzt statt in die Schleife -- und in
kalender.js an einen <span> statt ans <option>. Gemeldet von
pruef-sicht, das die Browserkonsole mitliest.
- Ein Kommentar mit `bild` in schraegen Anfuehrungszeichen stand INNEN
in einer Vorlagenzeichenkette und hat sie geschlossen. Die halbe SQL
wurde zu Programmtext.
Dazu: `.chat-neu` gibt es nicht (heisst `.chat__eingabe`), und der
Rollenknopf hatte fuer den Manager keinen sichtbaren Fokus -- ein
box-shadow wird von `overflow: hidden` abgeschnitten, ein outline nicht.
Gruen: spicy (43), creator-anlegen (29), personen-liste (33), sicht (48),
chat (48), chat-optik (24), buehne (38), struktur (32), css-klassen (15),
handy (59), breiten (23), formulare (19), start-ansicht (136),
lesbarkeit (14), barrierefrei (18), tempo (8), kopf-messen (3),
glocke (26), haerte (20), manager-sicht (43), alle-wege (19),
aufgabenbrett (44), kalender (84).
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -326,6 +326,70 @@ const ruf = async (art, weg, keks, koerper) => {
|
|||||||
ok(rein.status === 403 || rein.status === 404,
|
ok(rein.status === 403 || rein.status === 404,
|
||||||
`und kommt auch mit der Raumnummer nicht hinein (HTTP ${rein.status})`);
|
`und kommt auch mit der Raumnummer nicht hinein (HTTP ${rein.status})`);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
/* ===================================================================
|
||||||
|
WAS DOGFATHER GEHOERT, SIEHT SPICY MEDIA NICHT (07.09.2026)
|
||||||
|
|
||||||
|
Filipe: "wieso sieht die spicy rolle meine daten die ich habe und
|
||||||
|
speichere, meins sollen die nicht sehen von der rolle dogfather."
|
||||||
|
|
||||||
|
Beim ersten Anlauf bekam Spicy Media dieselbe Regel wie DogFather
|
||||||
|
(`1=1`) -- damit stimmte der Ueberblick und nebenbei standen seine
|
||||||
|
eigenen Termine, Aufgaben, Dateien und Eintraege mit drin.
|
||||||
|
|
||||||
|
Geprueft wird mit ZWEI Datensaetzen je Art: einem von DogFather und
|
||||||
|
einem von Max. Mit nur einem waere jedes Ergebnis mehrdeutig -- eine
|
||||||
|
leere Liste koennte auch heissen, dass die Regel ALLES ausblendet.
|
||||||
|
Genau das ist der Unterschied zwischen "sieht das Richtige nicht"
|
||||||
|
und "sieht gar nichts". */
|
||||||
|
/* ORTSZEIT, nicht UTC. `toISOString().slice(0,10)` liegt zwischen
|
||||||
|
Mitternacht und zwei Uhr einen Tag daneben -- die Pruefung waere
|
||||||
|
dann nachts rot, ohne dass sich etwas geaendert haette. Gefunden
|
||||||
|
von pruef-struktur, das genau danach sucht. */
|
||||||
|
const jetztHier = new Date();
|
||||||
|
const zz = (n) => String(n).padStart(2, "0");
|
||||||
|
const heute = `${jetztHier.getFullYear()}-${zz(jetztHier.getMonth() + 1)}-${zz(jetztHier.getDate())}`;
|
||||||
|
await ruf("POST", "/workspace/api/bereich/technik", keksDogi,
|
||||||
|
{ art: "problem", titel: "DogFathers Notiz", datum: heute });
|
||||||
|
await ruf("POST", "/workspace/api/bereich/technik", keksMax,
|
||||||
|
{ art: "problem", titel: "Max seine Notiz", datum: heute, creator_id: idLuna });
|
||||||
|
|
||||||
|
const { daten } = await ruf("GET", "/workspace/api/bereich/technik", keksSpicy);
|
||||||
|
const titel = (daten?.eintraege || []).map((e) => e.titel);
|
||||||
|
ok(!titel.includes("DogFathers Notiz"),
|
||||||
|
`DogFathers Eintrag ist fuer Spicy Media unsichtbar (sie sieht: ${titel.join(", ") || "nichts"})`);
|
||||||
|
ok(titel.includes("Max seine Notiz"),
|
||||||
|
"Max seiner steht aber da -- die Regel blendet nicht einfach alles aus");
|
||||||
|
|
||||||
|
/* Dasselbe fuer Aufgaben und Termine -- drei Module, drei Wege, und
|
||||||
|
jeder haette einzeln vergessen werden koennen. */
|
||||||
|
await ruf("POST", "/workspace/api/aufgaben", keksDogi, { titel: "DogFathers Aufgabe" });
|
||||||
|
await ruf("POST", "/workspace/api/aufgaben", keksMax,
|
||||||
|
{ titel: "Max seine Aufgabe", creator_id: idLuna });
|
||||||
|
const auf = await ruf("GET", "/workspace/api/aufgaben", keksSpicy);
|
||||||
|
const aTitel = (auf.daten?.aufgaben || []).map((a) => a.titel);
|
||||||
|
ok(!aTitel.includes("DogFathers Aufgabe"),
|
||||||
|
`auch seine Aufgabe nicht (sie sieht: ${aTitel.join(", ") || "nichts"})`);
|
||||||
|
ok(aTitel.includes("Max seine Aufgabe"), "Max seine schon");
|
||||||
|
|
||||||
|
await ruf("POST", "/workspace/api/termine", keksDogi,
|
||||||
|
{ titel: "DogFathers Termin", art: "termin", beginn: heute + "T20:00", dauer_min: 30 });
|
||||||
|
await ruf("POST", "/workspace/api/termine", keksMax,
|
||||||
|
{ titel: "Max sein Termin", art: "termin", beginn: heute + "T21:00", dauer_min: 30,
|
||||||
|
creator_id: idLuna });
|
||||||
|
const term = await ruf("GET", `/workspace/api/termine?von=${heute}&bis=${heute}`, keksSpicy);
|
||||||
|
const tTitel = (term.daten?.termine || []).map((t) => t.titel);
|
||||||
|
ok(!tTitel.includes("DogFathers Termin"),
|
||||||
|
`und seinen Termin nicht (sie sieht: ${tTitel.join(", ") || "nichts"})`);
|
||||||
|
ok(tTitel.includes("Max sein Termin"), "Max seinen schon");
|
||||||
|
|
||||||
|
/* GEGENPROBE: DogFather selbst sieht weiterhin BEIDE. Ohne sie
|
||||||
|
bewiesen die Zeilen oben nur, dass irgendetwas gefiltert wird. */
|
||||||
|
const beiDogi = await ruf("GET", "/workspace/api/bereich/technik", keksDogi);
|
||||||
|
const dTitel = (beiDogi.daten?.eintraege || []).map((e) => e.titel);
|
||||||
|
ok(dTitel.includes("DogFathers Notiz") && dTitel.includes("Max seine Notiz"),
|
||||||
|
`DogFather sieht weiterhin beide (${dTitel.length})`);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
/* Und DogFather bleibt der Einzige mit dem letzten Wort. */
|
/* Und DogFather bleibt der Einzige mit dem letzten Wort. */
|
||||||
const { status } = await ruf("GET", "/workspace/api/verwaltung/personen", keksDogi);
|
const { status } = await ruf("GET", "/workspace/api/verwaltung/personen", keksDogi);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import {
|
import {
|
||||||
db, protokolliere, echteIp, sitzungLesen, betreutWo, istLeitung, heuteLokal, ROLLEN_SORTIERUNG, betreuteIds,
|
db, protokolliere, echteIp, sitzungLesen, betreutWo, istLeitung, ohneDogFather, heuteLokal, ROLLEN_SORTIERUNG, betreuteIds,
|
||||||
externPruefen, externSql, sichtbarePersonenIds, sichtbareCreatorIds,
|
externPruefen, externSql, sichtbarePersonenIds, sichtbareCreatorIds,
|
||||||
} from "./workspace.js";
|
} from "./workspace.js";
|
||||||
|
|
||||||
@@ -58,6 +58,13 @@ export function sichtbar(person) {
|
|||||||
(01.09.2026) -- und ausdruecklich NUR er. */
|
(01.09.2026) -- und ausdruecklich NUR er. */
|
||||||
case "admin":
|
case "admin":
|
||||||
return { wo: "1=1", werte: [] };
|
return { wo: "1=1", werte: [] };
|
||||||
|
/* SPICY MEDIA sieht alles ausser dem, was DogFather gehoert
|
||||||
|
(07.09.2026). Die Bedingung kommt aus workspace.js -- eine
|
||||||
|
abgeschriebene Fassung waere die Stelle, an der es beim naechsten
|
||||||
|
Umbau wieder durchsickert. */
|
||||||
|
case "spicy":
|
||||||
|
return { wo: ohneDogFather("a", ["creator_id", "verantwortlich_id", "erstellt_von"]),
|
||||||
|
werte: [] };
|
||||||
case "creator":
|
case "creator":
|
||||||
return {
|
return {
|
||||||
wo: "(a.creator_id = ? OR a.verantwortlich_id = ? OR a.erstellt_von = ?)",
|
wo: "(a.creator_id = ? OR a.verantwortlich_id = ? OR a.erstellt_von = ?)",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import {
|
import {
|
||||||
db, protokolliere, echteIp, sitzungLesen, betreutWo, darfCreator, betreuteIds, istLeitung, istDogFather, siehtAlles,
|
db, protokolliere, echteIp, sitzungLesen, betreutWo, darfCreator, betreuteIds, istLeitung, istDogFather, siehtAlles, istSpicy, ohneDogFather,
|
||||||
externPruefen, externSql,
|
externPruefen, externSql,
|
||||||
} from "./workspace.js";
|
} from "./workspace.js";
|
||||||
|
|
||||||
@@ -262,6 +262,7 @@ export function sichtbar(person) {
|
|||||||
darf (freigeben, aendern, Personen verwalten), haengt weiterhin an
|
darf (freigeben, aendern, Personen verwalten), haengt weiterhin an
|
||||||
istLeitung und bleibt unveraendert -- sonst haette dieser eine
|
istLeitung und bleibt unveraendert -- sonst haette dieser eine
|
||||||
Wunsch stillschweigend seine halben Rechte mitgenommen. */
|
Wunsch stillschweigend seine halben Rechte mitgenommen. */
|
||||||
|
if (istSpicy(person)) return { wo: ohneDogFather("e"), werte: [] };
|
||||||
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
||||||
|
|
||||||
/* "ODER ich habe ihn selbst angelegt" kam am 02.09.2026 dazu -- aus
|
/* "ODER ich habe ihn selbst angelegt" kam am 02.09.2026 dazu -- aus
|
||||||
|
|||||||
@@ -88,13 +88,27 @@ function istDrin(raumId, personId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Alle (noch aktiven) Teilnehmer eines Raums. */
|
/** Alle (noch aktiven) Teilnehmer eines Raums. */
|
||||||
|
/* Das Profilbild gehoert dazu (07.09.2026). Ohne es zeigt die
|
||||||
|
Gespraechsliste Initialen, obwohl ein Bild hochgeladen ist -- der
|
||||||
|
Fehler liegt dann nicht in der Anzeige, sondern in der Abfrage. Die
|
||||||
|
fertige ADRESSE wird danach gebaut, nicht der Dateiname
|
||||||
|
weitergereicht: Sonst setzt jede Stelle im Browser denselben Pfad
|
||||||
|
zusammen.
|
||||||
|
|
||||||
|
UND DER KOMMENTAR STEHT AUSSERHALB DER ABFRAGE. Beim ersten Anlauf
|
||||||
|
stand er darin -- mit dem Wort `bild` in schraegen Anfuehrungszeichen.
|
||||||
|
Die beenden in JavaScript eine Vorlagenzeichenkette; die halbe SQL
|
||||||
|
wurde damit zu Programmtext, und die Datei liess sich nicht mehr
|
||||||
|
lesen. Ein Kommentar, der die Zeichenkette schliesst, in der er
|
||||||
|
steht. */
|
||||||
function teilnehmerVon(raumId) {
|
function teilnehmerVon(raumId) {
|
||||||
return db().prepare(`
|
return db().prepare(`
|
||||||
SELECT t.person_id AS id, p.name, p.rolle, t.leitung, t.gelesen_bis
|
SELECT t.person_id AS id, p.name, p.rolle, p.bild, t.leitung, t.gelesen_bis
|
||||||
FROM chat_teilnehmer t
|
FROM chat_teilnehmer t
|
||||||
JOIN personen p ON p.id = t.person_id
|
JOIN personen p ON p.id = t.person_id
|
||||||
WHERE t.raum_id = ? AND t.raus_am IS NULL
|
WHERE t.raum_id = ? AND t.raus_am IS NULL
|
||||||
ORDER BY ` + ROLLEN_SORTIERUNG + ", p.name").all(raumId);
|
ORDER BY ` + ROLLEN_SORTIERUNG + ", p.name").all(raumId)
|
||||||
|
.map((z) => ({ ...z, bild: z.bild ? `/workspace/api/steckbrief/bild/${z.bild}` : null }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Findet das Zweier-Gespräch der beiden -- oder legt es an.
|
/** Findet das Zweier-Gespräch der beiden -- oder legt es an.
|
||||||
@@ -287,7 +301,8 @@ chatRouter.get("/workspace/api/chat/raeume/:id/nachrichten", (req, res) => {
|
|||||||
über `vor`. */
|
über `vor`. */
|
||||||
const vor = Number(req.query.vor) || 0;
|
const vor = Number(req.query.vor) || 0;
|
||||||
const reihen = db().prepare(`
|
const reihen = db().prepare(`
|
||||||
SELECT n.id, n.person_id, n.text, n.erstellt, n.weg_am, p.name AS von, p.rolle
|
SELECT n.id, n.person_id, n.text, n.erstellt, n.weg_am, p.name AS von, p.rolle,
|
||||||
|
p.bild AS von_bild
|
||||||
FROM chat_nachrichten n
|
FROM chat_nachrichten n
|
||||||
LEFT JOIN personen p ON p.id = n.person_id
|
LEFT JOIN personen p ON p.id = n.person_id
|
||||||
WHERE n.raum_id = ? ${vor ? "AND n.id < ?" : ""}
|
WHERE n.raum_id = ? ${vor ? "AND n.id < ?" : ""}
|
||||||
@@ -300,11 +315,13 @@ chatRouter.get("/workspace/api/chat/raeume/:id/nachrichten", (req, res) => {
|
|||||||
raum: {
|
raum: {
|
||||||
id: raum.id, art: raum.art,
|
id: raum.id, art: raum.art,
|
||||||
name: raumName(raum, leute, req.person.id),
|
name: raumName(raum, leute, req.person.id),
|
||||||
teilnehmer: leute.map((t) => ({ id: t.id, name: t.name, rolle: t.rolle, leitung: !!t.leitung })),
|
teilnehmer: leute.map((t) => ({ id: t.id, name: t.name, rolle: t.rolle,
|
||||||
|
bild: t.bild, leitung: !!t.leitung })),
|
||||||
},
|
},
|
||||||
/* Aufsteigend zurück -- gelesen wird von oben nach unten. */
|
/* Aufsteigend zurück -- gelesen wird von oben nach unten. */
|
||||||
nachrichten: reihen.reverse().map((n) => ({
|
nachrichten: reihen.reverse().map((n) => ({
|
||||||
id: n.id, von_id: n.person_id, von: n.von || "Gelöscht", rolle: n.rolle,
|
id: n.id, von_id: n.person_id, von: n.von || "Gelöscht", rolle: n.rolle,
|
||||||
|
von_bild: n.von_bild ? `/workspace/api/steckbrief/bild/${n.von_bild}` : null,
|
||||||
text: n.weg_am ? null : n.text,
|
text: n.weg_am ? null : n.text,
|
||||||
zurueckgenommen: !!n.weg_am,
|
zurueckgenommen: !!n.weg_am,
|
||||||
erstellt: n.erstellt,
|
erstellt: n.erstellt,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import { randomBytes } from "node:crypto";
|
|||||||
import { join, extname, basename } from "node:path";
|
import { join, extname, basename } from "node:path";
|
||||||
import { mkdirSync, createReadStream, writeFileSync, unlinkSync, statSync } from "node:fs";
|
import { mkdirSync, createReadStream, writeFileSync, unlinkSync, statSync } from "node:fs";
|
||||||
import {
|
import {
|
||||||
db, protokolliere, echteIp, sitzungLesen, DATEN_ORDNER, betreutWo, darfCreator, betreuteIds, istLeitung, istDogFather, siehtAlles, ROLLEN_SORTIERUNG,
|
db, protokolliere, echteIp, sitzungLesen, DATEN_ORDNER, betreutWo, darfCreator, betreuteIds, istLeitung, istDogFather, siehtAlles, istSpicy, ohneDogFather, ROLLEN_SORTIERUNG,
|
||||||
externSql, EXTERN_MAX, sichtbarePersonenIds,
|
externSql, EXTERN_MAX, sichtbarePersonenIds,
|
||||||
} from "./workspace.js";
|
} from "./workspace.js";
|
||||||
|
|
||||||
@@ -79,6 +79,7 @@ export function sichtbar(person) {
|
|||||||
darf (freigeben, aendern, Personen verwalten), haengt weiterhin an
|
darf (freigeben, aendern, Personen verwalten), haengt weiterhin an
|
||||||
istLeitung und bleibt unveraendert -- sonst haette dieser eine
|
istLeitung und bleibt unveraendert -- sonst haette dieser eine
|
||||||
Wunsch stillschweigend seine halben Rechte mitgenommen. */
|
Wunsch stillschweigend seine halben Rechte mitgenommen. */
|
||||||
|
if (istSpicy(person)) return { wo: ohneDogFather("d", ["creator_id", "hochgeladen_von"]), werte: [] };
|
||||||
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
||||||
|
|
||||||
/* Ausdrueckliche Freigabe -- gilt fuer jede Rolle gleich. Wer in der
|
/* Ausdrueckliche Freigabe -- gilt fuer jede Rolle gleich. Wer in der
|
||||||
|
|||||||
@@ -112,6 +112,44 @@ export const istDogFather = (person) => !!person && person.rolle === "admin";
|
|||||||
gar keinen Weg gibt -- nicht, weil eine Abfrage es verbietet.
|
gar keinen Weg gibt -- nicht, weil eine Abfrage es verbietet.
|
||||||
======================================================================= */
|
======================================================================= */
|
||||||
export const istSpicy = (person) => !!person && person.rolle === "spicy";
|
export const istSpicy = (person) => !!person && person.rolle === "spicy";
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
SPICY MEDIA SIEHT ALLES -- AUSSER DEM, WAS DOGFATHER GEHOERT
|
||||||
|
(07.09.2026, Nachtrag am selben Tag)
|
||||||
|
|
||||||
|
Filipe: "wieso sieht die spicy rolle meine daten die ich habe und
|
||||||
|
speichere, meins sollen die nicht sehen von der rolle dogfather."
|
||||||
|
|
||||||
|
Beim ersten Anlauf bekam Spicy Media dieselbe Regel wie DogFather:
|
||||||
|
`1=1`. Damit stimmte der Ueberblick ueber Manager, Scouts und Creator
|
||||||
|
-- und nebenbei standen DogFathers eigene Termine, Aufgaben, Dateien
|
||||||
|
und Eintraege mit drin. Der Chat war ausgenommen (er haengt an der
|
||||||
|
Teilnehmerliste), alles andere nicht.
|
||||||
|
|
||||||
|
DIESE FUNKTION IST DIE EINE STELLE DAFUER. Sie baut die Bedingung
|
||||||
|
"gehoert keinem DogFather" fuer eine beliebige Tabelle. Jede
|
||||||
|
Sichtbarkeitsregel im Haus benutzt sie -- eine zweite, abgeschriebene
|
||||||
|
Fassung waere die Stelle, an der es beim naechsten Modul wieder
|
||||||
|
durchsickert.
|
||||||
|
|
||||||
|
ZWEI SPALTEN, NICHT EINE. `creator_id` sagt, UM WEN es geht;
|
||||||
|
`erstellt_von` sagt, WER es geschrieben hat. Beide muessen gepruegt
|
||||||
|
werden: Ein Termin, den DogFather fuer sich selbst anlegt, hat
|
||||||
|
moeglicherweise gar keine creator_id -- er haenge dann nur an
|
||||||
|
erstellt_von. Und eine Akte UEBER einen DogFather traegt seine
|
||||||
|
creator_id, auch wenn ein Manager sie geschrieben hat.
|
||||||
|
|
||||||
|
`IS NULL OR NOT IN` und nicht bloss `NOT IN`: In SQL ist
|
||||||
|
`NULL NOT IN (...)` weder wahr noch falsch, sondern NULL -- die Zeile
|
||||||
|
fiele stillschweigend heraus. Genau so verschwinden Daten, ohne dass
|
||||||
|
jemand einen Fehler sieht.
|
||||||
|
======================================================================= */
|
||||||
|
export function ohneDogFather(praefix, spalten = ["creator_id", "erstellt_von"]) {
|
||||||
|
return spalten
|
||||||
|
.map((sp) => `(${praefix}.${sp} IS NULL OR ${praefix}.${sp} NOT IN `
|
||||||
|
+ `(SELECT id FROM personen WHERE rolle = 'admin'))`)
|
||||||
|
.join(" AND ");
|
||||||
|
}
|
||||||
export const siehtAlles = (person) => !!person
|
export const siehtAlles = (person) => !!person
|
||||||
&& (person.rolle === "admin" || person.rolle === "spicy");
|
&& (person.rolle === "admin" || person.rolle === "spicy");
|
||||||
|
|
||||||
@@ -2329,6 +2367,7 @@ export const externSql = (personSpalte, externSpalte) =>
|
|||||||
spaeter auseinandergelaufen -- und dann haette eine Wiederholung
|
spaeter auseinandergelaufen -- und dann haette eine Wiederholung
|
||||||
jemandem etwas gezeigt, was der einzelne Termin ihm verbirgt. */
|
jemandem etwas gezeigt, was der einzelne Termin ihm verbirgt. */
|
||||||
export function termineSichtbar(person, praefix = "t") {
|
export function termineSichtbar(person, praefix = "t") {
|
||||||
|
if (istSpicy(person)) return { wo: ohneDogFather(praefix), werte: [] };
|
||||||
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
if (siehtAlles(person)) return { wo: "1=1", werte: [] };
|
||||||
const p = praefix;
|
const p = praefix;
|
||||||
|
|
||||||
|
|||||||
@@ -480,3 +480,159 @@
|
|||||||
.chat-tag::before, .chat-tag::after { background: CanvasText; }
|
.chat-tag::before, .chat-tag::after { background: CanvasText; }
|
||||||
.chat__verlauf { mask-image: none; }
|
.chat__verlauf { mask-image: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
DER CHAT (07.09.2026)
|
||||||
|
|
||||||
|
Wunsch Filipe: "mach die chat fenster auch viel geiler, viel
|
||||||
|
detaillierter und viel perfekter. ich will dass die leute auch bock
|
||||||
|
bekommen diesen chat zu benutzen."
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
WORAN MAN EINEN GUTEN CHAT ERKENNT
|
||||||
|
|
||||||
|
Nicht an Effekten. An vier Dingen, die alle mit ORIENTIERUNG zu tun
|
||||||
|
haben -- und alle vier fehlten:
|
||||||
|
|
||||||
|
1. MAN SIEHT, MIT WEM MAN SCHREIBT. Initialen sind ein Platzhalter,
|
||||||
|
kein Gesicht. Die Bilder liefert der Server seit heute mit; hier
|
||||||
|
werden sie gezeichnet -- rund, mit einem feinen Rand in der Farbe
|
||||||
|
der Rolle.
|
||||||
|
|
||||||
|
2. EINE NACHRICHT HAT EINE RICHTUNG. Eigene Nachrichten kommen von
|
||||||
|
rechts und tragen den Hausakzent, fremde von links und bleiben
|
||||||
|
neutral. Die Ecke am Anfang einer Folge ist eckig, die übrigen
|
||||||
|
rund -- so sieht man, wo ein Gedanke anfängt, ohne den Namen zu
|
||||||
|
lesen.
|
||||||
|
|
||||||
|
3. EIN GESPRÄCH HAT EIN GEWICHT. Ungelesenes ist nicht "auch da",
|
||||||
|
sondern das, weshalb man die Seite geöffnet hat: kräftigerer
|
||||||
|
Grund, farbige Schiene, die Zahl als Marke.
|
||||||
|
|
||||||
|
4. DAS EINGABEFELD IST DAS WICHTIGSTE ELEMENT DER SEITE. Es war
|
||||||
|
eines von vielen. Jetzt sitzt es in einer eigenen Leiste, die
|
||||||
|
sich beim Hineinschreiben hebt.
|
||||||
|
|
||||||
|
Und was NICHT passiert ist: kein Blinken, kein Springen, keine
|
||||||
|
Verläufe im Text. Ein Chat wird stundenlang angesehen -- alles, was
|
||||||
|
einmal auffällt, nervt beim zwanzigsten Mal.
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
/* ---------- Das Gesicht ---------------------------------------------- */
|
||||||
|
.chat-raum__zeichen,
|
||||||
|
.chat-nachricht__zeichen {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(150deg,
|
||||||
|
color-mix(in srgb, var(--rton, var(--akzent)) 30%, rgba(20, 27, 40, .9)),
|
||||||
|
rgba(12, 17, 26, .95));
|
||||||
|
box-shadow:
|
||||||
|
inset 0 0 0 1px color-mix(in srgb, var(--rton, var(--akzent)) 38%, transparent),
|
||||||
|
0 2px 6px -3px rgba(0, 0, 0, .8);
|
||||||
|
}
|
||||||
|
/* Die Farbe der Rolle -- dieselbe Zuordnung wie überall im Haus. */
|
||||||
|
.chat-raum__zeichen[data-rolle="spicy"],
|
||||||
|
.chat-nachricht__zeichen[data-rolle="spicy"] { --rton: #e9848c; }
|
||||||
|
.chat-raum__zeichen[data-rolle="admin"],
|
||||||
|
.chat-nachricht__zeichen[data-rolle="admin"] { --rton: var(--k-gold); }
|
||||||
|
.chat-raum__zeichen[data-rolle="manager"],
|
||||||
|
.chat-nachricht__zeichen[data-rolle="manager"] { --rton: var(--k-mittel); }
|
||||||
|
.chat-raum__zeichen[data-rolle="scout"],
|
||||||
|
.chat-nachricht__zeichen[data-rolle="scout"] { --rton: var(--k-gut); }
|
||||||
|
.chat-raum__zeichen[data-rolle="creator"],
|
||||||
|
.chat-nachricht__zeichen[data-rolle="creator"] { --rton: var(--akzent); }
|
||||||
|
|
||||||
|
/* Das Bild liegt ÜBER dem Buchstaben, nicht an seiner Stelle. Fällt es
|
||||||
|
aus, steht der Buchstabe weiterhin da. */
|
||||||
|
.chat-raum__zeichen img,
|
||||||
|
.chat-nachricht__zeichen img {
|
||||||
|
position: absolute; inset: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Die Gesprächsliste --------------------------------------- */
|
||||||
|
.chat-raum__knopf {
|
||||||
|
position: relative;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin: 0 8px 4px;
|
||||||
|
transition: background var(--tempo), box-shadow var(--tempo);
|
||||||
|
}
|
||||||
|
/* Das offene Gespräch trägt eine Schiene -- man sieht auch beim Scrollen
|
||||||
|
der Liste, wo man gerade ist. */
|
||||||
|
.chat-raum__knopf[data-an="ja"] {
|
||||||
|
background: linear-gradient(90deg,
|
||||||
|
color-mix(in srgb, var(--akzent) 16%, transparent),
|
||||||
|
rgba(255, 255, 255, .03) 55%);
|
||||||
|
box-shadow: inset 3px 0 0 var(--akzent);
|
||||||
|
}
|
||||||
|
/* Ungelesenes ist der Grund, warum man hier ist. */
|
||||||
|
.chat-raum__knopf:has(.chat-raum__zahl) {
|
||||||
|
background: rgba(255, 255, 255, .045);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Die Nachrichten ------------------------------------------ */
|
||||||
|
.chat-nachricht__blase {
|
||||||
|
border-radius: 16px 16px 16px 5px;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, .06),
|
||||||
|
0 2px 6px -3px rgba(0, 0, 0, .55);
|
||||||
|
}
|
||||||
|
/* Die erste Blase einer Folge bekommt oben eine eckige Ecke -- dort
|
||||||
|
fängt der Gedanke an. Die folgenden sind rundum weich. */
|
||||||
|
.chat-nachricht[data-folge="ja"] .chat-nachricht__blase {
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
}
|
||||||
|
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase {
|
||||||
|
border-radius: 16px 16px 5px 16px;
|
||||||
|
background: linear-gradient(160deg,
|
||||||
|
color-mix(in srgb, var(--akzent) 26%, rgba(17, 24, 37, .95)),
|
||||||
|
color-mix(in srgb, var(--akzent) 12%, rgba(12, 17, 27, .95)));
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, .10),
|
||||||
|
0 2px 8px -3px color-mix(in srgb, var(--akzent) 45%, transparent);
|
||||||
|
}
|
||||||
|
.chat-nachricht[data-selbst="ja"][data-folge="ja"] .chat-nachricht__blase {
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
border-top-left-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Der Tagestrenner: eine Linie mit dem Datum darin statt eines Wortes
|
||||||
|
im Nichts. */
|
||||||
|
.chat-tag {
|
||||||
|
display: flex; align-items: center; gap: 12px;
|
||||||
|
margin: 18px 0 12px;
|
||||||
|
}
|
||||||
|
.chat-tag::before, .chat-tag::after {
|
||||||
|
content: ""; flex: 1 1 auto; height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(150, 186, 220, .18), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Das Eingabefeld ------------------------------------------ */
|
||||||
|
/* Es ist das wichtigste Element der Seite und sah aus wie eines von
|
||||||
|
vielen. Eine eigene Leiste, die sich beim Hineinschreiben hebt. */
|
||||||
|
/* Sie heisst .chat__eingabe (chat.html), nicht .chat-neu -- ich hatte
|
||||||
|
den Namen aus dem Kopf geschrieben. pruef-struktur meldete es als
|
||||||
|
totes CSS: eine Regel, die auf nichts zeigt, sieht aus wie erledigte
|
||||||
|
Arbeit und ist keine. */
|
||||||
|
.chat__eingabe {
|
||||||
|
position: relative;
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-top: 1px solid rgba(150, 186, 220, .12);
|
||||||
|
background: linear-gradient(180deg, rgba(13, 18, 28, .6), rgba(9, 12, 20, .92));
|
||||||
|
transition: box-shadow var(--tempo);
|
||||||
|
}
|
||||||
|
.chat__eingabe:focus-within {
|
||||||
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--akzent) 34%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.chat-raum__knopf, .chat__eingabe { transition: none; }
|
||||||
|
}
|
||||||
|
@media (forced-colors: active) {
|
||||||
|
.chat-nachricht__blase,
|
||||||
|
.chat-raum__knopf[data-an="ja"] { box-shadow: none; border: 1px solid CanvasText; }
|
||||||
|
.chat-raum__zeichen, .chat-nachricht__zeichen { background: Canvas; box-shadow: none; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -1303,8 +1303,25 @@ body.gate {
|
|||||||
/* 1,50 statt 1,59: Bei 1280x800 ist die Tafel 512 px hoch, der
|
/* 1,50 statt 1,59: Bei 1280x800 ist die Tafel 512 px hoch, der
|
||||||
Karteninhalt bei 1,59 aber 536 -- gemessen, nicht geschaetzt.
|
Karteninhalt bei 1,59 aber 536 -- gemessen, nicht geschaetzt.
|
||||||
24 px Ueberstand sieht man an einem Neonrahmen sofort. */
|
24 px Ueberstand sieht man an einem Neonrahmen sofort. */
|
||||||
font-size: clamp(12px, 1.50cqh, 16px);
|
/* NACHGEMESSEN, WEIL EINE ROLLE DAZUKAM (07.09.2026).
|
||||||
padding: 1.75em 1.6em 1.4em;
|
|
||||||
|
Der Kommentar darueber warnt woertlich davor -- und ich habe
|
||||||
|
genau das gemacht, wovor er warnt: eine fuenfte Rolle eingefuegt
|
||||||
|
und die Zahl daneben nicht angefasst. Gemessen bei fuenf Rollen:
|
||||||
|
Der Inhalt war bei 1280x800 573 px hoch in einer 526 px hohen
|
||||||
|
Tafel, bei 1600x1000 712 in 658 -- die Fusszeile stand jedes Mal
|
||||||
|
unter dem Rahmen.
|
||||||
|
|
||||||
|
Die Schrift kleiner zu machen half nicht: Bei 1280 lag sie mit
|
||||||
|
12 px schon auf dem unteren Anschlag. Also sind die ABSTAENDE
|
||||||
|
enger geworden -- an neun Stellen ein bis zwei Zehntel, das
|
||||||
|
ergibt zusammen rund 4 em. Die Schrift bleibt lesbar, die Karte
|
||||||
|
passt wieder.
|
||||||
|
|
||||||
|
Wer eine SECHSTE Rolle einbaut, misst hier neu. Die Zahl gehoert
|
||||||
|
zu dem, was sie zaehlt. */
|
||||||
|
font-size: clamp(12px, 1.42cqh, 15.5px);
|
||||||
|
padding: 1.35em 1.5em 1.05em;
|
||||||
|
|
||||||
/* Die Tafel im Bild ist schon dunkel und hat ihren eigenen Rahmen.
|
/* Die Tafel im Bild ist schon dunkel und hat ihren eigenen Rahmen.
|
||||||
Die Karte legt sich deshalb NUR noch als leichter Schleier
|
Die Karte legt sich deshalb NUR noch als leichter Schleier
|
||||||
@@ -1326,21 +1343,21 @@ body.gate {
|
|||||||
weiterhin am Dokument orientieren und die Abstaende blieben stehen,
|
weiterhin am Dokument orientieren und die Abstaende blieben stehen,
|
||||||
waehrend die Schrift schrumpft. Genau daran erkennt man eine
|
waehrend die Schrift schrumpft. Genau daran erkennt man eine
|
||||||
schlecht skalierte Oberflaeche. */
|
schlecht skalierte Oberflaeche. */
|
||||||
.tafel .marke { font-size: .74em; margin-bottom: .5em; }
|
.tafel .marke { font-size: .78em; margin-bottom: .35em; }
|
||||||
.tafel .titel { font-size: 1.85em; margin-bottom: .3em; }
|
.tafel .titel { font-size: 1.78em; margin-bottom: .22em; }
|
||||||
.tafel .unterzeile { font-size: .92em; margin-bottom: 1.15em; }
|
.tafel .unterzeile { font-size: .9em; margin-bottom: .85em; }
|
||||||
.tafel .feldschild { font-size: .76em; margin-bottom: .6em; }
|
.tafel .feldschild { font-size: .76em; margin-bottom: .45em; }
|
||||||
.tafel .rollen { margin-bottom: 1.1em; }
|
.tafel .rollen { margin-bottom: .8em; }
|
||||||
.tafel .rolle { padding: .62em .85em; margin-bottom: .42em; gap: .8em; }
|
.tafel .rolle { padding: .50em .8em; margin-bottom: .30em; gap: .75em; }
|
||||||
.tafel .rolle__zeichen { width: 1.32em; height: 1.32em; }
|
.tafel .rolle__zeichen { width: 1.32em; height: 1.32em; }
|
||||||
.tafel .rolle__name { font-size: .94em; }
|
.tafel .rolle__name { font-size: .94em; }
|
||||||
.tafel .rolle__zusatz { font-size: .79em; }
|
.tafel .rolle__zusatz { font-size: .79em; }
|
||||||
.tafel #code { padding: .72em 2.7em .72em .9em; }
|
.tafel #code { padding: .72em 2.7em .72em .9em; }
|
||||||
.tafel .feld__auge { width: 2.2em; height: 2.2em; padding: .5em; right: .35em; }
|
.tafel .feld__auge { width: 2.2em; height: 2.2em; padding: .5em; right: .35em; }
|
||||||
.tafel .knopf { margin-top: .75em; padding: .7em 1.1em; font-size: .88em; width: 100%; }
|
.tafel .knopf { margin-top: .6em; padding: .62em 1.1em; font-size: .88em; width: 100%; }
|
||||||
.tafel .hinweis,
|
.tafel .hinweis,
|
||||||
.tafel .fehler { font-size: .82em; margin-top: .5em; }
|
.tafel .fehler { font-size: .82em; margin-top: .5em; }
|
||||||
.tafel .fuss { margin-top: 1.1em; padding-top: .8em; font-size: .76em; }
|
.tafel .fuss { margin-top: .75em; padding-top: .6em; font-size: .76em; }
|
||||||
|
|
||||||
/* ---- Der Schleier ------------------------------------------------
|
/* ---- Der Schleier ------------------------------------------------
|
||||||
Er verlief bisher von links dunkel nach rechts klar -- dort stand
|
Er verlief bisher von links dunkel nach rechts klar -- dort stand
|
||||||
@@ -1774,8 +1791,21 @@ body.gate {
|
|||||||
display: flex; align-items: baseline; gap: .42em;
|
display: flex; align-items: baseline; gap: .42em;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.marke--paar .marke__spicy { color: #e9848c; }
|
/* KRAEFTIGER (07.09.2026, Wunsch Filipe: "spicy x dogfather sieht man
|
||||||
.marke--paar .marke__dogi { color: #63b8ee; }
|
nicht richtig"). Die beiden Namen standen in gedeckten Toenen auf der
|
||||||
|
hellsten Stelle der Karte -- dort, wo der rote Schein von oben links
|
||||||
|
hereinkommt. Gedeckt ist auf dunklem Grund richtig und auf hellem zu
|
||||||
|
wenig. Jetzt heller, etwas groesser und mit einem eigenen Schatten,
|
||||||
|
der sie vom Untergrund abhebt statt sie zu ueberstrahlen. */
|
||||||
|
.marke--paar { letter-spacing: .13em; }
|
||||||
|
.marke--paar .marke__spicy {
|
||||||
|
color: #ffb3b9;
|
||||||
|
text-shadow: 0 1px 10px rgba(255, 95, 109, .45);
|
||||||
|
}
|
||||||
|
.marke--paar .marke__dogi {
|
||||||
|
color: #a9dcff;
|
||||||
|
text-shadow: 0 1px 10px rgba(99, 184, 238, .45);
|
||||||
|
}
|
||||||
.marke--paar .marke__x {
|
.marke--paar .marke__x {
|
||||||
/* Kleiner, leiser, und mit etwas Luft -- es verbindet, es benennt
|
/* Kleiner, leiser, und mit etwas Luft -- es verbindet, es benennt
|
||||||
nicht. */
|
nicht. */
|
||||||
@@ -1784,3 +1814,48 @@ body.gate {
|
|||||||
color: var(--text-still);
|
color: var(--text-still);
|
||||||
transform: translateY(-.02em);
|
transform: translateY(-.02em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
DAS GESICHT IN DER PERSONENAUSWAHL (07.09.2026)
|
||||||
|
|
||||||
|
Wunsch Filipe: "jeder soll auch immer das profilbild von denen sehen
|
||||||
|
mit denen sie verbunden sind."
|
||||||
|
|
||||||
|
Ein rundes Bild in einer Auswahlliste ist der billigste und stärkste
|
||||||
|
Zugewinn, den eine solche Liste haben kann: Man trifft den richtigen
|
||||||
|
Namen, ohne ihn zu lesen. Und wer kein Bild hat, bekommt seinen
|
||||||
|
Anfangsbuchstaben -- kein leerer Kreis, kein Platzhaltersymbol.
|
||||||
|
|
||||||
|
Der Buchstabe bleibt beim Laden des Bildes LIEGEN und wird nicht
|
||||||
|
ersetzt. Lädt das Bild nicht (Verbindung weg, Datei gelöscht), steht
|
||||||
|
dort weiterhin etwas Sinnvolles statt eines zerbrochenen Bildsymbols.
|
||||||
|
===================================================================== */
|
||||||
|
.wahl2__bild {
|
||||||
|
position: relative;
|
||||||
|
flex: none;
|
||||||
|
width: 26px; height: 26px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-flex; align-items: center; justify-content: center;
|
||||||
|
background: linear-gradient(150deg, rgba(63, 189, 245, .22), rgba(138, 118, 255, .18));
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(150, 186, 220, .22);
|
||||||
|
color: #dbe4ef;
|
||||||
|
/* .76rem = 12,16 px. Bei .7rem waren es 11,2 -- unter der Grenze von
|
||||||
|
11,5, die pruef-css-klassen zieht. Ein einzelner Grossbuchstabe in
|
||||||
|
einem 26-px-Kreis wirkt ohnehin kleiner, als die Zahl sagt. */
|
||||||
|
font-size: .76rem; font-weight: 700; line-height: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.wahl2__bild img {
|
||||||
|
position: absolute; inset: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
/* Der Name bekommt den restlichen Platz und wird gekürzt statt zu
|
||||||
|
umbrechen -- eine zweizeilige Zeile in einer Auswahlliste zerreißt
|
||||||
|
den Rhythmus, an dem das Auge entlangläuft. */
|
||||||
|
.wahl2__name {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.wahl2__eintrag { display: flex; align-items: center; gap: 10px; }
|
||||||
|
|||||||
@@ -171,8 +171,24 @@
|
|||||||
transition: border-color .16s ease, background .16s ease, color .16s ease;
|
transition: border-color .16s ease, background .16s ease, color .16s ease;
|
||||||
}
|
}
|
||||||
.rollenwahl__knopf:hover { border-color: rgba(255, 255, 255, .22); color: var(--text); }
|
.rollenwahl__knopf:hover { border-color: rgba(255, 255, 255, .22); color: var(--text); }
|
||||||
|
/* EIN ECHTER RAHMEN, NICHT NUR EIN SCHATTEN (07.09.2026).
|
||||||
|
|
||||||
|
Hier stand `outline: none` und stattdessen ein box-shadow. Das sieht
|
||||||
|
weicher aus und hat einen Haken: Ein Schatten wird von jedem
|
||||||
|
`overflow: hidden` eines Elternteils abgeschnitten -- und dann ist
|
||||||
|
der Fokus unsichtbar, ohne dass es irgendwo auffaellt. Genau das hat
|
||||||
|
pruef-barrierefrei gemeldet, und zwar NUR beim Manager: Er sieht auf
|
||||||
|
dieser Seite genau einen Rollenknopf, und der stand am Rand seines
|
||||||
|
Behaelters.
|
||||||
|
|
||||||
|
Jetzt beides: der Rahmen sorgt dafuer, dass man ihn IMMER sieht, der
|
||||||
|
Schatten dafuer, dass es gut aussieht. Wer mit der Tastatur arbeitet,
|
||||||
|
ist auf diesen Rahmen angewiesen -- er ist der einzige Hinweis
|
||||||
|
darauf, wo er gerade steht. */
|
||||||
.rollenwahl__knopf:focus-visible {
|
.rollenwahl__knopf:focus-visible {
|
||||||
outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--r) 32%, transparent);
|
outline: 2px solid color-mix(in srgb, var(--r) 85%, #ffffff);
|
||||||
|
outline-offset: 2px;
|
||||||
|
box-shadow: 0 0 0 3px color-mix(in srgb, var(--r) 32%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eine Farbe je Rolle -- dieselbe Sprache wie überall sonst. */
|
/* Eine Farbe je Rolle -- dieselbe Sprache wie überall sonst. */
|
||||||
|
|||||||
@@ -772,6 +772,14 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
|
|||||||
for (const ziel of ['f-creator', 'f-verant', 'b-creator', 'b-verant']) {
|
for (const ziel of ['f-creator', 'f-verant', 'b-creator', 'b-verant']) {
|
||||||
const o = el('option', null, `${p.name} (${p.rolle})`);
|
const o = el('option', null, `${p.name} (${p.rolle})`);
|
||||||
o.value = String(p.id);
|
o.value = String(p.id);
|
||||||
|
/* Bild ans <option> -- wahl.js zeichnet daraus das Gesicht.
|
||||||
|
Diese zwei Zeilen standen beim ersten Anlauf am DATEIENDE,
|
||||||
|
ausserhalb der Schleife: `o is not defined`, gemeldet von
|
||||||
|
pruef-sicht, das die Browserkonsole mitliest. Ein
|
||||||
|
Suchmuster ueber mehrere Dateien trifft eben nicht immer
|
||||||
|
die Stelle, die man meint. */
|
||||||
|
o.dataset.person = 'ja';
|
||||||
|
if (p.bild) o.dataset.bild = p.bild;
|
||||||
$(ziel).append(o);
|
$(ziel).append(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,6 +533,9 @@
|
|||||||
for (const p of personen.filter((p) => p.rolle === 'creator')) {
|
for (const p of personen.filter((p) => p.rolle === 'creator')) {
|
||||||
const o = document.createElement('option');
|
const o = document.createElement('option');
|
||||||
o.value = String(p.id); o.textContent = p.name;
|
o.value = String(p.id); o.textContent = p.name;
|
||||||
|
/* Bild ans <option> -- wahl.js zeichnet daraus das Gesicht. */
|
||||||
|
o.dataset.person = 'ja';
|
||||||
|
if (p.bild) o.dataset.bild = p.bild;
|
||||||
$('f-creator').append(o);
|
$('f-creator').append(o);
|
||||||
}
|
}
|
||||||
} catch { /* Zuordnung bleibt leer */ }
|
} catch { /* Zuordnung bleibt leer */ }
|
||||||
|
|||||||
@@ -129,7 +129,15 @@
|
|||||||
} else {
|
} else {
|
||||||
zeichen.textContent = initialen(r.name);
|
zeichen.textContent = initialen(r.name);
|
||||||
const gegen = r.teilnehmer.find((t) => t.id !== ich.id);
|
const gegen = r.teilnehmer.find((t) => t.id !== ich.id);
|
||||||
if (gegen) zeichen.dataset.rolle = gegen.rolle;
|
if (gegen) {
|
||||||
|
zeichen.dataset.rolle = gegen.rolle;
|
||||||
|
if (gegen.bild) {
|
||||||
|
const b = document.createElement('img');
|
||||||
|
b.src = gegen.bild; b.alt = '';
|
||||||
|
b.addEventListener('error', () => b.remove());
|
||||||
|
zeichen.append(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
knopf.append(zeichen);
|
knopf.append(zeichen);
|
||||||
|
|
||||||
@@ -233,9 +241,22 @@
|
|||||||
letzterVon = n.von_id;
|
letzterVon = n.von_id;
|
||||||
|
|
||||||
if (!gleicheFolge && !n.selbst) {
|
if (!gleicheFolge && !n.selbst) {
|
||||||
|
/* DAS GESICHT STATT DER INITIALEN (07.09.2026).
|
||||||
|
|
||||||
|
Der Anfangsbuchstabe bleibt als Unterlage LIEGEN und wird
|
||||||
|
nicht ersetzt: Laedt das Bild nicht, steht dort weiterhin
|
||||||
|
etwas Sinnvolles statt eines kaputten Bildsymbols. Dieselbe
|
||||||
|
Bauweise wie in der Kopfleiste und in der Personenauswahl --
|
||||||
|
drei Stellen, ein Verhalten. */
|
||||||
const z = el('span', 'chat-nachricht__zeichen', initialen(n.von));
|
const z = el('span', 'chat-nachricht__zeichen', initialen(n.von));
|
||||||
z.setAttribute('aria-hidden', 'true');
|
z.setAttribute('aria-hidden', 'true');
|
||||||
z.dataset.rolle = n.rolle || '';
|
z.dataset.rolle = n.rolle || '';
|
||||||
|
if (n.von_bild) {
|
||||||
|
const b = document.createElement('img');
|
||||||
|
b.src = n.von_bild; b.alt = '';
|
||||||
|
b.addEventListener('error', () => b.remove());
|
||||||
|
z.append(b);
|
||||||
|
}
|
||||||
zeile.append(z);
|
zeile.append(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -575,6 +575,8 @@
|
|||||||
for (const feld of ['f-creator', 's-creator']) {
|
for (const feld of ['f-creator', 's-creator']) {
|
||||||
const o = document.createElement('option');
|
const o = document.createElement('option');
|
||||||
o.value = String(p.id); o.textContent = p.name;
|
o.value = String(p.id); o.textContent = p.name;
|
||||||
|
o.dataset.person = 'ja';
|
||||||
|
if (p.bild) o.dataset.bild = p.bild;
|
||||||
$(feld).append(o);
|
$(feld).append(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -404,6 +404,8 @@
|
|||||||
const o = document.createElement('option');
|
const o = document.createElement('option');
|
||||||
o.value = String(p.id);
|
o.value = String(p.id);
|
||||||
o.textContent = p.name;
|
o.textContent = p.name;
|
||||||
|
o.dataset.person = 'ja';
|
||||||
|
if (p.bild) o.dataset.bild = p.bild;
|
||||||
$('f-creator').append(o);
|
$('f-creator').append(o);
|
||||||
}
|
}
|
||||||
} catch { /* Zuordnung bleibt leer */ }
|
} catch { /* Zuordnung bleibt leer */ }
|
||||||
|
|||||||
@@ -15,7 +15,19 @@
|
|||||||
const knopf = $('knopf');
|
const knopf = $('knopf');
|
||||||
const fuer = $('fuer');
|
const fuer = $('fuer');
|
||||||
|
|
||||||
const NAMEN = { admin: 'DogFather', manager: 'Manager', scout: 'Scout', creator: 'Creator' };
|
/* Die fuenfte Rolle stand hier nicht -- deshalb las man unter dem
|
||||||
|
Codefeld "PERSOENLICHER ZUGANGSCODE · undefined" (07.09.2026).
|
||||||
|
|
||||||
|
Eine zweite Namensliste im Browser neben der im Server
|
||||||
|
(ROLLEN_NAME in workspace.js) ist genau die Stelle, die beim
|
||||||
|
naechsten Mal wieder vergessen wird. Sie bleibt hier trotzdem: Die
|
||||||
|
Anmeldeseite laeuft, BEVOR es eine Sitzung gibt, kann also nichts
|
||||||
|
abfragen. Damit es auffaellt, faellt ein unbekannter Schluessel
|
||||||
|
jetzt auf den Schluessel selbst zurueck statt auf `undefined` --
|
||||||
|
"spicy" waere haesslich gewesen, aber sichtbar. */
|
||||||
|
const NAMEN = { spicy: 'Spicy Media', admin: 'DogFather', manager: 'Manager',
|
||||||
|
scout: 'Scout', creator: 'Creator' };
|
||||||
|
const rollenName = (r) => NAMEN[r] || r || '';
|
||||||
const SPEICHER = 'dfw.rolle';
|
const SPEICHER = 'dfw.rolle';
|
||||||
let gewaehlt = null;
|
let gewaehlt = null;
|
||||||
|
|
||||||
@@ -24,7 +36,7 @@
|
|||||||
function waehle(rolle, fokus = false) {
|
function waehle(rolle, fokus = false) {
|
||||||
gewaehlt = rolle;
|
gewaehlt = rolle;
|
||||||
rollen.forEach((b) => b.setAttribute('aria-checked', String(b.dataset.rolle === rolle)));
|
rollen.forEach((b) => b.setAttribute('aria-checked', String(b.dataset.rolle === rolle)));
|
||||||
fuer.textContent = `· ${NAMEN[rolle]}`;
|
fuer.textContent = `· ${rollenName(rolle)}`;
|
||||||
fuer.hidden = false;
|
fuer.hidden = false;
|
||||||
melde('');
|
melde('');
|
||||||
try { localStorage.setItem(SPEICHER, rolle); } catch { /* Privater Modus */ }
|
try { localStorage.setItem(SPEICHER, rolle); } catch { /* Privater Modus */ }
|
||||||
|
|||||||
@@ -1338,6 +1338,12 @@
|
|||||||
const o = document.createElement('option');
|
const o = document.createElement('option');
|
||||||
o.value = String(p.id);
|
o.value = String(p.id);
|
||||||
o.textContent = p.name + ' (' + p.rolle + ')';
|
o.textContent = p.name + ' (' + p.rolle + ')';
|
||||||
|
/* Beim ersten Anlauf landeten diese zwei Zeilen an einem
|
||||||
|
<span> in der Teilnehmerliste statt hier am <option> -- das
|
||||||
|
Suchmuster passte auf beide. Wirkungslos, aber irrefuehrend:
|
||||||
|
Es sah aus, als sei die Stelle erledigt. */
|
||||||
|
o.dataset.person = 'ja';
|
||||||
|
if (p.bild) o.dataset.bild = p.bild;
|
||||||
$('f-teilnehmer').append(o);
|
$('f-teilnehmer').append(o);
|
||||||
}
|
}
|
||||||
} catch { /* Zuordnung bleibt leer */ }
|
} catch { /* Zuordnung bleibt leer */ }
|
||||||
|
|||||||
@@ -7,7 +7,15 @@
|
|||||||
|
|
||||||
/* DogFather und Manager haben dieselben Rechte -- die Unterscheidung
|
/* DogFather und Manager haben dieselben Rechte -- die Unterscheidung
|
||||||
macht nur die Personenverwaltung, und die prueft der Server. */
|
macht nur die Personenverwaltung, und die prueft der Server. */
|
||||||
const LEITUNG = new Set(['admin', 'manager']);
|
/* 'spicy' gehoert dazu (07.09.2026). Ohne diesen Eintrag schickte die
|
||||||
|
Seite Spicy Media sofort auf die Startseite zurueck -- der Server
|
||||||
|
liess sie herein, das Skript warf sie wieder hinaus. Genau der
|
||||||
|
Fehler, den Filipe gemeldet hat: "bei spicy funktioniert dieser
|
||||||
|
button nicht, wenn sie drauf druecken geht es nicht auf."
|
||||||
|
|
||||||
|
Zwei Listen fuer dieselbe Frage, eine im Server und eine hier --
|
||||||
|
und beim Hinzufuegen einer Rolle wurde nur die erste gepflegt. */
|
||||||
|
const LEITUNG = new Set(['spicy', 'admin', 'manager']);
|
||||||
|
|
||||||
const $ = (id) => document.getElementById(id);
|
const $ = (id) => document.getElementById(id);
|
||||||
const ROLLENNAME = { admin: 'DogFather', manager: 'Manager', scout: 'Scout', creator: 'Creator' };
|
const ROLLENNAME = { admin: 'DogFather', manager: 'Manager', scout: 'Scout', creator: 'Creator' };
|
||||||
@@ -127,7 +135,31 @@
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
const datum = (iso) => (iso ? iso.slice(0, 16).replace('T', ' ') : '—');
|
/* ORTSZEIT, NICHT UTC (07.09.2026).
|
||||||
|
|
||||||
|
Hier stand `iso.slice(0, 16).replace('T', ' ')` -- also ein Schnitt
|
||||||
|
durch die Zeichenkette. Der Server schreibt seine Zeitstempel in
|
||||||
|
UTC; im Sommer sind das ZWEI STUNDEN weniger. Im Protokoll stand
|
||||||
|
deshalb "03:00", wo tatsaechlich 05:00 war. Filipe hat es gemeldet:
|
||||||
|
"wie 3 uhr, wir haben 5 uhr."
|
||||||
|
|
||||||
|
Das Tueckische daran: Es sieht nie kaputt aus. Eine Uhrzeit ist
|
||||||
|
immer plausibel -- man merkt es nur, wenn man zufaellig gerade auf
|
||||||
|
die Uhr sieht. Und im Winter waere es nur eine Stunde, also noch
|
||||||
|
schwerer zu bemerken.
|
||||||
|
|
||||||
|
`new Date(iso)` liest den Zeitstempel richtig und gibt ihn in der
|
||||||
|
Zeit des Geraets aus. Ein Schnitt durch die Zeichenkette ist
|
||||||
|
ausschliesslich bei einem reinen DATUM erlaubt ("2026-09-07") --
|
||||||
|
dort gibt es keine Zeitzone, um die man sich irren koennte. */
|
||||||
|
const datum = (iso) => {
|
||||||
|
if (!iso) return '—';
|
||||||
|
const d = new Date(iso);
|
||||||
|
if (Number.isNaN(d.getTime())) return '—';
|
||||||
|
const z = (n) => String(n).padStart(2, '0');
|
||||||
|
return `${d.getFullYear()}-${z(d.getMonth() + 1)}-${z(d.getDate())} `
|
||||||
|
+ `${z(d.getHours())}:${z(d.getMinutes())}`;
|
||||||
|
};
|
||||||
|
|
||||||
/* ---------- Code anzeigen -------------------------------------------- */
|
/* ---------- Code anzeigen -------------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,43 @@
|
|||||||
zeilen.append(el('p', 'wahl2__gruppe', gruppe));
|
zeilen.append(el('p', 'wahl2__gruppe', gruppe));
|
||||||
vorherigeGruppe = gruppe;
|
vorherigeGruppe = gruppe;
|
||||||
}
|
}
|
||||||
const zeile = el('button', 'wahl2__eintrag', o.textContent);
|
/* DAS GESICHT ZUM NAMEN (07.09.2026).
|
||||||
|
|
||||||
|
Wunsch Filipe: "jeder soll auch immer das profilbild von denen
|
||||||
|
sehen mit denen sie verbunden sind ... ich seh als
|
||||||
|
manager/betreuer von tili ihr profilbild immer noch nicht."
|
||||||
|
|
||||||
|
Der Server liefert die Bildadresse seit heute mit
|
||||||
|
(/api/personen). Gezeichnet wurde sie nirgends -- deshalb
|
||||||
|
aenderte sich fuer ihn nichts. Hier ist der wirksamste Ort:
|
||||||
|
Diese Liste ist die Personenauswahl in Aufgaben, Terminen,
|
||||||
|
Dateien, Bereichen und Calls. Ein Bild macht aus einer Liste
|
||||||
|
von Namen eine Liste von Menschen, und man trifft den
|
||||||
|
richtigen, ohne zu lesen.
|
||||||
|
|
||||||
|
Der ANFANGSBUCHSTABE bleibt als Unterlage LIEGEN und wird
|
||||||
|
nicht ersetzt: Laedt das Bild nicht (Verbindung weg, Datei
|
||||||
|
geloescht), steht dort weiterhin etwas Sinnvolles statt eines
|
||||||
|
kaputten Bildsymbols. Genau so macht es die Kopfleiste auch.
|
||||||
|
|
||||||
|
Wo es kein `data-bild` gibt (Kategorien, Saeulen, Takte),
|
||||||
|
bleibt die Zeile wie bisher -- die Auswahl weiss nicht, dass
|
||||||
|
sie manchmal Personen zeigt, und muss es auch nicht. */
|
||||||
|
const zeile = el('button', 'wahl2__eintrag');
|
||||||
|
if (o.dataset.bild || o.dataset.person === 'ja') {
|
||||||
|
const p = el('span', 'wahl2__bild');
|
||||||
|
p.setAttribute('aria-hidden', 'true');
|
||||||
|
p.textContent = (o.textContent || '?').trim().charAt(0).toUpperCase();
|
||||||
|
if (o.dataset.bild) {
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = o.dataset.bild;
|
||||||
|
img.alt = '';
|
||||||
|
img.addEventListener('error', () => img.remove());
|
||||||
|
p.append(img);
|
||||||
|
}
|
||||||
|
zeile.append(p);
|
||||||
|
}
|
||||||
|
zeile.append(el('span', 'wahl2__name', o.textContent));
|
||||||
zeile.type = 'button';
|
zeile.type = 'button';
|
||||||
zeile.setAttribute('role', 'option');
|
zeile.setAttribute('role', 'option');
|
||||||
const an = o.selected && !z.feld.dataset.extern;
|
const an = o.selected && !z.feld.dataset.extern;
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -211,10 +211,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/aufgaben.js?v=202609070507" defer></script>
|
<script src="assets/js/aufgaben.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/automation.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/automation.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -134,10 +134,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/automation.js?v=202609070507" defer></script>
|
<script src="assets/js/automation.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -143,14 +143,14 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609070507" defer></script>
|
<script src="assets/js/checkliste.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/ampel.js?v=202609070507" defer></script>
|
<script src="assets/js/ampel.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/schulung.js?v=202609070507" defer></script>
|
<script src="assets/js/schulung.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609070507" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereich.js?v=202609070507" defer></script>
|
<script src="assets/js/bereich.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/calls.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/calls.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -76,11 +76,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609070507" defer></script>
|
<script src="assets/js/ki.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/calls.js?v=202609070507" defer></script>
|
<script src="assets/js/calls.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+8
-8
@@ -9,16 +9,16 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
||||||
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
||||||
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
||||||
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
||||||
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
||||||
Dialog zu sehen bekam. -->
|
Dialog zu sehen bekam. -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/chat.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/chat.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -154,9 +154,9 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609070507"></script>
|
<script src="assets/js/bereiche.js?v=202609070539"></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507"></script>
|
<script src="assets/js/kopf.js?v=202609070539"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507"></script>
|
<script src="assets/js/glocke.js?v=202609070539"></script>
|
||||||
<script src="assets/js/chat.js?v=202609070507"></script>
|
<script src="assets/js/chat.js?v=202609070539"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+11
-11
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/content.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/content.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -166,12 +166,12 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609070507" defer></script>
|
<script src="assets/js/checkliste.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609070507" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/content.js?v=202609070507" defer></script>
|
<script src="assets/js/content.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/dateien.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -95,10 +95,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/dateien.js?v=202609070507" defer></script>
|
<script src="assets/js/dateien.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate">
|
<body class="gate">
|
||||||
@@ -202,6 +202,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202609070507" defer></script>
|
<script src="assets/js/gate.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/kalender.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -257,11 +257,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kalender.js?v=202609070507" defer></script>
|
<script src="assets/js/kalender.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kalender-abo.js?v=202609070507" defer></script>
|
<script src="assets/js/kalender-abo.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/leistung.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/leistung.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -211,10 +211,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507"></script>
|
<script src="assets/js/wahl.js?v=202609070539"></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507"></script>
|
<script src="assets/js/bereiche.js?v=202609070539"></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507"></script>
|
<script src="assets/js/kopf.js?v=202609070539"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507"></script>
|
<script src="assets/js/glocke.js?v=202609070539"></script>
|
||||||
<script src="assets/js/leistung.js?v=202609070507"></script>
|
<script src="assets/js/leistung.js?v=202609070539"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/personen.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/personen.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -128,10 +128,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/personen.js?v=202609070507" defer></script>
|
<script src="assets/js/personen.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -201,11 +201,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609070507" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/profil.js?v=202609070507" defer></script>
|
<script src="assets/js/profil.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/report.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/report.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -93,11 +93,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609070507" defer></script>
|
<script src="assets/js/ki.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/report.js?v=202609070507" defer></script>
|
<script src="assets/js/report.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/scouting.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -126,10 +126,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/scouting.js?v=202609070507" defer></script>
|
<script src="assets/js/scouting.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
||||||
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
||||||
<link rel="stylesheet" href="assets/css/heim.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/heim.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -263,10 +263,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/start.js?v=202609070507" defer></script>
|
<script src="assets/js/start.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -72,11 +72,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609070507" defer></script>
|
<script src="assets/js/ki.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/startcheck.js?v=202609070507" defer></script>
|
<script src="assets/js/startcheck.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -113,10 +113,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609070507" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
||||||
Dialog "Creator anlegen". -->
|
Dialog "Creator anlegen". -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -136,10 +136,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
|
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/uebersicht.js?v=202609070507" defer></script>
|
<script src="assets/js/uebersicht.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<meta name="theme-color" content="#0674b9" />
|
<meta name="theme-color" content="#0674b9" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609070539" />
|
||||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202609070507" />
|
<link rel="stylesheet" href="assets/css/wissen.css?v=202609070539" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -177,10 +177,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609070507" defer></script>
|
<script src="assets/js/wahl.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609070507" defer></script>
|
<script src="assets/js/bereiche.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609070507" defer></script>
|
<script src="assets/js/kopf.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609070507" defer></script>
|
<script src="assets/js/glocke.js?v=202609070539" defer></script>
|
||||||
<script src="assets/js/wissen.js?v=202609070507" defer></script>
|
<script src="assets/js/wissen.js?v=202609070539" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user