Nichts verschwindet mehr ohne eine Nachfrage, die sagt was passiert
Filipe: "Es darf vor allem keine Stellen geben, an denen ein Benutzer
etwas falsch machen kann, nur weil die Seite es nicht verstaendlich
genug erklaert."
Gemessen: 30 Stellen in 16 Dateien benutzten confirm() oder prompt().
Das Haus hatte die richtige Bauweise laengst -- einen <dialog>, in
aufgaben.html sogar ausfuehrlich begruendet -- aber sie stand IN EINER
SEITE. Wer anderswo etwas loeschen liess, hatte sie nicht.
confirm('Wirklich loeschen?') stellt die falsche Frage: Es fragt, ob
man sicher ist, und nennt nicht, WAS passiert, was BLEIBT und ob es
ZURUECK geht. Jetzt beantwortet jeder der 41 Dialoge alle drei.
Neu: workspace/assets/js/nachfrage.js -- window.frageNach() mit
Pflichtgrund, Zahlenfeld, einzeiliger Eingabe und Abtippsicherung.
Drei Ausgaenge: <dialog> / confirm()-Notnagel fuer Safari vor 15.4 /
Abbruch (Esc, Klick daneben, "Doch nicht" -- immer false).
DREIMAL DERSELBE FALLSTRICK, dreimal nachgemessen statt vermutet:
.dialog stand in aufgaben.css und leistung.css -> auf dateien.html
waere der Dialog ein weisser Systemkasten gewesen. 14 Regeln
klammergenau nach module.css verschoben (Klammern gezaehlt, nicht
per Muster geschnitten -- heute frueh hat ein nicht-gieriges
Muster schon einmal CSS zerrissen).
Das Formular trug .neu neu--blank -- und .neu gibt seine Abstaende
nur in aufgaben.css. Gemessen: padding 0px, und die Felder
verloren ihre height:44px. Jetzt steht alles unter
.nachfrage__form in module.css; der Dialog borgt nichts mehr.
Die erste Fassung der Pruefung zaehlte nachfrage.js SELBST als
Nutzer -- damit war jede Seite trivialerweise "Nutzer" und die
Pruefung gruen ohne Inhalt. Jetzt ausdruecklich ausgenommen.
ZWEI FUNDE NEBENBEI:
hilfeAufraeumen() wird im Betrieb NIE aufgerufen. Der Kommentar
behauptete "wird beim Start aufgerufen (siehe index.js)" -- das
war nie wahr; einziger Aufrufer ist die eigene Pruefung. Folge:
geschlossene vertrauliche Faelle bleiben unbegrenzt stehen. NICHT
eingeschaltet (das loescht echte Daten und ist Filipes
Entscheidung), sondern der Kommentar richtiggestellt.
Einen Hilfe-Fall zu schliessen ist endgueltig -- es gibt keine
Route, die ihn wieder oeffnet. Vorher stand darueber nur die
Frage nach einem Schlusswort. Jetzt sagt der Dialog es.
pruef-struktur hat meine eigene Pruefung von heute Nachmittag
erwischt: Sie bildete ihr Datum aus UTC. Beim Beheben erst
heuteLokal(datum) genommen -- die Funktion nimmt gar kein Argument
und haette still "heute" statt "+3 Tage" geliefert. Jetzt tagLokal(3),
nachgerechnet: Abstand 3 Tage.
Am Bildschirm angesehen (Rechner 1280, Handy 390): passt rein, Esc
ergibt false, Fokus liegt auf dem harmlosen Knopf, Knoepfe 44px auf
Touch. Der Platzhalter im Abtippfeld zeigte den erwarteten Namen --
das sah aus wie ein schon ausgefuelltes Feld, entfernt.
Neu: server/pruef-nachfrage.mjs -- 17/0, mit sechs Gegenproben und
beiden Richtungen (wer fragt, laedt die Datei; wer nie fragt, laedt
sie nicht -- sonst truege die Anmeldewand 4,8 KB fuer nichts).
pruef-meldungen 8/0, pruef-css-klassen gruen, pruef-struktur gruen,
pruef-leistung gruen.
This commit is contained in:
@@ -181,10 +181,24 @@
|
||||
}
|
||||
|
||||
async function entscheiden(id, status) {
|
||||
const entscheid = prompt(status === 'erledigt'
|
||||
? 'Was hast du getan?\n\nEin Satz genügt – er wird zur Meldung festgehalten.'
|
||||
: 'Warum ist daran nichts dran?\n\nEin Satz genügt – er wird festgehalten.');
|
||||
if (entscheid === null) return;
|
||||
const ae = await frageNach({
|
||||
titel: status === 'erledigt' ? 'Meldung als erledigt schließen'
|
||||
: 'Meldung als unbegründet schließen',
|
||||
was: status === 'erledigt'
|
||||
? 'Die Meldung gilt danach als bearbeitet.'
|
||||
: 'Die Meldung gilt danach als geprüft, ohne Folgen für die Person.',
|
||||
bleibt: 'Dein Satz wird zur Meldung festgehalten und bleibt im Verlauf '
|
||||
+ 'lesbar. Der Beitrag selbst ändert sich dadurch nicht.',
|
||||
ja: 'Schließen',
|
||||
grund: status === 'erledigt' ? 'Was hast du getan?'
|
||||
: 'Warum ist daran nichts dran?',
|
||||
grundPflicht: true,
|
||||
platzhalter: status === 'erledigt'
|
||||
? 'z. B. Beitrag entfernt und die Person angeschrieben.'
|
||||
: 'z. B. Der Beitrag verstößt gegen keine Regel.',
|
||||
});
|
||||
if (!ae) return;
|
||||
const entscheid = ae.grund;
|
||||
const a = await hole('/workspace/api/treff/meldung/' + id, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -270,24 +284,36 @@
|
||||
wird, hat die Strafe schon festgelegt, bevor er sie begründet hat.
|
||||
So steht am Anfang die Frage, was eigentlich passiert ist. */
|
||||
async function massnahme(m, art, darf) {
|
||||
const grund = prompt(art === 'hinweis'
|
||||
? `Hinweis an ${m.name} – worum geht es?`
|
||||
: `${art === 'pause' ? 'Pause' : 'Ausschluss'} für ${m.name} – warum?\n\n`
|
||||
+ 'Der Grund wird festgehalten, und die Person hat ein Recht darauf.');
|
||||
if (grund === null) return;
|
||||
|
||||
let tage;
|
||||
if (art !== 'hinweis') {
|
||||
const hinweis = darf?.frist_tage
|
||||
? `Du kannst bis zu ${darf.frist_tage} Tage geben.`
|
||||
: 'Leer lassen = dauerhaft (nur bei Ausschluss).';
|
||||
const ein = prompt(`Für wie viele Tage?\n\n${hinweis}`,
|
||||
darf?.frist_tage ? String(darf.frist_tage) : '7');
|
||||
if (ein === null) return;
|
||||
tage = ein.trim() === '' ? null : Number(ein);
|
||||
if (tage !== null && !(tage > 0)) { melde('Das ist keine Anzahl Tage.'); return; }
|
||||
if (tage === null && art === 'pause') { melde('Eine Pause braucht eine Dauer.'); return; }
|
||||
}
|
||||
const istHinweis = art === 'hinweis';
|
||||
const wieLang = istHinweis ? null : (darf?.frist_tage || 0);
|
||||
const a0 = await frageNach({
|
||||
titel: istHinweis
|
||||
? `Hinweis an ${m.name}`
|
||||
: `${art === 'pause' ? 'Pause' : 'Ausschluss'} für ${m.name}`,
|
||||
was: istHinweis
|
||||
? 'Die Person bekommt deinen Text zu lesen. Sie darf weiter mitmachen.'
|
||||
: (art === 'pause'
|
||||
? 'Die Person kann für die eingetragene Zeit nichts schreiben.'
|
||||
: 'Die Person kann nichts mehr schreiben.'),
|
||||
bleibt: 'Der Grund wird festgehalten und der Person mitgeteilt – sie hat '
|
||||
+ 'ein Recht darauf. Aufheben geht jederzeit.',
|
||||
ja: istHinweis ? 'Hinweis schicken' : 'Eintragen',
|
||||
grund: istHinweis ? 'Worum geht es?' : 'Warum?', grundPflicht: true,
|
||||
platzhalter: istHinweis
|
||||
? 'z. B. Bitte nicht mehrfach dasselbe posten.'
|
||||
: 'z. B. Wiederholte Beleidigungen trotz Hinweis.',
|
||||
zahl: istHinweis ? '' : 'Für wie viele Tage?',
|
||||
zahlWert: wieLang ? String(wieLang) : '7',
|
||||
zahlMax: wieLang || 0,
|
||||
/* Leer = dauerhaft, aber NUR beim Ausschluss -- eine Pause ohne
|
||||
Ende waere ein Ausschluss unter falschem Namen. */
|
||||
zahlLeer: art === 'ausschluss' && !wieLang,
|
||||
zahlHinweis: wieLang ? `Höchstens ${wieLang} Tage.`
|
||||
: (art === 'ausschluss' ? 'Leer lassen = dauerhaft.' : ''),
|
||||
});
|
||||
if (!a0) return;
|
||||
const grund = a0.grund;
|
||||
const tage = istHinweis ? undefined : a0.zahl;
|
||||
|
||||
const a = await hole('/workspace/api/treff/massnahme', {
|
||||
method: 'POST',
|
||||
@@ -324,7 +350,13 @@
|
||||
+ ' am ' + datum(m.zeitpunkt)],
|
||||
], laeuft && m.art !== 'hinweis' ? [
|
||||
knopf('aufheben', async () => {
|
||||
if (!confirm(`Maßnahme gegen ${m.person_name} aufheben?`)) return;
|
||||
if (!await frageNach({
|
||||
titel: `Maßnahme gegen ${m.person_name} aufheben?`,
|
||||
was: 'Die Person darf danach sofort wieder mitmachen.',
|
||||
bleibt: 'Die Maßnahme bleibt im Verlauf sichtbar – sie wird nur '
|
||||
+ 'beendet, nicht gelöscht.',
|
||||
ja: 'Aufheben',
|
||||
})) return;
|
||||
const r = await hole('/workspace/api/treff/massnahme/' + m.id, { method: 'DELETE' });
|
||||
if (!r.ok) {
|
||||
melde(sagWas((await r.json().catch(() => ({}))).fehler, 'Ging nicht.'));
|
||||
|
||||
Reference in New Issue
Block a user