esvn-react-barcode-print 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1865 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/index.ts
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ ModalBarcodePrint: () => ModalBarcodePrint,
33
+ ModalPreviewPrint: () => ModalPreviewPrint,
34
+ PreviewPrint: () => PreviewPrint,
35
+ SettingPrint: () => SettingPrint,
36
+ executePrint: () => executePrint,
37
+ generateBarcodeHtml: () => generateBarcodeHtml,
38
+ generatePrintDocument: () => generatePrintDocument,
39
+ getOrganizationName: () => getOrganizationName,
40
+ getPaperSizeLabel: () => getPaperSizeLabel,
41
+ renderSingleLabelHtml: () => renderSingleLabelHtml
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/helpers/print-helper.ts
46
+ var import_jsbarcode = __toESM(require("jsbarcode"));
47
+ var import_qrcode_generator = __toESM(require("qrcode-generator"));
48
+ var getOrganizationName = () => {
49
+ try {
50
+ const dataLocal = localStorage.getItem("organization");
51
+ const organization = JSON.parse(dataLocal && dataLocal !== "undefined" ? dataLocal : "null");
52
+ return (organization == null ? void 0 : organization.text) || (organization == null ? void 0 : organization.label) || (organization == null ? void 0 : organization.name) || "";
53
+ } catch (e) {
54
+ return "";
55
+ }
56
+ };
57
+ var generateBarcodeHtml = (value, printType, height = 24) => {
58
+ if (!value) {
59
+ value = "000000";
60
+ }
61
+ if (printType === 1) {
62
+ try {
63
+ const qr = (0, import_qrcode_generator.default)(0, "M");
64
+ qr.addData(value);
65
+ qr.make();
66
+ return `<div class="code-wrapper qr-wrapper">${qr.createSvgTag({ cellSize: 2, margin: 0, scalable: true })}</div>`;
67
+ } catch (e) {
68
+ return `<div style="font-size: 10px; text-align: center; word-break: break-word;">${value}</div>`;
69
+ }
70
+ }
71
+ try {
72
+ const len = value.length;
73
+ let barWidth = 1.3;
74
+ if (len <= 6) {
75
+ barWidth = 2.2;
76
+ } else if (len <= 10) {
77
+ barWidth = 1.7;
78
+ } else if (len <= 15) {
79
+ barWidth = 1.3;
80
+ } else if (len <= 20) {
81
+ barWidth = 1.05;
82
+ } else {
83
+ barWidth = 0.85;
84
+ }
85
+ const svgNode = document.createElementNS("http://www.w3.org/2000/svg", "svg");
86
+ (0, import_jsbarcode.default)(svgNode, value, {
87
+ format: "CODE128",
88
+ width: barWidth,
89
+ height,
90
+ displayValue: false,
91
+ margin: 0
92
+ });
93
+ svgNode.setAttribute("preserveAspectRatio", "none");
94
+ return `
95
+ <div class="code-wrapper barcode-wrapper">
96
+ <div class="barcode-svg-box">
97
+ ${svgNode.outerHTML}
98
+ </div>
99
+ </div>
100
+ `;
101
+ } catch (e) {
102
+ return `<div style="font-size: 10px; text-align: center; word-break: break-word;">${value}</div>`;
103
+ }
104
+ };
105
+ var renderSingleLabelHtml = (item, settings, companyNameDefault, barcodeHeight = 22) => {
106
+ const {
107
+ printType = 0,
108
+ hinge = false,
109
+ fields = []
110
+ } = settings;
111
+ const alignClass = hinge ? "text-right" : "text-left";
112
+ const currentOrgName = item.companyName || companyNameDefault || getOrganizationName();
113
+ if (fields && fields.length > 0) {
114
+ const renderedFields = fields.filter((f) => f.enabled).map((field) => {
115
+ if (field.type === "barcode") {
116
+ const barcodeContent = generateBarcodeHtml(item.code || "", printType, barcodeHeight);
117
+ if (field.offsetX && field.offsetX > 0) {
118
+ return `<div style="padding-left: ${field.offsetX}px !important;">${barcodeContent}</div>`;
119
+ }
120
+ return barcodeContent;
121
+ }
122
+ let rawVal = "";
123
+ if (field.type === "custom") {
124
+ rawVal = field.customValue || field.label || "";
125
+ } else if (field.key === "companyName" || field.id === "companyName") {
126
+ rawVal = currentOrgName;
127
+ } else if (field.key === "price" || field.id === "unitPrice") {
128
+ rawVal = item.price !== void 0 ? Number(item.price).toLocaleString("vi-VN") : "0";
129
+ } else {
130
+ rawVal = item[field.key] || item[field.id] || "";
131
+ }
132
+ if (!rawVal && field.type !== "custom") {
133
+ return "";
134
+ }
135
+ const prefix = field.prefix || "";
136
+ const suffix = field.suffix || "";
137
+ const displayVal = `${prefix}${rawVal}${suffix}`;
138
+ const isBold = field.bold !== false;
139
+ const isItalic = !!field.italic;
140
+ const isUnderline = !!field.underline;
141
+ const textColor = field.color || "#000000";
142
+ const customFontSize = field.fontSize ? `${field.fontSize}px` : void 0;
143
+ const offsetLeft = field.offsetX && field.offsetX > 0 ? `${field.offsetX}px` : void 0;
144
+ const styleRules = [
145
+ `font-weight: ${isBold ? 700 : 400} !important`,
146
+ isItalic ? "font-style: italic !important" : "",
147
+ isUnderline ? "text-decoration: underline !important" : "",
148
+ `color: ${textColor} !important`,
149
+ customFontSize ? `font-size: ${customFontSize} !important` : "",
150
+ offsetLeft ? `padding-left: ${offsetLeft} !important` : ""
151
+ ].filter(Boolean).join("; ");
152
+ return `<div class="lbl-dynamic ${alignClass}" style="${styleRules};">${displayVal}</div>`;
153
+ }).join("");
154
+ return `<div class="stamp-item">${renderedFields}</div>`;
155
+ }
156
+ const companyHtml = settings.companyName && currentOrgName ? `<div class="lbl-company ${alignClass}">${currentOrgName}</div>` : "";
157
+ const codeHtml = settings.productCode ? `<div class="lbl-code ${alignClass}">${item.code || ""}</div>` : "";
158
+ const nameHtml = settings.productName ? `<div class="lbl-name ${alignClass}">${item.name || ""}</div>` : "";
159
+ const barcodeHtml = generateBarcodeHtml(item.code || "", printType, barcodeHeight);
160
+ const priceHtml = settings.unitPrice ? `<div class="lbl-price ${alignClass}">Gi\xE1: ${item.price !== void 0 ? Number(item.price).toLocaleString("vi-VN") : "0"}</div>` : "";
161
+ return `<div class="stamp-item">${companyHtml}${codeHtml}${nameHtml}${barcodeHtml}${priceHtml}</div>`;
162
+ };
163
+ var getPaperSizeLabel = (paperSize, stampNumber) => {
164
+ switch (Number(paperSize)) {
165
+ case 1:
166
+ return "Kh\u1ED5 gi\u1EA5y 2 tem (80x22mm)";
167
+ case 2:
168
+ return "Kh\u1ED5 gi\u1EA5y 3 tem (105x22mm)";
169
+ case 3:
170
+ return "Kh\u1ED5 gi\u1EA5y A5 (40 tem - Tomy 108)";
171
+ case 4:
172
+ return "Kh\u1ED5 gi\u1EA5y A4 (65 tem - Tomy 145)";
173
+ case 0:
174
+ default:
175
+ return `Kh\u1ED5 gi\u1EA5y t\xF9y ch\u1ECDn (${stampNumber || 3} tem/h\xE0ng)`;
176
+ }
177
+ };
178
+ var generatePrintDocument = (settings, items, isTest = false, isPreview = false) => {
179
+ var _a;
180
+ let labelList = [];
181
+ const orgName = getOrganizationName();
182
+ if (isTest) {
183
+ const sampleItem = items.length > 0 ? { ...items[0], companyName: orgName } : { code: "SP-001", name: "S\u1EA3n ph\u1EA9m m\u1EABu", price: 1e5, companyName: orgName };
184
+ labelList = [sampleItem];
185
+ } else {
186
+ items.forEach((item) => {
187
+ const qty = Math.max(1, Number(item.printQuantity || item.quantity || 1));
188
+ for (let i = 0; i < qty; i++) {
189
+ labelList.push({ ...item, companyName: orgName });
190
+ }
191
+ });
192
+ }
193
+ const paperSize = Number((_a = settings.paperSize) != null ? _a : 2);
194
+ const stampNumber = Math.max(1, Number(settings.stampNumber || 3));
195
+ const paperLabel = getPaperSizeLabel(paperSize, stampNumber);
196
+ if (labelList.length === 0) {
197
+ return { html: "", totalStamps: 0, paperLabel, uniqueProducts: items.length };
198
+ }
199
+ let cols = 3;
200
+ let pageSizeCss = "105mm auto";
201
+ let pageMargin = "0";
202
+ let labelWidth = "33mm";
203
+ let labelHeight = "22mm";
204
+ let labelGap = "1.5mm";
205
+ let bodyPadding = "1mm";
206
+ let stampPadding = "2px 4px";
207
+ let dynamicFontSize = "8px";
208
+ let barcodeHeight = 16;
209
+ let sheetWidth = "105mm";
210
+ let sheetMinHeight = "60mm";
211
+ let sheetPadding = "2mm 1mm";
212
+ let stampsPerPage = 999999;
213
+ if (isTest) {
214
+ cols = 1;
215
+ pageSizeCss = "auto";
216
+ pageMargin = "10mm";
217
+ labelWidth = "75mm";
218
+ labelHeight = "auto";
219
+ labelGap = "0";
220
+ bodyPadding = "0";
221
+ stampPadding = "10px 14px";
222
+ dynamicFontSize = "12.5px";
223
+ barcodeHeight = 42;
224
+ sheetWidth = "90mm";
225
+ sheetMinHeight = "60mm";
226
+ sheetPadding = "6mm";
227
+ stampsPerPage = 1;
228
+ } else {
229
+ switch (paperSize) {
230
+ case 1:
231
+ cols = 2;
232
+ pageSizeCss = "80mm auto";
233
+ pageMargin = "0";
234
+ labelWidth = "38mm";
235
+ labelHeight = "22mm";
236
+ labelGap = "2mm";
237
+ bodyPadding = "1mm";
238
+ stampPadding = "2px 4px";
239
+ dynamicFontSize = "8px";
240
+ barcodeHeight = 18;
241
+ sheetWidth = "80mm";
242
+ sheetMinHeight = "60mm";
243
+ sheetPadding = "2mm 1mm";
244
+ stampsPerPage = 999999;
245
+ break;
246
+ case 2:
247
+ cols = 3;
248
+ pageSizeCss = "105mm auto";
249
+ pageMargin = "0";
250
+ labelWidth = "33mm";
251
+ labelHeight = "22mm";
252
+ labelGap = "1.5mm";
253
+ bodyPadding = "1mm";
254
+ stampPadding = "1px 3px";
255
+ dynamicFontSize = "7.5px";
256
+ barcodeHeight = 16;
257
+ sheetWidth = "105mm";
258
+ sheetMinHeight = "60mm";
259
+ sheetPadding = "2mm 1mm";
260
+ stampsPerPage = 999999;
261
+ break;
262
+ case 3:
263
+ cols = 5;
264
+ pageSizeCss = "A5 portrait";
265
+ pageMargin = "6mm 4mm";
266
+ labelWidth = "27mm";
267
+ labelHeight = "22mm";
268
+ labelGap = "1.5mm";
269
+ bodyPadding = "0";
270
+ stampPadding = "2px 3px";
271
+ dynamicFontSize = "7.5px";
272
+ barcodeHeight = 16;
273
+ sheetWidth = "148mm";
274
+ sheetMinHeight = "210mm";
275
+ sheetPadding = "6mm 4mm";
276
+ stampsPerPage = 40;
277
+ break;
278
+ case 4:
279
+ cols = 5;
280
+ pageSizeCss = "A4 portrait";
281
+ pageMargin = "8mm 5mm";
282
+ labelWidth = "38mm";
283
+ labelHeight = "20mm";
284
+ labelGap = "1.5mm";
285
+ bodyPadding = "0";
286
+ stampPadding = "2px 4px";
287
+ dynamicFontSize = "8px";
288
+ barcodeHeight = 18;
289
+ sheetWidth = "210mm";
290
+ sheetMinHeight = "297mm";
291
+ sheetPadding = "8mm 5mm";
292
+ stampsPerPage = 65;
293
+ break;
294
+ case 0:
295
+ // Tùy chọn
296
+ default:
297
+ cols = stampNumber;
298
+ pageSizeCss = "auto";
299
+ pageMargin = "5mm";
300
+ labelWidth = `${Math.floor(100 / cols)}%`;
301
+ labelHeight = "22mm";
302
+ labelGap = "3mm";
303
+ bodyPadding = "2mm";
304
+ stampPadding = "4px 6px";
305
+ dynamicFontSize = "9.5px";
306
+ barcodeHeight = 26;
307
+ sheetWidth = "210mm";
308
+ sheetMinHeight = "297mm";
309
+ sheetPadding = "8mm 6mm";
310
+ stampsPerPage = 999999;
311
+ break;
312
+ }
313
+ }
314
+ let printDocument = "";
315
+ if (isPreview) {
316
+ const pages = [];
317
+ if (stampsPerPage < 999999) {
318
+ for (let i = 0; i < labelList.length; i += stampsPerPage) {
319
+ const chunk = labelList.slice(i, i + stampsPerPage);
320
+ const emptyCount = stampsPerPage - chunk.length;
321
+ pages.push({ items: chunk, emptyCount });
322
+ }
323
+ } else {
324
+ pages.push({ items: labelList, emptyCount: 0 });
325
+ }
326
+ const pagesHtml = pages.map((page, pageIndex) => {
327
+ const pageLabelsHtml = page.items.map((item) => renderSingleLabelHtml(item, settings, orgName, barcodeHeight)).join("");
328
+ let emptySlotsHtml = "";
329
+ if (page.emptyCount > 0) {
330
+ emptySlotsHtml = Array(page.emptyCount).fill(0).map(() => '<div class="empty-slot" title="V\u1ECB tr\xED tem tr\u1ED1ng tr\xEAn decal"></div>').join("");
331
+ }
332
+ const pageIndicator = pages.length > 1 ? `<div class="page-indicator">Trang ${pageIndex + 1} / ${pages.length} (${page.items.length} tem)</div>` : "";
333
+ return `
334
+ <div class="page-wrapper">
335
+ ${pageIndicator}
336
+ <div class="preview-sheet-wrapper">
337
+ <div class="print-container">
338
+ ${pageLabelsHtml}
339
+ ${emptySlotsHtml}
340
+ </div>
341
+ </div>
342
+ </div>
343
+ `;
344
+ }).join("");
345
+ printDocument = `
346
+ <!DOCTYPE html>
347
+ <html>
348
+ <head>
349
+ <meta charset="utf-8" />
350
+ <title>Xem tr\u01B0\u1EDBc b\u1EA3n in</title>
351
+ <style>
352
+ * {
353
+ box-sizing: border-box;
354
+ margin: 0;
355
+ padding: 0;
356
+ }
357
+ body {
358
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
359
+ background: #e9ecef;
360
+ color: #000;
361
+ padding: 24px 16px 40px 16px;
362
+ display: flex;
363
+ flex-direction: column;
364
+ align-items: center;
365
+ min-height: 100vh;
366
+ transform-origin: top center;
367
+ }
368
+ .page-wrapper {
369
+ display: flex;
370
+ flex-direction: column;
371
+ align-items: center;
372
+ margin-bottom: 28px;
373
+ }
374
+ .page-indicator {
375
+ font-size: 12px;
376
+ font-weight: 600;
377
+ color: #495057;
378
+ margin-bottom: 8px;
379
+ background: #ffffff;
380
+ padding: 4px 14px;
381
+ border-radius: 20px;
382
+ box-shadow: 0 1px 4px rgba(0,0,0,0.08);
383
+ border: 1px solid #ced4da;
384
+ }
385
+ .preview-sheet-wrapper {
386
+ background: #ffffff;
387
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.04);
388
+ border: 1px solid #ced4da;
389
+ border-radius: 4px;
390
+ padding: ${sheetPadding};
391
+ width: ${sheetWidth};
392
+ min-height: ${sheetMinHeight};
393
+ box-sizing: border-box;
394
+ display: flex;
395
+ flex-direction: column;
396
+ }
397
+ .print-container {
398
+ display: grid;
399
+ grid-template-columns: repeat(${cols}, ${paperSize === 0 && !isTest ? "1fr" : labelWidth});
400
+ gap: ${labelGap};
401
+ justify-content: ${isTest ? "flex-start" : "center"};
402
+ }
403
+ .stamp-item {
404
+ width: 100%;
405
+ min-height: ${isTest ? "48mm" : labelHeight === "auto" ? "22mm" : labelHeight};
406
+ height: ${labelHeight === "auto" ? "auto" : labelHeight};
407
+ padding: ${stampPadding};
408
+ display: flex;
409
+ flex-direction: column;
410
+ justify-content: space-between;
411
+ overflow: hidden;
412
+ border: 1px solid #d8d6de;
413
+ border-radius: 3px;
414
+ background: #fff;
415
+ box-sizing: border-box;
416
+ }
417
+ .empty-slot {
418
+ width: 100%;
419
+ min-height: ${labelHeight === "auto" ? "22mm" : labelHeight};
420
+ height: ${labelHeight === "auto" ? "22mm" : labelHeight};
421
+ border: 1px dashed #e2e5eb;
422
+ border-radius: 3px;
423
+ background: #fafbfc;
424
+ box-sizing: border-box;
425
+ }
426
+ .text-left {
427
+ text-align: left;
428
+ justify-content: flex-start;
429
+ }
430
+ .text-right {
431
+ text-align: right;
432
+ justify-content: flex-end;
433
+ }
434
+ .lbl-dynamic, .lbl-company, .lbl-code, .lbl-name, .lbl-price {
435
+ font-size: ${dynamicFontSize};
436
+ line-height: 1.2;
437
+ word-break: break-word;
438
+ white-space: normal;
439
+ margin-bottom: 2px;
440
+ }
441
+ .code-wrapper {
442
+ display: flex;
443
+ flex-direction: column;
444
+ justify-content: center;
445
+ align-items: center;
446
+ margin: 2px 0;
447
+ width: 100%;
448
+ }
449
+ .barcode-svg-box {
450
+ width: 82%;
451
+ max-width: 82%;
452
+ display: flex;
453
+ justify-content: center;
454
+ align-items: center;
455
+ overflow: hidden;
456
+ }
457
+ .barcode-svg-box svg {
458
+ width: 100%;
459
+ height: ${barcodeHeight}px;
460
+ }
461
+ .qr-wrapper svg {
462
+ width: ${barcodeHeight + 6}px;
463
+ height: ${barcodeHeight + 6}px;
464
+ }
465
+ </style>
466
+ </head>
467
+ <body>
468
+ ${pagesHtml}
469
+ </body>
470
+ </html>
471
+ `;
472
+ } else {
473
+ const labelsHtml = labelList.map((item) => renderSingleLabelHtml(item, settings, orgName, barcodeHeight)).join("");
474
+ printDocument = `
475
+ <!DOCTYPE html>
476
+ <html>
477
+ <head>
478
+ <meta charset="utf-8" />
479
+ <title>In m\xE3 v\u1EA1ch</title>
480
+ <style>
481
+ @page {
482
+ size: ${pageSizeCss};
483
+ margin: ${pageMargin};
484
+ }
485
+ * {
486
+ box-sizing: border-box;
487
+ margin: 0;
488
+ padding: 0;
489
+ -webkit-print-color-adjust: exact !important;
490
+ print-color-adjust: exact !important;
491
+ color-adjust: exact !important;
492
+ }
493
+ body {
494
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
495
+ background: #fff;
496
+ color: #000;
497
+ padding: ${bodyPadding};
498
+ -webkit-print-color-adjust: exact !important;
499
+ print-color-adjust: exact !important;
500
+ }
501
+ .print-container {
502
+ display: grid;
503
+ grid-template-columns: repeat(${cols}, ${paperSize === 0 && !isTest ? "1fr" : labelWidth});
504
+ gap: ${labelGap};
505
+ justify-content: ${isTest ? "flex-start" : "center"};
506
+ }
507
+ .stamp-item {
508
+ width: 100%;
509
+ min-height: ${isTest ? "48mm" : labelHeight === "auto" ? "22mm" : labelHeight};
510
+ padding: ${stampPadding};
511
+ display: flex;
512
+ flex-direction: column;
513
+ justify-content: space-between;
514
+ page-break-inside: avoid;
515
+ break-inside: avoid;
516
+ overflow: hidden;
517
+ border: 1px solid #d8d6de;
518
+ border-radius: 4px;
519
+ background: #fff;
520
+ }
521
+ .text-left {
522
+ text-align: left;
523
+ justify-content: flex-start;
524
+ }
525
+ .text-right {
526
+ text-align: right;
527
+ justify-content: flex-end;
528
+ }
529
+ .lbl-dynamic, .lbl-company, .lbl-code, .lbl-name, .lbl-price {
530
+ font-size: ${dynamicFontSize};
531
+ line-height: 1.2;
532
+ word-break: break-word;
533
+ white-space: normal;
534
+ margin-bottom: 2px;
535
+ }
536
+ .code-wrapper {
537
+ display: flex;
538
+ flex-direction: column;
539
+ justify-content: center;
540
+ align-items: center;
541
+ margin: 2px 0;
542
+ width: 100%;
543
+ }
544
+ .barcode-svg-box {
545
+ width: 82%;
546
+ max-width: 82%;
547
+ display: flex;
548
+ justify-content: center;
549
+ align-items: center;
550
+ overflow: hidden;
551
+ }
552
+ .barcode-svg-box svg {
553
+ width: 100%;
554
+ height: ${barcodeHeight}px;
555
+ }
556
+ .qr-wrapper svg {
557
+ width: ${barcodeHeight + 6}px;
558
+ height: ${barcodeHeight + 6}px;
559
+ }
560
+ </style>
561
+ </head>
562
+ <body>
563
+ <div class="print-container">
564
+ ${labelsHtml}
565
+ </div>
566
+ </body>
567
+ </html>
568
+ `;
569
+ }
570
+ return { html: printDocument, totalStamps: labelList.length, paperLabel, uniqueProducts: items.length };
571
+ };
572
+ var executePrint = (settings, items, isTest = false) => {
573
+ var _a;
574
+ const { html, totalStamps } = generatePrintDocument(settings, items, isTest, false);
575
+ if (totalStamps === 0) {
576
+ return;
577
+ }
578
+ let iframe = document.getElementById("print-barcode-iframe");
579
+ if (!iframe) {
580
+ iframe = document.createElement("iframe");
581
+ iframe.id = "print-barcode-iframe";
582
+ iframe.style.position = "fixed";
583
+ iframe.style.right = "0";
584
+ iframe.style.bottom = "0";
585
+ iframe.style.width = "0";
586
+ iframe.style.height = "0";
587
+ iframe.style.border = "none";
588
+ document.body.appendChild(iframe);
589
+ }
590
+ const iframeDoc = iframe.contentDocument || ((_a = iframe.contentWindow) == null ? void 0 : _a.document);
591
+ if (iframeDoc) {
592
+ iframeDoc.open();
593
+ iframeDoc.write(html);
594
+ iframeDoc.close();
595
+ setTimeout(() => {
596
+ var _a2, _b;
597
+ (_a2 = iframe.contentWindow) == null ? void 0 : _a2.focus();
598
+ (_b = iframe.contentWindow) == null ? void 0 : _b.print();
599
+ }, 250);
600
+ }
601
+ };
602
+
603
+ // src/components/preview-print.tsx
604
+ var import_qrcode = require("qrcode.react");
605
+ var import_react = require("react");
606
+ var import_react_barcode = __toESM(require("react-barcode"));
607
+ var import_jsx_runtime = require("react/jsx-runtime");
608
+ var PreviewPrint = ({ watch, setValue, sampleItem }) => {
609
+ var _a, _b;
610
+ const printType = Number((_a = watch("printType")) != null ? _a : 0);
611
+ const fields = (_b = watch("fields")) != null ? _b : [];
612
+ const draggingRef = (0, import_react.useRef)(null);
613
+ const [activeDragId, setActiveDragId] = (0, import_react.useState)(null);
614
+ const getOrgName = () => {
615
+ try {
616
+ const dataLocal = localStorage.getItem("organization");
617
+ const organization = JSON.parse(dataLocal && dataLocal !== "undefined" ? dataLocal : "null");
618
+ return (organization == null ? void 0 : organization.text) || (organization == null ? void 0 : organization.label) || (organization == null ? void 0 : organization.name) || "T\xEAn c\xF4ng ty";
619
+ } catch (e) {
620
+ return "T\xEAn c\xF4ng ty";
621
+ }
622
+ };
623
+ const sampleData = sampleItem || {
624
+ companyName: getOrgName(),
625
+ code: "SP-001",
626
+ productCode: "SP-001",
627
+ name: "S\u1EA3n ph\u1EA9m m\u1EABu",
628
+ productName: "S\u1EA3n ph\u1EA9m m\u1EABu",
629
+ price: "250.000",
630
+ unitPrice: "250.000",
631
+ unitName: "C\xE1i",
632
+ origin: "Vi\u1EC7t Nam",
633
+ categoryRootName: "Danh m\u1EE5c m\u1EABu",
634
+ lotSerial: "LOT-2026",
635
+ specificationCode: "SIZE-L"
636
+ };
637
+ const barcodeValue = sampleData.code || "SP-001";
638
+ const hinge = watch("hinge");
639
+ const alignStyle = {
640
+ display: "flex",
641
+ justifyContent: hinge ? "flex-end" : "flex-start",
642
+ alignItems: "center",
643
+ textAlign: hinge ? "right" : "left"
644
+ };
645
+ const handleMouseDown = (e, field) => {
646
+ if (!setValue) {
647
+ return;
648
+ }
649
+ e.preventDefault();
650
+ e.stopPropagation();
651
+ draggingRef.current = {
652
+ fieldId: field.id,
653
+ startX: e.clientX,
654
+ initialOffset: field.offsetX || 0
655
+ };
656
+ setActiveDragId(field.id);
657
+ const handleMouseMove = (moveEvent) => {
658
+ if (!draggingRef.current) {
659
+ return;
660
+ }
661
+ const deltaX = moveEvent.clientX - draggingRef.current.startX;
662
+ const newOffset = Math.max(0, Math.min(180, Math.round(draggingRef.current.initialOffset + deltaX)));
663
+ const currentFields = watch("fields") || [];
664
+ const updatedFields = currentFields.map((f) => {
665
+ var _a2;
666
+ return f.id === ((_a2 = draggingRef.current) == null ? void 0 : _a2.fieldId) ? { ...f, offsetX: newOffset } : f;
667
+ });
668
+ setValue("fields", updatedFields);
669
+ };
670
+ const handleMouseUp = () => {
671
+ draggingRef.current = null;
672
+ setActiveDragId(null);
673
+ window.removeEventListener("mousemove", handleMouseMove);
674
+ window.removeEventListener("mouseup", handleMouseUp);
675
+ };
676
+ window.addEventListener("mousemove", handleMouseMove);
677
+ window.addEventListener("mouseup", handleMouseUp);
678
+ };
679
+ const renderCode = (field) => {
680
+ const offsetX = (field == null ? void 0 : field.offsetX) || 0;
681
+ const containerStyle = {
682
+ ...alignStyle,
683
+ marginTop: 4,
684
+ marginBottom: 4,
685
+ width: "100%",
686
+ flexDirection: "column",
687
+ alignItems: hinge ? "flex-end" : "center",
688
+ paddingLeft: offsetX > 0 ? `${offsetX}px` : void 0,
689
+ cursor: setValue ? "ew-resize" : "default",
690
+ position: "relative"
691
+ };
692
+ if (printType === 0) {
693
+ const len = barcodeValue.length;
694
+ let barWidth = 1.3;
695
+ if (len <= 6) {
696
+ barWidth = 2.2;
697
+ } else if (len <= 10) {
698
+ barWidth = 1.7;
699
+ } else if (len <= 15) {
700
+ barWidth = 1.3;
701
+ } else if (len <= 20) {
702
+ barWidth = 1.05;
703
+ } else {
704
+ barWidth = 0.85;
705
+ }
706
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
707
+ "div",
708
+ {
709
+ onMouseDown: (e) => field && handleMouseDown(e, field),
710
+ title: setValue ? "K\xE9o chu\u1ED9t sang tr\xE1i/ph\u1EA3i \u0111\u1EC3 d\u1ECBch chuy\u1EC3n l\u1EC1" : void 0,
711
+ style: containerStyle,
712
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
713
+ "div",
714
+ {
715
+ style: {
716
+ width: "82%",
717
+ maxWidth: "220px",
718
+ height: "42px",
719
+ display: "flex",
720
+ justifyContent: "center",
721
+ overflow: "hidden",
722
+ outline: activeDragId === (field == null ? void 0 : field.id) ? "1px dashed #7367f0" : "none"
723
+ },
724
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
725
+ import_react_barcode.default,
726
+ {
727
+ value: barcodeValue,
728
+ format: "CODE128",
729
+ displayValue: false,
730
+ margin: 0,
731
+ height: 40,
732
+ width: barWidth
733
+ }
734
+ )
735
+ }
736
+ )
737
+ },
738
+ "barcode-item"
739
+ );
740
+ }
741
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
742
+ "div",
743
+ {
744
+ onMouseDown: (e) => field && handleMouseDown(e, field),
745
+ title: setValue ? "K\xE9o chu\u1ED9t sang tr\xE1i/ph\u1EA3i \u0111\u1EC3 d\u1ECBch chuy\u1EC3n l\u1EC1" : void 0,
746
+ style: {
747
+ ...alignStyle,
748
+ minHeight: 80,
749
+ marginTop: 4,
750
+ marginBottom: 4,
751
+ width: "100%",
752
+ justifyContent: hinge ? "flex-end" : "center",
753
+ paddingLeft: offsetX > 0 ? `${offsetX}px` : void 0,
754
+ cursor: setValue ? "ew-resize" : "default"
755
+ },
756
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_qrcode.QRCodeCanvas, { value: barcodeValue, size: 85 })
757
+ },
758
+ "barcode-item"
759
+ );
760
+ };
761
+ const renderDynamicFields = () => {
762
+ if (!fields || fields.length === 0) {
763
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
764
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.codeText, ...alignStyle }, children: "SP-001" }),
765
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.normalText, ...alignStyle }, children: "S\u1EA3n ph\u1EA9m m\u1EABu" }),
766
+ renderCode(),
767
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.price, ...alignStyle }, children: "Gi\xE1: 250.000" })
768
+ ] });
769
+ }
770
+ return fields.filter((f) => f.enabled).map((field) => {
771
+ if (field.type === "barcode") {
772
+ return renderCode(field);
773
+ }
774
+ const rawVal = field.type === "custom" ? field.customValue || field.label : sampleData[field.key] || sampleData[field.id] || field.label;
775
+ const prefix = field.prefix || "";
776
+ const suffix = field.suffix || "";
777
+ const displayVal = `${prefix}${rawVal}${suffix}`;
778
+ const isBold = field.bold !== false;
779
+ const isItalic = !!field.italic;
780
+ const isUnderline = !!field.underline;
781
+ const textColor = field.color || "#111111";
782
+ const customFontSize = field.fontSize || 13;
783
+ const offsetX = field.offsetX || 0;
784
+ const fieldStyle = {
785
+ ...styles.dynamicText,
786
+ ...alignStyle,
787
+ fontWeight: isBold ? 700 : 400,
788
+ fontStyle: isItalic ? "italic" : "normal",
789
+ textDecoration: isUnderline ? "underline" : "none",
790
+ color: textColor,
791
+ fontSize: `${customFontSize}px`,
792
+ paddingLeft: offsetX > 0 ? `${offsetX}px` : void 0,
793
+ cursor: setValue ? "ew-resize" : "default",
794
+ userSelect: "none",
795
+ outline: activeDragId === field.id ? "1px dashed #7367f0" : "none",
796
+ borderRadius: "2px",
797
+ transition: activeDragId === field.id ? "none" : "padding-left 0.1s ease"
798
+ };
799
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
800
+ "div",
801
+ {
802
+ style: fieldStyle,
803
+ onMouseDown: (e) => handleMouseDown(e, field),
804
+ title: setValue ? "K\xE9o chu\u1ED9t sang tr\xE1i/ph\u1EA3i \u0111\u1EC3 d\u1ECBch chuy\u1EC3n l\u1EC1" : void 0,
805
+ children: displayVal
806
+ },
807
+ field.id
808
+ );
809
+ });
810
+ };
811
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.previewBox, children: renderDynamicFields() }) });
812
+ };
813
+ var styles = {
814
+ previewBox: {
815
+ width: "100%",
816
+ maxWidth: 320,
817
+ minHeight: 180,
818
+ border: "1px solid #d8d6de",
819
+ borderRadius: "4px",
820
+ background: "#fff",
821
+ padding: "12px 16px",
822
+ boxSizing: "border-box",
823
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.06)",
824
+ display: "flex",
825
+ flexDirection: "column",
826
+ justifyContent: "center",
827
+ position: "relative"
828
+ },
829
+ codeText: {
830
+ fontSize: 14,
831
+ fontWeight: 700,
832
+ color: "#111",
833
+ marginBottom: 2,
834
+ lineHeight: 1.25,
835
+ wordBreak: "break-word",
836
+ whiteSpace: "normal"
837
+ },
838
+ normalText: {
839
+ fontSize: 13,
840
+ fontWeight: 500,
841
+ color: "#333",
842
+ lineHeight: 1.25,
843
+ marginBottom: 4,
844
+ wordBreak: "break-word",
845
+ whiteSpace: "normal"
846
+ },
847
+ price: {
848
+ fontSize: 13,
849
+ fontWeight: 700,
850
+ color: "#111",
851
+ lineHeight: 1.25,
852
+ marginTop: 4,
853
+ wordBreak: "break-word",
854
+ whiteSpace: "normal"
855
+ },
856
+ dynamicText: {
857
+ fontSize: 13,
858
+ color: "#111",
859
+ lineHeight: 1.25,
860
+ marginBottom: 2,
861
+ wordBreak: "break-word",
862
+ whiteSpace: "normal"
863
+ }
864
+ };
865
+
866
+ // src/components/setting-print.tsx
867
+ var Icon = __toESM(require("becoxy-icons"));
868
+ var import_react2 = require("react");
869
+ var import_react_hook_form = require("react-hook-form");
870
+ var import_reactstrap = require("reactstrap");
871
+ var import_jsx_runtime2 = require("react/jsx-runtime");
872
+ var DEFAULT_EXTRA_FIELDS = [
873
+ { id: "unitName", key: "unitName", label: "\u0110\u01A1n v\u1ECB t\xEDnh", type: "text", prefix: "\u0110VT: " },
874
+ { id: "origin", key: "origin", label: "Xu\u1EA5t x\u1EE9", type: "text", prefix: "Xu\u1EA5t x\u1EE9: " },
875
+ { id: "categoryRootName", key: "categoryRootName", label: "Nh\xF3m h\xE0ng / Danh m\u1EE5c", type: "text", prefix: "Nh\xF3m: " },
876
+ { id: "specificationCode", key: "specificationCode", label: "M\xE3 quy c\xE1ch", type: "text", prefix: "Quy c\xE1ch: " },
877
+ { id: "lotSerial", key: "lotSerial", label: "S\u1ED1 l\xF4 / Serial", type: "text", prefix: "L\xF4: " },
878
+ { id: "customText", key: "custom", label: "V\u0103n b\u1EA3n t\xF9y ch\u1EC9nh", type: "custom", customValue: "H\xE0ng ch\xEDnh h\xE3ng" }
879
+ ];
880
+ var COLOR_PRESETS = [
881
+ { label: "\u0110en", value: "#000000" },
882
+ { label: "\u0110\u1ECF", value: "#dc3545" },
883
+ { label: "Xanh d\u01B0\u01A1ng", value: "#0d6efd" },
884
+ { label: "Xanh l\xE1", value: "#198754" },
885
+ { label: "X\xE1m", value: "#6c757d" }
886
+ ];
887
+ var SettingPrint = (props) => {
888
+ const { control, watch, setValue, availableExtraFields = DEFAULT_EXTRA_FIELDS, t = (s) => s } = props;
889
+ const [openPaperSection, setOpenPaperSection] = (0, import_react2.useState)(true);
890
+ const [openInfoSection, setOpenInfoSection] = (0, import_react2.useState)(true);
891
+ const [openCustomSection, setOpenCustomSection] = (0, import_react2.useState)(false);
892
+ const [expandedFieldId, setExpandedFieldId] = (0, import_react2.useState)(null);
893
+ const [draggedIndex, setDraggedIndex] = (0, import_react2.useState)(null);
894
+ const fields = watch("fields") || [];
895
+ const handleToggleField = (index) => {
896
+ const newFields = [...fields];
897
+ newFields[index] = { ...newFields[index], enabled: !newFields[index].enabled };
898
+ setValue("fields", newFields);
899
+ };
900
+ const handleMoveUp = (index) => {
901
+ if (index <= 0) {
902
+ return;
903
+ }
904
+ const newFields = [...fields];
905
+ const temp = newFields[index];
906
+ newFields[index] = newFields[index - 1];
907
+ newFields[index - 1] = temp;
908
+ setValue("fields", newFields);
909
+ };
910
+ const handleMoveDown = (index) => {
911
+ if (index >= fields.length - 1) {
912
+ return;
913
+ }
914
+ const newFields = [...fields];
915
+ const temp = newFields[index];
916
+ newFields[index] = newFields[index + 1];
917
+ newFields[index + 1] = temp;
918
+ setValue("fields", newFields);
919
+ };
920
+ const handleDeleteField = (index) => {
921
+ const newFields = fields.filter((_, i) => i !== index);
922
+ setValue("fields", newFields);
923
+ };
924
+ const handleAddField = (fieldTemplate) => {
925
+ const exists = fields.find((f) => f.id === fieldTemplate.id);
926
+ if (exists) {
927
+ const newFields = fields.map((f) => f.id === fieldTemplate.id ? { ...f, enabled: true } : f);
928
+ setValue("fields", newFields);
929
+ } else {
930
+ const newField = {
931
+ id: fieldTemplate.id,
932
+ key: fieldTemplate.key,
933
+ label: fieldTemplate.label,
934
+ type: fieldTemplate.type,
935
+ enabled: true,
936
+ bold: false,
937
+ prefix: fieldTemplate.prefix || "",
938
+ customValue: fieldTemplate.customValue || ""
939
+ };
940
+ setValue("fields", [...fields, newField]);
941
+ }
942
+ };
943
+ const updateFieldProperty = (index, propName, value) => {
944
+ const newFields = [...fields];
945
+ newFields[index] = { ...newFields[index], [propName]: value };
946
+ setValue("fields", newFields);
947
+ };
948
+ const handleDragStart = (index) => {
949
+ setDraggedIndex(index);
950
+ };
951
+ const handleDragOver = (e, index) => {
952
+ e.preventDefault();
953
+ if (draggedIndex === null || draggedIndex === index) {
954
+ return;
955
+ }
956
+ const newFields = [...fields];
957
+ const item = newFields.splice(draggedIndex, 1)[0];
958
+ newFields.splice(index, 0, item);
959
+ setDraggedIndex(index);
960
+ setValue("fields", newFields);
961
+ };
962
+ const handleDragEnd = () => {
963
+ setDraggedIndex(null);
964
+ };
965
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex flex-column h-100", style: { gap: "16px", overflowY: "auto", paddingRight: "4px" }, children: [
966
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "border-bottom pb-1", children: [
967
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fw-bolder text-dark mb-75", children: t("Lo\u1EA1i m\xE3 in") }),
968
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
969
+ import_react_hook_form.Controller,
970
+ {
971
+ name: "printType",
972
+ control,
973
+ render: ({ field: { value, onChange } }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex", style: { gap: "20px" }, children: [
974
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
975
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
976
+ import_reactstrap.Input,
977
+ {
978
+ type: "radio",
979
+ name: "printType",
980
+ className: "me-50 mt-0",
981
+ checked: Number(value) === 0,
982
+ onChange: () => onChange(0)
983
+ }
984
+ ),
985
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("M\xE3 v\u1EA1ch (Barcode)") })
986
+ ] }),
987
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
988
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
989
+ import_reactstrap.Input,
990
+ {
991
+ type: "radio",
992
+ name: "printType",
993
+ className: "me-50 mt-0",
994
+ checked: Number(value) === 1,
995
+ onChange: () => onChange(1)
996
+ }
997
+ ),
998
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("M\xE3 QR") })
999
+ ] })
1000
+ ] })
1001
+ }
1002
+ )
1003
+ ] }),
1004
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "border-bottom pb-1", children: [
1005
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1006
+ "div",
1007
+ {
1008
+ className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1009
+ onClick: () => setOpenPaperSection(!openPaperSection),
1010
+ children: [
1011
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fw-bolder text-dark", children: t("Kh\u1ED5 gi\u1EA5y in") }),
1012
+ openPaperSection ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronRight, { fontSize: 16 })
1013
+ ]
1014
+ }
1015
+ ),
1016
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_reactstrap.Collapse, { isOpen: openPaperSection, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1017
+ import_react_hook_form.Controller,
1018
+ {
1019
+ name: "paperSize",
1020
+ control,
1021
+ render: ({ field: { value, onChange } }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex flex-column ps-1", style: { gap: "8px" }, children: [
1022
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1023
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1024
+ import_reactstrap.Input,
1025
+ {
1026
+ type: "radio",
1027
+ name: "paperSize",
1028
+ className: "me-50 mt-0",
1029
+ checked: Number(value) === 1,
1030
+ onChange: () => onChange(1)
1031
+ }
1032
+ ),
1033
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Kh\u1ED5 gi\u1EA5y 2 tem (80x22mm / 3.15x0.9 inch)") })
1034
+ ] }),
1035
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1036
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1037
+ import_reactstrap.Input,
1038
+ {
1039
+ type: "radio",
1040
+ name: "paperSize",
1041
+ className: "me-50 mt-0",
1042
+ checked: Number(value) === 2,
1043
+ onChange: () => onChange(2)
1044
+ }
1045
+ ),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Kh\u1ED5 gi\u1EA5y 3 tem (105x22mm / 4.2x0.9 inch)") })
1047
+ ] }),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1049
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1050
+ import_reactstrap.Input,
1051
+ {
1052
+ type: "radio",
1053
+ name: "paperSize",
1054
+ className: "me-50 mt-0",
1055
+ checked: Number(value) === 3,
1056
+ onChange: () => onChange(3)
1057
+ }
1058
+ ),
1059
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Kh\u1ED5 gi\u1EA5y A5 - T\u1ED5ng 40 tem (Tomy 108)") })
1060
+ ] }),
1061
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1062
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1063
+ import_reactstrap.Input,
1064
+ {
1065
+ type: "radio",
1066
+ name: "paperSize",
1067
+ className: "me-50 mt-0",
1068
+ checked: Number(value) === 4,
1069
+ onChange: () => onChange(4)
1070
+ }
1071
+ ),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Kh\u1ED5 gi\u1EA5y A4 - T\u1ED5ng 65 tem (Tomy 145)") })
1073
+ ] }),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1075
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer me-1", children: [
1076
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1077
+ import_reactstrap.Input,
1078
+ {
1079
+ type: "radio",
1080
+ name: "paperSize",
1081
+ className: "me-50 mt-0",
1082
+ checked: Number(value) === 0,
1083
+ onChange: () => onChange(0)
1084
+ }
1085
+ ),
1086
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Kh\u1ED5 gi\u1EA5y t\xF9y ch\u1ECDn") })
1087
+ ] }),
1088
+ Number(value) === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1089
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1090
+ import_react_hook_form.Controller,
1091
+ {
1092
+ name: "stampNumber",
1093
+ control,
1094
+ render: ({ field: { value: stampVal, onChange: onStampChange } }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1095
+ import_reactstrap.Input,
1096
+ {
1097
+ type: "number",
1098
+ min: 1,
1099
+ max: 10,
1100
+ className: "form-control-sm text-center",
1101
+ style: { width: "60px" },
1102
+ value: stampVal != null ? stampVal : 3,
1103
+ onChange: (e) => onStampChange(Math.max(1, Number(e.target.value) || 1))
1104
+ }
1105
+ )
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "ms-50 small text-muted", children: t("tem/h\xE0ng") })
1109
+ ] })
1110
+ ] })
1111
+ ] })
1112
+ }
1113
+ ) })
1114
+ ] }),
1115
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "border-bottom pb-1", children: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1117
+ "div",
1118
+ {
1119
+ className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1120
+ onClick: () => setOpenInfoSection(!openInfoSection),
1121
+ children: [
1122
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fw-bolder text-dark", children: t("Th\xF4ng tin tr\xEAn tem") }),
1123
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1124
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { className: "text-muted me-50", style: { fontSize: "11px" }, children: t("(K\xE9o th\u1EA3 \u0111\u1EC3 \u0111\u1ED5i v\u1ECB tr\xED)") }),
1125
+ openInfoSection ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronRight, { fontSize: 16 })
1126
+ ] })
1127
+ ]
1128
+ }
1129
+ ),
1130
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_reactstrap.Collapse, { isOpen: openInfoSection, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex flex-column", style: { gap: "6px" }, children: [
1131
+ fields.map((field, index) => {
1132
+ const isExpanded = expandedFieldId === field.id;
1133
+ const isDragging = draggedIndex === index;
1134
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1135
+ "div",
1136
+ {
1137
+ draggable: true,
1138
+ onDragStart: () => handleDragStart(index),
1139
+ onDragOver: (e) => handleDragOver(e, index),
1140
+ onDragEnd: handleDragEnd,
1141
+ className: "border rounded p-50",
1142
+ style: {
1143
+ background: isDragging ? "#e8f0fe" : field.enabled ? "#fff" : "#f9f9f9",
1144
+ opacity: isDragging ? 0.6 : 1,
1145
+ transition: "background 0.2s",
1146
+ boxShadow: isExpanded ? "0 2px 6px rgba(0,0,0,0.08)" : "none"
1147
+ },
1148
+ children: [
1149
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1150
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1151
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1152
+ "span",
1153
+ {
1154
+ className: "cursor-move text-muted me-50 d-flex align-items-center",
1155
+ title: t("K\xE9o \u0111\u1EC3 \u0111\u1ED5i th\u1EE9 t\u1EF1"),
1156
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Menu, { fontSize: 13 })
1157
+ }
1158
+ ),
1159
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1160
+ import_reactstrap.Input,
1161
+ {
1162
+ type: "checkbox",
1163
+ id: `chk-field-${field.id}`,
1164
+ className: "me-50 mt-0",
1165
+ checked: field.enabled,
1166
+ onChange: () => handleToggleField(index)
1167
+ }
1168
+ ),
1169
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1170
+ import_reactstrap.Label,
1171
+ {
1172
+ htmlFor: `chk-field-${field.id}`,
1173
+ className: `mb-0 cursor-pointer ${field.enabled ? "fw-bold text-dark" : "text-muted"}`,
1174
+ style: { fontSize: "13px" },
1175
+ children: field.label
1176
+ }
1177
+ )
1178
+ ] }),
1179
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", style: { gap: "3px" }, children: [
1180
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1181
+ import_reactstrap.Button,
1182
+ {
1183
+ color: "flat-secondary",
1184
+ className: "btn-icon p-0",
1185
+ style: { width: "22px", height: "22px" },
1186
+ onClick: () => handleMoveUp(index),
1187
+ disabled: index === 0,
1188
+ title: t("Di chuy\u1EC3n l\xEAn"),
1189
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ArrowUp, { fontSize: 12 })
1190
+ }
1191
+ ),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1193
+ import_reactstrap.Button,
1194
+ {
1195
+ color: "flat-secondary",
1196
+ className: "btn-icon p-0",
1197
+ style: { width: "22px", height: "22px" },
1198
+ onClick: () => handleMoveDown(index),
1199
+ disabled: index === fields.length - 1,
1200
+ title: t("Di chuy\u1EC3n xu\u1ED1ng"),
1201
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ArrowDown, { fontSize: 12 })
1202
+ }
1203
+ ),
1204
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1205
+ import_reactstrap.Button,
1206
+ {
1207
+ color: "flat-secondary",
1208
+ className: "btn-icon p-0",
1209
+ style: { width: "22px", height: "22px" },
1210
+ onClick: () => setExpandedFieldId(isExpanded ? null : field.id),
1211
+ title: t("T\xF9y ch\u1EC9nh \u0111\u1ECBnh d\u1EA1ng"),
1212
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Settings, { fontSize: 12, className: isExpanded ? "text-primary" : "" })
1213
+ }
1214
+ ),
1215
+ field.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1216
+ import_reactstrap.Button,
1217
+ {
1218
+ color: "flat-danger",
1219
+ className: "btn-icon p-0 text-danger",
1220
+ style: { width: "22px", height: "22px" },
1221
+ onClick: () => handleDeleteField(index),
1222
+ title: t("X\xF3a tr\u01B0\u1EDDng"),
1223
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Trash2, { fontSize: 12 })
1224
+ }
1225
+ )
1226
+ ] })
1227
+ ] }),
1228
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mt-50 pt-50 border-top ps-1 pe-50", children: [
1229
+ field.type !== "barcode" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex flex-column", style: { gap: "6px" }, children: [
1230
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1231
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1232
+ t("Ki\u1EC3u ch\u1EEF"),
1233
+ ":"
1234
+ ] }),
1235
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.ButtonGroup, { size: "sm", children: [
1236
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1237
+ import_reactstrap.Button,
1238
+ {
1239
+ color: field.bold !== false ? "primary" : "outline-secondary",
1240
+ className: "btn-icon py-0 px-50",
1241
+ onClick: () => updateFieldProperty(index, "bold", field.bold === false),
1242
+ title: "In \u0111\u1EADm (Bold)",
1243
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "B" })
1244
+ }
1245
+ ),
1246
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1247
+ import_reactstrap.Button,
1248
+ {
1249
+ color: field.italic ? "primary" : "outline-secondary",
1250
+ className: "btn-icon py-0 px-50",
1251
+ onClick: () => updateFieldProperty(index, "italic", !field.italic),
1252
+ title: "In nghi\xEAng (Italic)",
1253
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: "I" })
1254
+ }
1255
+ ),
1256
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1257
+ import_reactstrap.Button,
1258
+ {
1259
+ color: field.underline ? "primary" : "outline-secondary",
1260
+ className: "btn-icon py-0 px-50",
1261
+ onClick: () => updateFieldProperty(index, "underline", !field.underline),
1262
+ title: "G\u1EA1ch ch\xE2n (Underline)",
1263
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("u", { children: "U" })
1264
+ }
1265
+ )
1266
+ ] })
1267
+ ] }),
1268
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1269
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1270
+ t("C\u1EE1 ch\u1EEF (px)"),
1271
+ ":"
1272
+ ] }),
1273
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1274
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1275
+ import_reactstrap.Button,
1276
+ {
1277
+ color: "outline-secondary",
1278
+ className: "btn-icon p-0",
1279
+ style: { width: "22px", height: "22px" },
1280
+ onClick: () => updateFieldProperty(index, "fontSize", Math.max(8, (field.fontSize || 13) - 1)),
1281
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Minus, { fontSize: 10 })
1282
+ }
1283
+ ),
1284
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "mx-50 small fw-bold", style: { minWidth: "24px", textAlign: "center" }, children: field.fontSize || 13 }),
1285
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1286
+ import_reactstrap.Button,
1287
+ {
1288
+ color: "outline-secondary",
1289
+ className: "btn-icon p-0",
1290
+ style: { width: "22px", height: "22px" },
1291
+ onClick: () => updateFieldProperty(index, "fontSize", Math.min(24, (field.fontSize || 13) + 1)),
1292
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Plus, { fontSize: 10 })
1293
+ }
1294
+ )
1295
+ ] })
1296
+ ] }),
1297
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1298
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1299
+ t("M\xE0u ch\u1EEF"),
1300
+ ":"
1301
+ ] }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "d-flex align-items-center", style: { gap: "4px" }, children: COLOR_PRESETS.map((colorItem) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1303
+ "div",
1304
+ {
1305
+ onClick: () => updateFieldProperty(index, "color", colorItem.value),
1306
+ title: colorItem.label,
1307
+ style: {
1308
+ width: "16px",
1309
+ height: "16px",
1310
+ borderRadius: "50%",
1311
+ backgroundColor: colorItem.value,
1312
+ cursor: "pointer",
1313
+ outline: (field.color || "#000000") === colorItem.value ? "2px solid #7367f0" : "none",
1314
+ outlineOffset: "1px"
1315
+ }
1316
+ },
1317
+ colorItem.value
1318
+ )) })
1319
+ ] }),
1320
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1321
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1322
+ t("Ti\u1EC1n t\u1ED1"),
1323
+ ":"
1324
+ ] }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1326
+ import_reactstrap.Input,
1327
+ {
1328
+ type: "text",
1329
+ className: "form-control-sm",
1330
+ style: { width: "120px" },
1331
+ value: field.prefix || "",
1332
+ onChange: (e) => updateFieldProperty(index, "prefix", e.target.value),
1333
+ placeholder: "VD: Gi\xE1: "
1334
+ }
1335
+ )
1336
+ ] }),
1337
+ field.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1338
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1339
+ t("N\u1ED9i dung"),
1340
+ ":"
1341
+ ] }),
1342
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1343
+ import_reactstrap.Input,
1344
+ {
1345
+ type: "text",
1346
+ className: "form-control-sm",
1347
+ style: { width: "140px" },
1348
+ value: field.customValue || "",
1349
+ onChange: (e) => updateFieldProperty(index, "customValue", e.target.value)
1350
+ }
1351
+ )
1352
+ ] })
1353
+ ] }),
1354
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between mt-50", children: [
1355
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-muted", children: [
1356
+ t("L\xF9i l\u1EC1 tr\xE1i (px)"),
1357
+ ":"
1358
+ ] }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center", children: [
1360
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1361
+ import_reactstrap.Button,
1362
+ {
1363
+ color: "outline-secondary",
1364
+ className: "btn-icon p-0",
1365
+ style: { width: "22px", height: "22px" },
1366
+ onClick: () => updateFieldProperty(index, "offsetX", Math.max(0, (field.offsetX || 0) - 2)),
1367
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Minus, { fontSize: 10 })
1368
+ }
1369
+ ),
1370
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "mx-50 small fw-bold", style: { minWidth: "24px", textAlign: "center" }, children: field.offsetX || 0 }),
1371
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1372
+ import_reactstrap.Button,
1373
+ {
1374
+ color: "outline-secondary",
1375
+ className: "btn-icon p-0",
1376
+ style: { width: "22px", height: "22px" },
1377
+ onClick: () => updateFieldProperty(index, "offsetX", Math.min(180, (field.offsetX || 0) + 2)),
1378
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Plus, { fontSize: 10 })
1379
+ }
1380
+ )
1381
+ ] })
1382
+ ] })
1383
+ ] })
1384
+ ]
1385
+ },
1386
+ field.id
1387
+ );
1388
+ }),
1389
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-50", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.UncontrolledDropdown, { children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.DropdownToggle, { color: "outline-primary", size: "sm", className: "w-100 d-flex align-items-center justify-content-center", children: [
1391
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.Plus, { fontSize: 13, className: "me-50" }),
1392
+ t("Th\xEAm tr\u01B0\u1EDDng th\xF4ng tin kh\xE1c")
1393
+ ] }),
1394
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_reactstrap.DropdownMenu, { className: "w-100", children: availableExtraFields.map((extra) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_reactstrap.DropdownItem, { onClick: () => handleAddField(extra), children: extra.label }, extra.id)) })
1395
+ ] }) })
1396
+ ] }) })
1397
+ ] }),
1398
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "border-bottom pb-1", children: [
1399
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1400
+ "div",
1401
+ {
1402
+ className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1403
+ onClick: () => setOpenCustomSection(!openCustomSection),
1404
+ children: [
1405
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fw-bolder text-dark", children: t("C\u0103n ch\u1EC9nh l\u1EC1") }),
1406
+ openCustomSection ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon.ChevronRight, { fontSize: 16 })
1407
+ ]
1408
+ }
1409
+ ),
1410
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_reactstrap.Collapse, { isOpen: openCustomSection, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "d-flex flex-column ps-1", style: { gap: "8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [
1411
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "small text-dark", children: [
1412
+ t("C\u0103n l\u1EC1 ch\u1EEF"),
1413
+ ":"
1414
+ ] }),
1415
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1416
+ import_react_hook_form.Controller,
1417
+ {
1418
+ name: "hinge",
1419
+ control,
1420
+ render: ({ field: { value, onChange } }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "d-flex", style: { gap: "15px" }, children: [
1421
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer small", children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1423
+ import_reactstrap.Input,
1424
+ {
1425
+ type: "radio",
1426
+ name: "hinge",
1427
+ className: "me-50 mt-0",
1428
+ checked: !value,
1429
+ onChange: () => onChange(false)
1430
+ }
1431
+ ),
1432
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("C\u0103n tr\xE1i") })
1433
+ ] }),
1434
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_reactstrap.Label, { className: "d-flex align-items-center mb-0 cursor-pointer small", children: [
1435
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1436
+ import_reactstrap.Input,
1437
+ {
1438
+ type: "radio",
1439
+ name: "hinge",
1440
+ className: "me-50 mt-0",
1441
+ checked: !!value,
1442
+ onChange: () => onChange(true)
1443
+ }
1444
+ ),
1445
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("C\u0103n ph\u1EA3i") })
1446
+ ] })
1447
+ ] })
1448
+ }
1449
+ )
1450
+ ] }) }) })
1451
+ ] }),
1452
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-1", children: [
1453
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "fw-bolder text-dark mb-1 d-flex align-items-center justify-content-between", children: [
1454
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("Xem tr\u01B0\u1EDBc m\u1EABu in") }),
1455
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { className: "text-muted fw-normal", style: { fontSize: "11px" }, children: t("(K\xE9o chu\u1ED9t tr\xEAn d\xF2ng \u0111\u1EC3 d\u1ECBch l\u1EC1)") })
1456
+ ] }),
1457
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "d-flex justify-content-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PreviewPrint, { watch, setValue }) })
1458
+ ] })
1459
+ ] }) });
1460
+ };
1461
+
1462
+ // src/components/modal-preview-print.tsx
1463
+ var Icon2 = __toESM(require("becoxy-icons"));
1464
+ var import_react3 = require("react");
1465
+ var import_reactstrap2 = require("reactstrap");
1466
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1467
+ var ModalPreviewPrint = ({
1468
+ isOpen,
1469
+ toggle,
1470
+ settings,
1471
+ items,
1472
+ onPrint,
1473
+ t = (s) => s
1474
+ }) => {
1475
+ const iframeRef = (0, import_react3.useRef)(null);
1476
+ const [zoom, setZoom] = (0, import_react3.useState)(100);
1477
+ const [isSingleSample, setIsSingleSample] = (0, import_react3.useState)(false);
1478
+ const { html, totalStamps, paperLabel, uniqueProducts } = generatePrintDocument(
1479
+ settings,
1480
+ items,
1481
+ isSingleSample,
1482
+ true
1483
+ );
1484
+ const updateIframeZoom = (zoomLevel) => {
1485
+ var _a;
1486
+ try {
1487
+ const doc = (_a = iframeRef.current) == null ? void 0 : _a.contentDocument;
1488
+ if (doc && doc.body) {
1489
+ ;
1490
+ doc.body.style.zoom = `${zoomLevel}%`;
1491
+ }
1492
+ } catch (e) {
1493
+ }
1494
+ };
1495
+ (0, import_react3.useEffect)(() => {
1496
+ updateIframeZoom(zoom);
1497
+ }, [zoom, html]);
1498
+ const handleZoomIn = () => {
1499
+ setZoom((prev) => Math.min(200, prev + 10));
1500
+ };
1501
+ const handleZoomOut = () => {
1502
+ setZoom((prev) => Math.max(40, prev - 10));
1503
+ };
1504
+ const handleZoomReset = () => {
1505
+ setZoom(100);
1506
+ };
1507
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1508
+ import_reactstrap2.Modal,
1509
+ {
1510
+ isOpen,
1511
+ toggle,
1512
+ className: "modal-dialog-centered modal-xl",
1513
+ contentClassName: "p-0 overflow-hidden",
1514
+ style: { maxWidth: "92vw", width: "92vw", margin: "auto" },
1515
+ children: [
1516
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "modal-header d-flex align-items-center justify-content-between px-1_5 py-1 mb-0 border-bottom bg-white", children: [
1517
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "d-flex align-items-center", children: [
1518
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2.Printer, { fontSize: 18, className: "text-primary me-50" }),
1519
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h5", { className: "modal-title m-0 fw-bolder text-dark", children: t("Xem tr\u01B0\u1EDBc b\u1EA3n in m\xE3 v\u1EA1ch") })
1520
+ ] }),
1521
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2.X, { fontSize: 20 }) })
1522
+ ] }),
1523
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1524
+ "div",
1525
+ {
1526
+ className: "d-flex flex-wrap align-items-center justify-content-between px-1_5 py-75 border-bottom",
1527
+ style: { background: "#f8f9fa", gap: "8px" },
1528
+ children: [
1529
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "d-flex flex-wrap align-items-center", style: { gap: "8px" }, children: [
1530
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_reactstrap2.Badge, { color: "light-primary", className: "d-flex align-items-center px-1 py-50", children: [
1531
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "fw-normal me-50", children: [
1532
+ t("Kh\u1ED5 gi\u1EA5y"),
1533
+ ":"
1534
+ ] }),
1535
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "fw-bolder", children: paperLabel })
1536
+ ] }),
1537
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_reactstrap2.Badge, { color: "light-success", className: "d-flex align-items-center px-1 py-50", children: [
1538
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "fw-normal me-50", children: [
1539
+ t("T\u1ED5ng s\u1ED1 tem"),
1540
+ ":"
1541
+ ] }),
1542
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "fw-bolder", children: [
1543
+ totalStamps,
1544
+ " tem"
1545
+ ] })
1546
+ ] }),
1547
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_reactstrap2.Badge, { color: "light-secondary", className: "d-flex align-items-center px-1 py-50", children: [
1548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "fw-normal me-50", children: [
1549
+ t("M\u1EB7t h\xE0ng"),
1550
+ ":"
1551
+ ] }),
1552
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "fw-bolder", children: [
1553
+ uniqueProducts,
1554
+ " s\u1EA3n ph\u1EA9m"
1555
+ ] })
1556
+ ] })
1557
+ ] }),
1558
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "d-flex align-items-center", style: { gap: "10px" }, children: [
1559
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_reactstrap2.ButtonGroup, { size: "sm", children: [
1560
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1561
+ import_reactstrap2.Button,
1562
+ {
1563
+ color: !isSingleSample ? "primary" : "outline-secondary",
1564
+ onClick: () => setIsSingleSample(false),
1565
+ children: [
1566
+ t("T\u1EA5t c\u1EA3 tem"),
1567
+ " (",
1568
+ totalStamps,
1569
+ ")"
1570
+ ]
1571
+ }
1572
+ ),
1573
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1574
+ import_reactstrap2.Button,
1575
+ {
1576
+ color: isSingleSample ? "primary" : "outline-secondary",
1577
+ onClick: () => setIsSingleSample(true),
1578
+ children: t("1 tem ph\xF3ng to")
1579
+ }
1580
+ )
1581
+ ] }),
1582
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "d-flex align-items-center border rounded bg-white px-50", style: { height: "31px" }, children: [
1583
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1584
+ import_reactstrap2.Button,
1585
+ {
1586
+ color: "flat-secondary",
1587
+ className: "btn-icon p-0 me-50",
1588
+ style: { width: "22px", height: "22px" },
1589
+ onClick: handleZoomOut,
1590
+ title: t("Thu nh\u1ECF"),
1591
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2.Minus, { fontSize: 14 })
1592
+ }
1593
+ ),
1594
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1595
+ "span",
1596
+ {
1597
+ className: "fw-bold cursor-pointer text-center text-dark",
1598
+ style: { minWidth: "46px", fontSize: "12px" },
1599
+ onClick: handleZoomReset,
1600
+ title: t("\u0110\u1EB7t l\u1EA1i 100%"),
1601
+ children: [
1602
+ zoom,
1603
+ "%"
1604
+ ]
1605
+ }
1606
+ ),
1607
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1608
+ import_reactstrap2.Button,
1609
+ {
1610
+ color: "flat-secondary",
1611
+ className: "btn-icon p-0 ms-50",
1612
+ style: { width: "22px", height: "22px" },
1613
+ onClick: handleZoomIn,
1614
+ title: t("Ph\xF3ng to"),
1615
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2.Plus, { fontSize: 14 })
1616
+ }
1617
+ )
1618
+ ] })
1619
+ ] })
1620
+ ]
1621
+ }
1622
+ ),
1623
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_reactstrap2.ModalBody, { className: "p-0 position-relative", style: { background: "#e9ecef" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { height: "74vh", minHeight: "540px", width: "100%", overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1624
+ "iframe",
1625
+ {
1626
+ ref: iframeRef,
1627
+ title: "barcode-print-preview",
1628
+ srcDoc: html,
1629
+ onLoad: () => updateIframeZoom(zoom),
1630
+ style: {
1631
+ width: "100%",
1632
+ height: "100%",
1633
+ border: "none",
1634
+ display: "block"
1635
+ }
1636
+ }
1637
+ ) }) }),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_reactstrap2.ModalFooter, { className: "d-flex justify-content-end align-items-center py-1 px-2 border-top bg-white", style: { gap: "10px" }, children: [
1639
+ onPrint && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1640
+ import_reactstrap2.Button,
1641
+ {
1642
+ color: "primary",
1643
+ onClick: onPrint,
1644
+ className: "d-flex align-items-center",
1645
+ children: [
1646
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon2.Printer, { fontSize: 14, className: "me-50" }),
1647
+ t("In")
1648
+ ]
1649
+ }
1650
+ ),
1651
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_reactstrap2.Button, { color: "secondary", outline: true, onClick: toggle, children: t("Close") })
1652
+ ] })
1653
+ ]
1654
+ }
1655
+ );
1656
+ };
1657
+
1658
+ // src/components/modal-barcode-print.tsx
1659
+ var Icon3 = __toESM(require("becoxy-icons"));
1660
+ var import_react4 = require("react");
1661
+ var import_react_hook_form2 = require("react-hook-form");
1662
+ var import_reactstrap3 = require("reactstrap");
1663
+ var import_sweetalert2 = __toESM(require("sweetalert2"));
1664
+ var import_sweetalert2_react_content = __toESM(require("sweetalert2-react-content"));
1665
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1666
+ var MySwal = (0, import_sweetalert2_react_content.default)(import_sweetalert2.default);
1667
+ var DEFAULT_PRINT_FIELDS = [
1668
+ { id: "companyName", key: "companyName", label: "T\xEAn c\xF4ng ty", type: "text", enabled: false, bold: true },
1669
+ { id: "productCode", key: "code", label: "M\xE3 h\xE0ng", type: "text", enabled: true, bold: true },
1670
+ { id: "productName", key: "name", label: "T\xEAn h\xE0ng", type: "text", enabled: true, bold: false },
1671
+ { id: "barcode", key: "code", label: "M\xE3 v\u1EA1ch / M\xE3 QR", type: "barcode", enabled: true },
1672
+ { id: "unitPrice", key: "price", label: "Gi\xE1 b\xE1n", type: "text", enabled: true, bold: true, prefix: "Gi\xE1: ", suffix: "" }
1673
+ ];
1674
+ var ModalBarcodePrint = ({
1675
+ isOpen,
1676
+ toggle,
1677
+ title = "In m\xE3 v\u1EA1ch / m\xE3 QR",
1678
+ dataSelected,
1679
+ setDataSelected,
1680
+ dataItem,
1681
+ defaultFields = DEFAULT_PRINT_FIELDS,
1682
+ availableExtraFields,
1683
+ renderTable,
1684
+ children,
1685
+ windowSize,
1686
+ t = (s) => s,
1687
+ onPrintSuccess,
1688
+ notifyError = (msg) => alert(msg),
1689
+ notifySuccess = (msg) => console.log(msg)
1690
+ }) => {
1691
+ const defaultValues = {
1692
+ printType: 0,
1693
+ paperSize: 2,
1694
+ // 3 tem (105x22mm)
1695
+ stampNumber: 3,
1696
+ productCode: true,
1697
+ productName: true,
1698
+ companyName: false,
1699
+ unitPrice: true,
1700
+ printSample: 3,
1701
+ hinge: false,
1702
+ fields: defaultFields
1703
+ };
1704
+ const [openPreviewModal, setOpenPreviewModal] = (0, import_react4.useState)(false);
1705
+ const { control, watch, setValue, reset, getValues, formState: { errors } } = (0, import_react_hook_form2.useForm)({
1706
+ mode: "onChange",
1707
+ defaultValues
1708
+ });
1709
+ const handleTestPrint = () => {
1710
+ const settings = getValues();
1711
+ const targetItems = dataSelected.length > 0 ? dataSelected : dataItem ? [dataItem] : [];
1712
+ executePrint(settings, targetItems, true);
1713
+ };
1714
+ const handleOpenPreview = () => {
1715
+ const targetItems = dataSelected.length > 0 ? dataSelected : dataItem ? [dataItem] : [];
1716
+ if (targetItems.length === 0) {
1717
+ notifyError(t("Vui l\xF2ng ch\u1ECDn \xEDt nh\u1EA5t m\u1ED9t s\u1EA3n ph\u1EA9m c\u1EA7n xem tr\u01B0\u1EDBc!"));
1718
+ return;
1719
+ }
1720
+ setOpenPreviewModal(true);
1721
+ };
1722
+ const handleRealPrint = () => {
1723
+ if (dataSelected.length === 0 && !dataItem) {
1724
+ notifyError(t("Vui l\xF2ng ch\u1ECDn \xEDt nh\u1EA5t m\u1ED9t s\u1EA3n ph\u1EA9m c\u1EA7n in m\xE3 v\u1EA1ch!"));
1725
+ return;
1726
+ }
1727
+ const settings = getValues();
1728
+ const itemsToPrint = dataSelected.length > 0 ? dataSelected : [dataItem];
1729
+ executePrint(settings, itemsToPrint, false);
1730
+ if (onPrintSuccess) {
1731
+ onPrintSuccess();
1732
+ }
1733
+ };
1734
+ const handleResetDefault = () => {
1735
+ MySwal.fire({
1736
+ title: t("X\xE1c nh\u1EADn"),
1737
+ text: t("B\u1EA1n c\xF3 ch\u1EAFc ch\u1EAFn mu\u1ED1n thi\u1EBFt l\u1EADp l\u1EA1i c\u1EA5u h\xECnh in v\u1EC1 m\u1EB7c \u0111\u1ECBnh kh\xF4ng?"),
1738
+ icon: "question",
1739
+ showCancelButton: true,
1740
+ confirmButtonText: t("X\xE1c nh\u1EADn"),
1741
+ cancelButtonText: t("H\u1EE7y"),
1742
+ customClass: {
1743
+ confirmButton: "btn btn-primary",
1744
+ cancelButton: "btn btn-secondary ms-1"
1745
+ },
1746
+ buttonsStyling: false
1747
+ }).then((result) => {
1748
+ if (result.isConfirmed || result.value) {
1749
+ reset(defaultValues);
1750
+ notifySuccess(t("\u0110\xE3 thi\u1EBFt l\u1EADp l\u1EA1i c\u1EA5u h\xECnh m\u1EB7c \u0111\u1ECBnh!"));
1751
+ }
1752
+ });
1753
+ };
1754
+ const renderFooterButtons = () => {
1755
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "d-flex align-items-center", style: { gap: "10px" }, children: [
1756
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_reactstrap3.Button, { color: "primary", onClick: handleResetDefault, className: "d-flex align-items-center text-white", children: [
1757
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.OutlineReply, { fontSize: 14, className: "me-50" }),
1758
+ t("Thi\u1EBFt l\u1EADp l\u1EA1i")
1759
+ ] }),
1760
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_reactstrap3.Button, { color: "info", outline: true, onClick: handleOpenPreview, className: "d-flex align-items-center", children: [
1761
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.Eye, { fontSize: 14, className: "me-50" }),
1762
+ t("Xem tr\u01B0\u1EDBc")
1763
+ ] }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_reactstrap3.Button, { color: "secondary", outline: true, onClick: handleTestPrint, className: "d-flex align-items-center", children: [
1765
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.Printer, { fontSize: 14, className: "me-50" }),
1766
+ t("In th\u1EED")
1767
+ ] }),
1768
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_reactstrap3.Button, { color: "primary", onClick: handleRealPrint, className: "d-flex align-items-center", children: [
1769
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.Printer, { fontSize: 14, className: "me-50" }),
1770
+ t("In")
1771
+ ] }),
1772
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_reactstrap3.Button, { color: "secondary", onClick: toggle, outline: true, children: t("Close") })
1773
+ ] });
1774
+ };
1775
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react4.Fragment, { children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1777
+ import_reactstrap3.Modal,
1778
+ {
1779
+ isOpen,
1780
+ toggle,
1781
+ className: "modal-dialog-centered modal-fullscreen",
1782
+ contentClassName: "p-0",
1783
+ children: [
1784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "modal-header d-flex align-items-center justify-content-between p-1 mb-0 border-bottom bg-white", children: [
1785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "d-flex align-items-center", children: [
1786
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.Printer, { fontSize: 18, className: "text-primary me-50" }),
1787
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h5", { className: "modal-title m-0 fw-bolder text-dark", children: t(title) })
1788
+ ] }),
1789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon3.X, { fontSize: 20 }) })
1790
+ ] }),
1791
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_reactstrap3.ModalBody, { className: "p-1", style: { background: "#f8f9fa" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_reactstrap3.Row, { className: "g-1 h-100", children: [
1792
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_reactstrap3.Col, { lg: 4, md: 12, xs: 12, className: "h-100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1793
+ "div",
1794
+ {
1795
+ className: "box d-flex flex-column h-100 p-1 border rounded",
1796
+ style: { background: "#fff" },
1797
+ children: [
1798
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h5", { className: "m-0 fw-bolder mb-1 pb-50 border-bottom", children: t("T\xF9y ch\u1EC9nh in") }),
1799
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1800
+ SettingPrint,
1801
+ {
1802
+ control,
1803
+ watch,
1804
+ setValue,
1805
+ errors,
1806
+ availableExtraFields,
1807
+ t
1808
+ }
1809
+ )
1810
+ ]
1811
+ }
1812
+ ) }),
1813
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_reactstrap3.Col, { lg: 8, md: 12, xs: 12, className: "h-100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1814
+ "div",
1815
+ {
1816
+ className: "box d-flex flex-column h-100 p-1 border rounded",
1817
+ style: { background: "#fff" },
1818
+ children: [
1819
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h5", { className: "m-0 fw-bolder mb-1 pb-50 border-bottom", children: t("Danh s\xE1ch c\u1EA7n in m\xE3 v\u1EA1ch") }),
1820
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-50 flex-grow-1", children: renderTable ? renderTable({
1821
+ selectedItems: dataSelected,
1822
+ setSelectedItems: setDataSelected
1823
+ }) : children })
1824
+ ]
1825
+ }
1826
+ ) })
1827
+ ] }) }),
1828
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1829
+ "div",
1830
+ {
1831
+ className: "d-flex justify-content-end p-1 border-top",
1832
+ style: { boxShadow: "0 4px 24px 0 rgb(34 41 47 / 10%)", background: "#fff" },
1833
+ children: renderFooterButtons()
1834
+ }
1835
+ )
1836
+ ]
1837
+ }
1838
+ ),
1839
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1840
+ ModalPreviewPrint,
1841
+ {
1842
+ isOpen: openPreviewModal,
1843
+ toggle: () => setOpenPreviewModal(false),
1844
+ settings: getValues(),
1845
+ items: dataSelected.length > 0 ? dataSelected : dataItem ? [dataItem] : [],
1846
+ onPrint: handleRealPrint,
1847
+ t
1848
+ }
1849
+ )
1850
+ ] });
1851
+ };
1852
+ // Annotate the CommonJS export names for ESM import in node:
1853
+ 0 && (module.exports = {
1854
+ ModalBarcodePrint,
1855
+ ModalPreviewPrint,
1856
+ PreviewPrint,
1857
+ SettingPrint,
1858
+ executePrint,
1859
+ generateBarcodeHtml,
1860
+ generatePrintDocument,
1861
+ getOrganizationName,
1862
+ getPaperSizeLabel,
1863
+ renderSingleLabelHtml
1864
+ });
1865
+ //# sourceMappingURL=index.js.map