Notizen je Auftrag + je Charge (Produktions-Board)
orders.internal_note + neue Collection charge_notes (charge_key). Editierbare Notizfelder in Auftrags- und Charge-Karte, speichern beim Verlassen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,15 @@ function chip(text, farbe) {
|
||||
function subdued(text, extra) {
|
||||
return h('div', { style: `color:var(--foreground-subdued);font-size:13px;${extra || ''}` }, text);
|
||||
}
|
||||
// Editierbares Notizfeld (speichert beim Verlassen/Blur).
|
||||
function notizFeld(wert, onSave, ph) {
|
||||
return h('textarea', {
|
||||
rows: 2, placeholder: ph || 'Notiz …',
|
||||
style: 'width:100%;margin:6px 0 2px;border:1px solid var(--border-subdued);border-radius:6px;padding:6px 8px;font:inherit;font-size:12px;background:var(--background-page);color:var(--foreground-normal);resize:vertical;',
|
||||
value: wert || '',
|
||||
onChange: (e) => onSave(e.target.value),
|
||||
}, wert || '');
|
||||
}
|
||||
// Zielland-Erkennung je Empfänger (wie im Backend): Deutschland, wenn Land DE/leer,
|
||||
// „Deutschland" im Freitext, „D-" vor der PLZ oder nur PLZ ohne Auslandshinweis.
|
||||
function zielInland(e) {
|
||||
@@ -187,7 +196,7 @@ const Board = defineComponent({
|
||||
+ 'envelope_labeling,shipping_type,shipping_day,keep_contacts,entries_count,count_inland,count_ausland,brief_gedruckt,kuvert_gedruckt,'
|
||||
+ 'date_updated,date_created,format.key,format.name,product.name,product.input_mode,'
|
||||
+ 'source,api_client.id,api_client.name,'
|
||||
+ 'source_file,'
|
||||
+ 'source_file,internal_note,'
|
||||
+ 'customer.first_name,customer.last_name,customer.email,customer.phone';
|
||||
async function ladeOrders() {
|
||||
try {
|
||||
@@ -260,6 +269,32 @@ const Board = defineComponent({
|
||||
} catch { /* Anzeige läuft dann ohne „gesendet" weiter */ }
|
||||
}
|
||||
|
||||
// Notizen je Charge (charge_key → Notiz) + Speichern von Auftrags-/Charge-Notizen.
|
||||
const chargeNotizen = ref({});
|
||||
async function ladeChargeNotizen() {
|
||||
try {
|
||||
const r = await api.get('/items/charge_notes', { params: { limit: -1, fields: 'charge_key,note' } });
|
||||
const m = {};
|
||||
for (const x of r.data?.data || []) m[x.charge_key] = x.note || '';
|
||||
chargeNotizen.value = m;
|
||||
} catch { /* Notizen optional */ }
|
||||
}
|
||||
async function setOrderNotiz(order, v) {
|
||||
const val = String(v || '');
|
||||
if (val === (order.internal_note || '')) return;
|
||||
try { await api.patch('/items/orders/' + order.id, { internal_note: val }); order.internal_note = val; }
|
||||
catch { fehler.value = 'Notiz konnte nicht gespeichert werden.'; }
|
||||
}
|
||||
async function setChargeNotiz(key, v) {
|
||||
const val = String(v || '');
|
||||
if (val === (chargeNotizen.value[key] || '')) return;
|
||||
try {
|
||||
const ex = (await api.get('/items/charge_notes', { params: { filter: { charge_key: { _eq: key } }, limit: 1, fields: 'id' } })).data?.data?.[0];
|
||||
if (ex) await api.patch('/items/charge_notes/' + ex.id, { note: val });
|
||||
else await api.post('/items/charge_notes', { charge_key: key, note: val });
|
||||
chargeNotizen.value = { ...chargeNotizen.value, [key]: val };
|
||||
} catch { fehler.value = 'Charge-Notiz konnte nicht gespeichert werden.'; }
|
||||
}
|
||||
async function laden(leise = false) {
|
||||
// leise = Hintergrund-Aktualisierung: kein Spinner, kein Fehlerbanner.
|
||||
if (!leise) { loading.value = true; fehler.value = ''; }
|
||||
@@ -284,7 +319,7 @@ const Board = defineComponent({
|
||||
muster.value = ms.data?.data || { text_du: '', text_sie: '' };
|
||||
// Empfänger-Index nur beim vollen Laden neu bauen (nicht bei der 15-s-
|
||||
// Hintergrund-Aktualisierung) – im Hintergrund, blockiert das Board nicht.
|
||||
if (!leise) { ladeEmpfIndex(); ladeSendIndex(); }
|
||||
if (!leise) { ladeEmpfIndex(); ladeSendIndex(); ladeChargeNotizen(); }
|
||||
} catch (e) {
|
||||
if (!leise) fehler.value = e?.response?.data?.errors?.[0]?.message || e?.message || 'Laden fehlgeschlagen.';
|
||||
} finally { if (!leise) loading.value = false; }
|
||||
@@ -885,7 +920,7 @@ const Board = defineComponent({
|
||||
send.brief.length ? chip('🖨 Brief gesendet: ' + send.brief.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,.14))') : null,
|
||||
]) : null;
|
||||
return h('div', { key: 'o' + o.id, style: CARD + `margin-bottom:14px;border-left:4px solid ${ACCENT};` }, [kopf, meta, badges, actionButtons(o)]);
|
||||
return h('div', { key: 'o' + o.id, style: CARD + `margin-bottom:14px;border-left:4px solid ${ACCENT};` }, [kopf, meta, badges, notizFeld(o.internal_note, (v) => setOrderNotiz(o, v), 'Notiz zum Auftrag …'), actionButtons(o)]);
|
||||
}
|
||||
function requestCard(req) {
|
||||
const istMuster = req.type === 'muster';
|
||||
@@ -929,7 +964,8 @@ const Board = defineComponent({
|
||||
c.faellig ? chip('⏰ fällig bis ' + dmY(c.faellig), faelligFarbe) : null,
|
||||
]);
|
||||
const body = auf ? h('div', { style: 'margin-top:12px;display:flex;flex-direction:column;gap:2px;' }, c.orders.map((o) => orderCard(o, opts))) : null;
|
||||
return h('div', { key: 'c' + c.key, style: CARD + `margin-bottom:14px;border-left:4px solid ${ACCENT};` }, [kopf, body]);
|
||||
const chargeNotiz = notizFeld(chargeNotizen.value[c.key], (v) => setChargeNotiz(c.key, v), 'Notiz zur Charge …');
|
||||
return h('div', { key: 'c' + c.key, style: CARD + `margin-bottom:14px;border-left:4px solid ${ACCENT};` }, [kopf, chargeNotiz, body]);
|
||||
}
|
||||
|
||||
// Aufträge einer Ansicht rendern: bei aktiver Suche als EINZELaufträge (damit
|
||||
|
||||
Reference in New Issue
Block a user