Anfuehrungszeichen: 199 falsche Schlusszeichen im sichtbaren Text

Deutsch oeffnet mit „ und schliesst mit “. An 199 Stellen, die ein
Mensch liest, stand als Schlusszeichen ein GERADES " -- „Nächstes"
statt „Nächstes“. Auf sechzehn oeffentlichen Seiten, in vierzig
Dateien des Workspace und in zwoelf Servermodulen, die Texte
verschicken.

Auf dem Bildschirm sieht man den Unterschied sofort. Beim Schreiben
nicht: Das gerade " liegt auf der Tastatur, die anderen nicht.

WARUM EIN ERSTER ANLAUF ZURUECKGENOMMEN WURDE

Ein gerades " ist an vielen Stellen SYNTAX und kein Schriftzeichen --
Grenze einer Zeichenkette, Grenze eines HTML-Attributs, Zeichen in
einem regulaeren Ausdruck. Wer stumpf ersetzt, macht aus

    „<a href="https://…                  ein kaputtes Attribut
    /^["'„»\s]+|["'“«.\s]+$/              einen kaputten Ausdruck
    "… nichts „mal " + "eben …"          eine kaputte Zeichenkette

DIE UNTERSCHEIDUNG LAEUFT AN MERKMALEN, NICHT AN EINER LISTE

  < > = dazwischen        -> HTML-Marke oder Attribut
  endet auf Leerzeichen   -> die Zeichenkette hoert hier auf, der
                             Satz geht in der naechsten Zeile weiter.
                             Ein deutsches Schlusszeichen steht NIE
                             hinter einem Leerzeichen.
  Rueckstrich mittendrin  -> regulaerer Ausdruck
  ${ ohne }               -> mitten in einem Ausdruck

Eine Liste erlaubter Ausnahmen waere die naechste, die niemand
pflegt. Zwoelf Stellen bleiben dadurch stehen, alle zwoelf einzeln
angesehen und alle zwoelf zu Recht -- dort steht das richtige
Schlusszeichen ohnehin weiter unten im Satz.

Fuenf davon waren allerdings ECHTE Fehler HINTER dem Link
(`…>HasiDog</a>".`) -- die erste Regel hatte nur das Attribut
gesehen, nicht den Satz danach. Gezielt nachgezogen.

Ein maskiertes `\"` in workspace-vorlagen.js (28 Hooks) wird zu “ --
ohne Rueckstrich, denn “ begrenzt nichts.

KOMMENTARE BLEIBEN, WIE SIE SIND. Dort liest es niemand ausser mir;
eine Wache, die auch Kosmetik anmahnt, wird weggeklickt. Beim ersten
Messen fielen ausserdem acht Stellen aus buehne.html faelschlich an,
weil `/* */` in HTML (in <style> und <script>) nicht ausgeblendet
war -- jetzt schon.

DIE WACHE DAZU

pruef-struktur prueft es ab sofort mit derselben Regel: 322 Dateien
mit sichtbarem Text, 0 Funde, und die zwoelf bewussten Ausnahmen
werden GEZAEHLT und genannt (erlaubt: 12). Eine Ausnahme, die niemand
sieht, waechst -- und irgendwann steht der echte Fall darin.

GEPRUEFT

  pruef-struktur   59 -> 68 Pruefungen, 0 Fehler
  node --check auf allen geaenderten JS-Dateien
  nachgemessen: 199 geaendert, 12 mit Grund stehen geblieben

  gruen geblieben: bewerbung-aufgaben 163, nachwuchs 262,
  reaktion 421, support 63, content 45, terminregel 35, treff 85

  Und nachgesehen, ob eine Pruefung noch die alte Schreibweise
  ERWARTET: 13 Fundstellen, alle dreizehn nur Text in ihrer eigenen
  Ausgabe, keine einzige ein Vergleich mit dem Seitentext.

GEGENPROBE: In reaktion.html ein Schlusszeichen zurueckgedreht ->
„workspace/reaktion.html:546 „Nächstes"", mit Datei und Zeile. Und
die Erkennung einzeln gegen HTML-Attribut, fortgesetzte
Zeichenkette, regulaeren Ausdruck und eingesetzten Wert geprueft.

Stempel gesetzt: workspace 670 Verweise in 45 Dateien, oeffentlich
554 in 48 Seiten.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-01 01:56:15 +02:00
co-authored by Claude Opus 5
parent 7dc5356c80
commit 95c4599baa
138 changed files with 1510 additions and 1390 deletions
+2 -2
View File
@@ -101,7 +101,7 @@
} else {
punkt('warn', 'Ton ist noch gesperrt',
'Der Browser lässt Ton erst zu, nachdem man einmal etwas angetippt hat. '
+ 'Drück unten auf „Klingelton anhören" – danach ist er frei, '
+ 'Drück unten auf „Klingelton anhören“ – danach ist er frei, '
+ 'solange die Seite offen bleibt.');
}
return raum;
@@ -148,7 +148,7 @@
const anrufArt = (d.arten || []).find((x) => x.schluessel === 'anruf');
if (anrufArt && anrufArt.an === false) {
punkt('schlecht', 'Anrufe sind bei dir abgeschaltet',
'In den Benachrichtigungen die Art „Jemand ruft an" wieder einschalten.');
'In den Benachrichtigungen die Art „Jemand ruft an“ wieder einschalten.');
} else if (d.ruhe.jetzt) {
punkt('gut', `Es ist Ruhezeit (${d.ruhe.ab}–${d.ruhe.bis} Uhr)`,
'Erinnerungen bleiben jetzt liegen – Anrufe kommen trotzdem durch.');
+1 -1
View File
@@ -470,7 +470,7 @@
nennt, den es immer gibt: die Geraeteeinstellungen. */
throw new Error('Das Mikrofon ist gesperrt. Erlaube es in den '
+ 'Einstellungen deines Geräts (Apps → Team Dogi → Mikrofon) '
+ 'und versuch es noch einmal. Unter „Klingelt nichts?" steht, '
+ 'und versuch es noch einmal. Unter „Klingelt nichts?“ steht, '
+ 'wie das geht.');
}
if (f?.name === 'NotFoundError') {
+7 -7
View File
@@ -408,7 +408,7 @@
if (DARF_ABBRECHEN.has(ich.rolle)) {
const ab = el('button', 'schritt schritt--ab', 'abbrechen');
ab.type = 'button';
ab.setAttribute('aria-label', `„${a.titel}" abbrechen`);
ab.setAttribute('aria-label', `„${a.titel}“ abbrechen`);
ab.addEventListener('click', () => abbruchOeffnen(a));
schritte.append(ab);
}
@@ -461,10 +461,10 @@
const dlg = $('abbruch-dialog');
if (!dlg) return;
dlg.dataset.id = String(a.id);
$('abbruch-titel').textContent = `„${a.titel}" abbrechen?`;
$('abbruch-titel').textContent = `„${a.titel}“ abbrechen?`;
/* Sagt, was gleich passiert -- und was NICHT passiert. Die Sorge
bei so einem Knopf ist immer, ob etwas verloren geht. */
$('abbruch-was').textContent = `Die Aufgabe steht danach unter „Abgebrochen" `
$('abbruch-was').textContent = `Die Aufgabe steht danach unter „Abgebrochen“ `
+ `statt in der Spalte ${STATUS_NAME[a.status] || a.status}. `
+ `Sie wird nicht gelöscht und lässt sich jederzeit wieder aufnehmen.`;
$('abbruch-grund').value = '';
@@ -559,7 +559,7 @@
if (DARF_ABBRECHEN.has(ich.rolle)) {
const zurueck = el('button', 'schritt', 'wieder aufnehmen ↩');
zurueck.type = 'button';
zurueck.setAttribute('aria-label', `„${a.titel}" wieder aufnehmen`);
zurueck.setAttribute('aria-label', `„${a.titel}“ wieder aufnehmen`);
zurueck.addEventListener('click', () => wiederAufnehmen(a, zurueck));
k.append(zurueck);
}
@@ -1077,7 +1077,7 @@
async function bewerbungEntscheiden(knopf, b, ja) {
const wer = b.selbst ? 'dich' : b.person_name;
const antwort = await window.frageNach({
titel: ja ? `„${b.titel}" an ${b.person_name}?` : `${b.person_name} absagen?`,
titel: ja ? `„${b.titel}“ an ${b.person_name}?` : `${b.person_name} absagen?`,
was: ja
? `Die Aufgabe wird angelegt und liegt danach bei ${b.person_name}.`
: `Die Vorlage bleibt auf dem Brett – ${wer} kann sich später wieder bewerben.`,
@@ -1832,9 +1832,9 @@
/* Loeschen ist hier fast nie das Richtige -- deshalb nennt der
Dialog den sanfteren Weg beim Namen, statt nur zu warnen. */
if (!await frageNach({
titel: `„${bearbeitet.titel}" löschen?`,
titel: `„${bearbeitet.titel}“ löschen?`,
was: 'Die Aufgabe wird samt Rückmeldungen und Verlauf entfernt.',
bleibt: 'Wenn sie nur nicht mehr stören soll: „Abbrechen" legt sie '
bleibt: 'Wenn sie nur nicht mehr stören soll: „Abbrechen“ legt sie '
+ 'beiseite, ohne etwas wegzuwerfen – dort ist sie später noch da.',
endgueltig: true, ja: 'Endgültig löschen',
})) return;
+1 -1
View File
@@ -34,7 +34,7 @@
const REGELN = [
{ name: 'Hinweise auf der Übersicht',
text: 'Überfälliges, heute Fälliges, Gespräche ohne Protokoll, fällige Follow-ups und dringende Punkte werden bei jedem Aufruf neu ermittelt. Sie führen keine eigene Liste – ein Hinweis verschwindet von selbst, sobald die Sache erledigt ist.' },
{ name: '„Neu" in der Bibliothek',
{ name: '„Neu“ in der Bibliothek',
text: 'Eine frisch eingestellte Anleitung steht 48 Stunden unter „Neu & wichtig“ und ist danach nur noch in ihrer Kategorie zu finden. Angepinntes bleibt, bis es jemand abschaltet.' },
{ name: 'Zuständigkeit bei der Übergabe',
text: 'Wird aus einem übergebenen Lead ein Creator angelegt, betreut ihn automatisch der Scout, der ihn gefunden hat. Die Angaben aus der Pipeline wandern dabei ins Creator-Profil.' },
+4 -4
View File
@@ -640,7 +640,7 @@
b.title = 'Schickt Art, Titel und Text als Nachricht in den Chat.';
b.addEventListener('click', async () => {
if (!await frageNach({
titel: `„${e.titel}" als Nachricht schicken?`,
titel: `„${e.titel}“ als Nachricht schicken?`,
was: 'Die Person bekommt Art, Titel und Text im Chat – einmalig.',
bleibt: 'Der Eintrag bleibt hier stehen. Zurückholen lässt sich '
+ 'die Nachricht nicht, sobald sie unterwegs ist.',
@@ -1123,7 +1123,7 @@
if (bereich === 'mitmachen' && e.erstellt_rolle === 'gast') {
zeile.append(tuKnopf('zu den Talenten', async () => {
if (!await frageNach({
titel: '„' + e.titel + '" zu den Talenten übernehmen?',
titel: '„' + e.titel + '“ zu den Talenten übernehmen?',
was: 'Die Person erscheint danach in der Talente-Liste.',
bleibt: 'Der Beitrag hier bleibt stehen. Übernehmen heißt noch '
+ 'keine Zusage – es entscheidet weiterhin ein Mensch.',
@@ -1144,7 +1144,7 @@
if (e.erstellt_von !== ich.id) {
zeile.append(tuKnopf('entfernen', async () => {
const a1 = await frageNach({
titel: '„' + e.titel + '" entfernen?',
titel: '„' + e.titel + '“ entfernen?',
was: 'Der Beitrag verschwindet vom Brett.',
bleibt: 'Der Grund wird festgehalten und der Person mitgeteilt – '
+ 'sie hat ein Recht darauf (DSA Art. 17).',
@@ -1432,7 +1432,7 @@
zweite Wahrheit, die beim nächsten neuen Brett ausläuft. */
const brauchtGrund = treffBrett && e.erstellt_von !== ich.id;
const antwort = await frageNach({
titel: `„${e.titel}" löschen?`,
titel: `„${e.titel}“ löschen?`,
was: 'Der Eintrag verschwindet vom Brett – für alle.',
bleibt: brauchtGrund
? 'Nachrichten, die dazu geschrieben wurden, gehen mit. Der Grund '
+2 -2
View File
@@ -40,7 +40,7 @@
if (!schluessel) {
sagFehler('Diese Adresse ist unvollständig — der Schlüssel fehlt. '
+ 'Hol sie dir im Regiepult unter „Bühne".');
+ 'Hol sie dir im Regiepult unter „Bühne“.');
return;
}
@@ -170,7 +170,7 @@
const a = await fetch(`/workspace/api/buehne/lage?s=${encodeURIComponent(schluessel)}`);
if (a.status === 404) {
sagFehler('Der Schlüssel stimmt nicht mehr. '
+ 'Hol dir die Adresse neu im Regiepult unter „Bühne".');
+ 'Hol dir die Adresse neu im Regiepult unter „Bühne“.');
return false;
}
if (!a.ok) return false;
+3 -3
View File
@@ -369,10 +369,10 @@
const weg = el('div', 'kk__knoepfe');
weg.append(tuKnopf('Protokoll löschen', async () => {
if (!await frageNach({
titel: 'Protokoll zu „' + c.titel + '" löschen?',
titel: 'Protokoll zu „' + c.titel + '“ löschen?',
was: 'Der Text ist danach weg und lässt sich nicht wiederholen.',
bleibt: 'Das Gespräch bleibt im Kalender und steht danach wieder '
+ 'unter „Protokoll fehlt". Daraus entstandene Aufgaben bleiben auch.',
+ 'unter „Protokoll fehlt“. Daraus entstandene Aufgaben bleiben auch.',
endgueltig: true, ja: 'Protokoll löschen',
})) return;
const a = await hole('/workspace/api/calls/' + c.id + '/protokoll', { method: 'DELETE' });
@@ -487,7 +487,7 @@
if (!daten.offen.length && !daten.anstehend.length
&& !(daten.serien || []).length && !daten.erledigt.length) {
const leer = el('div', 'leer-hinweis');
leer.append(document.createTextNode('Noch keine Calls. Termine mit der Art „Call" oder „Review" '));
leer.append(document.createTextNode('Noch keine Calls. Termine mit der Art „Call“ oder „Review“ '));
const a = el('a', 'call__verweis', 'im Kalender');
a.href = 'kalender.html';
leer.append(a, document.createTextNode(' erscheinen automatisch hier.'));
+7 -7
View File
@@ -1039,7 +1039,7 @@
einer Bequemlichkeit. */
const FAECHER = [
{ wert: 'direkt', name: 'Personen', leer: 'Noch kein Gespräch mit einer einzelnen Person.' },
{ wert: 'gruppe', name: 'Gruppen', leer: 'Noch keine Gruppe. Mit „Neu" legst du eine an.' },
{ wert: 'gruppe', name: 'Gruppen', leer: 'Noch keine Gruppe. Mit „Neu“ legst du eine an.' },
{ wert: 'kanal', name: 'Kanäle', leer: 'Noch kein Kanal.' },
];
let fach = (() => {
@@ -1247,7 +1247,7 @@
if (!zeigen.length && !suchtext) {
leerSatz.textContent = raeume.length
? (FAECHER.find((f) => f.wert === fach)?.leer || 'Hier ist noch nichts.')
: 'Noch keine Gespräche. Mit „Neu" schreibst du der ersten Person.';
: 'Noch keine Gespräche. Mit „Neu“ schreibst du der ersten Person.';
}
}
@@ -1429,7 +1429,7 @@
nadel.setAttribute('aria-pressed', String(fix));
nadel.title = fix ? 'Nicht mehr oben halten' : 'Oben halten';
nadel.setAttribute('aria-label',
fix ? `„${r.name}" nicht mehr oben halten` : `„${r.name}" oben halten`);
fix ? `„${r.name}“ nicht mehr oben halten` : `„${r.name}“ oben halten`);
nadel.addEventListener('click', async (e) => {
/* Sonst oeffnet der Klick zusaetzlich das Gespraech -- die
Zeile daneben ist ein Knopf, und der Klick blubbert im <li>
@@ -3316,7 +3316,7 @@
/* Kein „kopiere sie" mehr -- an der Nachricht steht jetzt ein
Knopf, der es in einem Griff wiederholt. */
melde(`${grund} Die Nachricht ist nicht angekommen – `
+ `mit „Nochmal senden" kannst du es gleich wiederholen.`);
+ `mit „Nochmal senden“ kannst du es gleich wiederholen.`);
}
async function zuruecknehmen(id, fremd = false) {
@@ -4066,7 +4066,7 @@
hinein, das schon drin ist. */
leer.textContent = gifs.length === 0
? 'Die Kiste ist noch leer. Leg das erste GIF hinein – alle aus dem Team sehen es dann auch.'
: `Nichts gefunden zu „${suche}". Insgesamt liegen ${gifs.length} GIFs in der Kiste.`;
: `Nichts gefunden zu „${suche}“. Insgesamt liegen ${gifs.length} GIFs in der Kiste.`;
}
const ruhig = ruhigerModus();
for (const g of zeigen) {
@@ -4117,7 +4117,7 @@
kommentarlos. */
if (!await frageNach({
titel: 'Aus der Kiste nehmen?',
was: `„${g.name}" ist danach fuer das ganze Team weg.`,
was: `„${g.name}“ ist danach fuer das ganze Team weg.`,
bleibt: 'Schon verschickte GIFs bleiben in den Gespraechen stehen.',
endgueltig: true, ja: 'Herausnehmen',
})) return;
@@ -4908,7 +4908,7 @@
const wasIstEs = offen.art === 'kanal' ? 'Kanal' : 'Gruppe';
const andere = Math.max(0, (offen.teilnehmer?.length || 1) - 1);
if (!await frageNach({
titel: `${wasIstEs} „${offen.name}" für alle auflösen?`,
titel: `${wasIstEs} „${offen.name}“ für alle auflösen?`,
was: `Der ganze Verlauf wird gelöscht – auch bei ${andere === 1
? 'der anderen Person' : `den ${andere} anderen`}, samt aller Anhänge.`,
bleibt: 'Wenn du sie nur bei dir loswerden willst, nimm den Knopf '
+3 -3
View File
@@ -167,7 +167,7 @@
er ist gesprochener Text, kein Etikett. Fehlt er, steht das da:
eine Luecke, die man sieht, wird gefuellt. */
if (e.hook) {
k.append(el('p', 'video__hook', '„' + e.hook + '"'));
k.append(el('p', 'video__hook', '„' + e.hook + '“'));
} else if (e.art !== 'idee' && e.art !== 'veroeffentlicht') {
k.append(el('p', 'video__hook video__hook--fehlt', 'Noch kein Hook'));
}
@@ -214,7 +214,7 @@
}
knoepfe.append(tuKnopf('löschen', 'Dieses Video entfernen', async () => {
if (!await frageNach({
titel: `„${e.titel}" löschen?`,
titel: `„${e.titel}“ löschen?`,
was: 'Die Idee verschwindet aus der Planung.',
bleibt: 'Ein schon eingetragener Drehtermin im Kalender bleibt stehen.',
endgueltig: true, ja: 'Löschen',
@@ -389,7 +389,7 @@
if (!darfEintragen()) { ziel.append(z); continue; }
z.append(tuKnopf('löschen', 'Säule entfernen, Videos bleiben', async () => {
if (!await frageNach({
titel: `Säule „${s.name}" entfernen?`,
titel: `Säule „${s.name}“ entfernen?`,
was: 'Die Säule verschwindet aus der Auswahl.',
bleibt: 'Alle Videos bleiben – sie stehen danach nur ohne Säule da '
+ 'und lassen sich jederzeit einer anderen zuordnen.',
+2 -2
View File
@@ -101,7 +101,7 @@
async function schicke(datei) {
melde('');
if (datei.size > maxBytes) {
melde(`„${datei.name}" ist ${groesse(datei.size)} groß – erlaubt sind ${groesse(maxBytes)}.`);
melde(`„${datei.name}“ ist ${groesse(datei.size)} groß – erlaubt sind ${groesse(maxBytes)}.`);
return;
}
/* MIT FORTSCHRITT UND ABBRUCH (19.09.2026). Vorher stand hier von
@@ -241,7 +241,7 @@
if (LEITUNG.has(ich.rolle) || (d.hochgeladen_von === ich.id && d.status !== 'freigegeben')) {
knoepfe.append(tuKnopf('löschen', async () => {
if (!await frageNach({
titel: `„${d.name_original}" löschen?`,
titel: `„${d.name_original}“ löschen?`,
was: 'Die Datei wird vom Server entfernt.',
bleibt: 'Wer sie schon heruntergeladen hat, behält seine Kopie.',
endgueltig: true, ja: 'Löschen',
+5 -5
View File
@@ -137,7 +137,7 @@
Die Liste deshalb NICHT neu zu holen ist Absicht: Jeder Neuaufbau
bewegt die Seite, und genau darüber hat Filipe sich im selben
Atemzug beschwert. Stattdessen wandert die Zahl mit. */
const personZahlen = new Map(); // Personennummer -> Element mit „x von 28"
const personZahlen = new Map(); // Personennummer -> Element mit „x von 28“
let letzteKarte = null; // { id, daten } der gerade offenen Karte
/** Alle sichtbaren Zähler auf den Stand bringen, den die Karte hat.
@@ -1052,11 +1052,11 @@
melde(fehlt
? `Angelegt — aber ${fehlt} Person(en) konnten nicht eingetragen werden.`
: wieViele === 1
? `„${titel}" steht jetzt bei ${ersterName || 'der gewählten Person'}.`
? `„${titel}“ steht jetzt bei ${ersterName || 'der gewählten Person'}.`
: istPool
? `„${titel}" liegt für ${wieViele} Leute bereit — wer zuerst Zeit hat,`
? `„${titel}“ liegt für ${wieViele} Leute bereit — wer zuerst Zeit hat,`
+ ' bewirbt sich, und du entscheidest.'
: `„${titel}" steht jetzt bei ${wieViele} Leuten — jede hat ihren`
: `„${titel}“ steht jetzt bei ${wieViele} Leuten — jede hat ihren`
+ ' eigenen Stand.',
!fehlt);
/* UND DIE LISTE DARUNTER ZEIGT DIE ERSTE PERSON. Sie ist die,
@@ -2434,7 +2434,7 @@
ziel.setAttribute('aria-busy', 'false');
if (!lage.personen.length) {
ziel.append(el('p', 'leise',
'Noch niemand im Team. Zugänge legst du in „Personen & Zugänge" an.'));
'Noch niemand im Team. Zugänge legst du in „Personen & Zugänge“ an.'));
}
gesucht = null;
for (const p of lage.personen) ziel.append(personKarte(p, lage));
+3 -3
View File
@@ -172,7 +172,7 @@
kopf.className = 'hochlade__kopf';
const text = document.createElement('span');
text.className = 'hochlade__text';
text.textContent = `„${dateiname}" wird hochgeladen …`;
text.textContent = `„${dateiname}“ wird hochgeladen …`;
kopf.append(text);
let abbruch = null;
@@ -204,12 +204,12 @@
fortschritt(anteil, gesendet, gesamt) {
if (anteil === null || anteil === undefined) {
balken.removeAttribute('value');
text.textContent = `„${dateiname}" wird hochgeladen …`;
text.textContent = `„${dateiname}“ wird hochgeladen …`;
return;
}
balken.value = anteil;
const g = window.groesseInWorten;
text.textContent = `„${dateiname}" – ${Math.round(anteil * 100)} %`
text.textContent = `„${dateiname}“ – ${Math.round(anteil * 100)} %`
+ (gesamt ? ` von ${g(gesamt)}` : '');
},
verarbeiten() {
+2 -2
View File
@@ -177,9 +177,9 @@ function knopfBauen(wohin) {
const titel = 'Als App auf dem Home-Bildschirm';
const weg = istApple
? 'Tippe unten in Safari auf das Teilen-Zeichen (Viereck mit Pfeil nach oben), '
+ 'dann auf „Zum Home-Bildschirm".'
+ 'dann auf „Zum Home-Bildschirm“.'
: 'Öffne das Menü deines Browsers (die drei Punkte) und wähle dort '
+ '„App installieren" oder „Zum Startbildschirm hinzufügen".';
+ '„App installieren“ oder „Zum Startbildschirm hinzufügen“.';
const dazu = 'Danach liegt die Seite wie eine App auf deinem Gerät – und '
+ 'Anrufe und Nachrichten kommen zuverlässiger an.';
+5 -5
View File
@@ -1102,7 +1102,7 @@
const knoepfe = el('div', 'k-serie__knoepfe');
knoepfe.append(tuKnopf(s.aktiv ? 'abstellen' : 'wieder starten', async () => {
if (s.aktiv && !await frageNach({
titel: 'Wiederholung „' + s.titel + '" abstellen?',
titel: 'Wiederholung „' + s.titel + '“ abstellen?',
was: 'Kommende Termine, die noch niemand angefasst hat, werden aus '
+ 'dem Kalender genommen.',
bleibt: 'Vergangene und bearbeitete Termine bleiben stehen. Du kannst '
@@ -1119,7 +1119,7 @@
}));
knoepfe.append(tuKnopf('löschen', async () => {
if (!await frageNach({
titel: 'Wiederholung „' + s.titel + '" ganz löschen?',
titel: 'Wiederholung „' + s.titel + '“ ganz löschen?',
was: 'Die Regel ist damit weg. Kommende, noch unangetastete Termine '
+ 'werden entfernt.',
bleibt: 'Vergangene und schon bearbeitete Termine bleiben als '
@@ -1391,13 +1391,13 @@
if (!await frageNach({
titel: e.serie_id
? 'Nur diesen einen Termin am ' + tagLang(e.tag) + ' streichen?'
: 'Termin „' + e.titel + '" löschen?',
: 'Termin „' + e.titel + '“ löschen?',
was: e.serie_id
? 'Nur dieser eine Tag entfällt.'
: 'Der Termin verschwindet aus dem Kalender.',
bleibt: e.serie_id
? 'Die Wiederholung „' + e.titel + '" läuft weiter. Zum Abstellen '
+ 'den Schalter unter „Läuft von allein" benutzen.'
? 'Die Wiederholung „' + e.titel + '“ läuft weiter. Zum Abstellen '
+ 'den Schalter unter „Läuft von allein“ benutzen.'
: 'Alle anderen Termine bleiben stehen.',
endgueltig: true, ja: e.serie_id ? 'Diesen Tag streichen' : 'Löschen',
})) return;
+1 -1
View File
@@ -1568,7 +1568,7 @@
function zeichne(d) {
ergebnis.textContent = '';
if (!d.gesamt) {
zeigeHinweis(`Nichts gefunden zu „${d.frage}".`);
zeigeHinweis(`Nichts gefunden zu „${d.frage}“.`);
return;
}
for (const g of d.gruppen) {
+3 -3
View File
@@ -219,7 +219,7 @@
if (!z || (!z.diamanten && !z.tage && !z.verweildauer)) {
ziel.append(el('p', 'leistung__leer',
darfEintragen()
? 'Noch keine Ziele gesetzt. Aus „mehr Reichweite" wird hier eine prüfbare Größe.'
? 'Noch keine Ziele gesetzt. Aus „mehr Reichweite“ wird hier eine prüfbare Größe.'
: 'Noch keine Ziele gesetzt.'));
return;
}
@@ -941,7 +941,7 @@
if (d.unbekannt.length) {
zeile(`Nicht zugeordnet (${d.unbekannt.length}): ${d.unbekannt.slice(0, 8).join(', ')}`
+ (d.unbekannt.length > 8 ? ' …' : ''), 'warn');
zeile('Diese Namen stehen bei keinem Creator im Feld „TikTok" im Steckbrief. '
zeile('Diese Namen stehen bei keinem Creator im Feld „TikTok“ im Steckbrief. '
+ 'Dort eintragen – danach werden sie beim nächsten Mal gefunden.', 'still');
}
if (d.probleme_gesamt) {
@@ -1050,7 +1050,7 @@
bei einer Ausgabe eine Titelzeile darueber), ist die Sorte
Hilfsbereitschaft, die spaeter niemand nachvollzieht. */
if (ausExcel) {
melde(`Excel gelesen: Blatt „${ausExcel.blatt}", ${ausExcel.zeilen} Zeilen, `
melde(`Excel gelesen: Blatt „${ausExcel.blatt}“, ${ausExcel.zeilen} Zeilen, `
+ `${ausExcel.spalten} Spalten`
+ (ausExcel.uebersprungen ? ` (${ausExcel.uebersprungen} Titelzeile übersprungen)` : ''));
setTimeout(() => melde(''), 7000);
+5 -5
View File
@@ -195,7 +195,7 @@
gesehen. Gemessen an der Quelle, nicht angenommen. */
const erg = await window.frageNach?.({
titel: 'Wirklich entfernen?',
was: `„${m.name}" verschwindet aus der Liste, und die Datei wird gelöscht.`,
was: `„${m.name}“ verschwindet aus der Liste, und die Datei wird gelöscht.`,
bleibt: 'Was schon jemand genommen hat, ist davon nicht betroffen — '
+ 'das liegt längst auf seinem Gerät.',
endgueltig: true,
@@ -526,12 +526,12 @@
schlicht gelogen und schickte jemanden los, der schon am Ziel ist. */
function leerSatz(untenAnzahl) {
if (katFilter && untenAnzahl) {
return `Unter „${ZUSTAND_WORT[katFilter] || katFilter}" steht nichts zum `
return `Unter „${ZUSTAND_WORT[katFilter] || katFilter}“ steht nichts zum `
+ 'Mitnehmen — was dazu passt, findest du weiter unten.';
}
if (katFilter) {
return `In „${ZUSTAND_WORT[katFilter] || katFilter}" ist gerade nichts. `
+ 'Tipp oben auf „Alle", um wieder alles zu sehen.';
return `In „${ZUSTAND_WORT[katFilter] || katFilter}“ ist gerade nichts. `
+ 'Tipp oben auf „Alle“, um wieder alles zu sehen.';
}
return stand.darf_einstellen
? 'Gerade nichts frei. Stell oben etwas bereit — dann können die anderen es sich holen.'
@@ -580,7 +580,7 @@
const sofort = frei.filter((m) => m.zustand === 'frei').length;
$('frei-satz').textContent = !frei.length ? ''
: katFilter
? `${frei.length} in „${ZUSTAND_WORT[katFilter] || katFilter}". `
? `${frei.length} in „${ZUSTAND_WORT[katFilter] || katFilter}“. `
+ 'Wer es nimmt, hat es — danach ist es für alle anderen weg.'
: `${frei.length} Stück zum Mitnehmen`
+ (sofort === frei.length ? '. ' : `, davon ${sofort} sofort. `)
+6 -6
View File
@@ -154,7 +154,7 @@
abgelehnt: 'Du hast diese Aufgabe abgelehnt. Wenn du sie doch machen willst, sag kurz Bescheid.',
darf_nicht_bewerten:'Rückmeldung geben dürfen nur DogFather und die Hände.',
ungueltige_bewertung:'Diese Rückmeldung kennt das System nicht. Lade die Seite neu.',
text_fehlt: 'Zu „Verbesserungsmöglichkeiten" gehört ein Satz – sonst weiß niemand, was gemeint ist.',
text_fehlt: 'Zu „Verbesserungsmöglichkeiten“ gehört ein Satz – sonst weiß niemand, was gemeint ist.',
text_zu_lang: 'Der Text ist zu lang. Kürze ihn etwas.',
noch_nicht_erledigt:'Rückmeldung gibt es erst, wenn die Aufgabe fertig ist.',
/* 22.09.2026: Seit die Modis sich keine Aufgaben mehr selbst geben,
@@ -217,7 +217,7 @@
+ 'zurückzusetzen würde allen das Video wegnehmen.',
satz_unbekannt:
'Diesen Münzsatz gibt es nicht. Wähl einen aus der Liste — '
+ '„Eigenes Zeichen" geht erst, wenn du eines hochgeladen hast.',
+ '„Eigenes Zeichen“ geht erst, wenn du eines hochgeladen hast.',
person_unbekannt:
'Diese Person gibt es hier nicht. Wähl jemanden aus der Liste '
+ 'oder lass das Feld leer.',
@@ -284,7 +284,7 @@
'Das Bild ist zu groß. Erlaubt sind 3 MB.',
kein_zweites:
'Es liegt kein zweites Video bereit. Trag eins unter „Sendung" ein, '
'Es liegt kein zweites Video bereit. Trag eins unter „Sendung“ ein, '
+ 'dann kannst du hin und her wechseln.',
betrag_unklar:
'Diese Zahl ergibt keinen Sinn. Schreib sie in Dogen, '
@@ -304,7 +304,7 @@
'Diese Maßnahme gibt es nicht. Möglich sind: stumm und aus der Sendung.',
nicht_gegen_team:
'Gegen jemanden aus dem Team geht das hier nicht. '
+ 'Wenn wirklich etwas ist, gehört das zu „Personen & Zugänge".',
+ 'Wenn wirklich etwas ist, gehört das zu „Personen & Zugänge“.',
dauer_unklar:
'Eine Stummschaltung geht höchstens eine Stunde. '
+ 'Für länger nimm die Maßnahmen im Treff – die haben eine Begründung und eine Frist.',
@@ -355,7 +355,7 @@
kein_block: 'Diesen Bereich gibt es nicht mehr. Lade die Seite neu.',
kein_hakt:
'Daraus lässt sich kein Schritt machen – dafür müsste der Punkt auf '
+ '„Da hakt es" stehen.',
+ '„Da hakt es“ stehen.',
/* ---- Erst das andere zu Ende -------------------------------- */
uebergang_offen:
@@ -387,7 +387,7 @@
'Da war jemand schneller – das ist schon vergeben. Such dir ein '
+ 'anderes aus, damit nichts zweimal gepostet wird.',
nicht_genommen:
'Dieses Bild gehört dir nicht. Nimm dir eines aus „Zum Mitnehmen", '
'Dieses Bild gehört dir nicht. Nimm dir eines aus „Zum Mitnehmen“, '
+ 'dann kannst du es laden.',
art_nicht_erlaubt:
'Das geht hier nicht – es nimmt nur Bilder (JPG, PNG, WebP, GIF, '
+2 -2
View File
@@ -800,7 +800,7 @@
/* HIER WIRD GEFRAGT, und nur hier. Der Unterschied zum Wegtun ist
genau der, der eine Rückfrage rechtfertigt: Danach gibt es
keinen Weg zurück mehr. */
const name = titel ? `„${titel}"` : 'dieses Blatt';
const name = titel ? `„${titel}“` : 'dieses Blatt';
/* DER HAUSDIALOG, NICHT `confirm()` (30.09.2026).
Hier stand der nackte Kasten des Browsers — ohne Notnagel, ohne
@@ -899,7 +899,7 @@
const dazu = rest && notizen.find((x) => x.id === rest.id);
if (dazu && rest.text !== dazu.text) {
melde('Auf diesem Gerät liegt noch eine ungesicherte Fassung von '
+ `„${dazu.titel || 'Ohne Titel'}". Öffne das Blatt – du kannst sie dann übernehmen.`);
+ `„${dazu.titel || 'Ohne Titel'}“. Öffne das Blatt – du kannst sie dann übernehmen.`);
dazu.rest = rest.text;
} else if (rest) {
lagerLeeren();
+5 -5
View File
@@ -215,7 +215,7 @@
if (a.status === 401) {
if (codeOffen) {
melde('Deine Sitzung ist beendet. Schreib den Code oben JETZT ab – '
+ 'die Seite bleibt stehen, bis du „Verstanden" drückst.');
+ 'die Seite bleibt stehen, bis du „Verstanden“ drückst.');
throw new Error('abgemeldet, Code steht noch');
}
location.assign('/workspace/'); throw new Error('abgemeldet');
@@ -350,11 +350,11 @@
const name = $('rolle-wahl').querySelector('.rollenwahl__knopf[data-an="ja"] .rollenwahl__name')?.textContent || gewaehlt;
if (!await frageNach({
titel: `${rolleFuer.name}: Rolle ändern?`,
was: `Von „${ROLLENNAME[rolleFuer.rolle] || rolleFuer.rolle}" zu „${name}".`
was: `Von „${ROLLENNAME[rolleFuer.rolle] || rolleFuer.rolle}“ zu „${name}“.`
+ ' Damit ändert sich, welche Seiten die Person öffnen darf.',
bleibt: 'Der Zugangscode bleibt derselbe. Offene Sitzungen werden beendet, '
+ 'danach kann sie sich mit dem alten Code wieder anmelden.',
ja: `Zu „${name}" machen`,
ja: `Zu „${name}“ machen`,
})) return;
const a = await hole(`/workspace/api/verwaltung/personen/${rolleFuer.id}/rolle`, {
@@ -942,7 +942,7 @@ Der Code gilt einmal fuer die `
].filter(Boolean).join(' ');
if (!await frageNach({
titel: `„${v.person.name}" löschen?`,
titel: `„${v.person.name}“ löschen?`,
was: wasWeg,
bleibt: wasBleibt,
endgueltig: true,
@@ -960,7 +960,7 @@ Der Code gilt einmal fuer die `
if (!a.ok) { melde(sagWas(d.fehler, 'Löschen hat nicht geklappt.')); return; }
/* Die Sicherung nennen. Wer gerade etwas Unumkehrbares getan hat,
soll sofort wissen, woraus es sich zurückholen lässt. */
melde(`„${v.person.name}" wurde gelöscht. Sicherung davor: ${d.sicherung}`);
melde(`„${v.person.name}“ wurde gelöscht. Sicherung davor: ${d.sicherung}`);
await laden();
} catch { /* umgeleitet */ }
}
+7 -7
View File
@@ -334,7 +334,7 @@
denselben Worten wie überall im Haus. */
const ja = await window.frageNach?.({
titel: 'Botschaft löschen?',
was: `„${b.text}" wird aus dem Band genommen.`,
was: `„${b.text}“ wird aus dem Band genommen.`,
endgueltig: true,
ja: 'Löschen', nein: 'Behalten',
});
@@ -2338,7 +2338,7 @@
reihe.append(kasten);
}
$('ton-hinweis').textContent =
'Die Regler gelten für das, was DU hörst. Nur „Mein Mikro" und der '
'Die Regler gelten für das, was DU hörst. Nur „Mein Mikro“ und der '
+ 'Stummschalter an einer Gastkarte gelten für alle. Der Balken zeigt '
+ 'den gemessenen Pegel — beim YouTube-Regler die eingestellte '
+ 'Lautstärke, denn Ton aus einem fremden Rahmen lässt sich nicht messen.';
@@ -3131,11 +3131,11 @@
gleichzeitig, und drei Zeilen untereinander liest mitten in
einer Sendung niemand. */
$('kamecke-hinweis').textContent = !kamerasDa
? 'Bei „Nur Video" sind die Kamerafenster ganz weg — Größe und Ecke '
? 'Bei „Nur Video“ sind die Kamerafenster ganz weg — Größe und Ecke '
+ 'gelten wieder, sobald sie zurückkommen.'
: eckeGilt
? 'Unten rechts liegt bei TikTok die Knopfreihe — such dir eine freie Ecke.'
: 'Die Ecke gilt bei „Video groß" — gerade stehen die Fenster in der Mitte.';
: 'Die Ecke gilt bei „Video groß“ — gerade stehen die Fenster in der Mitte.';
/* ---- Der Umschalter ----
Er steht nur da, wenn es etwas zum Umschalten GIBT. Ein Knopf,
@@ -3146,7 +3146,7 @@
if (lage.zweit) {
const wort = lage.zweit.titel || lage.zweit.video;
$('v-tausch-titel').textContent = wort.length > 34 ? wort.slice(0, 33) + '…' : wort;
tausch.title = `Wechseln zu „${wort}"`
tausch.title = `Wechseln zu „${wort}“`
+ (lage.zweit.sekunde > 2 ? ` — weiter bei ${alsZeit(lage.zweit.sekunde)}` : '');
}
if (document.activeElement !== $('p-zweit')) {
@@ -3510,7 +3510,7 @@
const leer = el('li');
leer.append(el('p', 'warte-leer',
'Nichts vorbereitet. Häng oben eine YouTube-Adresse an — dann '
+ 'reicht im Live ein Druck auf „Nächstes".'));
+ 'reicht im Live ein Druck auf „Nächstes“.'));
kasten.append(leer);
return;
}
@@ -4585,7 +4585,7 @@
kasten.append(el('p', 'raus__text',
wort === 'treff_massnahme'
? 'Im Treff läuft eine Maßnahme gegen dich. Solange sie läuft, bist du '
+ 'bei der Reaction nicht dabei. Was los ist, steht im Treff unter „Meine Maßnahmen".'
+ 'bei der Reaction nicht dabei. Was los ist, steht im Treff unter „Meine Maßnahmen“.'
: 'Die Moderation hat dich aus dieser Sendung genommen. Das gilt nur für heute — '
+ 'bei der nächsten Reaction bist du wieder dabei.'));
document.body.append(kasten);
+2 -2
View File
@@ -144,7 +144,7 @@
lange niemand — und genau das ist der Klick, bei dem eine
Sekunde Nachdenken etwas wert ist. */
if (erlaubt && !await frageNach({
titel: `„${rolle.name}" darf danach ${seite.datei} öffnen`,
titel: `„${rolle.name}“ darf danach ${seite.datei} öffnen`,
was: 'Das gilt sofort, für alle mit dieser Rolle.',
bleibt: 'Zurücknehmen geht jederzeit mit demselben Schalter – aber bis '
+ 'dahin hat jeder mit dieser Rolle Zugang.',
@@ -162,7 +162,7 @@
melde(sagWas((await a.json().catch(() => ({}))).fehler, 'Ging nicht.'));
return;
}
melde(`Gespeichert: „${rolle.name}" darf ${seite.datei} `
melde(`Gespeichert: „${rolle.name}“ darf ${seite.datei} `
+ `${erlaubt ? 'jetzt' : 'nicht mehr'} öffnen.`, 'gut');
await laden();
} finally {
+4 -4
View File
@@ -174,7 +174,7 @@
const knöpfe = el('div', 'kk__knoepfe');
const ziel = WEITER[l.status];
if (ziel) {
const w = el('button', 'knopf knopf--klein knopf--weiter', 'Weiter zu „' + stufen[ziel] + '"');
const w = el('button', 'knopf knopf--klein knopf--weiter', 'Weiter zu „' + stufen[ziel] + '“');
w.type = 'button';
w.addEventListener('click', () => stufeSetzen(l, ziel));
knöpfe.append(w);
@@ -330,7 +330,7 @@
wg.type = 'button';
wg.addEventListener('click', async () => {
if (!await frageNach({
titel: `„${l.name}" aus der Pipeline entfernen?`,
titel: `„${l.name}“ aus der Pipeline entfernen?`,
was: 'Der Lead verschwindet aus der Liste, samt Notizen und Verlauf.',
bleibt: 'Andere Leads bleiben unberührt.',
endgueltig: true, ja: 'Entfernen',
@@ -350,7 +350,7 @@
async function onboarding(l, knopf) {
if (!await frageNach({
titel: `Aus „${l.name}" einen Creator mit eigenem Zugang anlegen?`,
titel: `Aus „${l.name}“ einen Creator mit eigenem Zugang anlegen?`,
was: 'Es entsteht ein Konto mit eigenem Zugangscode.',
bleibt: 'Der Lead bleibt in der Pipeline stehen und wird als '
+ 'übernommen markiert.',
@@ -448,7 +448,7 @@
+ 'also nicht daran denken, die Seite denkt für dich.'));
kasten.append(el('p', 'erklaerung__los',
'„Neuer Kontakt" oben rechts legt den ersten an.'));
'„Neuer Kontakt“ oben rechts legt den ersten an.'));
ziel.append(kasten);
return;
+2 -2
View File
@@ -429,10 +429,10 @@
titel: nachtrag ? 'Noch etwas nachschicken?' : 'Behoben – beim Melder nachfragen?',
was: nachtrag
? 'Dein neuer Satz ERSETZT den alten in dieser Runde – der Melder sieht nur ihn.'
: 'Er bekommt deinen Satz und zwei Knöpfe: „Geht wieder" oder „Noch nicht".',
: 'Er bekommt deinen Satz und zwei Knöpfe: „Geht wieder“ oder „Noch nicht“.',
bleibt: nachtrag
? 'Die Meldung bleibt bei ihm liegen. Der Verlauf davor bleibt stehen.'
: 'Erledigt ist sie erst, wenn ER bestätigt. Sagt er „noch nicht", '
: 'Erledigt ist sie erst, wenn ER bestätigt. Sagt er „noch nicht“, '
+ 'kommt sie zurück – mit allem, was ihr bisher geschrieben habt.',
ja: nachtrag ? 'Nachschicken' : 'Nachfragen',
grund: 'Was ist daraus geworden?',
+2 -2
View File
@@ -78,7 +78,7 @@
if (!schluessel) {
sagFehler('Diese Adresse ist unvollständig — der Schlüssel fehlt. '
+ 'Hol sie dir im Regiepult unter „Bühne".');
+ 'Hol sie dir im Regiepult unter „Bühne“.');
return;
}
@@ -129,7 +129,7 @@
.then((a) => {
if (a.status === 404) {
sagFehler('Der Schlüssel stimmt nicht mehr. '
+ 'Hol dir die Adresse neu im Regiepult unter „Bühne".');
+ 'Hol dir die Adresse neu im Regiepult unter „Bühne“.');
return;
}
verbinden();
+4 -4
View File
@@ -499,7 +499,7 @@
hier: Was der Browser prüft, ist Höflichkeit, was der Server
prüft, ist die Regel. */
if (grund.length < 10) {
melde('Ein Satz gehört dazu – „passt nicht" ist keiner.');
melde('Ein Satz gehört dazu – „passt nicht“ ist keiner.');
feld.focus();
return;
}
@@ -1102,7 +1102,7 @@
const a = el('a', null, 'Talente-Brett öffnen');
a.href = 'bereich.html?b=talente';
fuss.append(a);
fuss.append('. Von dort landet es hier automatisch auf „Aufgefallen".');
fuss.append('. Von dort landet es hier automatisch auf „Aufgefallen“.');
ziel.append(fuss);
beendeteZeigen(ziel);
@@ -1154,7 +1154,7 @@
stehen, statt auf einen eigenen Wert „beendet" umgeschrieben zu
werden -- „nach dem ersten Hinsehen" und „in der Probe" sind
zwei verschiedene Sätze. */
kopf.append(el('span', 't-beendet__stufe', 'in „' + k.stufe_name + '"'));
kopf.append(el('span', 't-beendet__stufe', 'in „' + k.stufe_name + '“'));
kopf.append(el('span', 't-beendet__zeit', kurzDatum(k.beendet.am)));
a.append(kopf);
@@ -1165,7 +1165,7 @@
const wieder = el('button', 't-beendet__wieder', 'Wieder aufnehmen');
wieder.type = 'button';
wieder.title = 'Beginnt neu bei „Aufgefallen". Der Satz von damals '
wieder.title = 'Beginnt neu bei „Aufgefallen“. Der Satz von damals '
+ 'wandert in die Notiz.';
wieder.addEventListener('click', async () => {
wieder.disabled = true;
+1 -1
View File
@@ -277,7 +277,7 @@
const darfPersonen = Array.isArray(window.__ich?.seiten)
&& window.__ich.seiten.includes('/workspace/personen.html');
ziel.append(el('p', 'leise', darfPersonen
? 'Noch niemand. Zugänge legst du in „Personen & Zugänge" an, Rolle Community.'
? 'Noch niemand. Zugänge legst du in „Personen & Zugänge“ an, Rolle Community.'
: 'Noch niemand. Zugänge für die Community legt DogFather an – '
+ 'sag ihm im Chat Bescheid, wenn jemand dazukommen soll.'));
return;
+3 -3
View File
@@ -334,7 +334,7 @@
Tastatur bedienen — `confirm` sperrt die ganze Seite. */
const ja = window.bestaetige
? await window.bestaetige({
titel: `„${w.titel}" entfernen?`,
titel: `„${w.titel}“ entfernen?`,
text: 'Der Weg verschwindet für alle, und die Striche der letzten '
+ 'Monate gehen mit. Das lässt sich nicht zurückholen.',
ja: 'Entfernen', nein: 'Behalten',
@@ -439,8 +439,8 @@
if (ohne.length || unsichtbar.length) {
const namen = [...new Set([...ohne, ...unsichtbar].map((w) => w.titel))].join(', ');
satz.textContent = `Noch ohne Adresse und deshalb für niemanden sichtbar: ${namen}. `
+ 'Drück auf „Ändern", trag die Adresse ein und setz den Haken bei '
+ '„steht für alle da".';
+ 'Drück auf „Ändern“, trag die Adresse ein und setz den Haken bei '
+ '„steht für alle da“.';
satz.dataset.warnung = 'ja';
} else {
satz.textContent = 'Du kannst hier jeden Weg umschreiben, ausblenden oder '
+5 -5
View File
@@ -574,7 +574,7 @@
den Menschen, nicht über die Aufgabe. */
if (a2.entscheid_text) {
z.append(el('span', 'vorlagenbrett__antwort-grund',
'„' + a2.entscheid_text + '"'
'„' + a2.entscheid_text + '“'
+ (a2.von_name ? ' – ' + a2.von_name : '')));
}
band.append(z);
@@ -710,7 +710,7 @@
z.append(el('span', 'vorlagenbrett__absagen-was', a3.titel));
if (a3.entscheid_text) {
z.append(el('span', 'vorlagenbrett__absagen-grund',
'„' + a3.entscheid_text + '"'
'„' + a3.entscheid_text + '“'
+ (a3.von_name ? ' – ' + a3.von_name : '')));
}
block.append(z);
@@ -1336,7 +1336,7 @@
if (i === 0 && offeneB.length > 1) {
reihe.append(el('span', 'vorlagenbrett__bzuerst', 'zuerst da'));
}
if (b2.text) reihe.append(el('span', 'vorlagenbrett__bwort', `„${b2.text}"`));
if (b2.text) reihe.append(el('span', 'vorlagenbrett__bwort', `„${b2.text}“`));
for (const [weg, schild, klasse] of [
['annehmen', 'Annehmen', 'knopf--klar'],
['ablehnen', 'Ablehnen', ''],
@@ -1430,7 +1430,7 @@
async function bewerben(knopf, v) {
const antwort = await window.frageNach({
titel: 'Für diese Aufgabe bewerben?',
was: `„${v.titel}" – DogFather oder die rechte Hand entscheiden, ob du sie bekommst.`,
was: `„${v.titel}“ – DogFather oder die rechte Hand entscheiden, ob du sie bekommst.`,
bleibt: 'Du kannst deine Bewerbung jederzeit wieder zurückziehen.',
grund: 'Willst du etwas dazuschreiben? (freiwillig)',
grundPflicht: false,
@@ -1486,7 +1486,7 @@
const antwort = await window.frageNach({
titel: `${schild} — ${wem}`,
was: weg === 'annehmen'
? `${wem} bekommt „${v.titel}" als Aufgabe auf das Brett.`
? `${wem} bekommt „${v.titel}“ als Aufgabe auf das Brett.`
: `${wem} bekommt sie nicht. Die Vorlage bleibt für alle offen.`,
/* DER TEXT IST DER GRUND, WARUM FILIPE DAS SO WOLLTE: „mit einem
text als notiz". Eine Absage ohne Satz ist die, nach der
+1 -1
View File
@@ -222,7 +222,7 @@
der Unterschied nicht in Zahlen zu sehen (`scrollWidth`
ist in beiden Faellen gleich) -- nur im Bild. */
const eigen = el('button', 'wahl2__eintrag wahl2__eintrag--eigen');
eigen.append(el('span', 'wahl2__name', `„${suche.trim()}" eintragen`));
eigen.append(el('span', 'wahl2__name', `„${suche.trim()}“ eintragen`));
eigen.type = 'button';
eigen.setAttribute('role', 'option');
eigen.addEventListener('click', () => {
+1 -1
View File
@@ -252,7 +252,7 @@
weg.type = 'button';
weg.addEventListener('click', async () => {
if (!await frageNach({
titel: `„${e.titel}" löschen?`,
titel: `„${e.titel}“ löschen?`,
was: 'Der Eintrag verschwindet aus dem Wissen. Die PDF wird dabei '
+ 'auch vom Server entfernt.',
bleibt: 'Wer sie schon heruntergeladen hat, behält seine Kopie.',
+4 -4
View File
@@ -199,7 +199,7 @@
/* DER GRUND GEHÖRT DANEBEN, nicht hinter einen zweiten Klick:
Wer "abgelehnt" liest, will als Nächstes wissen, warum. */
if (z.zustand === 'abgelehnt' && z.grund) {
zeile.append(el('span', 'z-wer__grund', '„' + z.grund + '"'));
zeile.append(el('span', 'z-wer__grund', '„' + z.grund + '“'));
}
if (z.bewertung) {
var b = el('span', 'z-wer__bewertung', z.bewertung_text_kurz);
@@ -212,7 +212,7 @@
sie gehoert daneben, nicht hinter einen zweiten Klick. */
if (z.entscheid_text) {
zeile.append(el('span', 'z-wer__grund',
'„' + z.entscheid_text + '"'
'„' + z.entscheid_text + '“'
+ (z.entschieden_von_name ? ' – ' + z.entschieden_von_name : '')));
}
wer.append(zeile);
@@ -437,7 +437,7 @@
if (i === 0 && bewerbungen.length > 1) {
reihe.append(el('span', 'z-bewerbung__zuerst', 'zuerst da'));
}
if (z.grund) reihe.append(el('span', 'z-bewerbung__wort', '„' + z.grund + '"'));
if (z.grund) reihe.append(el('span', 'z-bewerbung__wort', '„' + z.grund + '“'));
[['annehmen', 'Annehmen', 'knopf--klar'],
['ablehnen', 'Ablehnen', ''],
@@ -522,7 +522,7 @@
{ person_id: z.person_id, bewertung: art, text: antwort.grund || '' });
if (r.ok) { nachLaden(); return; }
sagen(meldung, r.json.fehler === 'text_fehlt'
? 'Bei „Verbesserungsmöglichkeiten" gehört ein Satz dazu — sonst weiß '
? 'Bei „Verbesserungsmöglichkeiten“ gehört ein Satz dazu — sonst weiß '
+ wem + ' nicht, was gemeint ist.'
: (window.sagWas ? window.sagWas(r.json.fehler) : 'Hat nicht geklappt.'), false);
});