nexabase-report 0.2.10 → 0.2.12
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/{html2canvas-CX3Va04O.js → html2canvas-CfXDaoV_.js} +2 -2
- package/dist/{html2canvas-BR5Zfk2I.js → html2canvas-LflXVpnS.js} +1 -1
- package/dist/{html2pdf-DWBRzG46.js → html2pdf-Bi79Idsl.js} +3 -3
- package/dist/{index-BPSYeQz4.js → index-Bg8Qh7hD.js} +15258 -15235
- package/dist/{index.es-tialsC4T.js → index.es-48wJ6bnG.js} +2 -2
- package/dist/{jspdf.es.min-Dcx0wUQ4.js → jspdf.es.min-COz5Nq2T.js} +2 -2
- package/dist/nexabase-report.es.js +1 -1
- package/dist/nexabase-report.umd.js +128 -128
- package/examples/BlazorServer/Pages/FacturaReport.razor +52 -52
- package/examples/blazor-report/Components/App.razor +19 -19
- package/examples/blazor-report/Components/Layout/MainLayout.razor +7 -7
- package/examples/blazor-report/Components/Layout/NavMenu.razor +1 -1
- package/examples/blazor-report/Components/Layout/ReconnectModal.razor +1 -1
- package/examples/blazor-report/Components/Pages/Counter.razor +1 -1
- package/examples/blazor-report/Components/Pages/Error.razor +1 -1
- package/examples/blazor-report/Components/Pages/Factura.razor +36 -37
- package/examples/blazor-report/Components/Pages/Home.razor +16 -16
- package/examples/blazor-report/Components/Pages/NotFound.razor +2 -2
- package/examples/blazor-report/Components/Pages/Weather.razor +1 -1
- package/examples/blazor-report/Components/Routes.razor +1 -1
- package/examples/blazor-report/Components/_Imports.razor +1 -1
- package/examples/blazor-report/bin/Debug/net10.0/blazor-report.dll +0 -0
- package/examples/blazor-report/bin/Debug/net10.0/blazor-report.exe +0 -0
- package/examples/blazor-report/bin/Debug/net10.0/blazor-report.pdb +0 -0
- package/examples/blazor-report/bin/Debug/net10.0/blazor-report.staticwebassets.endpoints.json +1 -1
- package/examples/blazor-report/bin/Debug/net10.0/blazor-report.staticwebassets.runtime.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/apphost.exe +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.AssemblyInfo.cs +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.AssemblyInfoInputs.cache +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.csproj.FileListAbsolute.txt +0 -2
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.dll +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.pdb +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/blazor-report.sourcelink.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/rbcswa.dswa.cache.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/ref/blazor-report.dll +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/refint/blazor-report.dll +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/rjimswa.dswa.cache.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/rjsmcshtml.dswa.cache.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/rjsmrazor.dswa.cache.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/rpswa.dswa.cache.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/staticwebassets.build.endpoints.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/staticwebassets.build.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/staticwebassets.build.json.cache +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/staticwebassets.development.json +1 -1
- package/examples/integration/BlazorRazor.razor +84 -84
- package/examples/integration/BlazorServer.razor +91 -91
- package/examples/integration/index.html +100 -100
- package/examples/integration/integration-jquery.html +142 -142
- package/examples/integration-angular.html +99 -99
- package/examples/integration-api.html +80 -80
- package/examples/integration-react.html +80 -80
- package/examples/integration-vanilla.html +66 -66
- package/examples/integration-vue.html +85 -85
- package/examples/viewer.html +58 -58
- package/package.json +1 -1
- package/examples/blazor-report/obj/Debug/net10.0/compressed/4oukg00khs-{0}-p3yawhb8cp-p3yawhb8cp.gz +0 -0
- package/examples/blazor-report/obj/Debug/net10.0/compressed/6vz3ynifev-{0}-z72ixxujkx-z72ixxujkx.gz +0 -0
- package/examples/blazor-report/wwwroot/nexabase-report.umd.js +0 -517
- package/examples/blazor-report/wwwroot/style.css +0 -7
|
@@ -1,99 +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>
|
|
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>
|
|
@@ -1,80 +1,80 @@
|
|
|
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 — Carga desde API</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
|
-
.controls { padding: 8px 20px; background: #f8fafc; border-bottom: 1px solid #e2e8f0; display: flex; gap: 8px; align-items: center; }
|
|
15
|
-
.controls button { padding: 6px 14px; background: #3b82f6; color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 13px; }
|
|
16
|
-
.controls button:hover { background: #2563eb; }
|
|
17
|
-
.controls input { flex: 1; padding: 6px 10px; border: 1px solid #cbd5e1; border-radius: 4px; font-size: 13px; }
|
|
18
|
-
#status { font-size: 12px; color: #64748b; }
|
|
19
|
-
nexa-viewer { flex: 1; display: block; }
|
|
20
|
-
</style>
|
|
21
|
-
</head>
|
|
22
|
-
<body>
|
|
23
|
-
<div id="app">
|
|
24
|
-
<header>
|
|
25
|
-
<h1>NexaReport</h1>
|
|
26
|
-
<small>Carga desde API · Demo</small>
|
|
27
|
-
</header>
|
|
28
|
-
<div class="controls">
|
|
29
|
-
<span style="font-size:13px;font-weight:600">Reporte:</span>
|
|
30
|
-
<input id="reportUrl" type="text" value="/examples/report-productos.json" placeholder="URL del JSON de definición" />
|
|
31
|
-
<button id="btnLoad">Cargar</button>
|
|
32
|
-
<span id="status">Listo</span>
|
|
33
|
-
</div>
|
|
34
|
-
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
<script src="../dist/nexabase-report.umd.js"></script>
|
|
38
|
-
<script>
|
|
39
|
-
window.NexaReport.registerNexaReport();
|
|
40
|
-
|
|
41
|
-
const viewer = document.getElementById('viewer');
|
|
42
|
-
const statusEl = document.getElementById('status');
|
|
43
|
-
const reportUrl = document.getElementById('reportUrl');
|
|
44
|
-
|
|
45
|
-
async function loadReport(url) {
|
|
46
|
-
statusEl.textContent = 'Cargando definición...';
|
|
47
|
-
try {
|
|
48
|
-
const res = await fetch(url);
|
|
49
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
50
|
-
const definition = await res.json();
|
|
51
|
-
viewer.definition = definition;
|
|
52
|
-
|
|
53
|
-
// Si el reporte tiene dataSources, cargar datos de ejemplo
|
|
54
|
-
if (definition.dataSources && definition.dataSources.length > 0) {
|
|
55
|
-
const alias = definition.dataSources[0].alias || 'main';
|
|
56
|
-
statusEl.textContent = `Cargando datos para "${alias}"...`;
|
|
57
|
-
// En producción, aquí llamarías a tu API real
|
|
58
|
-
viewer.data = [
|
|
59
|
-
{ nombre: 'Producto A', precio: 100, cantidad: 5 },
|
|
60
|
-
{ nombre: 'Producto B', precio: 200, cantidad: 3 },
|
|
61
|
-
{ nombre: 'Producto C', precio: 150, cantidad: 8 },
|
|
62
|
-
];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
statusEl.textContent = `Reporte: ${definition.metadata?.name || 'sin nombre'} (${new Date().toLocaleTimeString()})`;
|
|
66
|
-
} catch (err) {
|
|
67
|
-
statusEl.textContent = `Error: ${err.message}`;
|
|
68
|
-
console.error(err);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
document.getElementById('btnLoad').addEventListener('click', () => {
|
|
73
|
-
loadReport(reportUrl.value);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// Cargar reporte por defecto al iniciar
|
|
77
|
-
loadReport(reportUrl.value);
|
|
78
|
-
</script>
|
|
79
|
-
</body>
|
|
80
|
-
</html>
|
|
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 — Carga desde API</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
|
+
.controls { padding: 8px 20px; background: #f8fafc; border-bottom: 1px solid #e2e8f0; display: flex; gap: 8px; align-items: center; }
|
|
15
|
+
.controls button { padding: 6px 14px; background: #3b82f6; color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 13px; }
|
|
16
|
+
.controls button:hover { background: #2563eb; }
|
|
17
|
+
.controls input { flex: 1; padding: 6px 10px; border: 1px solid #cbd5e1; border-radius: 4px; font-size: 13px; }
|
|
18
|
+
#status { font-size: 12px; color: #64748b; }
|
|
19
|
+
nexa-viewer { flex: 1; display: block; }
|
|
20
|
+
</style>
|
|
21
|
+
</head>
|
|
22
|
+
<body>
|
|
23
|
+
<div id="app">
|
|
24
|
+
<header>
|
|
25
|
+
<h1>NexaReport</h1>
|
|
26
|
+
<small>Carga desde API · Demo</small>
|
|
27
|
+
</header>
|
|
28
|
+
<div class="controls">
|
|
29
|
+
<span style="font-size:13px;font-weight:600">Reporte:</span>
|
|
30
|
+
<input id="reportUrl" type="text" value="/examples/report-productos.json" placeholder="URL del JSON de definición" />
|
|
31
|
+
<button id="btnLoad">Cargar</button>
|
|
32
|
+
<span id="status">Listo</span>
|
|
33
|
+
</div>
|
|
34
|
+
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<script src="../dist/nexabase-report.umd.js"></script>
|
|
38
|
+
<script>
|
|
39
|
+
window.NexaReport.registerNexaReport();
|
|
40
|
+
|
|
41
|
+
const viewer = document.getElementById('viewer');
|
|
42
|
+
const statusEl = document.getElementById('status');
|
|
43
|
+
const reportUrl = document.getElementById('reportUrl');
|
|
44
|
+
|
|
45
|
+
async function loadReport(url) {
|
|
46
|
+
statusEl.textContent = 'Cargando definición...';
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch(url);
|
|
49
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
50
|
+
const definition = await res.json();
|
|
51
|
+
viewer.definition = definition;
|
|
52
|
+
|
|
53
|
+
// Si el reporte tiene dataSources, cargar datos de ejemplo
|
|
54
|
+
if (definition.dataSources && definition.dataSources.length > 0) {
|
|
55
|
+
const alias = definition.dataSources[0].alias || 'main';
|
|
56
|
+
statusEl.textContent = `Cargando datos para "${alias}"...`;
|
|
57
|
+
// En producción, aquí llamarías a tu API real
|
|
58
|
+
viewer.data = [
|
|
59
|
+
{ nombre: 'Producto A', precio: 100, cantidad: 5 },
|
|
60
|
+
{ nombre: 'Producto B', precio: 200, cantidad: 3 },
|
|
61
|
+
{ nombre: 'Producto C', precio: 150, cantidad: 8 },
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
statusEl.textContent = `Reporte: ${definition.metadata?.name || 'sin nombre'} (${new Date().toLocaleTimeString()})`;
|
|
66
|
+
} catch (err) {
|
|
67
|
+
statusEl.textContent = `Error: ${err.message}`;
|
|
68
|
+
console.error(err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
document.getElementById('btnLoad').addEventListener('click', () => {
|
|
73
|
+
loadReport(reportUrl.value);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Cargar reporte por defecto al iniciar
|
|
77
|
+
loadReport(reportUrl.value);
|
|
78
|
+
</script>
|
|
79
|
+
</body>
|
|
80
|
+
</html>
|
|
@@ -1,80 +1,80 @@
|
|
|
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 — React</title>
|
|
7
|
-
<link rel="stylesheet" href="../dist/style.css">
|
|
8
|
-
<style>
|
|
9
|
-
body { margin: 0; font-family: system-ui, sans-serif; }
|
|
10
|
-
#root { 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="root">
|
|
19
|
-
<header>
|
|
20
|
-
<h1>NexaReport</h1>
|
|
21
|
-
<small>React · Demo</small>
|
|
22
|
-
</header>
|
|
23
|
-
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
27
|
-
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
28
|
-
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
29
|
-
<script src="../dist/nexabase-report.umd.js"></script>
|
|
30
|
-
<script type="text/babel">
|
|
31
|
-
NexaReport.registerNexaReport();
|
|
32
|
-
|
|
33
|
-
const reportDef = {
|
|
34
|
-
metadata: { version: '1', name: 'Órdenes', createdAt: new Date().toISOString() },
|
|
35
|
-
layout: {
|
|
36
|
-
page: { format: 'A4', orientation: 'portrait', margins: { top: 1, right: 1, bottom: 1, left: 1 } },
|
|
37
|
-
bands: [
|
|
38
|
-
{ id: 'b_hdr', type: 'ReportHeader', height: 60, elements: [
|
|
39
|
-
{ id: 'e_titulo', type: 'Text', x: 20, y: 10, width: 500, height: 30,
|
|
40
|
-
content: 'Órdenes de Compra', style: { fontSize: '22px', fontWeight: 'bold' } }
|
|
41
|
-
]},
|
|
42
|
-
{ id: 'b_data', type: 'DataBand', height: 30, dataSource: 'main', elements: [
|
|
43
|
-
{ id: 'e_orden', type: 'Text', x: 20, y: 5, width: 100, height: 20,
|
|
44
|
-
binding: 'orden', style: { fontSize: '12px' } },
|
|
45
|
-
{ id: 'e_cliente', type: 'Text', x: 140, y: 5, width: 200, height: 20,
|
|
46
|
-
binding: 'cliente', style: { fontSize: '12px' } },
|
|
47
|
-
{ id: 'e_monto', type: 'Text', x: 370, y: 5, width: 100, height: 20,
|
|
48
|
-
binding: 'monto', style: { fontSize: '12px', textAlign: 'right' } }
|
|
49
|
-
]},
|
|
50
|
-
{ id: 'b_ftr', type: 'PageFooter', height: 30, elements: [
|
|
51
|
-
{ id: 'e_page', type: 'Text', x: 20, y: 5, width: 200, height: 20,
|
|
52
|
-
content: 'Página {[Page]} de {[TotalPages]}', style: { fontSize: '10px', color: '#666' } }
|
|
53
|
-
]}
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
dataSources: [{ id: 'ds1', collection: '', alias: 'main', enabled: true }]
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const data = [
|
|
60
|
-
{ orden: 'ORD-001', cliente: 'Juan Pérez', monto: 15000 },
|
|
61
|
-
{ orden: 'ORD-002', cliente: 'María López', monto: 23000 },
|
|
62
|
-
{ orden: 'ORD-003', cliente: 'Carlos Ruiz', monto: 8700 },
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
function ReportViewer() {
|
|
66
|
-
const viewerRef = React.useRef(null);
|
|
67
|
-
React.useEffect(() => {
|
|
68
|
-
if (viewerRef.current) {
|
|
69
|
-
viewerRef.current.definition = reportDef;
|
|
70
|
-
viewerRef.current.data = data;
|
|
71
|
-
}
|
|
72
|
-
}, []);
|
|
73
|
-
return React.createElement('nexa-viewer', { ref: viewerRef, minimal: true });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
77
|
-
root.render(React.createElement(ReportViewer));
|
|
78
|
-
</script>
|
|
79
|
-
</body>
|
|
80
|
-
</html>
|
|
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 — React</title>
|
|
7
|
+
<link rel="stylesheet" href="../dist/style.css">
|
|
8
|
+
<style>
|
|
9
|
+
body { margin: 0; font-family: system-ui, sans-serif; }
|
|
10
|
+
#root { 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="root">
|
|
19
|
+
<header>
|
|
20
|
+
<h1>NexaReport</h1>
|
|
21
|
+
<small>React · Demo</small>
|
|
22
|
+
</header>
|
|
23
|
+
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
27
|
+
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
28
|
+
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
29
|
+
<script src="../dist/nexabase-report.umd.js"></script>
|
|
30
|
+
<script type="text/babel">
|
|
31
|
+
NexaReport.registerNexaReport();
|
|
32
|
+
|
|
33
|
+
const reportDef = {
|
|
34
|
+
metadata: { version: '1', name: 'Órdenes', createdAt: new Date().toISOString() },
|
|
35
|
+
layout: {
|
|
36
|
+
page: { format: 'A4', orientation: 'portrait', margins: { top: 1, right: 1, bottom: 1, left: 1 } },
|
|
37
|
+
bands: [
|
|
38
|
+
{ id: 'b_hdr', type: 'ReportHeader', height: 60, elements: [
|
|
39
|
+
{ id: 'e_titulo', type: 'Text', x: 20, y: 10, width: 500, height: 30,
|
|
40
|
+
content: 'Órdenes de Compra', style: { fontSize: '22px', fontWeight: 'bold' } }
|
|
41
|
+
]},
|
|
42
|
+
{ id: 'b_data', type: 'DataBand', height: 30, dataSource: 'main', elements: [
|
|
43
|
+
{ id: 'e_orden', type: 'Text', x: 20, y: 5, width: 100, height: 20,
|
|
44
|
+
binding: 'orden', style: { fontSize: '12px' } },
|
|
45
|
+
{ id: 'e_cliente', type: 'Text', x: 140, y: 5, width: 200, height: 20,
|
|
46
|
+
binding: 'cliente', style: { fontSize: '12px' } },
|
|
47
|
+
{ id: 'e_monto', type: 'Text', x: 370, y: 5, width: 100, height: 20,
|
|
48
|
+
binding: 'monto', style: { fontSize: '12px', textAlign: 'right' } }
|
|
49
|
+
]},
|
|
50
|
+
{ id: 'b_ftr', type: 'PageFooter', height: 30, elements: [
|
|
51
|
+
{ id: 'e_page', type: 'Text', x: 20, y: 5, width: 200, height: 20,
|
|
52
|
+
content: 'Página {[Page]} de {[TotalPages]}', style: { fontSize: '10px', color: '#666' } }
|
|
53
|
+
]}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
dataSources: [{ id: 'ds1', collection: '', alias: 'main', enabled: true }]
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const data = [
|
|
60
|
+
{ orden: 'ORD-001', cliente: 'Juan Pérez', monto: 15000 },
|
|
61
|
+
{ orden: 'ORD-002', cliente: 'María López', monto: 23000 },
|
|
62
|
+
{ orden: 'ORD-003', cliente: 'Carlos Ruiz', monto: 8700 },
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
function ReportViewer() {
|
|
66
|
+
const viewerRef = React.useRef(null);
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
if (viewerRef.current) {
|
|
69
|
+
viewerRef.current.definition = reportDef;
|
|
70
|
+
viewerRef.current.data = data;
|
|
71
|
+
}
|
|
72
|
+
}, []);
|
|
73
|
+
return React.createElement('nexa-viewer', { ref: viewerRef, minimal: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
77
|
+
root.render(React.createElement(ReportViewer));
|
|
78
|
+
</script>
|
|
79
|
+
</body>
|
|
80
|
+
</html>
|