etiquetas.js 1.0.0-alpha.1
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/README.git.md +486 -0
- package/README.md +38 -0
- package/api/api-labels.json +114 -0
- package/api/api.js +316 -0
- package/api/mock/data-volume-id_680.json +64 -0
- package/api/mock/labels-input.json +96 -0
- package/api/mock/labels-part.json +216 -0
- package/api/mock/labels-scrap.json +76 -0
- package/api/mock/labels-thickened.json +96 -0
- package/api/mock/labels-volume.json +56 -0
- package/api/token.txt +1 -0
- package/package.json +43 -0
- package/services/index.js +28 -0
- package/src/constants.js +247 -0
- package/src/createLabel.js +342 -0
- package/src/etiquetas.js +654 -0
- package/src/formatData.js +96 -0
- package/src/formatDataIntegrated.js +498 -0
- package/src/index.js +86 -0
- package/src/label/services/index.js +1201 -0
- package/src/label/services/sortFunctions.js +158 -0
- package/src/label/services/utils.js +280 -0
- package/src/labelWorker.js +123 -0
- package/src/reducer.js +40 -0
- package/src/store.js +55 -0
- package/src/templates.js +139 -0
- package/src/types.ts +575 -0
- package/src/useLabelData.js +99 -0
- package/src/usePrinterStore.js +115 -0
- package/src/variableManager.js +224 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos TypeScript para o Sistema de Etiquetas
|
|
3
|
+
* Baseado na análise dos arquivos existentes e mock de dados
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// TIPOS BÁSICOS
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
export type LabelType = "parts" | "woodwork" | "inputs" | "scraps" | "volumes";
|
|
11
|
+
|
|
12
|
+
export type PartType = "cabinet" | "door" | "drawer" | "thickened";
|
|
13
|
+
|
|
14
|
+
export type MachiningSide = "A" | "B";
|
|
15
|
+
|
|
16
|
+
export type HoleType = "circle" | "rectangle";
|
|
17
|
+
|
|
18
|
+
export type ElementType = "textbox" | "image" | "barcode";
|
|
19
|
+
|
|
20
|
+
export type SpecialProp = "variable" | "barcode" | "image";
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// INTERFACES DE DADOS
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Dados de uma peça do projeto
|
|
28
|
+
*/
|
|
29
|
+
export interface PartData {
|
|
30
|
+
// Identificação
|
|
31
|
+
i: string; // Índice da peça
|
|
32
|
+
id: string; // ID único
|
|
33
|
+
pid: string; // ID do projeto da peça
|
|
34
|
+
pref: string; // Referência da peça
|
|
35
|
+
mref: string; // Referência do módulo
|
|
36
|
+
key: number; // Chave numérica
|
|
37
|
+
|
|
38
|
+
// Informações básicas
|
|
39
|
+
name: string; // Nome da peça
|
|
40
|
+
note: string; // Observações da peça
|
|
41
|
+
index: string; // Índice formatado
|
|
42
|
+
number?: string; // Número da peça
|
|
43
|
+
ref?: string; // Referência alternativa
|
|
44
|
+
|
|
45
|
+
// Dimensões
|
|
46
|
+
width: string | number; // Largura
|
|
47
|
+
height: string | number; // Altura
|
|
48
|
+
thickness: number; // Espessura
|
|
49
|
+
rotated: boolean; // Se está rotacionada
|
|
50
|
+
|
|
51
|
+
// Tipo e classificação
|
|
52
|
+
type: PartType; // Tipo da peça
|
|
53
|
+
group_id?: string; // ID do grupo
|
|
54
|
+
|
|
55
|
+
// Material
|
|
56
|
+
material_name: string; // Nome do material
|
|
57
|
+
material_id: string; // ID do material
|
|
58
|
+
material_width: string; // Largura do material
|
|
59
|
+
material_height: string; // Altura do material
|
|
60
|
+
sheetMaterial: string; // Material da folha
|
|
61
|
+
sheetIndex: number; // Índice da folha
|
|
62
|
+
labelKey: string; // Chave da etiqueta
|
|
63
|
+
|
|
64
|
+
// Bordas/Fitas
|
|
65
|
+
edge_left: string | null; // Fita esquerda
|
|
66
|
+
edge_left_id: string; // ID da fita esquerda
|
|
67
|
+
edge_right: string | null; // Fita direita
|
|
68
|
+
edge_right_id: string; // ID da fita direita
|
|
69
|
+
edge_top: string | null; // Fita superior
|
|
70
|
+
edge_top_id: string; // ID da fita superior
|
|
71
|
+
edge_bottom: string | null; // Fita inferior
|
|
72
|
+
edge_bottom_id: string; // ID da fita inferior
|
|
73
|
+
|
|
74
|
+
// Códigos de furação
|
|
75
|
+
code_a: string; // Código A
|
|
76
|
+
code_a2: string; // Código A2
|
|
77
|
+
code_b: string | null; // Código B
|
|
78
|
+
code_b2: string | null; // Código B2
|
|
79
|
+
|
|
80
|
+
// Informações do projeto
|
|
81
|
+
project_id: string; // ID do projeto
|
|
82
|
+
project_description: string; // Descrição do projeto
|
|
83
|
+
project_customer_id: string; // ID do cliente
|
|
84
|
+
project_customer_name: string; // Nome do cliente
|
|
85
|
+
project_note: string; // Observações do projeto
|
|
86
|
+
|
|
87
|
+
// Usinagem
|
|
88
|
+
machining_side: MachiningSide; // Lado de usinagem
|
|
89
|
+
holes?: HoleData[] | HoleDiagram; // Dados de furação
|
|
90
|
+
|
|
91
|
+
// Módulo
|
|
92
|
+
mname?: string; // Nome do módulo
|
|
93
|
+
mnote?: string; // Observações do módulo
|
|
94
|
+
mtype?: string; // Tipo do módulo
|
|
95
|
+
moduleLength?: number; // Comprimento do módulo
|
|
96
|
+
moduleIndex?: number; // Índice do módulo
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Dados de furação (formato simplificado)
|
|
101
|
+
*/
|
|
102
|
+
export interface HoleData {
|
|
103
|
+
di: number; // Diâmetro
|
|
104
|
+
px: number; // Posição X
|
|
105
|
+
py: number; // Posição Y
|
|
106
|
+
pz: number; // Profundidade Z
|
|
107
|
+
r1: string; // Referência 1
|
|
108
|
+
r2: string; // Referência 2
|
|
109
|
+
type: HoleType; // Tipo do furo
|
|
110
|
+
rotated: boolean; // Se está rotacionado
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Diagrama de furação (formato complexo)
|
|
115
|
+
*/
|
|
116
|
+
export interface HoleDiagram {
|
|
117
|
+
A?: HoleDetail[] | null; // Furos lado A
|
|
118
|
+
B?: HoleDetail[] | null; // Furos lado B
|
|
119
|
+
C?: HoleDetail[] | null; // Furos lado C
|
|
120
|
+
D?: HoleDetail[] | null; // Furos lado D
|
|
121
|
+
E?: HoleDetail[] | null; // Furos lado E
|
|
122
|
+
F?: HoleDetail[] | null; // Furos lado F
|
|
123
|
+
invert: boolean; // Se está invertido
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Detalhe de furo no diagrama
|
|
128
|
+
*/
|
|
129
|
+
export interface HoleDetail {
|
|
130
|
+
d: number; // Diâmetro
|
|
131
|
+
t: string; // Tipo de ferramenta
|
|
132
|
+
x: number; // Posição X
|
|
133
|
+
y: number; // Posição Y
|
|
134
|
+
z: number; // Profundidade Z
|
|
135
|
+
r1: string; // Referência 1
|
|
136
|
+
r2: string; // Referência 2
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Dados de insumo
|
|
141
|
+
*/
|
|
142
|
+
export interface InputData {
|
|
143
|
+
id: string; // ID do insumo
|
|
144
|
+
name: string; // Nome do insumo
|
|
145
|
+
dimensions?: string; // Dimensões
|
|
146
|
+
qt?: number; // Quantidade
|
|
147
|
+
weight?: number; // Peso
|
|
148
|
+
ref?: string; // Referência
|
|
149
|
+
manufacturer?: string; // Fabricante
|
|
150
|
+
|
|
151
|
+
// Dados do projeto (herdados)
|
|
152
|
+
project_id: string;
|
|
153
|
+
project_description: string;
|
|
154
|
+
project_customer_id: string;
|
|
155
|
+
project_customer_name: string;
|
|
156
|
+
project_note: string;
|
|
157
|
+
|
|
158
|
+
// Dados do módulo (herdados)
|
|
159
|
+
mref: string;
|
|
160
|
+
mname: string;
|
|
161
|
+
mnote: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Dados de retalho
|
|
166
|
+
*/
|
|
167
|
+
export interface ScrapData {
|
|
168
|
+
scrapId: string; // ID do retalho
|
|
169
|
+
id: string; // ID alternativo
|
|
170
|
+
name: string; // Nome
|
|
171
|
+
ref?: string; // Referência
|
|
172
|
+
qt?: number; // Quantidade
|
|
173
|
+
weight?: number; // Peso
|
|
174
|
+
date?: string; // Data de criação
|
|
175
|
+
material?: string; // Material
|
|
176
|
+
|
|
177
|
+
// Dados do projeto (herdados)
|
|
178
|
+
project_id: string;
|
|
179
|
+
project_description: string;
|
|
180
|
+
project_customer_id: string;
|
|
181
|
+
project_customer_name: string;
|
|
182
|
+
project_note: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Dados de volume
|
|
187
|
+
*/
|
|
188
|
+
export interface VolumeData {
|
|
189
|
+
volume_id: string; // ID do volume
|
|
190
|
+
volume_name: string; // Nome do volume
|
|
191
|
+
volume_weight: number; // Peso do volume
|
|
192
|
+
volume_date: string; // Data do volume
|
|
193
|
+
|
|
194
|
+
// Dados do projeto (herdados)
|
|
195
|
+
project_id: string;
|
|
196
|
+
project_description: string;
|
|
197
|
+
project_customer_id: string;
|
|
198
|
+
project_customer_name: string;
|
|
199
|
+
project_note: string;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// INTERFACES DE CONFIGURAÇÃO
|
|
204
|
+
// ============================================================================
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Configuração de etiqueta
|
|
208
|
+
*/
|
|
209
|
+
export interface LabelConfig {
|
|
210
|
+
type: LabelType; // Tipo da etiqueta
|
|
211
|
+
index: number; // Índice selecionado
|
|
212
|
+
specific: boolean; // Se é específica
|
|
213
|
+
dataIndex: string | null; // Índice dos dados
|
|
214
|
+
source: any | null; // Fonte dos dados
|
|
215
|
+
otherData: string | null; // Outros dados
|
|
216
|
+
category: string[]; // Categorias selecionadas
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Estado do reducer
|
|
221
|
+
*/
|
|
222
|
+
export interface ReducerState extends LabelConfig {}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Ações do reducer
|
|
226
|
+
*/
|
|
227
|
+
export type ReducerAction =
|
|
228
|
+
| { type: "CHANGE_INDEX"; payload: { index: number } }
|
|
229
|
+
| { type: "CHANGE_TYPE"; payload: { type: LabelType } }
|
|
230
|
+
| { type: "CHANGE_TO_SPECIFIC"; payload: Partial<LabelConfig> }
|
|
231
|
+
| { type: "RESET" };
|
|
232
|
+
|
|
233
|
+
// ============================================================================
|
|
234
|
+
// INTERFACES DE ELEMENTOS VISUAIS
|
|
235
|
+
// ============================================================================
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Elemento base da etiqueta
|
|
239
|
+
*/
|
|
240
|
+
export interface BaseLabelElement {
|
|
241
|
+
type: ElementType; // Tipo do elemento
|
|
242
|
+
version: string; // Versão
|
|
243
|
+
originX: "left" | "center" | "right";
|
|
244
|
+
originY: "top" | "center" | "bottom";
|
|
245
|
+
left: number; // Posição X
|
|
246
|
+
top: number; // Posição Y
|
|
247
|
+
width: number; // Largura
|
|
248
|
+
height: number; // Altura
|
|
249
|
+
scaleX: number; // Escala X
|
|
250
|
+
scaleY: number; // Escala Y
|
|
251
|
+
angle: number; // Rotação
|
|
252
|
+
opacity: number; // Opacidade
|
|
253
|
+
visible: boolean; // Visibilidade
|
|
254
|
+
id: string; // ID único
|
|
255
|
+
name: string; // Nome do elemento
|
|
256
|
+
|
|
257
|
+
// Configurações de página
|
|
258
|
+
labelType: LabelType; // Tipo da etiqueta
|
|
259
|
+
pageWidth: number; // Largura da página
|
|
260
|
+
pageHeight: number; // Altura da página
|
|
261
|
+
pageMarginTop: number; // Margem superior
|
|
262
|
+
pageMarginLeft: number; // Margem esquerda
|
|
263
|
+
pageMarginRight: number; // Margem direita
|
|
264
|
+
pageColumns: number; // Colunas por página
|
|
265
|
+
pageLines: number; // Linhas por página
|
|
266
|
+
pageVerticalSpace: number; // Espaço vertical
|
|
267
|
+
pageHorizontalSpace: number; // Espaço horizontal
|
|
268
|
+
pageShowBorder: number; // Mostrar borda
|
|
269
|
+
|
|
270
|
+
// Propriedades especiais
|
|
271
|
+
specialProp?: SpecialProp; // Propriedade especial
|
|
272
|
+
showEdges?: boolean; // Mostrar bordas
|
|
273
|
+
keepProportion?: boolean; // Manter proporção
|
|
274
|
+
editable?: boolean; // Editável
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Elemento de texto
|
|
279
|
+
*/
|
|
280
|
+
export interface TextLabelElement extends BaseLabelElement {
|
|
281
|
+
type: "textbox";
|
|
282
|
+
text: string; // Texto
|
|
283
|
+
fontSize: string | number; // Tamanho da fonte
|
|
284
|
+
fontWeight: string; // Peso da fonte
|
|
285
|
+
fontFamily: string; // Família da fonte
|
|
286
|
+
fontStyle: string; // Estilo da fonte
|
|
287
|
+
textAlign: "left" | "center" | "right"; // Alinhamento
|
|
288
|
+
fill: string; // Cor do texto
|
|
289
|
+
stroke: string; // Cor da borda
|
|
290
|
+
strokeWidth: number; // Largura da borda
|
|
291
|
+
lineHeight: number; // Altura da linha
|
|
292
|
+
charSpacing: number; // Espaçamento de caracteres
|
|
293
|
+
underline: boolean; // Sublinhado
|
|
294
|
+
overline: boolean; // Sobrelinhado
|
|
295
|
+
linethrough: boolean; // Riscado
|
|
296
|
+
textBackgroundColor: string; // Cor de fundo do texto
|
|
297
|
+
minWidth: number; // Largura mínima
|
|
298
|
+
splitByGrapheme: boolean; // Dividir por grafema
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Elemento de imagem
|
|
303
|
+
*/
|
|
304
|
+
export interface ImageLabelElement extends BaseLabelElement {
|
|
305
|
+
type: "image";
|
|
306
|
+
src: string; // URL da imagem
|
|
307
|
+
crossOrigin: string; // CORS
|
|
308
|
+
cropX: number; // Recorte X
|
|
309
|
+
cropY: number; // Recorte Y
|
|
310
|
+
file: File | null; // Arquivo
|
|
311
|
+
backgroundColor: string; // Cor de fundo
|
|
312
|
+
workareaWidth?: number; // Largura da área de trabalho
|
|
313
|
+
workareaHeight?: number; // Altura da área de trabalho
|
|
314
|
+
layout?: string; // Layout
|
|
315
|
+
filters?: any[]; // Filtros
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Elemento de código de barras
|
|
320
|
+
*/
|
|
321
|
+
export interface BarcodeLabelElement extends BaseLabelElement {
|
|
322
|
+
type: "barcode";
|
|
323
|
+
originBarcode: string; // Código original
|
|
324
|
+
barcodeType?: string; // Tipo do código de barras
|
|
325
|
+
showText?: boolean; // Mostrar texto
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* União de todos os tipos de elementos
|
|
330
|
+
*/
|
|
331
|
+
export type LabelElement = TextLabelElement | ImageLabelElement | BarcodeLabelElement;
|
|
332
|
+
|
|
333
|
+
// ============================================================================
|
|
334
|
+
// INTERFACES DE STORE E HOOKS
|
|
335
|
+
// ============================================================================
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Estado do store principal
|
|
339
|
+
*/
|
|
340
|
+
export interface LabelStore {
|
|
341
|
+
// PDF e dados básicos
|
|
342
|
+
pdfInstance: any | null; // Instância do PDF
|
|
343
|
+
cacheKey: string | null; // Chave do cache
|
|
344
|
+
labelType: LabelType | null; // Tipo da etiqueta
|
|
345
|
+
isGenerating: boolean; // Se está gerando
|
|
346
|
+
progress: number; // Progresso (0-100)
|
|
347
|
+
error: string | null; // Erro atual
|
|
348
|
+
fileName?: string; // Nome do arquivo
|
|
349
|
+
|
|
350
|
+
// Dados atuais
|
|
351
|
+
currentData: any | null; // Dados atuais
|
|
352
|
+
currentConfig: LabelConfig | null; // Configuração atual
|
|
353
|
+
|
|
354
|
+
// Métodos
|
|
355
|
+
setPDFInstance: (pdfInstance: any, cacheKey: string, labelType: LabelType) => void;
|
|
356
|
+
setGenerating: (isGenerating: boolean) => void;
|
|
357
|
+
setProgress: (progress: number) => void;
|
|
358
|
+
setError: (error: string | null) => void;
|
|
359
|
+
setCurrentData: (data: any) => void;
|
|
360
|
+
setCurrentConfig: (config: LabelConfig) => void;
|
|
361
|
+
resetPDFInstance: () => void;
|
|
362
|
+
reset: () => void;
|
|
363
|
+
getFileName?: () => string;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Status da impressora
|
|
368
|
+
*/
|
|
369
|
+
export interface PrinterStatus {
|
|
370
|
+
name: string;
|
|
371
|
+
connected: boolean;
|
|
372
|
+
status: 'connected' | 'disconnected' | 'no-printer' | 'connecting';
|
|
373
|
+
hasDefaultPrinter: boolean;
|
|
374
|
+
message: string;
|
|
375
|
+
printer: PrinterInfo | null;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Informações da impressora
|
|
380
|
+
*/
|
|
381
|
+
export interface PrinterInfo {
|
|
382
|
+
name: string;
|
|
383
|
+
[key: string]: any; // Outras propriedades específicas da impressora
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Store para gerenciamento de impressoras
|
|
388
|
+
*/
|
|
389
|
+
export interface PrinterStore {
|
|
390
|
+
// Estado da impressora
|
|
391
|
+
printerStatus: PrinterStatus;
|
|
392
|
+
setPrinterStatus: (status: PrinterStatus) => void;
|
|
393
|
+
updatePrinterStatus: (updates: Partial<PrinterStatus>) => void;
|
|
394
|
+
|
|
395
|
+
// Conexão SSE (opcional para compatibilidade com Node.js)
|
|
396
|
+
sseConnected: boolean;
|
|
397
|
+
eventSource: any | null; // Mudado de EventSource para any para compatibilidade
|
|
398
|
+
setSseConnected: (connected: boolean) => void;
|
|
399
|
+
setEventSource: (eventSource: any | null) => void;
|
|
400
|
+
connectToSSE: () => void;
|
|
401
|
+
disconnectSSE: () => void;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Dados retornados pelo hook useLabelData
|
|
406
|
+
*/
|
|
407
|
+
export interface LabelDataHookResult {
|
|
408
|
+
// Estado
|
|
409
|
+
isReady: boolean; // Se está pronto para uso
|
|
410
|
+
isGenerating: boolean; // Se está gerando
|
|
411
|
+
progress: number; // Progresso atual
|
|
412
|
+
error: string | null; // Erro atual
|
|
413
|
+
|
|
414
|
+
// Dados
|
|
415
|
+
data: PartData[] | InputData[] | ScrapData[] | VolumeData[]; // Dados formatados
|
|
416
|
+
label: LabelElement[]; // Elementos da etiqueta
|
|
417
|
+
userPrefs: Record<string, any>; // Preferências do usuário
|
|
418
|
+
cacheKey: string; // Chave do cache
|
|
419
|
+
|
|
420
|
+
// Métodos
|
|
421
|
+
generateLabels: () => Promise<void>; // Gerar etiquetas
|
|
422
|
+
downloadPDF: (blob: Blob) => void; // Baixar PDF
|
|
423
|
+
checkPrinterAvailability: () => Promise<boolean>; // Verificar impressora
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Parâmetros para geração de etiquetas
|
|
428
|
+
*/
|
|
429
|
+
export interface GenerateLabelsParams {
|
|
430
|
+
dataSource: any[]; // Dados fonte
|
|
431
|
+
labels: LabelElement[]; // Elementos da etiqueta
|
|
432
|
+
userPrefs: Record<string, any>; // Preferências do usuário
|
|
433
|
+
sheets?: any[]; // Folhas
|
|
434
|
+
group?: string; // Grupo
|
|
435
|
+
labelId?: string; // ID da etiqueta
|
|
436
|
+
cacheKey: string; // Chave do cache
|
|
437
|
+
sheetsByPartCode?: Record<string, any>; // Folhas por código
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Callback de progresso
|
|
442
|
+
*/
|
|
443
|
+
export interface ProgressCallback {
|
|
444
|
+
(data: {
|
|
445
|
+
percentage: number; // Porcentagem (0-100)
|
|
446
|
+
cacheKey: string; // Chave do cache
|
|
447
|
+
pdfInstance: any; // Instância do PDF
|
|
448
|
+
}): void;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// ============================================================================
|
|
452
|
+
// INTERFACES DE WORKER
|
|
453
|
+
// ============================================================================
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Classe worker para geração de etiquetas
|
|
457
|
+
*/
|
|
458
|
+
export interface LabelWorker {
|
|
459
|
+
isGenerating: boolean; // Se está gerando
|
|
460
|
+
currentGenerator: any | null; // Gerador atual
|
|
461
|
+
progressCallback: ProgressCallback | null; // Callback de progresso
|
|
462
|
+
|
|
463
|
+
generateLabels(params: GenerateLabelsParams, progressCallback?: ProgressCallback): Promise<any>;
|
|
464
|
+
generateLabelsPromise(params: GenerateLabelsParams, progressCallback?: ProgressCallback): Promise<any>;
|
|
465
|
+
cancel(): void;
|
|
466
|
+
isInProgress(): boolean;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// ============================================================================
|
|
470
|
+
// CONSTANTES
|
|
471
|
+
// ============================================================================
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Nomes dos tipos de etiqueta
|
|
475
|
+
*/
|
|
476
|
+
export const LABEL_TYPE_NAMES: Record<LabelType, string> = {
|
|
477
|
+
parts: "Peças",
|
|
478
|
+
woodwork: "Tamponamentos",
|
|
479
|
+
inputs: "Insumos",
|
|
480
|
+
scraps: "Retalhos",
|
|
481
|
+
volumes: "Volumes"
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Tipos de peça
|
|
486
|
+
*/
|
|
487
|
+
export const PART_TYPES: Record<PartType, string> = {
|
|
488
|
+
cabinet: "Caixa",
|
|
489
|
+
door: "Porta",
|
|
490
|
+
drawer: "Gaveta",
|
|
491
|
+
thickened: "Tamponamento"
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Variáveis de template disponíveis
|
|
496
|
+
*/
|
|
497
|
+
export const TEMPLATE_VARIABLES = [
|
|
498
|
+
// Projeto
|
|
499
|
+
"{{PROJETO_ID}}",
|
|
500
|
+
"{{PROJETO_NOME}}",
|
|
501
|
+
"{{PROJETO_OBS}}",
|
|
502
|
+
"{{CLIENTE_ID}}",
|
|
503
|
+
"{{CLIENTE_NOME}}",
|
|
504
|
+
|
|
505
|
+
// Peça
|
|
506
|
+
"{{PECA_ID}}",
|
|
507
|
+
"{{PECA_CODIGO}}",
|
|
508
|
+
"{{PECA_REF}}",
|
|
509
|
+
"{{PECA_INDICE}}",
|
|
510
|
+
"{{PECA_INDICE2}}",
|
|
511
|
+
"{{PECA_NOME}}",
|
|
512
|
+
"{{PECA_OBS}}",
|
|
513
|
+
"{{PECA_TIPO}}",
|
|
514
|
+
|
|
515
|
+
// Dimensões
|
|
516
|
+
"{{LARGURA}}",
|
|
517
|
+
"{{ALTURA}}",
|
|
518
|
+
"{{ESPESSURA}}",
|
|
519
|
+
|
|
520
|
+
// Material
|
|
521
|
+
"{{MN}}",
|
|
522
|
+
"{{MA}}",
|
|
523
|
+
"{{ML}}",
|
|
524
|
+
"{{MATERIAL_NOME}}",
|
|
525
|
+
|
|
526
|
+
// Bordas
|
|
527
|
+
"{{FE}}",
|
|
528
|
+
"{{FD}}",
|
|
529
|
+
"{{FS}}",
|
|
530
|
+
"{{FI}}",
|
|
531
|
+
|
|
532
|
+
// Furação
|
|
533
|
+
"{{FURO_A}}",
|
|
534
|
+
"{{FURO_A2}}",
|
|
535
|
+
"{{FURO_B}}",
|
|
536
|
+
"{{FURO_B2}}",
|
|
537
|
+
"{{LADO_USINAGEM}}",
|
|
538
|
+
|
|
539
|
+
// Módulo
|
|
540
|
+
"{{MODULO_REF}}",
|
|
541
|
+
"{{MODULO_NOME}}",
|
|
542
|
+
"{{MODULO_OBS}}",
|
|
543
|
+
|
|
544
|
+
// Insumos
|
|
545
|
+
"{{INSUMO_NOME}}",
|
|
546
|
+
"{{INSUMO_ID}}",
|
|
547
|
+
"{{INSUMO_DIMENSOES}}",
|
|
548
|
+
"{{INSUMO_QTD}}",
|
|
549
|
+
"{{INSUMO_PESO}}",
|
|
550
|
+
"{{INSUMO_REF}}",
|
|
551
|
+
"{{INSUMO_MARCA}}",
|
|
552
|
+
|
|
553
|
+
// Tamponamentos
|
|
554
|
+
"{{TAMPONAMENTO_ID}}",
|
|
555
|
+
"{{TAMPONAMENTO_REF}}",
|
|
556
|
+
"{{TAMPONAMENTO_QT}}",
|
|
557
|
+
"{{TAMPONAMENTO_PESO}}",
|
|
558
|
+
"{{TAMPONAMENTO_NOME}}",
|
|
559
|
+
|
|
560
|
+
// Retalhos
|
|
561
|
+
"{{RETALHO_ID}}",
|
|
562
|
+
"{{RETALHO_INDICE}}",
|
|
563
|
+
|
|
564
|
+
// Volume
|
|
565
|
+
"{{VOLUME_ID}}",
|
|
566
|
+
"{{VOLUME_NOME}}",
|
|
567
|
+
"{{VOLUME_PESO}}",
|
|
568
|
+
"{{VOLUME_DATA}}",
|
|
569
|
+
|
|
570
|
+
// Outros
|
|
571
|
+
"{{LOTE_ID}}",
|
|
572
|
+
"{{DATA_CRIACAO}}"
|
|
573
|
+
] as const;
|
|
574
|
+
|
|
575
|
+
export type TemplateVariable = typeof TEMPLATE_VARIABLES[number];
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Imports básicos para o pacote npm
|
|
2
|
+
import { getPartsForLabels, getPartsFromProjectToLabels } from './formatData.js';
|
|
3
|
+
import { createLabelWorker } from './labelWorker.js';
|
|
4
|
+
import { labelTypeNames } from './constants.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook simplificado para uso em pacote npm
|
|
8
|
+
* Retorna funções utilitárias para trabalhar com dados de etiquetas
|
|
9
|
+
*/
|
|
10
|
+
export const useLabelData = (config = {}) => {
|
|
11
|
+
// Configuração padrão
|
|
12
|
+
const defaultConfig = {
|
|
13
|
+
type: 'parts',
|
|
14
|
+
category: [],
|
|
15
|
+
specific: false,
|
|
16
|
+
dataIndex: null,
|
|
17
|
+
otherData: null,
|
|
18
|
+
source: null
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const finalConfig = { ...defaultConfig, ...config };
|
|
22
|
+
|
|
23
|
+
// Função para gerar etiquetas com dados fornecidos
|
|
24
|
+
const generateLabels = async (data, labels, userPrefs = {}, additionalParams = {}) => {
|
|
25
|
+
const worker = createLabelWorker();
|
|
26
|
+
|
|
27
|
+
const params = {
|
|
28
|
+
dataSource: data || [],
|
|
29
|
+
labels: labels || [],
|
|
30
|
+
userPrefs: userPrefs,
|
|
31
|
+
cacheKey: `label-${Date.now()}`,
|
|
32
|
+
...additionalParams
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return await worker.generateLabels(params);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Função para download de PDF (compatível com Node.js)
|
|
39
|
+
const downloadPDF = (pdfBlob, filename = 'etiqueta.pdf') => {
|
|
40
|
+
// Em ambiente Node.js, retorna os dados do blob para processamento externo
|
|
41
|
+
if (typeof window === 'undefined') {
|
|
42
|
+
return pdfBlob;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Em ambiente browser, mantém funcionalidade original
|
|
46
|
+
const url = URL.createObjectURL(pdfBlob);
|
|
47
|
+
const link = document.createElement('a');
|
|
48
|
+
link.href = url;
|
|
49
|
+
link.download = filename;
|
|
50
|
+
document.body.appendChild(link);
|
|
51
|
+
link.click();
|
|
52
|
+
document.body.removeChild(link);
|
|
53
|
+
URL.revokeObjectURL(url);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Função para verificar disponibilidade da impressora
|
|
57
|
+
const checkPrinterAvailability = async () => {
|
|
58
|
+
try {
|
|
59
|
+
// Implementação básica - pode ser expandida
|
|
60
|
+
return false;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn('Não foi possível verificar impressoras:', error);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Função para obter dados formatados de peças
|
|
68
|
+
const getLabelData = (type = 'parts') => {
|
|
69
|
+
return {
|
|
70
|
+
data: [],
|
|
71
|
+
label: [],
|
|
72
|
+
userPrefs: {},
|
|
73
|
+
cacheKey: `${type}-${Date.now()}`
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
// Estado
|
|
79
|
+
isReady: true,
|
|
80
|
+
isGenerating: false,
|
|
81
|
+
progress: 0,
|
|
82
|
+
error: null,
|
|
83
|
+
|
|
84
|
+
// Dados
|
|
85
|
+
data: [],
|
|
86
|
+
label: [],
|
|
87
|
+
userPrefs: {},
|
|
88
|
+
cacheKey: `label-${Date.now()}`,
|
|
89
|
+
|
|
90
|
+
// Métodos
|
|
91
|
+
generateLabels,
|
|
92
|
+
downloadPDF,
|
|
93
|
+
checkPrinterAvailability,
|
|
94
|
+
getLabelData,
|
|
95
|
+
|
|
96
|
+
// Configuração
|
|
97
|
+
config: finalConfig
|
|
98
|
+
};
|
|
99
|
+
};
|