Files
dogfather-universe/workspace/assets/js/vorlagen.js
T
DogFatherGitandClaude Opus 5 f9bf7d5674 "Hilfe anfordern" entfaellt - es bleibt die Rueckmeldung
Wunsch: "die sollen nirgendwo Hilfe anfordern koennen, sondern nur
Rueckmeldungen."

Es ist auch die klarere Loesung. Es gab zwei Wege, dasselbe zu sagen:
einen Knopf, der eine Aufgabe erzeugte, und ein Textfeld, das eine
Nachricht schrieb. Zwei Wege fuer eine Sache heisst, dass niemand weiss,
welcher der richtige ist -- und dass Antworten mal als Aufgabe und mal
als Nachricht landen. Wer dann nachsieht, findet die Haelfte nicht.

Geblieben ist die Rueckmeldung an jedem Punkt: ein Verlauf, in dem beide
Seiten schreiben koennen, sichtbar dort, wo es hingehoert -- am Punkt
selbst und nicht in einer zweiten Liste.

VOLLSTAENDIG entfernt, nicht nur ausgeblendet:
  * der Knopf in der Checkliste
  * der Knopf und die Marke "Hilfe moeglich" im Vorlagenblock
  * die Route /workspace/api/vorlagen/hilfe
  * 47 Datenfelder hilfe: true/false in den Vorlagen
  * die zugehoerigen Stile
  * der Abschnitt in pruef-vorlagen.mjs

Datenfelder, die nichts mehr bewirken, und Routen, die niemand mehr
aufruft, werden beim naechsten Mal fuer lebenden Code gehalten und
mitgepflegt. Das ist teurer als das Entfernen heute.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 17:19:19 +02:00

190 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===================================================================
Vorlagen — fertige Inhalte, die man übernehmen kann.
EIN Bauteil für mehrere Seiten (Content-Ideen, LIVE-Analyse). Es
hängt sich an einen Behälter mit `data-vorlagen="<art>"` und baut
dort eine aufklappbare Liste von Vorschlägen.
Warum ausgeklappt-per-Knopf und nicht offen: Wer schon zwanzig eigene
Einträge hat, braucht die Vorschläge nicht mehr im Weg. Wer noch
keinen hat, sieht den Knopf sofort -- und er ist dann das Auffälligste
auf der Seite, weil sonst nichts da ist.
Übernehmen macht aus dem Vorschlag einen ganz normalen Eintrag. Ab
dann ist er unabhängig von der Vorlage: änderbar, löschbar, und
spätere Änderungen an der Vorlage berühren ihn nicht.
=================================================================== */
(() => {
'use strict';
const el = (tag, klasse, text) => {
const k = document.createElement(tag);
if (klasse) k.className = klasse;
if (text !== undefined) k.textContent = text;
return k;
};
async function hole(pfad, optionen = {}) {
const a = await fetch(pfad, { credentials: 'same-origin', ...optionen });
if (a.status === 401) { location.assign('/workspace/'); throw new Error('abgemeldet'); }
return a;
}
let vorlagen = null;
/* Was in dieser Sitzung schon uebernommen wurde. Muss AUSSERHALB des
Bauvorgangs stehen: Nach dem Uebernehmen wird die Liste neu geladen
und der Block neu gebaut -- eine Markierung am Element allein waere
dabei jedes Mal verloren. Genau das hat die Pruefung gemeldet
("als uebernommen markiert: 0").
Bewusst nur fuer diese Sitzung und nicht dauerhaft gespeichert: Wer
die Seite neu laedt, hat seine Eintraege ja in der Liste stehen --
dort gehoeren sie hin, nicht in eine zweite Buchfuehrung. */
const genommen = new Set();
/** Baut den Vorlagenblock in einen Behälter.
* art: 'content' | 'live'
* unterart: bei live der Abschnitt (vorbereitung | mitschrift | auswertung)
* creatorId: für wen übernommen wird (Betreuer); bei Creator egal
* danach: wird nach dem Übernehmen aufgerufen (Liste neu laden) */
window.vorlagenBlock = async function (behaelter, { art, unterart, creatorId, danach }) {
if (!behaelter) return;
if (!vorlagen) {
try {
const a = await hole('/workspace/api/vorlagen');
if (!a.ok) return;
vorlagen = await a.json();
} catch { return; }
}
const liste = art === 'content' ? vorlagen.content
: (vorlagen.live?.[unterart] || []);
if (!liste.length) return;
behaelter.textContent = '';
const block = el('section', 'vorlagen');
/* ---- Kopf mit Aufklappknopf ---- */
const kopf = el('div', 'vorlagen__kopf');
const titel = el('div', null);
titel.append(el('p', 'feldschild', 'Fertige Vorschläge'));
titel.append(el('p', 'vorlagen__unter',
art === 'content'
? `${liste.length} Ideen mit Aufhänger und Format – zum Übernehmen und Anpassen.`
: `${liste.length} Punkte, die sich bewährt haben. Übernehmen und abhaken.`));
kopf.append(titel);
const auf = el('button', 'knopf knopf--klein');
auf.type = 'button';
auf.setAttribute('aria-expanded', 'false');
auf.textContent = 'Vorschläge zeigen';
kopf.append(auf);
block.append(kopf);
/* ---- Die Liste ---- */
const raster = el('div', 'vorlagen__raster');
raster.hidden = true;
for (const [nr, v] of liste.entries()) {
const k = el('article', 'vorlage');
const schluessel = art + ':' + (unterart || '') + ':' + nr;
if (genommen.has(schluessel)) k.dataset.genommen = 'ja';
if (v.saeule) k.dataset.saeule = v.saeule;
k.append(el('h3', 'vorlage__titel', v.titel));
/* Der Aufhänger ist der wichtigste Teil einer Content-Idee -- die
ersten Sekunden entscheiden über die Verbreitung. Deshalb steht
er hervorgehoben und nicht im Fließtext. */
if (v.hook) {
const h = el('p', 'vorlage__hook');
h.append(el('span', 'vorlage__hookschild', 'Aufhänger'));
h.append(document.createTextNode(v.hook));
k.append(h);
}
if (v.text) k.append(el('p', 'vorlage__text', v.text));
const fuss = el('div', 'vorlage__fuss');
if (v.format) fuss.append(el('span', 'vorlage__marke', v.format));
if (v.saeule) fuss.append(el('span', 'vorlage__marke vorlage__marke--saeule', v.saeule));
const nehmen = el('button', 'schritt', 'Übernehmen');
nehmen.type = 'button';
nehmen.addEventListener('click', async () => {
nehmen.disabled = true;
nehmen.textContent = 'wird übernommen …';
try {
const a = await hole('/workspace/api/vorlagen/uebernehmen', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ art, unterart, nr, creator_id: creatorId }),
});
if (!a.ok) {
const f = await a.json().catch(() => ({}));
nehmen.textContent = f.fehler || 'ging nicht';
nehmen.disabled = false;
return;
}
/* Übernommen bleibt sichtbar markiert -- man soll sehen, was
man schon geholt hat, ohne die Liste zu verlassen. */
genommen.add(schluessel);
k.dataset.genommen = 'ja';
nehmen.textContent = 'übernommen';
danach?.();
} catch { nehmen.disabled = false; nehmen.textContent = 'Übernehmen'; }
});
fuss.append(nehmen);
k.append(fuss);
raster.append(k);
}
/* ---- Alle auf einmal ---- */
const alle = el('div', 'vorlagen__alle');
const allesNehmen = el('button', 'knopf-still',
art === 'content' ? `Alle ${liste.length} Ideen übernehmen`
: `Alle ${liste.length} Punkte übernehmen`);
allesNehmen.type = 'button';
allesNehmen.addEventListener('click', async () => {
if (!confirm(`Wirklich alle ${liste.length} übernehmen? `
+ 'Sie landen als eigene Einträge in der Liste und lassen sich einzeln löschen.')) return;
allesNehmen.disabled = true;
allesNehmen.textContent = 'wird übernommen …';
try {
const a = await hole('/workspace/api/vorlagen/uebernehmen', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ art: art + '_alle', unterart, creator_id: creatorId }),
});
if (!a.ok) { allesNehmen.textContent = 'ging nicht'; allesNehmen.disabled = false; return; }
const { angelegt } = await a.json();
/* Alle auf einmal: dann sind auch alle markiert. */
for (let i = 0; i < liste.length; i++) genommen.add(art + ':' + (unterart || '') + ':' + i);
allesNehmen.textContent = `${angelegt} übernommen`;
danach?.();
} catch { allesNehmen.disabled = false; }
});
alle.append(allesNehmen);
raster.append(alle);
block.append(raster);
auf.addEventListener('click', () => {
const offen = auf.getAttribute('aria-expanded') === 'true';
auf.setAttribute('aria-expanded', offen ? 'false' : 'true');
raster.hidden = offen;
auf.textContent = offen ? 'Vorschläge zeigen' : 'Vorschläge ausblenden';
});
behaelter.append(block);
behaelter.hidden = false;
};
/* Der frühere Knopf "Hilfe anfordern" ist am 01.09.2026 entfallen.
Es gab damit zwei Wege, dasselbe zu sagen -- einen Knopf, der eine
Aufgabe erzeugte, und ein Textfeld für eine Nachricht. Zwei Wege
für eine Sache heißt, dass niemand weiß, welcher der richtige ist,
und dass Antworten mal hier und mal dort landen. Geblieben ist die
Rückmeldung an jedem Punkt. */
})();