diff --git a/bootstrap/bootstrap.mjs b/bootstrap/bootstrap.mjs index 5dba4dd..3df2a8c 100644 --- a/bootstrap/bootstrap.mjs +++ b/bootstrap/bootstrap.mjs @@ -531,6 +531,26 @@ const collections = [ { field: 'date_updated', type: 'timestamp', meta: { interface: 'datetime', readonly: true, special: ['date-updated'] }, schema: {} }, ] }, + // Logs & Fehler vom Produktions-Agenten und von AutoRecover (Plotter-Fehler). + { collection: 'agent_logs', meta: { icon: 'article', note: 'Logs & Fehlermeldungen vom Produktions-Agenten / AutoRecover.' }, fields: [ + m2o('machine', 'machines', { onDelete: 'SET NULL', note: 'Maschine (optional).' }), + dropdown('level', ['info', 'warn', 'error'], { default: 'info' }), + f('source', 'string', { interface: 'input', note: 'Quelle: agent | plotter | recover | restart.' }), + f('message', 'text', { interface: 'input-multiline' }), + { field: 'date_created', type: 'timestamp', meta: { interface: 'datetime', readonly: true, special: ['date-created'] }, schema: {} }, + ] }, + + // Befehle an den Agenten (z. B. Programm-Neustart). Der Agent pollt „pending". + { collection: 'agent_commands', meta: { icon: 'terminal', note: 'Befehle an den Agenten (Programm-Neustart). Der Agent arbeitet „pending" ab.' }, fields: [ + m2o('machine', 'machines', { onDelete: 'CASCADE', note: 'Zielmaschine/-agent.' }), + dropdown('type', ['restart'], { default: 'restart' }), + f('target', 'string', { interface: 'input', note: 'Optionaler Programmname/-befehl (überschreibt Agent-Config).' }), + dropdown('status', ['pending', 'done', 'error'], { default: 'pending' }), + f('result', 'text', { interface: 'input-multiline', note: 'Ergebnis/Fehler vom Agenten.' }), + { field: 'date_created', type: 'timestamp', meta: { interface: 'datetime', readonly: true, special: ['date-created'] }, schema: {} }, + { field: 'date_updated', type: 'timestamp', meta: { interface: 'datetime', readonly: true, special: ['date-updated'] }, schema: {} }, + ] }, + { collection: 'customer_offers', meta: { icon: 'local_offer', note: 'Kundenangebote: Aufschläge/Name-Zusatz je Kunde+Produkt (Kunde wählt im Konfigurator).' }, fields: [ m2o('customer', 'directus_users', { onDelete: 'CASCADE' }), m2o('product', 'products', { onDelete: 'CASCADE' }), diff --git a/extensions/directus-extension-skrift-produktion/dist/index.js b/extensions/directus-extension-skrift-produktion/dist/index.js index 9054aba..032f499 100644 --- a/extensions/directus-extension-skrift-produktion/dist/index.js +++ b/extensions/directus-extension-skrift-produktion/dist/index.js @@ -921,6 +921,17 @@ const Board = defineComponent({ } function closeDateien() { pvClear(); dateien.open = false; } + // Neustart-Befehl an den Agenten (Programm auf dem Windows-Rechner neu starten). + // Der Agent pollt agent_commands und führt den Neustart aus (Ziel = Agent-Config). + async function programmNeustarten() { + const m = aktiveMaschinen.value[0]; + if (typeof window !== 'undefined' && !window.confirm(`Programm auf dem Agenten${m ? ' (' + m.name + ')' : ''} neu starten?`)) return; + try { + await api.post('/items/agent_commands', { type: 'restart', status: 'pending', machine: m?.id ?? null }); + flash('Neustart-Befehl an den Agenten gesendet – wird beim nächsten Poll ausgeführt.'); + } catch (e) { fehler.value = e?.response?.data?.errors?.[0]?.message || e?.message || 'Konnte Neustart-Befehl nicht senden.'; } + } + // ── Render-Bausteine ────────────────────────────────────────────────── function actionButtons(order) { // Drucken + Empfänger immer sichtbar; Rest hinter „Weiteres". @@ -1407,6 +1418,7 @@ const Board = defineComponent({ style: S_INPUT + 'flex:1;min-width:240px;', onInput: (e) => { suche.value = e.target.value; } }), sichtbareOrders().length ? btn(alleSichtbarGewaehlt() ? '☐ Auswahl aufheben' : '☑ Alle auswählen', alleAuswaehlen) : null, btn('↻ Aktualisieren', laden), + btn('🔄 Programm neustarten', programmNeustarten), ]); // Leicht getönte Inhaltsfläche → weiße Karten heben sich klar ab (wie im Referenz-Dashboard).