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/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
+ };