"Review" heisst jetzt "Zur Freigabe" -- und Datumsfelder sind so hoch wie alle anderen
Im Code stand die Begruendung selbst: "«Review» allein sagt einem Neuen nichts." Das Wort ist englisch, ein Hauptwort ohne Handlung, und es verraet nicht, WER jetzt dran ist. "Zur Freigabe" sagt beides: fertig von mir, wartet auf jemanden. Geaendert wurde nur, was ein Mensch LIEST -- der Zustandsschluessel bleibt `review`, der gehoert der Datenbank. Betroffen: Spalte und Weiterknopf im Aufgabenbrett, Dateien-Filter, Startseiten-Zaehler, Kachel-Unterzeile, Hinweis "Datei wartet auf Freigabe", Report. NICHT geaendert: der Kalender. Dort ist `review` eine TERMINART (ein Gespraech, in dem man zurueckschaut), kein Zustand. Ich hatte das beim Umbenennen selbst verwechselt und wieder zurueckgenommen -- ein Kommentar an der Stelle haelt die zwei Bedeutungen jetzt auseinander. pruef-sprung hing an der Wortwahl (`/review/i` auf der Beschriftung) und wurde rot, obwohl der Filter richtig stand. Sie prueft jetzt `data-status` -- den Schluessel, der sich nicht mit der Sprache aendert. DAZU, unabhaengig gefunden: Datumsfelder waren 48 px hoch, alle anderen Felder 44. Gemessen auf drei Seiten bei 390 px. Alle liegen auf dem 44-px-Beruehrziel -- nur das Datumsfeld drueckte sich darueber, weil Chromium in `::-webkit-datetime-edit` eine eigene Innenpolsterung setzt, die sogar ein gesetztes `height: 44px` ueberstimmt. Zwei Anteile, einzeln nachgemessen (jeder allein 48->46, erst beide zusammen 48->44): 1 px Polsterung oben und unten im Feldkasten, und eine Zeilenhoehe von 24 statt 22. Keine feste Hoehe gesetzt -- die Zeilenhoehe wird aus Beruehrziel und Polsterung gerechnet, damit sie mitwandert, wenn sich eines davon aendert. Geprueft: pruef-formulare 19/0 (war 16 mit 3 Fehlern), pruef-sprung 43/0, pruef-start-ansicht 151/0, pruef-aufgabenbrett 49/0, pruef-uebersicht 35/0, pruef-uebersicht-browser 20/0, pruef-deutsche-texte, pruef-css-klassen. Ausserdem: vorlagen.js geloescht (8,2 KB). `vorlagenBlock(` wurde inca104799eingebaut und in9267797dwieder ausgebaut -- seither laedt die Datei auf zwei Seiten, ohne dass jemand sie aufruft. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -3921,6 +3921,49 @@ body.start #protokoll {
|
||||
:where(.inhalt) :where(textarea) {
|
||||
resize: vertical; min-height: 52px;
|
||||
}
|
||||
|
||||
/* DATUMS- UND ZEITFELDER MACHEN SICH GROESSER, ALS SIE DUERFEN (20.09.2026).
|
||||
|
||||
Gemessen auf aufgaben.html bei 390 px, alle Felder derselben Reihe:
|
||||
Auswahlfeld 44, Textfeld 44, Datumsfeld 48. Dasselbe auf
|
||||
kalender.html und bereich.html?b=live -- dreimal dieselbe Ursache.
|
||||
|
||||
44 px ist kein Zufallsmass, sondern das Beruehrziel weiter oben.
|
||||
Jedes andere Feld landet von selbst darauf. Das Datumsfeld nicht:
|
||||
Chromium rechnet fuer `input[type=date]` eine eigene Mindesthoehe
|
||||
aus dem Innenleben (`::-webkit-datetime-edit`), und die ueberstimmt
|
||||
sogar ein gesetztes `height: 44px` -- deshalb half die Regel in
|
||||
aufgaben.css nicht, die genau das versucht.
|
||||
|
||||
Zwei Anteile, einzeln nachgemessen (jeder fuer sich bringt 48 -> 46,
|
||||
erst beide zusammen 48 -> 44):
|
||||
1. Der Feldkasten innen hat oben und unten je 1 px Polsterung.
|
||||
2. Seine Zeilenhoehe folgt unseren 1.5 -- 24 statt der 22 px,
|
||||
die in ein 44-px-Feld passen.
|
||||
|
||||
Vier Pixel klingen nach nichts. In einer Reihe aus fuenf Feldern
|
||||
steht aber genau eines heraus: zu wenig, um es benennen zu koennen,
|
||||
genug, damit die Reihe unruhig aussieht. Gefunden hat es
|
||||
pruef-formulare, nicht das Auge.
|
||||
|
||||
KEINE ABGESCHRIEBENE ZAHL: Die Zeilenhoehe wird aus dem Beruehrziel
|
||||
und der Polsterung GERECHNET. Aendert sich eines von beiden, wandert
|
||||
das Datumsfeld mit, statt still wieder auszuscheren.
|
||||
|
||||
Andere Browser kennen `::-webkit-datetime-edit-fields-wrapper` nicht
|
||||
und ueberspringen diese eine Zeile -- die Rechnung darueber gilt dort
|
||||
trotzdem. */
|
||||
:where(.inhalt) :where(input[type="date"], input[type="time"],
|
||||
input[type="datetime-local"]) {
|
||||
--feld-ziel: 44px; /* das Beruehrziel aus dem Handy-Block */
|
||||
--feld-pad-y: 10px; /* dieselbe Polsterung wie bei allen Feldern */
|
||||
--feld-rand: 1px;
|
||||
line-height: calc(var(--feld-ziel) - 2 * var(--feld-pad-y) - 2 * var(--feld-rand));
|
||||
}
|
||||
:where(.inhalt) :where(input[type="date"], input[type="time"],
|
||||
input[type="datetime-local"])::-webkit-datetime-edit-fields-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
:where(.inhalt) :where(input, textarea, select):hover {
|
||||
border-color: color-mix(in srgb, var(--akzent) 26%, var(--rand));
|
||||
}
|
||||
|
||||
@@ -19,14 +19,21 @@
|
||||
dort in allen vier Spalten ein Gedankenstrich -- vier graue Striche
|
||||
nebeneinander sehen aus, als sei die Seite kaputt, obwohl gar nichts
|
||||
kaputt ist. Jeder Satz sagt jetzt, was das Leersein BEDEUTET: eine
|
||||
leere Review-Spalte ist etwas anderes als eine leere Erledigt-Spalte.
|
||||
leere Freigabe-Spalte ist etwas anderes als eine leere Erledigt-Spalte.
|
||||
`unter` erklärt die Spalte auch dann, wenn sie voll ist. */
|
||||
const SPALTEN = [
|
||||
{ status: 'offen', name: 'Offen', unter: 'Angenommen, noch nicht angefangen',
|
||||
leer: 'Nichts liegt herum.' },
|
||||
{ status: 'arbeit', name: 'In Arbeit', unter: 'Läuft gerade',
|
||||
leer: 'Gerade läuft nichts.' },
|
||||
{ status: 'review', name: 'Review', unter: 'Wartet auf Freigabe',
|
||||
/* AUS 'REVIEW' WURDE 'ZUR FREIGABE' (20.09.2026).
|
||||
Weiter unten stand die Begruendung schon selbst da: 'Review'
|
||||
allein sagt einem Neuen nichts. Es ist englisch, es ist ein
|
||||
Hauptwort ohne Handlung, und es verraet nicht, WER jetzt dran
|
||||
ist. 'Zur Freigabe' sagt beides: fertig von mir, wartet auf
|
||||
jemanden. Der Schluessel bleibt `review` -- der gehoert der
|
||||
Datenbank, nicht dem Menschen. */
|
||||
{ status: 'review', name: 'Zur Freigabe', unter: 'Wartet darauf, dass jemand draufschaut',
|
||||
leer: 'Nichts wartet auf Freigabe.' },
|
||||
{ status: 'erledigt', name: 'Erledigt', unter: 'Fertig und abgehakt',
|
||||
leer: 'Hier landet, was fertig ist.' },
|
||||
@@ -45,7 +52,7 @@
|
||||
vergessen, und ein fehlender Knopf faellt niemandem auf. */
|
||||
const DARF_ABBRECHEN = new Set([...window.Bereiche.LEITUNG, 'scout']);
|
||||
const STATUS_NAME = {
|
||||
offen: 'Offen', arbeit: 'In Arbeit', review: 'Review', erledigt: 'Erledigt',
|
||||
offen: 'Offen', arbeit: 'In Arbeit', review: 'Zur Freigabe', erledigt: 'Erledigt',
|
||||
};
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
@@ -437,7 +444,7 @@
|
||||
}
|
||||
|
||||
const beschriftung = (status) => ({
|
||||
offen: 'starten ▶', arbeit: 'zum Review ▶', review: 'erledigt ▶',
|
||||
offen: 'starten ▶', arbeit: 'zur Freigabe ▶', review: 'erledigt ▶',
|
||||
})[status];
|
||||
|
||||
function knopf(text, aufgabe, neuerStatus) {
|
||||
@@ -660,7 +667,8 @@
|
||||
el('span', 'spalte__zahl', String(eigene.length)));
|
||||
spalte.append(kopf);
|
||||
/* Was diese Spalte bedeutet -- steht immer da, nicht nur wenn sie
|
||||
leer ist. "Review" allein sagt einem Neuen nichts. */
|
||||
leer ist. "Review" sagte einem Neuen nichts -- deshalb heisst
|
||||
die Spalte seit dem 20.09.2026 "Zur Freigabe". */
|
||||
spalte.append(el('p', 'spalte__unter', s.unter));
|
||||
|
||||
if (!eigene.length) spalte.append(el('p', 'spalte__leer', s.leer));
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
const HINWEISTEXT = {
|
||||
aufgaben_ueberfaellig: 'überfällige Aufgaben', aufgaben_heute: 'heute fällige Aufgaben',
|
||||
aufgaben_review: 'Aufgaben warten auf Freigabe', termine_heute: 'Termine heute',
|
||||
protokoll_fehlt: 'Gespräche ohne Protokoll', dateien_review: 'Dateien im Review',
|
||||
protokoll_fehlt: 'Gespräche ohne Protokoll', dateien_review: 'Dateien, die auf Freigabe warten',
|
||||
bereiche_dringend: 'dringende Punkte in den Bereichen', startcheck_handlung: 'Punkte im Start-Check',
|
||||
followup_faellig: 'fällige Follow-ups', uebergabe_offen: 'übergebene Leads ohne Creator',
|
||||
review_faellig: 'überfällige Review-Termine', review_bald: 'Reviews in den nächsten 7 Tagen',
|
||||
|
||||
@@ -392,7 +392,7 @@
|
||||
bereiche: [
|
||||
{ name: 'Dashboard', unter: 'Alle Creator auf einen Blick', zeichen: 'dashboard', ton: 1,
|
||||
gross: true, rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'uebersicht.html', szene: 'showbuehne' },
|
||||
{ name: 'Aufgaben', unter: 'Offen, in Arbeit, Review', zeichen: 'aufgaben', ton: 13,
|
||||
{ name: 'Aufgaben', unter: 'Offen, in Arbeit, zur Freigabe', zeichen: 'aufgaben', ton: 13,
|
||||
rollen: ['spicy', 'admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html', szene: 'garage' },
|
||||
/* REIHENFOLGE: CHAT, KALENDER, CALLS (08.09.2026).
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
const LEITUNG = window.Bereiche.LEITUNG;
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const STATUSNAME = { entwurf: 'Entwurf', review: 'Review', freigegeben: 'Freigegeben' };
|
||||
/* 'Review' heisst seit 20.09.2026 'Zur Freigabe' -- Begruendung in
|
||||
aufgaben.js. Der Schluessel bleibt, nur das Wort auf dem
|
||||
Bildschirm aendert sich. */
|
||||
const STATUSNAME = { entwurf: 'Entwurf', review: 'Zur Freigabe', freigegeben: 'Freigegeben' };
|
||||
const WEITER = { entwurf: 'review', review: 'freigegeben' };
|
||||
const ZURUECK = { review: 'entwurf', freigegeben: 'review' };
|
||||
|
||||
@@ -229,7 +232,7 @@
|
||||
if (WEITER[d.status]) {
|
||||
const darf = d.status !== 'review' || LEITUNG.has(ich.rolle);
|
||||
if (darf) knoepfe.append(tuKnopf(
|
||||
d.status === 'entwurf' ? 'zum Review ▶' : 'freigeben ▶',
|
||||
d.status === 'entwurf' ? 'zur Freigabe ▶' : 'freigeben ▶',
|
||||
() => statusSetzen(d, WEITER[d.status])));
|
||||
}
|
||||
if (ZURUECK[d.status] && (d.status !== 'freigegeben' || LEITUNG.has(ich.rolle))) {
|
||||
@@ -383,7 +386,7 @@
|
||||
? 'In diesem Zustand liegt gerade nichts.'
|
||||
: 'Noch keine Datei abgelegt.'));
|
||||
/* AUCH HIER springen, und das ist der wichtigere Fall: Wer auf
|
||||
"2 Dateien im Review" klickt und auf einer leeren Seite
|
||||
"2 Dateien warten auf Freigabe" klickt und auf einer leeren Seite
|
||||
landet, glaubt, er sei falsch abgebogen. Die Leiste sagt ihm,
|
||||
dass er richtig ist und die Sache erledigt.
|
||||
(Dieselbe Luecke gab es in bereich.js -- ein frueher Ausstieg
|
||||
|
||||
@@ -730,7 +730,7 @@
|
||||
den Satz laengst hat.
|
||||
|
||||
Bei dreien war das richtig so: Auf `aufgaben.html` heisst die
|
||||
Ueberschrift „Offen. In Arbeit. Review. Erledigt.", auf
|
||||
Ueberschrift „Offen. In Arbeit. Zur Freigabe. Erledigt.", auf
|
||||
`teamlage.html` „Was auf dich wartet" -- der Satz stuende dort
|
||||
ein zweites Mal. Nachgesehen, nicht gerechnet.
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
.sort((a, b) => b[1].dringend - a[1].dringend)[0];
|
||||
k2.append(kachel(dringend, 'dringende Punkte',
|
||||
{ warn: dringend > 0, ziel: meiste ? bereichZiel(meiste[0], 'dringend') : null }));
|
||||
k2.append(kachel(d.dateien.offen_review, 'Dateien im Review',
|
||||
k2.append(kachel(d.dateien.offen_review, 'Dateien warten auf Freigabe',
|
||||
{ ziel: 'dateien.html?zeigen=review' }));
|
||||
const b2 = block('Was blockiert?', 'Die drei Aufgaben, die am längsten offen liegen:', k2);
|
||||
if (d.aufgaben.aeltester.length) {
|
||||
|
||||
@@ -1369,7 +1369,7 @@
|
||||
aufgaben_review: (n) => `${n} ${n === 1 ? 'Aufgabe wartet' : 'Aufgaben warten'} auf Freigabe`,
|
||||
termine_heute: (n) => `${n} ${n === 1 ? 'Termin steht' : 'Termine stehen'} heute an`,
|
||||
protokoll_fehlt: (n) => `${n} ${n === 1 ? 'Gespräch hat' : 'Gespräche haben'} noch kein Protokoll`,
|
||||
dateien_review: (n) => `${n} ${n === 1 ? 'Datei liegt' : 'Dateien liegen'} im Review`,
|
||||
dateien_review: (n) => `${n} ${n === 1 ? 'Datei wartet' : 'Dateien warten'} auf Freigabe`,
|
||||
bereiche_dringend: (n) => `${n} ${n === 1 ? 'dringender Punkt' : 'dringende Punkte'} in den Bereichen`,
|
||||
followup_faellig: (n) => `${n} Follow-up${n === 1 ? '' : 's'} ${n === 1 ? 'ist' : 'sind'} fällig`,
|
||||
uebergabe_offen: (n) => `${n} übergebene${n === 1 ? 'r Lead wartet' : ' Leads warten'} auf das Onboarding`,
|
||||
@@ -1719,7 +1719,7 @@
|
||||
{ schluessel: 'heute', name: 'Heute fällig' },
|
||||
{ schluessel: 'offen', name: 'Offen' },
|
||||
{ schluessel: 'arbeit', name: 'In Arbeit' },
|
||||
{ schluessel: 'review', name: 'Review' },
|
||||
{ schluessel: 'review', name: 'Zur Freigabe' },
|
||||
{ schluessel: 'erledigt', name: 'Erledigt' },
|
||||
/* ABGEBROCHEN als eigene Zahl (08.09.2026, screen12). Sie steht
|
||||
hinten bei "Erledigt", weil beides dasselbe bedeutet: vom Tisch.
|
||||
@@ -1760,7 +1760,8 @@
|
||||
/* ---- WER KEINE AUFGABEN HAT, BEKOMMT KEINE ZAHLEN (18.09.2026)
|
||||
|
||||
Ein Mitglied der Community sah hier „Deine Aufgaben" mit sieben
|
||||
Zaehlern: Ueberfaellig, Heute faellig, Offen, In Arbeit, Review,
|
||||
Zaehlern: Ueberfaellig, Heute faellig, Offen, In Arbeit, Zur
|
||||
Freigabe,
|
||||
Erledigt, Abgebrochen -- alle null. Darunter „Nichts offen.
|
||||
Alles abgearbeitet – goenn dir was."
|
||||
|
||||
|
||||
@@ -172,7 +172,10 @@
|
||||
a.href = 'kalender.html';
|
||||
rechts.append(a);
|
||||
} else if (c.naechster_review) {
|
||||
rechts.append(el('span', 'naechstes__schild', 'Nächster Review'));
|
||||
/* "Nächster Review" war grammatisch schief und sagte nicht, dass
|
||||
ein DATUM folgt. Kuerzer als das Geschwisterschild daneben,
|
||||
kann also nicht umbrechen, wo jenes passt. */
|
||||
rechts.append(el('span', 'naechstes__schild', 'Review-Termin'));
|
||||
const a = el('a', 'naechstes__wert', datum(c.naechster_review));
|
||||
a.href = 'report.html';
|
||||
rechts.append(a);
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
/* ===================================================================
|
||||
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 = sagWas(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 (!await frageNach({
|
||||
titel: `Alle ${liste.length} übernehmen?`,
|
||||
was: 'Sie landen als eigene Einträge in deiner Liste.',
|
||||
bleibt: 'Die Vorlage bleibt unverändert. Jeder übernommene Eintrag '
|
||||
+ 'lässt sich einzeln wieder löschen.',
|
||||
ja: `Alle ${liste.length} übernehmen`,
|
||||
})) 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. */
|
||||
})();
|
||||
Reference in New Issue
Block a user