Produktions-Board: einheitliches Design (ruhigere, klarere Optik)
Gemeinsames Token-/Helfer-System (Card 12px, ruhige Pills, klarer Primaer- Button, groessere Felder). Auftragskarte neu: grosse Auftragsnummer, ruhige Eckdaten-Zeile statt Chip-Wand, Status-Pills nur wo sie Bedeutung tragen, Versandadresse als Block. Angebots-/Musterkarte mit zitierter Nachricht. Navigation mit Pillen-Zaehlern. Reiner Optik-Refactor, keine Logikaenderung. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -74,39 +74,46 @@ const PARAM_FELDER = [
|
|||||||
['width', 'Breite'], ['height', 'Höhe'], ['xpos', 'X'], ['ypos', 'Y'], ['scale', 'Scale'], ['rotation', 'Rot°'],
|
['width', 'Breite'], ['height', 'Höhe'], ['xpos', 'X'], ['ypos', 'Y'], ['scale', 'Scale'], ['rotation', 'Rot°'],
|
||||||
];
|
];
|
||||||
|
|
||||||
// ── kleine Stil-/Render-Helfer ──────────────────────────────────────────────
|
// ── Design-System: Tokens + Render-Helfer ───────────────────────────────────
|
||||||
// Weiße Karte, die sich klar von der (leicht getönten) Inhaltsfläche abhebt.
|
// Einheitliche, ruhige Optik über das ganze Board (Directus-Theme-Variablen →
|
||||||
const CARD = 'border:1px solid var(--border-subdued);border-radius:8px;padding:16px 18px;background:var(--background-page,#fff);box-shadow:0 1px 3px rgba(0,0,0,.08);';
|
// Light/Dark-sicher). Flach, klare Hierarchie, großzügige Abstände.
|
||||||
// Getönte Sektion (Briefe/Kuverts) mit Rand + Radius; Abstand über margin-bottom.
|
// Karte: 12px Radius, Haarlinie, dezenter Schatten, viel Innenabstand.
|
||||||
const SECTION = 'background:var(--background-subdued,#f1f4f9);border:1px solid var(--border-normal);border-radius:8px;padding:16px 18px;margin-bottom:16px;';
|
const CARD = 'border:1px solid var(--border-subdued);border-radius:12px;padding:18px 20px;background:var(--background-page,#fff);box-shadow:0 1px 2px rgba(0,0,0,.04);';
|
||||||
// Deutlich sichtbares Eingabefeld (weiß auf getönter Sektion).
|
// Getönte Sektion (Formulare).
|
||||||
const S_FELD = 'border:1px solid var(--border-normal);border-radius:7px;padding:6px 10px;background:var(--background-page,#fff);';
|
const SECTION = 'background:var(--background-subdued,#f1f4f9);border:1px solid var(--border-subdued);border-radius:12px;padding:18px 20px;margin-bottom:16px;';
|
||||||
const S_INPUT = 'padding:7px 10px;border:1px solid var(--border-normal);border-radius:7px;background:var(--background-page);color:var(--foreground-normal);font:inherit;font-size:13px;';
|
const S_FELD = 'border:1px solid var(--border-normal);border-radius:8px;padding:8px 11px;background:var(--background-page,#fff);';
|
||||||
|
const S_INPUT = 'padding:8px 11px;border:1px solid var(--border-normal);border-radius:8px;background:var(--background-page);color:var(--foreground-normal);font:inherit;font-size:14px;';
|
||||||
const S_SELECT = S_INPUT + 'cursor:pointer;';
|
const S_SELECT = S_INPUT + 'cursor:pointer;';
|
||||||
|
|
||||||
// Directus-Primärfarbe (Marke) + Kartenfarben je Vorgangstyp.
|
// Directus-Primärfarbe (Marke) + Vorgangs-Akzente.
|
||||||
const ACCENT = '#1E50A5'; // Aufträge / Druck → blau
|
const ACCENT = 'var(--primary,#1E50A5)'; // Aufträge / Druck → blau (Theme-Primär)
|
||||||
const FARBE_MUSTER = '#d13438'; // Musteranfrage → rot
|
const FARBE_MUSTER = '#d13438'; // Musteranfrage → rot
|
||||||
const FARBE_ANGEBOT = '#e07b00'; // Angebotsanfrage → orange
|
const FARBE_ANGEBOT = '#e07b00'; // Angebotsanfrage → orange
|
||||||
|
|
||||||
|
// Button: klarer Primär (gefüllt), ruhiger Sekundär (Umriss), dezenter Danger.
|
||||||
function btn(label, onClick, kind) {
|
function btn(label, onClick, kind) {
|
||||||
const base = 'cursor:pointer;border-radius:7px;padding:6px 14px;font:inherit;font-size:13px;border:1px solid;';
|
const base = 'cursor:pointer;border-radius:8px;padding:8px 16px;font:inherit;font-size:14px;font-weight:500;border:1px solid;display:inline-flex;align-items:center;justify-content:center;gap:6px;line-height:1.25;';
|
||||||
const style = kind === 'primary'
|
const style = kind === 'primary'
|
||||||
? base + `border-color:${ACCENT};background:${ACCENT};color:#fff;`
|
? base + `border-color:${ACCENT};background:${ACCENT};color:#fff;`
|
||||||
: kind === 'danger'
|
: kind === 'danger'
|
||||||
? base + 'border-color:var(--danger,#c62828);background:transparent;color:var(--danger,#c62828);'
|
? base + 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--danger,#c62828);'
|
||||||
: base + 'border-color:var(--border-normal);background:var(--background-subdued);color:var(--foreground-normal);';
|
: base + 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--foreground-normal);';
|
||||||
return h('button', { type: 'button', onClick, style }, label);
|
return h('button', { type: 'button', onClick, style }, label);
|
||||||
}
|
}
|
||||||
function chip(text, farbe) {
|
// Pill (Status/Badge): ruhig, lesbar. farbe = Hintergrund (Theme-Tint), textFarbe optional.
|
||||||
|
function chip(text, farbe, textFarbe) {
|
||||||
return h('span', {
|
return h('span', {
|
||||||
style: `display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:2px 8px;border-radius:20px;`
|
style: `display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;padding:3px 11px;border-radius:999px;`
|
||||||
+ `background:${farbe || 'var(--background-subdued)'};color:var(--foreground-subdued);white-space:nowrap;`,
|
+ `background:${farbe || 'var(--background-subdued)'};color:${textFarbe || 'var(--foreground-subdued)'};white-space:nowrap;`,
|
||||||
}, text);
|
}, text);
|
||||||
}
|
}
|
||||||
function subdued(text, extra) {
|
function subdued(text, extra) {
|
||||||
return h('div', { style: `color:var(--foreground-subdued);font-size:13px;${extra || ''}` }, text);
|
return h('div', { style: `color:var(--foreground-subdued);font-size:13px;${extra || ''}` }, text);
|
||||||
}
|
}
|
||||||
|
// Eckdaten-Zeile: eine ruhige Zeile „Icon Wert · Icon Wert" statt Chip-Wand.
|
||||||
|
function metaItem(text) {
|
||||||
|
return h('span', { style: 'display:inline-flex;align-items:center;gap:5px;color:var(--foreground-subdued);font-size:13.5px;white-space:nowrap;' }, text);
|
||||||
|
}
|
||||||
// Editierbares Notizfeld (speichert beim Verlassen/Blur).
|
// Editierbares Notizfeld (speichert beim Verlassen/Blur).
|
||||||
function notizFeld(wert, onSave, ph) {
|
function notizFeld(wert, onSave, ph) {
|
||||||
return h('textarea', {
|
return h('textarea', {
|
||||||
@@ -1371,7 +1378,7 @@ const Board = defineComponent({
|
|||||||
}
|
}
|
||||||
function statusSelect(order) {
|
function statusSelect(order) {
|
||||||
return h('select', {
|
return h('select', {
|
||||||
style: S_SELECT + 'font-size:12px;padding:4px 8px;',
|
style: S_SELECT + 'font-size:13px;padding:6px 12px;font-weight:500;flex-shrink:0;',
|
||||||
value: order.production_status || 'eingegangen',
|
value: order.production_status || 'eingegangen',
|
||||||
onChange: (e) => setStatus(order, e.target.value),
|
onChange: (e) => setStatus(order, e.target.value),
|
||||||
}, Object.entries(STATUS_LABEL).map(([k, v]) => h('option', { value: k, selected: (order.production_status || 'eingegangen') === k }, v)));
|
}, Object.entries(STATUS_LABEL).map(([k, v]) => h('option', { value: k, selected: (order.production_status || 'eingegangen') === k }, v)));
|
||||||
@@ -1390,57 +1397,62 @@ const Board = defineComponent({
|
|||||||
function orderCard(order, opts) {
|
function orderCard(order, opts) {
|
||||||
const o = order;
|
const o = order;
|
||||||
const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;' }, [
|
const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;' }, [
|
||||||
h('div', { style: 'display:flex;gap:10px;align-items:flex-start;' }, [
|
h('div', { style: 'display:flex;gap:12px;align-items:flex-start;' }, [
|
||||||
h('input', { type: 'checkbox', checked: istGewaehlt(o.id), onClick: (e) => toggleAuswahl(o.id, e),
|
h('input', { type: 'checkbox', checked: istGewaehlt(o.id), onClick: (e) => toggleAuswahl(o.id, e),
|
||||||
title: 'Für Sammel-Druck auswählen', style: 'width:16px;height:16px;margin-top:3px;cursor:pointer;' }),
|
title: 'Für Sammel-Druck auswählen', style: 'width:18px;height:18px;margin-top:4px;cursor:pointer;flex-shrink:0;' }),
|
||||||
h('div', {}, [
|
h('div', {}, [
|
||||||
h('div', { style: 'font-weight:700;font-size:15px;' }, `#${o.order_number}`),
|
h('div', { style: 'font-weight:500;font-size:18px;letter-spacing:-.01em;' }, `#${o.order_number}`),
|
||||||
subdued(`${kundeName(o)}${o.customer?.email ? ' · ' + o.customer.email : ''}${o.customer?.phone ? ' · ' + o.customer.phone : ''}`, 'margin-top:2px;'),
|
subdued(`${kundeName(o)}${o.customer?.email ? ' · ' + o.customer.email : ''}${o.customer?.phone ? ' · ' + o.customer.phone : ''}`, 'margin-top:1px;'),
|
||||||
h('a', { href: `/admin/content/orders/${o.id}`, target: '_blank', rel: 'noopener',
|
h('a', { href: `/admin/content/orders/${o.id}`, target: '_blank', rel: 'noopener',
|
||||||
style: 'display:inline-block;margin-top:3px;font-size:12px;color:var(--primary,#1e50a5);text-decoration:none;font-weight:600;' },
|
style: 'display:inline-flex;align-items:center;gap:4px;margin-top:5px;font-size:12px;color:var(--primary,#1e50a5);text-decoration:none;font-weight:500;' },
|
||||||
'↗ Auftrag öffnen'),
|
'↗ Auftrag öffnen'),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
statusSelect(o),
|
statusSelect(o),
|
||||||
]);
|
]);
|
||||||
const meta = h('div', { style: 'display:flex;gap:6px;flex-wrap:wrap;margin:10px 0;' }, [
|
// Eckdaten: eine ruhige Zeile mit dezenten Trennpunkten (immer vorhanden).
|
||||||
chip(`${o.entries_count || 0} Briefe`),
|
const trenn = () => h('span', { style: 'color:var(--border-normal);', 'aria-hidden': 'true' }, '·');
|
||||||
chip(o.needs_envelope ? `${o.entries_count || 0} Kuverts` : 'ohne Kuvert'),
|
const eck = [
|
||||||
// Versandländer: getrennt sichtbar (Deutschland / weltweit), wenn gemischt bzw. Ausland.
|
metaItem(`📄 ${o.entries_count || 0} Briefe`),
|
||||||
(Number(o.count_ausland) > 0)
|
metaItem(o.needs_envelope ? `✉ ${o.entries_count || 0} Kuverts` : 'ohne Kuvert'),
|
||||||
? chip(`🇩🇪 ${o.count_inland ?? 0} · 🌍 ${o.count_ausland} weltweit`, 'var(--primary-25,rgba(30,80,165,.14))')
|
metaItem(o.format?.name || o.format?.key || 'Format?'),
|
||||||
: null,
|
metaItem(o.shipping_type === 'einzeln' ? 'Einzelversand' : 'Sammelversand'),
|
||||||
chip(o.shipping_type === 'einzeln' ? 'Einzelversand' : 'Sammelversand'),
|
(Number(o.count_ausland) > 0) ? metaItem(`🇩🇪 ${o.count_inland ?? 0} · 🌍 ${o.count_ausland}`) : null,
|
||||||
o.shipping_day ? chip('📅 Versandtag: ' + o.shipping_day.charAt(0).toUpperCase() + o.shipping_day.slice(1), 'var(--primary-25,rgba(30,80,165,.14))') : null,
|
o.shipping_day ? metaItem('📅 ' + o.shipping_day.charAt(0).toUpperCase() + o.shipping_day.slice(1)) : null,
|
||||||
chip(o.product?.name || 'Produkt?'),
|
].filter(Boolean);
|
||||||
chip(o.format?.name || o.format?.key || 'Format?'),
|
const metaRow = h('div', { style: 'display:flex;gap:11px;align-items:center;flex-wrap:wrap;margin:12px 0;padding:11px 0;border-top:1px solid var(--border-subdued);border-bottom:1px solid var(--border-subdued);' },
|
||||||
// Postkarten-Motiv: deutlich hervorheben, damit das Motiv beim Druck berücksichtigt wird.
|
eck.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(trenn(), el)), []));
|
||||||
|
// Status-Pills: nur Aussagekräftiges, Farbe nur wo sie Bedeutung trägt.
|
||||||
|
const bezahlt = o.payment_status === 'bezahlt';
|
||||||
|
const pills = [
|
||||||
|
chip(bezahlt ? '✓ bezahlt' : (o.payment_status === 'storniert' ? 'storniert' : 'offen'),
|
||||||
|
bezahlt ? 'var(--success-25,rgba(46,125,50,.14))' : 'var(--warning-25,rgba(230,160,0,.16))',
|
||||||
|
bezahlt ? 'var(--success,#2e7d32)' : '#8a6d00'),
|
||||||
(o.motif?.name || (o.motif_mode && !['ohne', ''].includes(o.motif_mode)))
|
(o.motif?.name || (o.motif_mode && !['ohne', ''].includes(o.motif_mode)))
|
||||||
? chip('🖼 Motiv' + (o.motif?.name ? ': ' + o.motif.name : (o.motif_mode === 'eigene_karten' ? ': eigene Karten' : (o.motif_mode === 'upload' ? ': Upload' : ''))), 'var(--warning-25,rgba(230,160,0,.22))')
|
? chip('🖼 Motiv' + (o.motif?.name ? ': ' + o.motif.name : (o.motif_mode === 'eigene_karten' ? ': eigene Karten' : (o.motif_mode === 'upload' ? ': Upload' : ''))), 'var(--warning-25,rgba(230,160,0,.18))', '#8a6d00')
|
||||||
: null,
|
: null,
|
||||||
chip(o.payment_status === 'bezahlt' ? '✓ bezahlt' : (o.payment_status === 'storniert' ? 'storniert' : 'offen'),
|
o.product?.name ? chip(o.product.name) : null,
|
||||||
o.payment_status === 'bezahlt' ? 'var(--success-25,rgba(46,125,50,.15))' : 'var(--warning-25,rgba(230,160,0,.15))'),
|
o.linked_order?.order_number ? chip('🔗 Kuverts: #' + o.linked_order.order_number) : null,
|
||||||
o.linked_order?.order_number ? chip('🔗 Kuverts: #' + o.linked_order.order_number, 'var(--primary-25,rgba(30,80,165,.14))') : null,
|
o.approval_status === 'pending' ? chip('⏳ wartet auf Freigabe', 'var(--warning-25,rgba(230,160,0,.18))', '#8a6d00') : null,
|
||||||
o.approval_status === 'pending' ? chip('⏳ wartet auf Freigabe', 'var(--warning-25,rgba(230,160,0,.2))') : null,
|
o.approval_status === 'approved' ? chip('✓ Motiv freigegeben', 'var(--success-25,rgba(46,125,50,.14))', 'var(--success,#2e7d32)') : null,
|
||||||
o.approval_status === 'approved' ? chip('✓ Motiv freigegeben', 'var(--success-25,rgba(46,125,50,.15))') : null,
|
o.approval_status === 'changes' ? chip('✏ Änderungswunsch', 'var(--danger-25,rgba(198,40,40,.14))', 'var(--danger,#c62828)') : null,
|
||||||
o.approval_status === 'changes' ? chip('✏ Änderungswunsch', 'var(--danger-25,rgba(198,40,40,.15))') : null,
|
].filter(Boolean);
|
||||||
]);
|
const pillRow = pills.length ? h('div', { style: 'display:flex;gap:7px;flex-wrap:wrap;margin-bottom:12px;' }, pills) : null;
|
||||||
// „Auf einen Blick": welche Nummern wurden schon in den Druck gesendet
|
// „Auf einen Blick": welche Nummern wurden schon in den Druck gesendet.
|
||||||
// (aus den Jobs, inkl. bereits gedruckter). Kein Status, nur die Eingabe.
|
|
||||||
const send = sendIndex.value[String(o.id)];
|
const send = sendIndex.value[String(o.id)];
|
||||||
const badges = send && (send.brief.length || send.umschlag.length)
|
const badges = send && (send.brief.length || send.umschlag.length)
|
||||||
? h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px;' }, [
|
? h('div', { style: 'display:flex;gap:7px;flex-wrap:wrap;margin-bottom:12px;' }, [
|
||||||
send.brief.length ? chip('🖨 Brief gesendet: ' + send.brief.join(' · '), 'var(--primary-25,rgba(30,80,165,.14))') : null,
|
send.brief.length ? chip('🖨 Brief gesendet: ' + send.brief.join(' · '), 'var(--primary-25,rgba(30,80,165,.1))', 'var(--primary,#1e50a5)') : null,
|
||||||
send.umschlag.length ? chip('✉ Kuvert gesendet: ' + send.umschlag.join(' · '), 'var(--primary-25,rgba(30,80,165,.14))') : null,
|
send.umschlag.length ? chip('✉ Kuvert gesendet: ' + send.umschlag.join(' · '), 'var(--primary-25,rgba(30,80,165,.1))', 'var(--primary,#1e50a5)') : null,
|
||||||
]) : null;
|
]) : null;
|
||||||
// Sammelversand: Lieferadresse direkt auf der Karte (kein Sprung in die Order nötig).
|
// Sammelversand: Lieferadresse direkt auf der Karte (kein Sprung in die Order nötig).
|
||||||
const liefer = (o.shipping_type !== 'einzeln') ? lieferAdresse(o) : null;
|
const liefer = (o.shipping_type !== 'einzeln') ? lieferAdresse(o) : null;
|
||||||
const lieferBox = liefer ? h('div', { style: 'margin:0 0 10px;padding:8px 10px;background:var(--background-subdued,#f1f4f9);border-radius:8px;font-size:13px;line-height:1.5;' }, [
|
const lieferBox = liefer ? h('div', { style: 'margin:0 0 12px;padding:11px 13px;background:var(--background-subdued,#f1f4f9);border-radius:10px;font-size:13.5px;line-height:1.55;' }, [
|
||||||
h('div', { style: 'font-weight:600;color:var(--foreground-subdued);font-size:11px;text-transform:uppercase;letter-spacing:.03em;margin-bottom:2px;' }, '📦 Versand an · ' + liefer.quelle),
|
h('div', { style: 'font-weight:500;color:var(--foreground-subdued);font-size:11px;text-transform:uppercase;letter-spacing:.04em;margin-bottom:3px;' }, '📦 Versand an · ' + liefer.quelle),
|
||||||
...liefer.zeilen.map((z) => h('div', {}, z)),
|
...liefer.zeilen.map((z) => h('div', {}, z)),
|
||||||
]) : null;
|
]) : null;
|
||||||
return h('div', { key: 'o' + o.id, style: CARD + `margin-bottom:14px;border-left:4px solid ${ACCENT};` }, [
|
return h('div', { key: 'o' + o.id, style: CARD + `margin-bottom:14px;border-left:3px solid ${ACCENT};` }, [
|
||||||
kopf, meta, badges, lieferBox,
|
kopf, metaRow, pillRow, badges, lieferBox,
|
||||||
notizFeld(o.internal_note, (v) => setOrderNotiz(o, v), 'Notiz zum Auftrag …'),
|
notizFeld(o.internal_note, (v) => setOrderNotiz(o, v), 'Notiz zum Auftrag …'),
|
||||||
actionButtons(o),
|
actionButtons(o),
|
||||||
weiteresOffen.value[o.id] ? weiteresPanel(o) : null,
|
weiteresOffen.value[o.id] ? weiteresPanel(o) : null,
|
||||||
@@ -1448,24 +1460,28 @@ const Board = defineComponent({
|
|||||||
}
|
}
|
||||||
function requestCard(req) {
|
function requestCard(req) {
|
||||||
const istMuster = req.type === 'muster';
|
const istMuster = req.type === 'muster';
|
||||||
|
const akzent = istMuster ? FARBE_MUSTER : FARBE_ANGEBOT;
|
||||||
const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;' }, [
|
const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;' }, [
|
||||||
h('div', {}, [
|
h('div', {}, [
|
||||||
h('div', { style: 'font-weight:700;font-size:15px;' }, `${istMuster ? '🧪 Muster' : '📝 Angebot'} · ${req.name}`),
|
h('div', { style: 'display:flex;align-items:center;gap:8px;' }, [
|
||||||
subdued(`${req.email}${req.phone ? ' · ' + req.phone : ''}`, 'margin-top:2px;'),
|
chip(istMuster ? 'Muster' : 'Angebot', istMuster ? 'rgba(209,52,56,.12)' : 'rgba(224,123,0,.14)', akzent),
|
||||||
|
h('span', { style: 'font-weight:500;font-size:18px;letter-spacing:-.01em;' }, req.name),
|
||||||
]),
|
]),
|
||||||
h('select', { style: S_SELECT + 'font-size:12px;padding:4px 8px;', value: req.status, onChange: (e) => setRequestStatus(req, e.target.value) },
|
subdued(`${req.email}${req.phone ? ' · ' + req.phone : ''}`, 'margin-top:3px;'),
|
||||||
|
]),
|
||||||
|
h('select', { style: S_SELECT + 'font-size:13px;padding:6px 12px;font-weight:500;flex-shrink:0;', value: req.status, onChange: (e) => setRequestStatus(req, e.target.value) },
|
||||||
['neu', 'in_bearbeitung', 'beantwortet', 'abgelehnt'].map((s) => h('option', { value: s, selected: req.status === s }, s))),
|
['neu', 'in_bearbeitung', 'beantwortet', 'abgelehnt'].map((s) => h('option', { value: s, selected: req.status === s }, s))),
|
||||||
]);
|
]);
|
||||||
const meta = h('div', { style: 'display:flex;gap:6px;flex-wrap:wrap;margin:10px 0;' }, [
|
const eck = [metaItem(req.product || 'Produkt?'), req.quantity ? metaItem(`Menge ${req.quantity}`) : null].filter(Boolean);
|
||||||
chip(req.product || 'Produkt?'), req.quantity ? chip(`Menge ${req.quantity}`) : null,
|
const metaRow = h('div', { style: 'display:flex;gap:11px;align-items:center;flex-wrap:wrap;margin:12px 0;padding:11px 0;border-top:1px solid var(--border-subdued);border-bottom:1px solid var(--border-subdued);' },
|
||||||
]);
|
eck.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(h('span', { style: 'color:var(--border-normal);', 'aria-hidden': 'true' }, '·'), el)), []));
|
||||||
const nachricht = req.message ? subdued(req.message, 'margin:0 0 10px;white-space:pre-wrap;') : null;
|
const nachricht = req.message ? h('div', { style: 'margin:0 0 12px;padding:12px 14px;background:var(--background-subdued,#f1f4f9);border-radius:10px;font-size:14px;line-height:1.6;white-space:pre-wrap;color:var(--foreground-normal);' }, req.message) : null;
|
||||||
const aktionen = h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [
|
const aktionen = h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [
|
||||||
// Muster (Druckprodukt) → manueller Druck; individuelles Angebot → kein Druck.
|
// Muster (Druckprodukt) → manueller Druck; individuelles Angebot → kein Druck.
|
||||||
istMuster ? btn('✍ In manuellen Druck', () => musterUebernehmen(req), 'primary') : null,
|
istMuster ? btn('✍ In manuellen Druck', () => musterUebernehmen(req), 'primary') : null,
|
||||||
btn('👤 Details', () => openReqInfo(req)),
|
btn('👤 Details', () => openReqInfo(req)),
|
||||||
]);
|
]);
|
||||||
return h('div', { key: 'r' + req.id, style: CARD + `margin-bottom:14px;border-left:4px solid ${istMuster ? FARBE_MUSTER : FARBE_ANGEBOT};` }, [kopf, meta, nachricht, aktionen]);
|
return h('div', { key: 'r' + req.id, style: CARD + `margin-bottom:14px;border-left:3px solid ${akzent};` }, [kopf, metaRow, nachricht, aktionen]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Charge-Karte: fasst API-Aufträge (Kunde+Typ+Versandtag+Eingangstag) zusammen.
|
// Charge-Karte: fasst API-Aufträge (Kunde+Typ+Versandtag+Eingangstag) zusammen.
|
||||||
@@ -2057,16 +2073,19 @@ const Board = defineComponent({
|
|||||||
// In <private-view> gehängt → normaler Directus-Content-Bereich + Kopf.
|
// In <private-view> gehängt → normaler Directus-Content-Bereich + Kopf.
|
||||||
// Die sechs Umschalter liegen in der nativen Navigationsspalte links.
|
// Die sechs Umschalter liegen in der nativen Navigationsspalte links.
|
||||||
return () => {
|
return () => {
|
||||||
const navi = h('div', { style: 'padding:12px 10px;' }, TABS.map((t) =>
|
const navi = h('div', { style: 'padding:14px 12px;' }, TABS.map((t) => {
|
||||||
h('button', {
|
const aktiv = tab.value === t.key;
|
||||||
|
return h('button', {
|
||||||
type: 'button', onClick: () => { if (tab.value === 'suche' && t.key !== 'suche') { clearTimeout(sucheTimer); sucheText.value = ''; } tab.value = t.key; },
|
type: 'button', onClick: () => { if (tab.value === 'suche' && t.key !== 'suche') { clearTimeout(sucheTimer); sucheText.value = ''; } tab.value = t.key; },
|
||||||
style: 'display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%;text-align:left;'
|
style: 'display:flex;justify-content:space-between;align-items:center;gap:10px;width:100%;text-align:left;'
|
||||||
+ 'cursor:pointer;border:none;border-radius:6px;padding:10px 12px;margin-bottom:3px;font:inherit;font-size:14px;'
|
+ 'cursor:pointer;border:none;border-radius:8px;padding:11px 13px;margin-bottom:3px;font:inherit;font-size:14px;'
|
||||||
+ (tab.value === t.key ? `background:${ACCENT};color:#fff;font-weight:600;` : 'background:transparent;color:var(--foreground-normal);'),
|
+ (aktiv ? `background:${ACCENT};color:#fff;font-weight:500;` : 'background:transparent;color:var(--foreground-normal);'),
|
||||||
}, [
|
}, [
|
||||||
h('span', {}, t.label),
|
h('span', {}, t.label),
|
||||||
h('span', { style: 'font-size:12px;opacity:.75;' }, String(tabCount(t.key))),
|
h('span', { style: 'font-size:12px;font-weight:500;min-width:20px;text-align:center;border-radius:999px;padding:1px 8px;'
|
||||||
])));
|
+ (aktiv ? 'background:rgba(255,255,255,.22);color:#fff;' : 'background:var(--background-subdued);color:var(--foreground-subdued);') }, String(tabCount(t.key))),
|
||||||
|
]);
|
||||||
|
}));
|
||||||
|
|
||||||
const kopfzeile = h('div', { style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:18px;' }, [
|
const kopfzeile = h('div', { style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:18px;' }, [
|
||||||
// Globales Filter-Feld – im Suche-Reiter ausgeblendet (dort gilt das eigene
|
// Globales Filter-Feld – im Suche-Reiter ausgeblendet (dort gilt das eigene
|
||||||
|
|||||||
Reference in New Issue
Block a user