nexabase-report 0.4.0 → 0.4.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.md +4 -4
- package/dist/html2canvas.esm-d2sM-0Wm.js +4870 -0
- package/dist/html2pdf-BouVVRU8.js +9114 -0
- package/dist/{index-EE5FdcwR.js → index-DkJsGKYX.js} +16494 -16450
- package/dist/{index.es-Dlgpv5Mf.js → index.es-BG9KbWGU.js} +2 -2
- package/dist/{jspdf.es.min-CEYFDnSg.js → jspdf.es.min-BBCJAJIV.js} +3 -2
- package/dist/nexabase-report.es.js +1 -1
- package/dist/nexabase-report.umd.js +226 -218
- package/docs/PUBLISHING.md +17 -17
- package/docs/guide/designer.md +130 -0
- package/docs/guide/getting-started.md +179 -0
- package/docs/guide/quick-start.md +170 -0
- package/docs/guide/viewer.md +199 -0
- package/docs/index.md +65 -0
- package/package.json +20 -17
- package/dist/html2canvas-CIl29z_V.js +0 -26
- package/dist/html2canvas-DrQHzW4S.js +0 -4877
- package/dist/html2pdf-CqVUYxiC.js +0 -4242
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Viewer
|
|
2
|
+
|
|
3
|
+
`<nexa-viewer>` is a custom element (Web Component) that renders NexaReport definitions. It works in any framework (Vue, React, Angular, Svelte, Blazor, plain HTML) and requires no Vue dependency in the consumer application.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### HTML / Vanilla JS
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/nexabase-report/dist/nexabase-report.umd.js"></script>
|
|
11
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nexabase-report/dist/style.css">
|
|
12
|
+
|
|
13
|
+
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
NexaReport.registerNexaReport();
|
|
17
|
+
|
|
18
|
+
const viewer = document.getElementById('viewer');
|
|
19
|
+
viewer.definition = { /* report JSON */ };
|
|
20
|
+
viewer.data = [ /* data array */ ];
|
|
21
|
+
</script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Vue 3
|
|
25
|
+
|
|
26
|
+
```vue
|
|
27
|
+
<script setup>
|
|
28
|
+
import { registerNexaReport } from 'nexabase-report';
|
|
29
|
+
|
|
30
|
+
registerNexaReport();
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<nexa-viewer
|
|
35
|
+
:definition="reportDef"
|
|
36
|
+
:data="reportData"
|
|
37
|
+
:parameters="{ year: 2024 }"
|
|
38
|
+
skip-params-dialog
|
|
39
|
+
show-toolbar
|
|
40
|
+
/>
|
|
41
|
+
</template>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### React
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useEffect, useRef } from 'react';
|
|
48
|
+
|
|
49
|
+
export function ReportViewer({ definition, data }) {
|
|
50
|
+
const viewerRef = useRef(null);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
window.NexaReport?.registerNexaReport();
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (viewerRef.current) {
|
|
58
|
+
viewerRef.current.definition = definition;
|
|
59
|
+
viewerRef.current.data = data;
|
|
60
|
+
}
|
|
61
|
+
}, [definition, data]);
|
|
62
|
+
|
|
63
|
+
return <nexa-viewer ref={viewerRef} />;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Blazor
|
|
68
|
+
|
|
69
|
+
```razor
|
|
70
|
+
@page "/report/{ReportId}"
|
|
71
|
+
|
|
72
|
+
<div class="viewer-container">
|
|
73
|
+
<nexa-viewer id="reportViewer" style="width:100%; height:1200px;"></nexa-viewer>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<script src="https://cdn.jsdelivr.net/npm/nexabase-report/dist/nexabase-report.umd.js"></script>
|
|
77
|
+
<script>
|
|
78
|
+
window.loadReport = async function(reportJson, data) {
|
|
79
|
+
if (!window._nexaReg) {
|
|
80
|
+
NexaReport.registerNexaReport();
|
|
81
|
+
window._nexaReg = true;
|
|
82
|
+
}
|
|
83
|
+
const viewer = document.getElementById('reportViewer');
|
|
84
|
+
viewer.definition = reportJson;
|
|
85
|
+
viewer.data = data;
|
|
86
|
+
};
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
@code {
|
|
90
|
+
[Parameter] public string ReportId { get; set; }
|
|
91
|
+
|
|
92
|
+
protected override async Task OnInitializedAsync() {
|
|
93
|
+
await JSRuntime.InvokeVoidAsync("loadReport", reportDef, reportData);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Viewer Props
|
|
99
|
+
|
|
100
|
+
| Prop | Type | Default | Description |
|
|
101
|
+
|------|------|---------|-------------|
|
|
102
|
+
| `definition` | `NexaReportDefinition \| string` | — | Report definition object or JSON string. |
|
|
103
|
+
| `data` | `any[] \| Record<string, any[]> \| string` | — | Data for the report. Array (single source) or object keyed by datasource alias. |
|
|
104
|
+
| `parameters` | `Record<string, any>` | `{}` | Initial values for report parameters. |
|
|
105
|
+
| `minimal` | `boolean \| string` | `false` | Compact mode: hides toolbar and sidebar. |
|
|
106
|
+
| `showToolbar` | `boolean \| string` | `true` | Show/hide the export toolbar. |
|
|
107
|
+
| `showThumbs` | `boolean \| string` | `true` | Show/hide the thumbnail sidebar. |
|
|
108
|
+
| `skipParamsDialog` | `boolean` | `false` | Skip the parameter input dialog at load time. |
|
|
109
|
+
| `currentPage` | `number` | `1` | Initial page number to display. |
|
|
110
|
+
| `apiBaseUrl` | `string` | — | NexaBase API URL for dynamic data loading. |
|
|
111
|
+
| `apiKey` | `string` | — | NexaBase API key for authenticated data. |
|
|
112
|
+
| `locale` | `string` | `'es'` | UI language: `'es'`, `'en'`, or `'pt'`. |
|
|
113
|
+
| `licenseKey` | `string` | — | Commercial license key. Without a valid key, an "Unlicensed" watermark appears at the bottom. |
|
|
114
|
+
|
|
115
|
+
## Viewer Methods
|
|
116
|
+
|
|
117
|
+
Access via `document.querySelector('nexa-viewer')` or a template ref:
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
const viewer = document.querySelector('nexa-viewer');
|
|
121
|
+
|
|
122
|
+
// Navigation
|
|
123
|
+
viewer.goToPage(3); // Jump to page 3
|
|
124
|
+
viewer.nextPage(); // Go to next page
|
|
125
|
+
viewer.previousPage(); // Go to previous page
|
|
126
|
+
|
|
127
|
+
// Export
|
|
128
|
+
await viewer.exportPdf(); // Standard PDF
|
|
129
|
+
await viewer.exportPdfWithBookmarks(); // PDF with bookmarks/TOC
|
|
130
|
+
await viewer.exportExcel(); // Excel .xlsx
|
|
131
|
+
await viewer.exportWord(); // Word .docx
|
|
132
|
+
await viewer.exportCsv(); // CSV with UTF-8 BOM
|
|
133
|
+
|
|
134
|
+
// State
|
|
135
|
+
console.log(viewer.pageNumber); // Current page (get/set)
|
|
136
|
+
console.log(viewer.totalPages); // Total pages (read-only)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Events
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
const viewer = document.querySelector('nexa-viewer');
|
|
143
|
+
|
|
144
|
+
viewer.addEventListener('data-request', (e) => {
|
|
145
|
+
console.log('Data requested for:', e.detail.alias);
|
|
146
|
+
// Fetch data and set: viewer.data = { [e.detail.alias]: [...] }
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
viewer.addEventListener('page-change', (e) => {
|
|
150
|
+
console.log('Page changed to:', e.detail);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
viewer.addEventListener('drill-click', (e) => {
|
|
154
|
+
console.log('Drill-down clicked:', e.detail);
|
|
155
|
+
// e.detail = { element, sourceData, targetReportId, parameters, config }
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Renderers
|
|
160
|
+
|
|
161
|
+
The viewer includes specialized renderers for each element type:
|
|
162
|
+
|
|
163
|
+
| Renderer | Description |
|
|
164
|
+
|----------|-------------|
|
|
165
|
+
| `TextRenderer` | Text, expressions, bindings with highlight search |
|
|
166
|
+
| `ImageRenderer` | Image from URL or data field, with `object-fit` support (contain/cover/fill) |
|
|
167
|
+
| `TableRenderer` | Tabular data with headers, alternating row colors, conditional styling |
|
|
168
|
+
| `ChartRenderer` | ECharts (bar, line, pie, area, scatter, radar, etc.) |
|
|
169
|
+
| `CrosstabRenderer` | Pivot table with row/column grouping and aggregations |
|
|
170
|
+
| `BarcodeRenderer` | CODE128, EAN13, CODE39, etc. via jsbarcode |
|
|
171
|
+
| `QRCodeRenderer` | QR codes via qrcode library |
|
|
172
|
+
| `ShapeRenderer` | Rectangle, Ellipse, Line, Arrow rendered as SVG/canvas |
|
|
173
|
+
| `DashboardWidgetRenderer` | Dashboard widgets (Indicator, Chart, Gauge, Table) |
|
|
174
|
+
|
|
175
|
+
## Pagination
|
|
176
|
+
|
|
177
|
+
NexaReport uses a two-phase pagination engine:
|
|
178
|
+
|
|
179
|
+
1. **Streaming Phase** (`generateStream`): Processes all bands and data rows, computing page breaks based on element heights, table row heights, and watermark space.
|
|
180
|
+
|
|
181
|
+
2. **Page Generation Phase** (`generatePages`): Splits the stream into individual pages, handling table row splitting across page boundaries and accounting for `PageHeader`, `PageFooter`, and `ReportFooter` space.
|
|
182
|
+
|
|
183
|
+
The `currentPage` prop allows programmatically navigating to any page. The thumbnail sidebar shows all pages and lets users click to navigate.
|
|
184
|
+
|
|
185
|
+
## Watermark
|
|
186
|
+
|
|
187
|
+
Without a valid `licenseKey`, the viewer displays an "Unlicensed · Trial version" banner at the bottom. This does not block functionality but serves as a reminder to activate a commercial license.
|
|
188
|
+
|
|
189
|
+
## Styling
|
|
190
|
+
|
|
191
|
+
The viewer uses scoped styles. Global overrides can be applied via CSS custom properties on the host element:
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
nexa-viewer {
|
|
195
|
+
--viewer-bg: #f8fafc;
|
|
196
|
+
--viewer-toolbar-bg: #ffffff;
|
|
197
|
+
--viewer-border: #e2e8f0;
|
|
198
|
+
}
|
|
199
|
+
```
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: home
|
|
3
|
+
|
|
4
|
+
hero:
|
|
5
|
+
name: "NexaReport"
|
|
6
|
+
text: "Professional Report Designer & Viewer"
|
|
7
|
+
tagline: "Vue 3 · TypeScript · WYSIWYG · Export to PDF/Excel/Word · 100% Client-Side"
|
|
8
|
+
image:
|
|
9
|
+
src: /logo.svg
|
|
10
|
+
alt: NexaReport
|
|
11
|
+
actions:
|
|
12
|
+
- theme: brand
|
|
13
|
+
text: Get Started
|
|
14
|
+
link: /guide/getting-started
|
|
15
|
+
- theme: alt
|
|
16
|
+
text: View on GitHub
|
|
17
|
+
link: https://github.com/nexabase/nexabase-report
|
|
18
|
+
|
|
19
|
+
features:
|
|
20
|
+
- icon: 🎨
|
|
21
|
+
title: WYSIWYG Designer
|
|
22
|
+
details: Drag & drop report designer with ribbon, sidebar, snap-to-grid, i18n support (ES/EN/PT) and real-time preview.
|
|
23
|
+
|
|
24
|
+
- icon: 📦
|
|
25
|
+
title: Custom Element Viewer
|
|
26
|
+
details: "<nexa-viewer> works in Vue, React, Angular, Svelte, Blazor, or plain HTML — no Vue dependency in the consumer."
|
|
27
|
+
|
|
28
|
+
- icon: 📊
|
|
29
|
+
title: Charts, Crosstabs, Tables
|
|
30
|
+
details: ECharts integration (bar, line, pie, area, scatter), crosstab pivot tables, banded report model with data bands.
|
|
31
|
+
|
|
32
|
+
- icon: 📄
|
|
33
|
+
title: PDF, Excel, Word, CSV
|
|
34
|
+
details: 100% client-side export. Native vector PDF, SheetJS Excel, docx Word, and UTF-8 BOM CSV — no server required.
|
|
35
|
+
|
|
36
|
+
- icon: 🔑
|
|
37
|
+
title: Commercial Licensing
|
|
38
|
+
details: Designer supports license key activation (personal, business, enterprise). Watermark-free with valid license.
|
|
39
|
+
|
|
40
|
+
- icon: 🌐
|
|
41
|
+
title: CDN Ready
|
|
42
|
+
details: One script tag to include in any project. No build step required for HTML demos or quick integrations.
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<div class="vp-doc flex flex-col items-center justify-center min-h-[30vh] text-center px-6">
|
|
46
|
+
<h2 class="mb-4 text-2xl font-bold text-[var(--vp-c-brand-1)]">Try it now — no install needed</h2>
|
|
47
|
+
<div class="code-block w-full max-w-2xl rounded-lg overflow-hidden text-left">
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<script src="https://cdn.jsdelivr.net/npm/nexabase-report/dist/nexabase-report.umd.js"></script>
|
|
51
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nexabase-report/dist/style.css">
|
|
52
|
+
|
|
53
|
+
<nexa-viewer id="viewer" minimal></nexa-viewer>
|
|
54
|
+
|
|
55
|
+
<script>
|
|
56
|
+
NexaReport.registerNexaReport();
|
|
57
|
+
|
|
58
|
+
const viewer = document.getElementById('viewer');
|
|
59
|
+
viewer.definition = { /* your report JSON */ };
|
|
60
|
+
viewer.data = [ /* your data array */ ];
|
|
61
|
+
</script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexabase-report",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Professional report designer and viewer for NexaBase — drag & drop designer, PDF/Excel export, charts, crosstabs, subreports.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NexaBase Team",
|
|
@@ -54,21 +54,6 @@
|
|
|
54
54
|
"custom-element",
|
|
55
55
|
"web-component"
|
|
56
56
|
],
|
|
57
|
-
"scripts": {
|
|
58
|
-
"dev": "vite",
|
|
59
|
-
"build": "vue-tsc -b && vite build",
|
|
60
|
-
"preview": "vite preview",
|
|
61
|
-
"test": "vitest run",
|
|
62
|
-
"test:watch": "vitest",
|
|
63
|
-
"test:coverage": "vitest run --coverage",
|
|
64
|
-
"release:patch": "npm test && npm run build && npm version patch",
|
|
65
|
-
"release:minor": "npm test && npm run build && npm version minor",
|
|
66
|
-
"release:major": "npm test && npm run build && npm version major",
|
|
67
|
-
"prepack": "npm run build",
|
|
68
|
-
"lint": "eslint src/lib/",
|
|
69
|
-
"lint:fix": "eslint src/lib/ --fix",
|
|
70
|
-
"license:gen": "node scripts/gen-license.mjs"
|
|
71
|
-
},
|
|
72
57
|
"dependencies": {
|
|
73
58
|
"@nexabase/sdk": "^2.17.6",
|
|
74
59
|
"@types/jsbarcode": "^3.11.4",
|
|
@@ -99,7 +84,25 @@
|
|
|
99
84
|
"typescript-eslint": "^8.31.1",
|
|
100
85
|
"vite": "^5.4.14",
|
|
101
86
|
"vite-plugin-dts": "^4.5.4",
|
|
87
|
+
"vitepress": "^1.6.4",
|
|
102
88
|
"vitest": "^4.1.5",
|
|
103
89
|
"vue-tsc": "^3.2.6"
|
|
90
|
+
},
|
|
91
|
+
"scripts": {
|
|
92
|
+
"dev": "vite",
|
|
93
|
+
"build": "vue-tsc -b && vite build",
|
|
94
|
+
"preview": "vite preview",
|
|
95
|
+
"test": "vitest run",
|
|
96
|
+
"test:watch": "vitest",
|
|
97
|
+
"test:coverage": "vitest run --coverage",
|
|
98
|
+
"release:patch": "pnpm test && pnpm build && pnpm version patch",
|
|
99
|
+
"release:minor": "pnpm test && pnpm build && pnpm version minor",
|
|
100
|
+
"release:major": "pnpm test && pnpm build && pnpm version major",
|
|
101
|
+
"lint": "eslint src/lib/",
|
|
102
|
+
"lint:fix": "eslint src/lib/ --fix",
|
|
103
|
+
"license:gen": "node scripts/gen-license.mjs",
|
|
104
|
+
"docs:dev": "vitepress dev docs-site",
|
|
105
|
+
"docs:build": "vitepress build docs-site",
|
|
106
|
+
"docs:preview": "vitepress preview docs-site"
|
|
104
107
|
}
|
|
105
|
-
}
|
|
108
|
+
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { a as c } from "./index-EE5FdcwR.js";
|
|
2
|
-
import { r as f } from "./html2canvas-DrQHzW4S.js";
|
|
3
|
-
function l(r, n) {
|
|
4
|
-
for (var o = 0; o < n.length; o++) {
|
|
5
|
-
const e = n[o];
|
|
6
|
-
if (typeof e != "string" && !Array.isArray(e)) {
|
|
7
|
-
for (const t in e)
|
|
8
|
-
if (t !== "default" && !(t in r)) {
|
|
9
|
-
const a = Object.getOwnPropertyDescriptor(e, t);
|
|
10
|
-
a && Object.defineProperty(r, t, a.get ? a : {
|
|
11
|
-
enumerable: !0,
|
|
12
|
-
get: () => e[t]
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return Object.freeze(Object.defineProperty(r, Symbol.toStringTag, { value: "Module" }));
|
|
18
|
-
}
|
|
19
|
-
var s = f();
|
|
20
|
-
const i = /* @__PURE__ */ c(s), u = /* @__PURE__ */ l({
|
|
21
|
-
__proto__: null,
|
|
22
|
-
default: i
|
|
23
|
-
}, [s]);
|
|
24
|
-
export {
|
|
25
|
-
u as h
|
|
26
|
-
};
|