nexabase-report 0.2.1 → 0.2.4

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/style.css CHANGED
@@ -2489,6 +2489,67 @@ html, body, #app {
2489
2489
  font-style: italic;
2490
2490
  }
2491
2491
 
2492
+ /* Table footer styles for nexabase-report viewer */
2493
+ .nexa-table {
2494
+ width: 100%;
2495
+ border-collapse: collapse;
2496
+ font-size: 11px;
2497
+ }
2498
+
2499
+ .nexa-table thead tr {
2500
+ background: #f1f5f9;
2501
+ border-bottom: 2px solid var(--nd-border-strong, #e2e8f0);
2502
+ }
2503
+
2504
+ .nexa-table th {
2505
+ padding: 6px 8px;
2506
+ font-weight: 600;
2507
+ color: var(--nd-text, #1e293b);
2508
+ text-align: left;
2509
+ border-right: 1px solid var(--nd-border, #e2e8f0);
2510
+ }
2511
+
2512
+ .nexa-table th:last-child { border-right: none; }
2513
+
2514
+ .nexa-table td {
2515
+ padding: 5px 8px;
2516
+ border-right: 1px solid var(--nd-border, #e2e8f0);
2517
+ border-bottom: 1px solid var(--nd-border, #e2e8f0);
2518
+ color: #475569;
2519
+ }
2520
+
2521
+ .nexa-table td:last-child { border-right: none; }
2522
+
2523
+ .nexa-table tfoot tr {
2524
+ background: #f8fafc;
2525
+ border-top: 2px solid #94a3b8;
2526
+ }
2527
+
2528
+ .nexa-table-footer td {
2529
+ font-weight: 600;
2530
+ color: #1e3a8a;
2531
+ background: #f1f5f9;
2532
+ }
2533
+
2534
+ .nexa-table-group-header td {
2535
+ font-weight: 700;
2536
+ background: #e0e7ff;
2537
+ color: #1e3a8a;
2538
+ font-size: 12px;
2539
+ padding: 4px 8px;
2540
+ }
2541
+
2542
+ .nexa-table-group-footer td {
2543
+ font-weight: 600;
2544
+ background: #f1f5f9;
2545
+ color: #374151;
2546
+ border-top: 1px solid #cbd5e1;
2547
+ }
2548
+
2549
+ .nexa-footer-val {
2550
+ font-family: 'Courier New', monospace;
2551
+ }
2552
+
2492
2553
  .nd-footer {
2493
2554
  height: 30px;
2494
2555
  background: var(--nd-surface);
Binary file
@@ -0,0 +1,528 @@
1
+ {
2
+ "metadata": {
3
+ "version": "1.0",
4
+ "name": "Factura de Recolección de Residuos",
5
+ "description": "Ejemplo de factura ambiental con datos del cliente, detalle de residuos recolectados y tarifas aplicadas. Usa tres DataSources manuales relacionados por nofactura.",
6
+ "author": "NexaBase",
7
+ "createdAt": "2025-05-01T00:00:00.000Z"
8
+ },
9
+ "layout": {
10
+ "page": {
11
+ "format": "A4",
12
+ "orientation": "portrait",
13
+ "margins": {
14
+ "top": 1,
15
+ "right": 0.5,
16
+ "bottom": 1,
17
+ "left": 0.5
18
+ }
19
+ },
20
+ "bands": [
21
+ {
22
+ "id": "rh_factura",
23
+ "type": "ReportHeader",
24
+ "height": 230,
25
+ "elements": [
26
+ {
27
+ "id": "rect_header",
28
+ "type": "Rectangle",
29
+ "x": 0,
30
+ "y": 0,
31
+ "width": 720,
32
+ "height": 120,
33
+ "shapeType": "Rectangle",
34
+ "options": {
35
+ "lineColor": "#1e40af",
36
+ "strokeWidth": 2,
37
+ "fillColor": "#f8fafc"
38
+ }
39
+ },
40
+ {
41
+ "id": "t_titulo",
42
+ "type": "Text",
43
+ "x": 20,
44
+ "y": 15,
45
+ "width": 400,
46
+ "height": 28,
47
+ "content": "FACTURA DE RECOLECCIÓN",
48
+ "style": {
49
+ "fontSize": "18px",
50
+ "fontWeight": "bold",
51
+ "color": "#1e3a8a"
52
+ }
53
+ },
54
+ {
55
+ "id": "t_nofactura",
56
+ "type": "Text",
57
+ "x": 500,
58
+ "y": 15,
59
+ "width": 200,
60
+ "height": 24,
61
+ "content": "N° {{nofactura}}",
62
+ "style": {
63
+ "fontSize": "16px",
64
+ "fontWeight": "bold",
65
+ "color": "#1e40af",
66
+ "textAlign": "right"
67
+ }
68
+ },
69
+ {
70
+ "id": "t_razon",
71
+ "type": "Text",
72
+ "x": 20,
73
+ "y": 50,
74
+ "width": 350,
75
+ "height": 18,
76
+ "content": "{{nombre}}",
77
+ "style": {
78
+ "fontSize": "14px",
79
+ "fontWeight": "bold",
80
+ "color": "#0f172a"
81
+ }
82
+ },
83
+ {
84
+ "id": "t_nit",
85
+ "type": "Text",
86
+ "x": 20,
87
+ "y": 70,
88
+ "width": 250,
89
+ "height": 16,
90
+ "content": "NIT: {{nit}}",
91
+ "style": {
92
+ "fontSize": "11px",
93
+ "color": "#475569"
94
+ }
95
+ },
96
+ {
97
+ "id": "t_direccion",
98
+ "type": "Text",
99
+ "x": 20,
100
+ "y": 88,
101
+ "width": 350,
102
+ "height": 16,
103
+ "content": "{{direccion}}",
104
+ "style": {
105
+ "fontSize": "11px",
106
+ "color": "#64748b"
107
+ }
108
+ },
109
+ {
110
+ "id": "t_ciudad",
111
+ "type": "Text",
112
+ "x": 20,
113
+ "y": 104,
114
+ "width": 250,
115
+ "height": 16,
116
+ "content": "{{ciudad}}",
117
+ "style": {
118
+ "fontSize": "11px",
119
+ "color": "#64748b"
120
+ }
121
+ },
122
+ {
123
+ "id": "line_div",
124
+ "type": "Line",
125
+ "x": 0,
126
+ "y": 125,
127
+ "width": 720,
128
+ "height": 2,
129
+ "shapeType": "Line",
130
+ "options": {
131
+ "lineColor": "#1e40af",
132
+ "strokeWidth": 2
133
+ }
134
+ },
135
+ {
136
+ "id": "t_fecha",
137
+ "type": "Text",
138
+ "x": 500,
139
+ "y": 130,
140
+ "width": 200,
141
+ "height": 16,
142
+ "content": "Fecha: {{fechaRecoleccion}}",
143
+ "style": {
144
+ "fontSize": "11px",
145
+ "color": "#64748b",
146
+ "textAlign": "right"
147
+ }
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ "id": "db_residuos",
153
+ "type": "DataBand",
154
+ "height": 180,
155
+ "dataSource": "residuos",
156
+ "elements": [
157
+ {
158
+ "id": "t_items_title",
159
+ "type": "Text",
160
+ "x": 0,
161
+ "y": 5,
162
+ "width": 300,
163
+ "height": 20,
164
+ "content": "Detalle de Residuos Recolectados",
165
+ "style": {
166
+ "fontSize": "13px",
167
+ "fontWeight": "bold",
168
+ "color": "#1e3a8a"
169
+ }
170
+ },
171
+ {
172
+ "id": "table_residuos",
173
+ "type": "Table",
174
+ "x": 0,
175
+ "y": 30,
176
+ "width": 720,
177
+ "height": 140,
178
+ "tableColumns": [
179
+ {
180
+ "id": "col1",
181
+ "title": "Fecha Recolección",
182
+ "width": 140,
183
+ "binding": "fechaRecoleccion"
184
+ },
185
+ {
186
+ "id": "col2",
187
+ "title": "Nombre del Residuo",
188
+ "width": 280,
189
+ "binding": "nombreResiduo",
190
+ "groupHeaderText": "{[UPPER(groupKey)]}",
191
+ "groupFooterText": "Subtotal {[groupKey]}: {sum(cantidad)} kg"
192
+ },
193
+ {
194
+ "id": "col3",
195
+ "title": "Cantidad (kg)",
196
+ "width": 120,
197
+ "binding": "cantidad",
198
+ "footerText": "Total: {[sum(cantidad)]}"
199
+ },
200
+ {
201
+ "id": "col4",
202
+ "title": "Doc. Relacionado",
203
+ "width": 160,
204
+ "binding": "documentoRelacionado"
205
+ }
206
+ ],
207
+ "tableShowFooter": true,
208
+ "tableShowGroupHeader": true,
209
+ "tableShowGroupFooter": true,
210
+ "tableGroupBy": "nombreResiduo",
211
+ "style": {
212
+ "fontSize": "11px"
213
+ }
214
+ }
215
+ ]
216
+ },
217
+ {
218
+ "id": "db_tarifas",
219
+ "type": "DataBand",
220
+ "height": 160,
221
+ "dataSource": "tarifas",
222
+ "elements": [
223
+ {
224
+ "id": "t_tarifas_title",
225
+ "type": "Text",
226
+ "x": 0,
227
+ "y": 5,
228
+ "width": 300,
229
+ "height": 20,
230
+ "content": "Tarifas Aplicadas",
231
+ "style": {
232
+ "fontSize": "13px",
233
+ "fontWeight": "bold",
234
+ "color": "#1e3a8a"
235
+ }
236
+ },
237
+ {
238
+ "id": "table_tarifas",
239
+ "type": "Table",
240
+ "x": 0,
241
+ "y": 30,
242
+ "width": 720,
243
+ "height": 110,
244
+ "tableColumns": [
245
+ {
246
+ "id": "col1",
247
+ "title": "Residuo",
248
+ "width": 240,
249
+ "binding": "residuo"
250
+ },
251
+ {
252
+ "id": "col2",
253
+ "title": "Tipo Tarifa",
254
+ "width": 140,
255
+ "binding": "tipoTarifa"
256
+ },
257
+ {
258
+ "id": "col3",
259
+ "title": "Precio Unit.",
260
+ "width": 120,
261
+ "binding": "precio"
262
+ },
263
+ {
264
+ "id": "col4",
265
+ "title": "Kilos Mínimos",
266
+ "width": 100,
267
+ "binding": "kilosMinimos"
268
+ },
269
+ {
270
+ "id": "col5",
271
+ "title": "Fact. Mínima",
272
+ "width": 100,
273
+ "binding": "facturacionMinima"
274
+ }
275
+ ],
276
+ "style": {
277
+ "fontSize": "11px"
278
+ }
279
+ }
280
+ ]
281
+ },
282
+ {
283
+ "id": "rf_totales",
284
+ "type": "ReportFooter",
285
+ "height": 100,
286
+ "elements": [
287
+ {
288
+ "id": "line_footer",
289
+ "type": "Line",
290
+ "x": 300,
291
+ "y": 0,
292
+ "width": 400,
293
+ "height": 1,
294
+ "shapeType": "Line",
295
+ "options": {
296
+ "lineColor": "#94a3b8",
297
+ "strokeWidth": 1
298
+ }
299
+ },
300
+ {
301
+ "id": "t_resumen",
302
+ "type": "Text",
303
+ "x": 350,
304
+ "y": 10,
305
+ "width": 150,
306
+ "height": 20,
307
+ "content": "Subtotal:",
308
+ "style": {
309
+ "fontSize": "12px",
310
+ "fontWeight": "bold",
311
+ "color": "#374151",
312
+ "textAlign": "right"
313
+ }
314
+ },
315
+ {
316
+ "id": "t_subtotal_val",
317
+ "type": "Text",
318
+ "x": 510,
319
+ "y": 10,
320
+ "width": 180,
321
+ "height": 20,
322
+ "content": "${[sum(precio) * cantidad]}",
323
+ "style": {
324
+ "fontSize": "12px",
325
+ "color": "#1e40af",
326
+ "textAlign": "right"
327
+ }
328
+ },
329
+ {
330
+ "id": "t_iva_label",
331
+ "type": "Text",
332
+ "x": 350,
333
+ "y": 32,
334
+ "width": 150,
335
+ "height": 18,
336
+ "content": "Total Items:",
337
+ "style": {
338
+ "fontSize": "11px",
339
+ "color": "#64748b",
340
+ "textAlign": "right"
341
+ }
342
+ },
343
+ {
344
+ "id": "t_total_items",
345
+ "type": "Text",
346
+ "x": 510,
347
+ "y": 32,
348
+ "width": 180,
349
+ "height": 18,
350
+ "content": "${[count(nofactura)]}",
351
+ "style": {
352
+ "fontSize": "11px",
353
+ "color": "#475569",
354
+ "textAlign": "right"
355
+ }
356
+ },
357
+ {
358
+ "id": "line_total",
359
+ "type": "Line",
360
+ "x": 350,
361
+ "y": 55,
362
+ "width": 340,
363
+ "height": 2,
364
+ "shapeType": "Line",
365
+ "options": {
366
+ "lineColor": "#1e40af",
367
+ "strokeWidth": 2
368
+ }
369
+ },
370
+ {
371
+ "id": "t_total_label",
372
+ "type": "Text",
373
+ "x": 350,
374
+ "y": 60,
375
+ "width": 150,
376
+ "height": 24,
377
+ "content": "TOTAL A PAGAR:",
378
+ "style": {
379
+ "fontSize": "14px",
380
+ "fontWeight": "bold",
381
+ "color": "#1e3a8a",
382
+ "textAlign": "right"
383
+ }
384
+ },
385
+ {
386
+ "id": "t_total_val",
387
+ "type": "Text",
388
+ "x": 510,
389
+ "y": 60,
390
+ "width": 180,
391
+ "height": 24,
392
+ "content": "${[sum(precio) * cantidad]}",
393
+ "style": {
394
+ "fontSize": "16px",
395
+ "fontWeight": "bold",
396
+ "color": "#1e40af",
397
+ "textAlign": "right"
398
+ }
399
+ }
400
+ ]
401
+ },
402
+ {
403
+ "id": "pf_factura",
404
+ "type": "PageFooter",
405
+ "height": 30,
406
+ "elements": [
407
+ {
408
+ "id": "t_pagina",
409
+ "type": "Text",
410
+ "x": 0,
411
+ "y": 8,
412
+ "width": 720,
413
+ "height": 16,
414
+ "content": "Página {{Page}} de {{TotalPages}} — Generado: {{Now}}",
415
+ "style": {
416
+ "fontSize": "9px",
417
+ "color": "#94a3b8",
418
+ "textAlign": "center"
419
+ }
420
+ }
421
+ ]
422
+ }
423
+ ],
424
+ "watermark": {
425
+ "text": "BORRADOR",
426
+ "opacity": 0.15,
427
+ "rotation": -45,
428
+ "color": "#cccccc",
429
+ "position": "center",
430
+ "pages": "all",
431
+ "behindContent": true
432
+ },
433
+ "generateTOC": false
434
+ },
435
+ "dataSources": [
436
+ {
437
+ "id": "ds_cliente",
438
+ "collection": "",
439
+ "alias": "cliente",
440
+ "enabled": true,
441
+ "isManual": true,
442
+ "manualData": [
443
+ {
444
+ "nofactura": "34",
445
+ "nombre": "CLIENTE EJEMPLO S.A.S.",
446
+ "nit": "900.123.456-7",
447
+ "direccion": "Calle 100 # 15-20",
448
+ "ciudad": "Bogotá D.C.",
449
+ "fechaRecoleccion": "2025-05-01"
450
+ }
451
+ ]
452
+ },
453
+ {
454
+ "id": "ds_residuos",
455
+ "collection": "",
456
+ "alias": "residuos",
457
+ "enabled": true,
458
+ "isManual": true,
459
+ "manualData": [
460
+ {
461
+ "nofactura": "34",
462
+ "fechaRecoleccion": "2025-05-01",
463
+ "nombreResiduo": "ÁCIDO CLORHÍDRICO",
464
+ "cantidad": 5,
465
+ "documentoRelacionado": "25"
466
+ },
467
+ {
468
+ "nofactura": "34",
469
+ "fechaRecoleccion": "2025-05-02",
470
+ "nombreResiduo": "ÁCIDO CLORHÍDRICO",
471
+ "cantidad": 3,
472
+ "documentoRelacionado": "26"
473
+ },
474
+ {
475
+ "nofactura": "34",
476
+ "fechaRecoleccion": "2025-05-01",
477
+ "nombreResiduo": "BIO SANITARIOS",
478
+ "cantidad": 5,
479
+ "documentoRelacionado": "28"
480
+ },
481
+ {
482
+ "nofactura": "34",
483
+ "fechaRecoleccion": "2025-05-03",
484
+ "nombreResiduo": "BIO SANITARIOS",
485
+ "cantidad": 2,
486
+ "documentoRelacionado": "30"
487
+ },
488
+ {
489
+ "nofactura": "34",
490
+ "fechaRecoleccion": "2025-05-01",
491
+ "nombreResiduo": "CLORURO FÉRRICO",
492
+ "cantidad": 8,
493
+ "documentoRelacionado": "31"
494
+ }
495
+ ]
496
+ },
497
+ {
498
+ "id": "ds_tarifas",
499
+ "collection": "",
500
+ "alias": "tarifas",
501
+ "enabled": true,
502
+ "isManual": true,
503
+ "manualData": [
504
+ {
505
+ "nofactura": "34",
506
+ "facturacionMinima": 0,
507
+ "kilosMinimos": 0,
508
+ "precio": 52200,
509
+ "residuo": "ÁCIDO CLORHÍDRICO",
510
+ "tipoTarifa": "Tarifa x Kilo"
511
+ },
512
+ {
513
+ "nofactura": "34",
514
+ "facturacionMinima": 0,
515
+ "kilosMinimos": 0,
516
+ "precio": 52200,
517
+ "residuo": "BIO SANITARIOS",
518
+ "tipoTarifa": "Tarifa x Kilo"
519
+ }
520
+ ]
521
+ }
522
+ ],
523
+ "dictionary": {
524
+ "dataSources": [],
525
+ "manualFields": []
526
+ },
527
+ "documentType": "Report"
528
+ }
@@ -0,0 +1,99 @@
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>NexaReport — Angular</title>
7
+ <link rel="stylesheet" href="../dist/style.css">
8
+ <style>
9
+ body { margin: 0; font-family: system-ui, sans-serif; }
10
+ #app { height: 100vh; display: flex; flex-direction: column; }
11
+ header { padding: 12px 20px; background: #1e293b; color: #fff; display: flex; align-items: center; gap: 12px; }
12
+ header h1 { margin: 0; font-size: 18px; font-weight: 600; }
13
+ header small { opacity: 0.7; }
14
+ nexa-viewer { flex: 1; display: block; }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <div id="app">
19
+ <header>
20
+ <h1>NexaReport</h1>
21
+ <small>Angular · Demo</small>
22
+ </header>
23
+ <nexa-viewer id="viewer" minimal></nexa-viewer>
24
+ </div>
25
+
26
+ <script src="https://unpkg.com/@angular/core@18/bundles/core.umd.js"></script>
27
+ <script src="https://unpkg.com/@angular/common@18/bundles/common.umd.js"></script>
28
+ <script src="https://unpkg.com/@angular/compiler@18/bundles/compiler.umd.js"></script>
29
+ <script src="https://unpkg.com/@angular/platform-browser@18/bundles/platform-browser.umd.js"></script>
30
+ <script src="https://unpkg.com/@angular/platform-browser-dynamic@18/bundles/platform-browser-dynamic.umd.js"></script>
31
+ <script src="https://unpkg.com/zone.js@0.14/dist/zone.js"></script>
32
+ <script src="https://unpkg.com/rxjs@7/dist/bundles/rxjs.umd.js"></script>
33
+ <script src="../dist/nexabase-report.umd.js"></script>
34
+ <script>
35
+ NexaReport.registerNexaReport();
36
+
37
+ const reportDef = {
38
+ metadata: { version: '1', name: 'Clientes', createdAt: new Date().toISOString() },
39
+ layout: {
40
+ page: { format: 'A4', orientation: 'portrait', margins: { top: 1, right: 1, bottom: 1, left: 1 } },
41
+ bands: [
42
+ { id: 'b_hdr', type: 'ReportHeader', height: 60, elements: [
43
+ { id: 'e_titulo', type: 'Text', x: 20, y: 10, width: 500, height: 30,
44
+ content: 'Directorio de Clientes', style: { fontSize: '22px', fontWeight: 'bold' } }
45
+ ]},
46
+ { id: 'b_data', type: 'DataBand', height: 30, dataSource: 'main', elements: [
47
+ { id: 'e_nombre', type: 'Text', x: 20, y: 5, width: 200, height: 20,
48
+ binding: 'nombre', style: { fontSize: '12px' } },
49
+ { id: 'e_email', type: 'Text', x: 240, y: 5, width: 250, height: 20,
50
+ binding: 'email', style: { fontSize: '12px' } },
51
+ { id: 'e_ciudad', type: 'Text', x: 510, y: 5, width: 150, height: 20,
52
+ binding: 'ciudad', style: { fontSize: '12px' } }
53
+ ]},
54
+ { id: 'b_ftr', type: 'PageFooter', height: 30, elements: [
55
+ { id: 'e_page', type: 'Text', x: 20, y: 5, width: 200, height: 20,
56
+ content: 'Página {[Page]} de {[TotalPages]}', style: { fontSize: '10px', color: '#666' } }
57
+ ]}
58
+ ]
59
+ },
60
+ dataSources: [{ id: 'ds1', collection: '', alias: 'main', enabled: true }]
61
+ };
62
+
63
+ const data = [
64
+ { nombre: 'Juan Pérez', email: 'juan@mail.com', ciudad: 'Madrid' },
65
+ { nombre: 'María López', email: 'maria@mail.com', ciudad: 'Barcelona' },
66
+ { nombre: 'Carlos Ruiz', email: 'carlos@mail.com', ciudad: 'Valencia' },
67
+ ];
68
+
69
+ (function() {
70
+ const { Component, NgModule } = ng.core;
71
+ const { BrowserModule } = ng.platformBrowser;
72
+ const { platformBrowserDynamic } = ng.platformBrowserDynamic;
73
+ const { CommonModule } = ng.common;
74
+
75
+ @Component({
76
+ selector: 'app-root',
77
+ template: '<nexa-viewer id="viewer" minimal></nexa-viewer>'
78
+ })
79
+ class AppComponent {
80
+ ngAfterViewInit() {
81
+ const viewer = document.getElementById('viewer');
82
+ viewer.definition = reportDef;
83
+ viewer.data = data;
84
+ }
85
+ }
86
+
87
+ @NgModule({
88
+ imports: [BrowserModule],
89
+ declarations: [AppComponent],
90
+ schemas: [ng.core.CUSTOM_ELEMENTS_SCHEMA],
91
+ bootstrap: [AppComponent]
92
+ })
93
+ class AppModule {}
94
+
95
+ platformBrowserDynamic().bootstrapModule(AppModule);
96
+ })();
97
+ </script>
98
+ </body>
99
+ </html>