@zentto/report-designer 1.6.6 → 1.7.0
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/data-panel/code-editor.d.ts +4 -0
- package/dist/data-panel/code-editor.d.ts.map +1 -1
- package/dist/data-panel/code-editor.js +38 -19
- package/dist/data-panel/code-editor.js.map +1 -1
- package/dist/data-panel/er-diagram.d.ts +7 -0
- package/dist/data-panel/er-diagram.d.ts.map +1 -1
- package/dist/data-panel/er-diagram.js +53 -13
- package/dist/data-panel/er-diagram.js.map +1 -1
- package/dist/data-panel/formula-editor.d.ts.map +1 -1
- package/dist/data-panel/formula-editor.js +4 -1
- package/dist/data-panel/formula-editor.js.map +1 -1
- package/dist/data-panel/relation-editor.d.ts.map +1 -1
- package/dist/data-panel/relation-editor.js +4 -1
- package/dist/data-panel/relation-editor.js.map +1 -1
- package/dist/zentto-report-designer.d.ts.map +1 -1
- package/dist/zentto-report-designer.js +91 -45
- package/dist/zentto-report-designer.js.map +1 -1
- package/package.json +1 -1
|
@@ -72,14 +72,35 @@ const ELEMENT_TYPE_ICONS = {
|
|
|
72
72
|
totalPages: '#',
|
|
73
73
|
};
|
|
74
74
|
const TOOLBOX_ITEMS = [
|
|
75
|
-
|
|
76
|
-
{ type: '
|
|
77
|
-
{ type: '
|
|
78
|
-
{ type: '
|
|
79
|
-
{ type: '
|
|
80
|
-
{ type: '
|
|
81
|
-
|
|
82
|
-
{ type: '
|
|
75
|
+
// ─── Text & Data ───
|
|
76
|
+
{ type: 'text', label: 'Text', icon: 'T', preview: 'Aa', description: 'Static text label or title', category: 'Text & Data' },
|
|
77
|
+
{ type: 'field', label: 'Field', icon: 'F', preview: '[Field]', description: 'Data-bound field from a source', category: 'Text & Data' },
|
|
78
|
+
{ type: 'text', label: 'Title', icon: 'H', preview: 'Title', description: 'Large bold title text', category: 'Text & Data', extraProps: { content: 'Title', style: { fontSize: 18, fontWeight: 'bold' }, width: 80, height: 10 } },
|
|
79
|
+
{ type: 'text', label: 'Subtitle', icon: 'h', preview: 'Subtitle', description: 'Medium subtitle text', category: 'Text & Data', extraProps: { content: 'Subtitle', style: { fontSize: 13, fontWeight: 'bold', color: '#666' }, width: 60, height: 8 } },
|
|
80
|
+
{ type: 'text', label: 'Label', icon: 'L', preview: 'Label:', description: 'Small bold label', category: 'Text & Data', extraProps: { content: 'Label:', style: { fontSize: 9, fontWeight: 'bold' }, width: 25, height: 6 } },
|
|
81
|
+
// ─── Shapes & Lines ───
|
|
82
|
+
{ type: 'line', label: 'Line', icon: '\u2500', preview: '\u2500\u2500\u2500', description: 'Horizontal line separator', category: 'Shapes' },
|
|
83
|
+
{ type: 'line', label: 'Thick Line', icon: '\u2501', preview: '\u2501\u2501\u2501', description: 'Thick separator line', category: 'Shapes', extraProps: { lineStyle: { color: '#000', width: 3, style: 'solid' }, width: 80 } },
|
|
84
|
+
{ type: 'line', label: 'Dashed Line', icon: '\u2504', preview: '- - -', description: 'Dashed separator', category: 'Shapes', extraProps: { lineStyle: { color: '#999', width: 1, style: 'dashed' }, width: 80 } },
|
|
85
|
+
{ type: 'rect', label: 'Rectangle', icon: '\u25AD', preview: '\u25AD', description: 'Rectangle or filled box', category: 'Shapes' },
|
|
86
|
+
{ type: 'rect', label: 'Filled Box', icon: '\u25A0', preview: '\u25A0', description: 'Filled color box', category: 'Shapes', extraProps: { fill: '#1976d2', lineStyle: { width: 0 }, width: 30, height: 15 } },
|
|
87
|
+
{ type: 'rect', label: 'Rounded Box', icon: '\u25A2', preview: '\u25A2', description: 'Box with rounded corners', category: 'Shapes', extraProps: { cornerRadius: 6, lineStyle: { color: '#ccc', width: 1, style: 'solid' }, width: 40, height: 15 } },
|
|
88
|
+
// ─── Media ───
|
|
89
|
+
{ type: 'image', label: 'Image', icon: '\u{1F5BC}', preview: '\u{1F304}', description: 'Static or dynamic image', category: 'Media' },
|
|
90
|
+
{ type: 'barcode', label: 'QR Code', icon: '\u2588', preview: 'QR', description: 'QR code from field or value', category: 'Media', extraProps: { barcodeType: 'qr', value: '12345', width: 20, height: 20 } },
|
|
91
|
+
{ type: 'barcode', label: 'Barcode 128', icon: '|||', preview: '||||', description: 'Code128 barcode', category: 'Media', extraProps: { barcodeType: 'code128', value: '12345' } },
|
|
92
|
+
{ type: 'barcode', label: 'EAN-13', icon: '\u2584', preview: 'EAN', description: 'EAN-13 product barcode', category: 'Media', extraProps: { barcodeType: 'ean13', value: '5901234123457' } },
|
|
93
|
+
// ─── Charts ───
|
|
94
|
+
{ type: 'chart', label: 'Bar Chart', icon: '\u{1F4CA}', preview: '\u{2581}\u{2583}\u{2585}\u{2587}', description: 'Bar chart visualization', category: 'Charts', extraProps: { chartType: 'bar', labelField: '', valueFields: [], width: 80, height: 50 } },
|
|
95
|
+
{ type: 'chart', label: 'Line Chart', icon: '\u{1F4C8}', preview: '\u{2571}\u{2572}\u{2571}', description: 'Line chart with trends', category: 'Charts', extraProps: { chartType: 'line', labelField: '', valueFields: [], width: 80, height: 50 } },
|
|
96
|
+
{ type: 'chart', label: 'Pie Chart', icon: '\u{1F967}', preview: '\u{25D4}', description: 'Pie/donut chart', category: 'Charts', extraProps: { chartType: 'pie', labelField: '', valueFields: [], width: 50, height: 50 } },
|
|
97
|
+
{ type: 'chart', label: 'Area Chart', icon: '\u{1F30A}', preview: '\u{2586}\u{2584}\u{2582}', description: 'Area chart with fill', category: 'Charts', extraProps: { chartType: 'area', labelField: '', valueFields: [], width: 80, height: 50 } },
|
|
98
|
+
{ type: 'chart', label: 'Combo Chart', icon: '\u{1F4CA}', preview: '\u{2581}\u{2571}\u{2585}', description: 'Bars + lines combined', category: 'Charts', extraProps: { chartType: 'combo', labelField: '', valueFields: [], width: 80, height: 50 } },
|
|
99
|
+
// ─── Page & Special ───
|
|
100
|
+
{ type: 'pageNumber', label: 'Page Number', icon: '#', preview: '1/5', description: 'Page N of M', category: 'Special' },
|
|
101
|
+
{ type: 'currentDate', label: 'Print Date', icon: '\u{1F4C5}', preview: '27/03', description: 'Current date/time', category: 'Special' },
|
|
102
|
+
{ type: 'currentDate', label: 'Print Time', icon: '\u{1F552}', preview: '14:30', description: 'Current time only', category: 'Special', extraProps: { format: 'HH:mm:ss' } },
|
|
103
|
+
{ type: 'text', label: 'Watermark', icon: '\u{1F4A7}', preview: 'DRAFT', description: 'Semi-transparent watermark text', category: 'Special', extraProps: { content: 'DRAFT', style: { fontSize: 48, fontWeight: 'bold', color: '#ccc', textAlign: 'center', opacity: 0.3 }, width: 120, height: 30 } },
|
|
83
104
|
];
|
|
84
105
|
let ZenttoReportDesigner = class ZenttoReportDesigner extends LitElement {
|
|
85
106
|
constructor() {
|
|
@@ -1575,6 +1596,9 @@ let ZenttoReportDesigner = class ZenttoReportDesigner extends LitElement {
|
|
|
1575
1596
|
case 'barcode':
|
|
1576
1597
|
element = { ...baseProps, type: 'barcode', barcodeType: 'qr', value: '12345', width: 15, height: 15 };
|
|
1577
1598
|
break;
|
|
1599
|
+
case 'chart':
|
|
1600
|
+
element = { ...baseProps, type: 'chart', chartType: 'bar', dataSource: '', labelField: '', valueFields: [], width: 80, height: 50 };
|
|
1601
|
+
break;
|
|
1578
1602
|
case 'pageNumber':
|
|
1579
1603
|
element = { ...baseProps, type: 'pageNumber', format: 'Page {page} of {pages}', width: 30 };
|
|
1580
1604
|
break;
|
|
@@ -1901,7 +1925,10 @@ let ZenttoReportDesigner = class ZenttoReportDesigner extends LitElement {
|
|
|
1901
1925
|
});
|
|
1902
1926
|
}
|
|
1903
1927
|
else if (type) {
|
|
1904
|
-
|
|
1928
|
+
// Check for extra props from toolbox items (Title, Watermark, etc.)
|
|
1929
|
+
const extraJson = e.dataTransfer?.getData('extra-props');
|
|
1930
|
+
const extraProps = extraJson ? JSON.parse(extraJson) : undefined;
|
|
1931
|
+
this._addElementToBand(bandId, type, extraProps);
|
|
1905
1932
|
}
|
|
1906
1933
|
}
|
|
1907
1934
|
_onBandDragOver(e) {
|
|
@@ -2983,17 +3010,32 @@ REGLAS:
|
|
|
2983
3010
|
}
|
|
2984
3011
|
// ─── Toolbox ──────────────────────────────────────────────────
|
|
2985
3012
|
_renderToolbox() {
|
|
3013
|
+
// Group items by category
|
|
3014
|
+
const categories = new Map();
|
|
3015
|
+
for (const item of TOOLBOX_ITEMS) {
|
|
3016
|
+
if (!categories.has(item.category))
|
|
3017
|
+
categories.set(item.category, []);
|
|
3018
|
+
categories.get(item.category).push(item);
|
|
3019
|
+
}
|
|
2986
3020
|
return html `
|
|
2987
|
-
${
|
|
2988
|
-
<div
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
3021
|
+
${[...categories.entries()].map(([cat, items]) => html `
|
|
3022
|
+
<div style="padding:4px 10px 2px;font-size:10px;font-weight:600;color:var(--zrd-text-muted,#999);text-transform:uppercase;letter-spacing:0.5px;margin-top:4px;">${cat}</div>
|
|
3023
|
+
${items.map(item => html `
|
|
3024
|
+
<div class="toolbox-item"
|
|
3025
|
+
draggable="true"
|
|
3026
|
+
@dragstart=${(e) => {
|
|
3027
|
+
this._onToolboxDragStart(e, item.type);
|
|
3028
|
+
if (item.extraProps) {
|
|
3029
|
+
e.dataTransfer?.setData('extra-props', JSON.stringify(item.extraProps));
|
|
3030
|
+
}
|
|
3031
|
+
}}>
|
|
3032
|
+
<div class="toolbox-icon" data-type="${item.type}">${item.preview}</div>
|
|
3033
|
+
<div class="toolbox-info">
|
|
3034
|
+
<span class="toolbox-label">${item.label}</span>
|
|
3035
|
+
<span class="toolbox-desc">${item.description}</span>
|
|
3036
|
+
</div>
|
|
2995
3037
|
</div>
|
|
2996
|
-
|
|
3038
|
+
`)}
|
|
2997
3039
|
`)}
|
|
2998
3040
|
`;
|
|
2999
3041
|
}
|
|
@@ -3023,31 +3065,28 @@ REGLAS:
|
|
|
3023
3065
|
${this._renderOverlays()}
|
|
3024
3066
|
`;
|
|
3025
3067
|
}
|
|
3026
|
-
// Action buttons bar
|
|
3027
|
-
const hasActions = this.dbProvider || this.zenttoProvider || this._layout.dataSources.length > 0;
|
|
3068
|
+
// Action buttons bar — always show so user can connect data sources
|
|
3028
3069
|
return html `
|
|
3029
|
-
|
|
3030
|
-
<
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
</div>
|
|
3050
|
-
` : nothing}
|
|
3070
|
+
<div style="padding:6px 8px;display:flex;gap:4px;border-bottom:1px solid var(--zrd-border,#e0e0e0);flex-shrink:0;flex-wrap:wrap;">
|
|
3071
|
+
<button style="flex:1;padding:5px 6px;border:1px solid var(--zrd-border,#ddd);border-radius:4px;cursor:pointer;font-size:10px;font-weight:600;background:var(--zrd-input-bg,#fff);color:var(--zrd-primary,#1976d2);min-width:50px;"
|
|
3072
|
+
@click=${() => { this._dbConnectorOpen = true; }}>
|
|
3073
|
+
\u{1F5C4} DB
|
|
3074
|
+
</button>
|
|
3075
|
+
<button style="flex:1;padding:5px 6px;border:1px solid var(--zrd-border,#ddd);border-radius:4px;cursor:pointer;font-size:10px;font-weight:600;background:var(--zrd-input-bg,#fff);color:#e65100;min-width:50px;"
|
|
3076
|
+
@click=${() => { this._zenttoConnectorOpen = true; }}>
|
|
3077
|
+
\u{1F310} Zentto
|
|
3078
|
+
</button>
|
|
3079
|
+
<button style="flex:1;padding:5px 6px;border:1px solid var(--zrd-border,#ddd);border-radius:4px;cursor:pointer;font-size:10px;font-weight:600;background:var(--zrd-input-bg,#fff);color:#2e7d32;min-width:50px;"
|
|
3080
|
+
@click=${() => { this.dispatchEvent(new CustomEvent('add-rest-source', { bubbles: true, composed: true })); }}>
|
|
3081
|
+
\u{1F517} REST
|
|
3082
|
+
</button>
|
|
3083
|
+
${this._layout.dataSources.length > 0 ? html `
|
|
3084
|
+
<button style="flex:1;padding:5px 6px;border:1px solid var(--zrd-border,#ddd);border-radius:4px;cursor:pointer;font-size:10px;font-weight:600;background:var(--zrd-input-bg,#fff);color:var(--zrd-text,#555);min-width:50px;"
|
|
3085
|
+
@click=${() => { this._erOverlayOpen = true; }}>
|
|
3086
|
+
\u{1F4CA} ER
|
|
3087
|
+
</button>
|
|
3088
|
+
` : nothing}
|
|
3089
|
+
</div>
|
|
3051
3090
|
<zrd-data-source-tree
|
|
3052
3091
|
.dataSources=${this._layout.dataSources}
|
|
3053
3092
|
.relations=${this._layout.relations || []}
|
|
@@ -3091,7 +3130,10 @@ REGLAS:
|
|
|
3091
3130
|
_renderErOverlay() {
|
|
3092
3131
|
return html `
|
|
3093
3132
|
<div style="position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:10000;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(2px);"
|
|
3094
|
-
@click=${() => { this._erOverlayOpen = false; }}
|
|
3133
|
+
@click=${() => { this._erOverlayOpen = false; }}
|
|
3134
|
+
@keydown=${(e) => { if (e.key === 'Escape')
|
|
3135
|
+
this._erOverlayOpen = false; }}
|
|
3136
|
+
tabindex="-1">
|
|
3095
3137
|
<div style="background:var(--zrd-panel-bg,#fff);border-radius:12px;box-shadow:0 20px 60px rgba(0,0,0,0.3);width:85vw;height:80vh;display:flex;flex-direction:column;overflow:hidden;"
|
|
3096
3138
|
@click=${(e) => e.stopPropagation()}>
|
|
3097
3139
|
<div style="padding:16px 20px;border-bottom:1px solid var(--zrd-border,#eee);display:flex;justify-content:space-between;align-items:center;">
|
|
@@ -3103,6 +3145,8 @@ REGLAS:
|
|
|
3103
3145
|
<zrd-er-diagram
|
|
3104
3146
|
.dataSources=${this._layout.dataSources}
|
|
3105
3147
|
.relations=${this._layout.relations || []}
|
|
3148
|
+
.dbProvider=${this.dbProvider}
|
|
3149
|
+
.zenttoProvider=${this.zenttoProvider}
|
|
3106
3150
|
@relation-edit=${(e) => {
|
|
3107
3151
|
this._editingRelation = e.detail.relation;
|
|
3108
3152
|
this._relationEditorOpen = true;
|
|
@@ -3115,8 +3159,7 @@ REGLAS:
|
|
|
3115
3159
|
this._layout = { ...this._layout, relations: (this._layout.relations || []).filter(r => r.id !== id) };
|
|
3116
3160
|
this._commitChange();
|
|
3117
3161
|
}}
|
|
3118
|
-
@
|
|
3119
|
-
@add-zentto=${() => { this._erOverlayOpen = false; this._zenttoConnectorOpen = true; this._activePanel = 'data'; }}
|
|
3162
|
+
@datasources-ready=${(e) => this._onDatasourcesReady(e.detail)}
|
|
3120
3163
|
@add-rest=${() => { }}
|
|
3121
3164
|
@table-focus=${() => {
|
|
3122
3165
|
this._erOverlayOpen = false;
|
|
@@ -3385,6 +3428,9 @@ REGLAS:
|
|
|
3385
3428
|
case 'barcode':
|
|
3386
3429
|
content = `[${el.barcodeType}]`;
|
|
3387
3430
|
break;
|
|
3431
|
+
case 'chart':
|
|
3432
|
+
content = `\u{1F4CA} [${el.chartType || 'chart'}]`;
|
|
3433
|
+
break;
|
|
3388
3434
|
case 'pageNumber':
|
|
3389
3435
|
content = el.format || 'Page #';
|
|
3390
3436
|
break;
|