106 lines
4.0 KiB
JavaScript
106 lines
4.0 KiB
JavaScript
/**
|
||
* Skrift – Interface „Auftragsdateien"
|
||
* ---------------------------------------------------------------------------
|
||
* Zeigt im Auftrag die generierten Dateien (Schriftstücke, Umschläge,
|
||
* Platzhalter-CSV) direkt aus dem gemounteten Ausgabe-Ordner an – ohne Kopie
|
||
* in den Directus-Speicher. Die Liste und der Download laufen über den
|
||
* Endpoint /skrift-orders/files/* und die angemeldete Directus-Session
|
||
* (kein Token in der URL nötig).
|
||
*
|
||
* Bewusst von Hand als ESM geschrieben (kein Build-Schritt): Vue und der
|
||
* Extensions-SDK werden von Directus zur Laufzeit bereitgestellt.
|
||
*/
|
||
import { defineComponent, ref, inject, watch, onMounted, h } from 'vue';
|
||
import { useApi } from '@directus/extensions-sdk';
|
||
|
||
const KIND_LABEL = {
|
||
schriftstueck: 'Schriftstück',
|
||
umschlag: 'Umschlag',
|
||
platzhalter: 'Platzhalter-CSV',
|
||
sonstiges: 'Datei',
|
||
};
|
||
|
||
const AuftragsDateien = defineComponent({
|
||
setup() {
|
||
const api = useApi();
|
||
const values = inject('values', ref({}));
|
||
const files = ref([]);
|
||
const loading = ref(false);
|
||
const error = ref('');
|
||
const geladen = ref(false);
|
||
|
||
function nummer() {
|
||
return values && values.value ? values.value.order_number : null;
|
||
}
|
||
|
||
async function laden() {
|
||
const nr = nummer();
|
||
if (!nr) { files.value = []; geladen.value = true; return; }
|
||
loading.value = true; error.value = '';
|
||
try {
|
||
const res = await api.get('/skrift-orders/files/' + encodeURIComponent(nr));
|
||
files.value = (res.data && res.data.files) || [];
|
||
} catch (e) {
|
||
error.value = (e && e.response && e.response.data && e.response.data.error) || (e && e.message) || 'Fehler beim Laden.';
|
||
} finally {
|
||
loading.value = false; geladen.value = true;
|
||
}
|
||
}
|
||
|
||
async function download(f) {
|
||
const nr = nummer();
|
||
if (!nr) return;
|
||
try {
|
||
const res = await api.get('/skrift-orders/files/' + encodeURIComponent(nr) + '/download', {
|
||
params: { rel: f.rel }, responseType: 'blob',
|
||
});
|
||
const url = URL.createObjectURL(res.data);
|
||
const a = document.createElement('a');
|
||
a.href = url; a.download = f.name;
|
||
document.body.appendChild(a); a.click(); a.remove();
|
||
URL.revokeObjectURL(url);
|
||
} catch {
|
||
error.value = 'Download fehlgeschlagen.';
|
||
}
|
||
}
|
||
|
||
onMounted(laden);
|
||
watch(nummer, laden);
|
||
|
||
const hinweis = (txt) => h('div', { style: 'color:var(--foreground-subdued);font-size:14px;padding:8px 0;' }, txt);
|
||
|
||
return () => {
|
||
if (loading.value) return hinweis('Dateien werden geladen …');
|
||
if (error.value) return hinweis(error.value);
|
||
if (!files.value.length) return hinweis(geladen.value ? 'Noch keine generierten Dateien.' : '');
|
||
return h('div', { style: 'display:flex;flex-direction:column;gap:6px;' }, files.value.map((f) =>
|
||
h('div', {
|
||
key: f.rel,
|
||
style: 'display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--border-normal);border-radius:6px;',
|
||
}, [
|
||
h('span', { style: 'font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--foreground-subdued);min-width:110px;' },
|
||
KIND_LABEL[f.kind] || 'Datei'),
|
||
h('span', { style: 'flex:1;font-family:var(--family-monospace, monospace);font-size:13px;word-break:break-all;' }, f.name),
|
||
h('button', {
|
||
type: 'button',
|
||
onClick: () => download(f),
|
||
style: 'cursor:pointer;border:1px solid var(--border-normal);background:var(--background-subdued);border-radius:6px;padding:4px 12px;font:inherit;font-size:13px;',
|
||
}, 'Herunterladen'),
|
||
]),
|
||
));
|
||
};
|
||
},
|
||
});
|
||
|
||
export default {
|
||
id: 'skrift-order-files',
|
||
name: 'Auftragsdateien',
|
||
icon: 'folder_open',
|
||
description: 'Zeigt die generierten Dateien des Auftrags (Direktzugriff auf den Server-Ordner).',
|
||
component: AuftragsDateien,
|
||
types: ['alias'],
|
||
localTypes: ['presentation'],
|
||
group: 'presentation',
|
||
options: null,
|
||
};
|