import { useCallback, useEffect, useState } from "react";
import { api } from "../api";
import Icon from "./Icon";
import { useConfirm } from "../confirm";
import { useToast } from "../toast";
import { asTree } from "../categoryTree";
/**
* Gespeicherte Zusammenstellungen für den Etikettenexport.
*
* Ersetzt die beiden früheren Abschnitte mit festen Spalten. Der Gewinn sind
* nicht die Vorlagen an sich, sondern die frei wählbaren Spalten: Erst dadurch
* kommen eigene Felder wie eine Kabellänge oder die Kapazität einer Powerbank
* überhaupt aufs Etikett.
*
* Die CSV baut der Server – dort liegen die Feldwerte, und dort lässt sich das
* Ergebnis prüfen.
*/
const ARTEN = [
{ wert: "items", label: "Einzelstücke", hinweis: "Ein Etikett je Stück, mit UID und QR." },
{ wert: "products", label: "Artikel", hinweis: "Ein Etikett je Artikel statt je Stück." },
{ wert: "locations", label: "Lagerorte", hinweis: "Ein Etikett je Lagerort, mit dessen QR." },
];
const TRENNZEICHEN = [
{ wert: ",", label: "Komma" },
{ wert: ";", label: "Semikolon" },
{ wert: "\t", label: "Tabulator" },
];
export default function EtikettenVorlagen({ onError }) {
const confirm = useConfirm();
const toast = useToast();
const [vorlagen, setVorlagen] = useState(null);
const [offen, setOffen] = useState(null); // id der bearbeiteten Vorlage
const [busy, setBusy] = useState(false);
const laden = useCallback(async () => {
try { setVorlagen(await api.etikettenVorlagen()); }
catch (err) { onError(err.message); setVorlagen([]); }
}, [onError]);
useEffect(() => { laden(); }, [laden]);
async function anlegen() {
const name = await confirm({
title: "Neue Vorlage",
message: "Wie soll sie heißen? Zum Beispiel „Kabelexport“.",
confirmLabel: "Anlegen",
prompt: true,
});
if (!name || typeof name !== "string") return;
setBusy(true);
try {
const neu = await api.etikettenVorlageAnlegen({
name: name.trim(),
art: "items",
spalten: ["qr", "uid", "produkt"],
kategorie_ids: [],
trennzeichen: ",",
});
await laden();
setOffen(neu.id);
toast(`Vorlage „${neu.name}“ angelegt.`);
} catch (err) { onError(err.message); } finally { setBusy(false); }
}
async function loeschen(v) {
const ok = await confirm({
title: `Vorlage „${v.name}“ löschen?`,
message: "Die hinterlegte P-touch-Datei geht mit verloren.",
confirmLabel: "Löschen",
danger: true,
});
if (!ok) return;
try {
await api.etikettenVorlageLoeschen(v.id);
if (offen === v.id) setOffen(null);
await laden();
} catch (err) { onError(err.message); }
}
async function csv(v) {
setBusy(true);
try { await api.etikettenCsv(v.id, v.name); }
catch (err) { onError(err.message); } finally { setBusy(false); }
}
return (
Eine Vorlage hält fest, worauf sie sich bezieht, welche Spalten in welcher
Reihenfolge exportiert werden und wie gefiltert wird – samt eigener Felder.
Dazu lässt sich die P-touch-Datei (.lbx) hinterlegen.
Noch keine Vorlage.Etiketten-Vorlagen
{(vorlagen || []).map((v) => (
{ARTEN.find((a) => a.wert === art)?.hinweis}
{art !== "locations" && ( <> Kategorien (leer = alle)Eigene Felder hängen am Artikel, nicht am einzelnen Stück – alle Stücke eines Artikels tragen denselben Wert.
> )}Noch keine gewählt – es greifen dann die Standardspalten.
)}Alle Spalten sind gewählt.
}Eine .lbx merkt sich den Pfad zu ihrer Datenquelle. Auf einem fremden Rechner muss die CSV in P-touch einmal neu verknüpft werden – die Datei dabeizuhaben erspart trotzdem das Suchen.