From af63fd66be5f1563759d7f72627df8ca3035693b Mon Sep 17 00:00:00 2001 From: s4luorth Date: Mon, 21 Sep 2026 12:09:58 +0200 Subject: [PATCH] =?UTF-8?q?Neuauftrag:=20St=C3=BCckzahl=20statt=20Empf?= =?UTF-8?q?=C3=A4ngerzeilen=20bei=20identischem=20Druck=20ohne=20Kuvert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ohne Kuvert (kein Postkarten-Format, „Kuverts generieren" aus) und ohne eigene [[Platzhalter]] im Brieftext sind alle Schriftstücke identisch – Empfängeradressen sind dort unnötig. Statt N Zeilen anzulegen, gibt es jetzt ein Feld „Anzahl identischer Schriftstücke"; beim Anlegen werden entsprechend viele gleiche Schriftstücke erzeugt. Sobald Kuverts aktiv sind oder der Text eigene Platzhalter enthält, erscheint wieder die Empfängertabelle. Co-Authored-By: Claude Opus 4.8 --- .../dist/index.js | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/extensions/directus-extension-skrift-neuauftrag/dist/index.js b/extensions/directus-extension-skrift-neuauftrag/dist/index.js index 84cb5e6..4f19fb3 100644 --- a/extensions/directus-extension-skrift-neuauftrag/dist/index.js +++ b/extensions/directus-extension-skrift-neuauftrag/dist/index.js @@ -81,6 +81,8 @@ const NeuAuftrag = defineComponent({ mehrseitig: false, seitenInfo: '', // Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig). adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()], + // Ohne Kuvert & ohne eigene Platzhalter: einfach N identische Schriftstücke. + anzahl: 1, importOpen: false, importText: '', docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '', lbDoc: null, }); @@ -239,6 +241,12 @@ const NeuAuftrag = defineComponent({ const entries = () => neu.rows.filter((e) => String(e.free_text || '').trim() || felderGefuellt(e) || (e.placeholders && Object.values(e.placeholders).some((v) => String(v || '').trim()))); + // Ohne Kuvert (und keine Postkarte) sind Empfängeradressen unnötig. Hat der Text + // zudem keine eigenen Platzhalter, sind alle Schriftstücke identisch → dann genügt + // eine Stückzahl statt einzelner Empfängerzeilen. + const keinKuvert = () => !istPostkarte() && !neu.kuverts; + const identischModus = () => keinKuvert() && customPlaceholders().length === 0; + const anzahlNorm = () => Math.max(1, Math.min(1000, Math.round(Number(neu.anzahl) || 1))); // Aus Excel/CSV eingefügte Zeilen übernehmen. Erst die individuellen // Platzhalter-Spalten, dann die Adresszeilen (Tab/Semikolon/Komma-getrennt). @@ -382,9 +390,15 @@ const NeuAuftrag = defineComponent({ neu.msg = `✓ Auftrag ${nr} angelegt – Dokumente werden noch generiert. Status im Produktions-Board prüfen.`; } async function absenden() { - // Empfänger sind optional – ohne Empfänger genau ein Schriftstück (Blankozeile). - const ent = entries(); - const payloadEntries = ent.length ? ent : [leereZeile()]; + // Ohne Kuvert & ohne eigene Platzhalter: N identische Schriftstücke (Blankozeilen). + // Sonst: die erfassten Empfänger – ohne Empfänger genau ein Schriftstück. + let payloadEntries; + if (identischModus()) { + payloadEntries = Array.from({ length: anzahlNorm() }, () => leereZeile()); + } else { + const ent = entries(); + payloadEntries = ent.length ? ent : [leereZeile()]; + } neu.err = ''; neu.msg = 'Wird angelegt …'; try { const kv = kuvertPayload(); @@ -415,6 +429,7 @@ const NeuAuftrag = defineComponent({ fontSizeLetter: 100, fontSizeEnvelope: 100, sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, mehrseitig: false, seitenInfo: '', adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()], + anzahl: 1, importOpen: false, importText: '', docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '', }); @@ -543,17 +558,29 @@ const NeuAuftrag = defineComponent({ const b2 = h('div', { style: BEREICH }, [ h('div', { style: 'display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px;' }, [ bereichKopf('✉ Kuvert'), - h('div', { style: 'width:420px;max-width:100%;' }, [segToggle(neu.adressModus, [{ key: '5zeilen', label: '5 Zeilen' }, { key: 'felder', label: 'Einzelfelder' }, { key: 'individuell', label: 'Ind. Text' }], (k) => { neu.adressModus = k; neu.previewSession = null; })]), + identischModus() ? null : h('div', { style: 'width:420px;max-width:100%;' }, [segToggle(neu.adressModus, [{ key: '5zeilen', label: '5 Zeilen' }, { key: 'felder', label: 'Einzelfelder' }, { key: 'individuell', label: 'Ind. Text' }], (k) => { neu.adressModus = k; neu.previewSession = null; })]), ]), - h('div', { style: 'display:flex;flex-direction:column;gap:8px;max-height:34vh;overflow:auto;' }, - neu.rows.map((e, i) => h('div', { style: 'display:flex;gap:8px;align-items:center;' }, [ - h('span', { style: `min-width:22px;font-weight:700;color:${ACCENT};` }, `#${i + 1}`), - h('div', { style: 'flex:1;min-width:0;display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;' }, zeile(e, i)), - h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:var(--danger,#c62828);font-size:18px;padding:2px 6px;' }, '×'), - ]))), - h('div', { style: 'margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:12px;' }, [ - btn('+ Empfänger', addZeile), - btn(neu.importOpen ? 'Import schließen' : '⇪ Aus Excel einfügen', () => { neu.importOpen = !neu.importOpen; }), + // Ohne Kuvert & ohne eigene Platzhalter genügt eine Stückzahl (identische + // Schriftstücke). Sonst die Empfängertabelle mit Zeilen/Import. + identischModus() ? h('div', {}, [ + label('Anzahl identischer Schriftstücke'), + h('input', { type: 'number', min: 1, max: 1000, step: 1, value: neu.anzahl, style: WFELD + 'width:170px;', + onInput: (e) => { neu.anzahl = e.target.value; neu.previewSession = null; }, + onBlur: (e) => { const n = Math.round(Number(e.target.value)); neu.anzahl = (Number.isFinite(n) && n) ? Math.max(1, Math.min(1000, n)) : 1; } }), + h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:6px;line-height:1.5;' }, + 'Ohne Kuvert werden keine Empfängeradressen gebraucht – es entstehen so viele gleiche Schriftstücke wie angegeben. ' + + 'Sobald „Kuverts generieren" aktiv ist oder der Text eigene [[Platzhalter]] enthält, erscheint wieder die Empfängertabelle.'), + ]) : h('div', {}, [ + h('div', { style: 'display:flex;flex-direction:column;gap:8px;max-height:34vh;overflow:auto;' }, + neu.rows.map((e, i) => h('div', { style: 'display:flex;gap:8px;align-items:center;' }, [ + h('span', { style: `min-width:22px;font-weight:700;color:${ACCENT};` }, `#${i + 1}`), + h('div', { style: 'flex:1;min-width:0;display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;' }, zeile(e, i)), + h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:var(--danger,#c62828);font-size:18px;padding:2px 6px;' }, '×'), + ]))), + h('div', { style: 'margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:12px;' }, [ + btn('+ Empfänger', addZeile), + btn(neu.importOpen ? 'Import schließen' : '⇪ Aus Excel einfügen', () => { neu.importOpen = !neu.importOpen; }), + ]), ]), // Postkarte: Hinweis auf das Kartenlayout; kein separates Kuvert. istPostkarte() ? h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:12px;line-height:1.5;' }, @@ -583,7 +610,7 @@ const NeuAuftrag = defineComponent({ h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' }, istPostkarte() ? 'Empfänger steht darunter in der Anschriftzone (rechte Hälfte).' : 'Der Empfänger rutscht dann auf dem Kuvert automatisch nach unten rechts.'), ]) : null, - neu.importOpen ? h('div', { style: 'margin-top:12px;' }, [ + (neu.importOpen && !identischModus()) ? h('div', { style: 'margin-top:12px;' }, [ subdued('Aus Excel kopieren und einfügen – eine Zeile pro Empfänger, Spalten mit Tab/Semikolon/Komma. ' + 'Reihenfolge: erst individuelle Platzhalter, dann ' + (neu.adressModus === 'individuell' ? 'die eine Adresszeile.' : 'Zeile 1–5.'), 'margin-bottom:6px;'), h('textarea', { value: neu.importText, rows: 5, style: WFELD + 'width:100%;font-family:var(--family-monospace,monospace);', onInput: (e) => { neu.importText = e.target.value; } }),