Etiketten-Export: Trennzeichen waehlbar (Komma/Semikolon/Tab), gemerkt
P-touch will Komma, wir hatten fest Semikolon - jetzt einstellbar und in localStorage gemerkt, sodass man es nur einmal setzt. Standard ist Komma. Anfuehrungszeichen werden passend zum gewaehlten Trennzeichen gesetzt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,17 +4,20 @@ import { useConfirm } from "../confirm";
|
||||
import Icon from "../components/Icon";
|
||||
import { asTree } from "../categoryTree";
|
||||
|
||||
// Baut die Etiketten-CSV (Semikolon, BOM für Excel). QR-Inhalt = Link aufs Stück.
|
||||
function buildLabelCsv(rows, origin) {
|
||||
// Baut die Etiketten-CSV mit wählbarem Trennzeichen (BOM für Excel-Umlaute).
|
||||
// QR-Inhalt = Link aufs Stück.
|
||||
function buildLabelCsv(rows, origin, delim = ",") {
|
||||
const head = ["QR-Inhalt", "UID", "Produkt", "Marke", "Kategorie", "Lagerort"];
|
||||
const delimRe = delim === "\t" ? "\\t" : delim;
|
||||
const needsQuote = new RegExp(`[${delimRe}"\\n\\r]`);
|
||||
const esc = (v) => {
|
||||
const s = String(v ?? "");
|
||||
return /[";\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
||||
return needsQuote.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
||||
};
|
||||
const lines = [head.join(";")];
|
||||
const lines = [head.map(esc).join(delim)];
|
||||
for (const r of rows) {
|
||||
lines.push([`${origin}/i/${r.uid}`, r.uid, r.product, r.brand, r.category, r.location]
|
||||
.map(esc).join(";"));
|
||||
.map(esc).join(delim));
|
||||
}
|
||||
return "" + lines.join("\r\n");
|
||||
}
|
||||
@@ -32,9 +35,16 @@ export default function Transfer() {
|
||||
const [selCats, setSelCats] = useState(() => new Set());
|
||||
const [labelBusy, setLabelBusy] = useState(false);
|
||||
const [labelInfo, setLabelInfo] = useState(null);
|
||||
// Gemerktes Trennzeichen (Standard Komma – P-touch mag das lieber).
|
||||
const [labelDelim, setLabelDelim] = useState(() => localStorage.getItem("label_delim") || ",");
|
||||
|
||||
useEffect(() => { api.listCategories().then(setCategories).catch(() => {}); }, []);
|
||||
|
||||
function changeDelim(v) {
|
||||
setLabelDelim(v);
|
||||
localStorage.setItem("label_delim", v);
|
||||
}
|
||||
|
||||
function toggleCat(id, on) {
|
||||
setSelCats((prev) => {
|
||||
const neu = new Set(prev);
|
||||
@@ -50,7 +60,7 @@ export default function Transfer() {
|
||||
try {
|
||||
const rows = await api.labelRows([...selCats]);
|
||||
if (!rows.length) { setLabelInfo("Keine Einzelstücke in der Auswahl."); return; }
|
||||
const csv = buildLabelCsv(rows, window.location.origin);
|
||||
const csv = buildLabelCsv(rows, window.location.origin, labelDelim);
|
||||
const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
@@ -206,6 +216,14 @@ export default function Transfer() {
|
||||
verknüpfen – sie erzeugt QR-Code und Text automatisch. Kategorien wählen
|
||||
(Unterkategorien sind enthalten); ohne Auswahl kommen alle Einzelstücke.
|
||||
</p>
|
||||
<label style={{ maxWidth: 340 }}>
|
||||
Trennzeichen (für die Etiketten-Software)
|
||||
<select value={labelDelim} onChange={(e) => changeDelim(e.target.value)}>
|
||||
<option value=",">Komma ( , ) – z.B. P-touch</option>
|
||||
<option value=";">Semikolon ( ; ) – z.B. Excel (Deutsch)</option>
|
||||
<option value={"\t"}>Tabulator</option>
|
||||
</select>
|
||||
</label>
|
||||
<div className="kat-check-liste">
|
||||
{asTree(categories).filter((c) => c.tracking === "object").map((c) => (
|
||||
<label key={c.id} className="check-inline" style={{ paddingLeft: c.depth * 18 }}>
|
||||
|
||||
Reference in New Issue
Block a user