@zentto/report-core 0.4.0 → 1.0.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.
Files changed (36) hide show
  1. package/dist/engine/conditional-format.d.ts +48 -0
  2. package/dist/engine/conditional-format.d.ts.map +1 -0
  3. package/dist/engine/conditional-format.js +167 -0
  4. package/dist/engine/conditional-format.js.map +1 -0
  5. package/dist/engine/cross-tab.d.ts +68 -0
  6. package/dist/engine/cross-tab.d.ts.map +1 -0
  7. package/dist/engine/cross-tab.js +549 -0
  8. package/dist/engine/cross-tab.js.map +1 -0
  9. package/dist/engine/expression.d.ts +46 -2
  10. package/dist/engine/expression.d.ts.map +1 -1
  11. package/dist/engine/expression.js +1415 -90
  12. package/dist/engine/expression.js.map +1 -1
  13. package/dist/engine/multi-pass-engine.d.ts +74 -0
  14. package/dist/engine/multi-pass-engine.d.ts.map +1 -0
  15. package/dist/engine/multi-pass-engine.js +1082 -0
  16. package/dist/engine/multi-pass-engine.js.map +1 -0
  17. package/dist/engine/running-totals.d.ts +74 -0
  18. package/dist/engine/running-totals.d.ts.map +1 -0
  19. package/dist/engine/running-totals.js +247 -0
  20. package/dist/engine/running-totals.js.map +1 -0
  21. package/dist/engine/subreport.d.ts +59 -0
  22. package/dist/engine/subreport.d.ts.map +1 -0
  23. package/dist/engine/subreport.js +295 -0
  24. package/dist/engine/subreport.js.map +1 -0
  25. package/dist/index.d.ts +11 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +10 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/schema/report-schema.d.ts +346 -346
  30. package/dist/serialization/json.d.ts +88 -88
  31. package/dist/templates/page-sizes.d.ts.map +1 -1
  32. package/dist/templates/page-sizes.js +95 -3
  33. package/dist/templates/page-sizes.js.map +1 -1
  34. package/dist/types.d.ts +38 -2
  35. package/dist/types.d.ts.map +1 -1
  36. package/package.json +1 -1
@@ -0,0 +1,549 @@
1
+ // @zentto/report-core — Cross-Tab (Pivot Table) engine
2
+ // Crystal Reports-style cross-tab with multi-level grouping, summaries, and totals
3
+ // ─── Date Grouping ─────────────────────────────────────────────────
4
+ function groupDateValue(value, groupBy) {
5
+ if (groupBy === 'value' || !groupBy)
6
+ return String(value ?? '');
7
+ const date = value instanceof Date ? value : new Date(String(value));
8
+ if (isNaN(date.getTime()))
9
+ return String(value ?? '');
10
+ switch (groupBy) {
11
+ case 'year':
12
+ return String(date.getFullYear());
13
+ case 'quarter':
14
+ return `${date.getFullYear()}-Q${Math.ceil((date.getMonth() + 1) / 3)}`;
15
+ case 'month':
16
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
17
+ case 'week': {
18
+ // ISO week number
19
+ const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
20
+ const dayNum = d.getUTCDay() || 7;
21
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
22
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
23
+ const weekNo = Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
24
+ return `${d.getUTCFullYear()}-W${String(weekNo).padStart(2, '0')}`;
25
+ }
26
+ case 'day':
27
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
28
+ default:
29
+ return String(value ?? '');
30
+ }
31
+ }
32
+ // ─── Key Extraction ────────────────────────────────────────────────
33
+ /**
34
+ * Extract the composite key from a row based on a set of CrossTabFields.
35
+ * Each field is grouped according to its groupBy setting.
36
+ */
37
+ function extractKey(row, fields) {
38
+ return fields.map((f) => groupDateValue(row[f.field], f.groupBy));
39
+ }
40
+ /** Serialize a composite key to a single string for map lookups */
41
+ function keyToString(key) {
42
+ return key.join('\x00');
43
+ }
44
+ function createAccumulator() {
45
+ return {
46
+ sum: 0,
47
+ count: 0,
48
+ min: Infinity,
49
+ max: -Infinity,
50
+ distinctValues: new Set(),
51
+ values: [],
52
+ };
53
+ }
54
+ function feedAccumulator(acc, value) {
55
+ acc.count++;
56
+ acc.distinctValues.add(value);
57
+ const num = typeof value === 'number' ? value : Number(value);
58
+ if (!isNaN(num)) {
59
+ acc.sum += num;
60
+ acc.values.push(num);
61
+ if (num < acc.min)
62
+ acc.min = num;
63
+ if (num > acc.max)
64
+ acc.max = num;
65
+ }
66
+ }
67
+ function resolveAccumulator(acc, fn) {
68
+ switch (fn) {
69
+ case 'sum':
70
+ return acc.sum;
71
+ case 'avg':
72
+ return acc.values.length > 0 ? acc.sum / acc.values.length : 0;
73
+ case 'count':
74
+ return acc.count;
75
+ case 'min':
76
+ return acc.min === Infinity ? 0 : acc.min;
77
+ case 'max':
78
+ return acc.max === -Infinity ? 0 : acc.max;
79
+ case 'distinctCount':
80
+ return acc.distinctValues.size;
81
+ default:
82
+ return 0;
83
+ }
84
+ }
85
+ // ─── Build Cross-Tab ───────────────────────────────────────────────
86
+ /**
87
+ * Process raw data into a CrossTabResult structure.
88
+ * This is the main cross-tab computation engine.
89
+ */
90
+ export function buildCrossTab(def, data) {
91
+ if (data.length === 0 || def.summaryFields.length === 0) {
92
+ return {
93
+ rowKeys: [],
94
+ columnKeys: [],
95
+ cells: [],
96
+ rowTotals: [],
97
+ columnTotals: [],
98
+ grandTotals: def.summaryFields.map(() => 0),
99
+ };
100
+ }
101
+ const summaryCount = def.summaryFields.length;
102
+ // ─── Step 1: Collect unique row and column keys ──────────────
103
+ const rowKeyMap = new Map();
104
+ const colKeyMap = new Map();
105
+ // Cell accumulators: Map<"rowKeyStr\x01colKeyStr", Accumulator[]>
106
+ const cellAccumulators = new Map();
107
+ for (const row of data) {
108
+ const rk = extractKey(row, def.rowFields);
109
+ const ck = extractKey(row, def.columnFields);
110
+ const rkStr = keyToString(rk);
111
+ const ckStr = keyToString(ck);
112
+ if (!rowKeyMap.has(rkStr))
113
+ rowKeyMap.set(rkStr, rk);
114
+ if (!colKeyMap.has(ckStr))
115
+ colKeyMap.set(ckStr, ck);
116
+ const cellKey = `${rkStr}\x01${ckStr}`;
117
+ let accs = cellAccumulators.get(cellKey);
118
+ if (!accs) {
119
+ accs = def.summaryFields.map(() => createAccumulator());
120
+ cellAccumulators.set(cellKey, accs);
121
+ }
122
+ for (let si = 0; si < summaryCount; si++) {
123
+ feedAccumulator(accs[si], row[def.summaryFields[si].field]);
124
+ }
125
+ }
126
+ // ─── Step 2: Sort keys ──────────────────────────────────────
127
+ let rowKeys = Array.from(rowKeyMap.values());
128
+ let columnKeys = Array.from(colKeyMap.values());
129
+ if (def.rowSort && def.rowSort !== 'none') {
130
+ rowKeys = sortKeys(rowKeys, def.rowSort);
131
+ }
132
+ if (def.columnSort && def.columnSort !== 'none') {
133
+ columnKeys = sortKeys(columnKeys, def.columnSort);
134
+ }
135
+ // ─── Step 3: Build cells matrix ─────────────────────────────
136
+ const cells = [];
137
+ const rowTotals = [];
138
+ const columnTotals = columnKeys.map(() => def.summaryFields.map(() => 0));
139
+ const grandAccumulators = def.summaryFields.map(() => createAccumulator());
140
+ // We also need column-level accumulators for proper avg/min/max
141
+ const colAccumulators = columnKeys.map(() => def.summaryFields.map(() => createAccumulator()));
142
+ const rowAccumulators = [];
143
+ for (let ri = 0; ri < rowKeys.length; ri++) {
144
+ const rkStr = keyToString(rowKeys[ri]);
145
+ const rowCells = [];
146
+ const rowAccs = def.summaryFields.map(() => createAccumulator());
147
+ rowAccumulators.push(rowAccs);
148
+ for (let ci = 0; ci < columnKeys.length; ci++) {
149
+ const ckStr = keyToString(columnKeys[ci]);
150
+ const cellKey = `${rkStr}\x01${ckStr}`;
151
+ const accs = cellAccumulators.get(cellKey);
152
+ if (accs) {
153
+ const cellValues = [];
154
+ for (let si = 0; si < summaryCount; si++) {
155
+ const val = resolveAccumulator(accs[si], def.summaryFields[si].function);
156
+ cellValues.push(val);
157
+ // Feed row accumulator
158
+ for (const v of accs[si].values)
159
+ feedAccumulator(rowAccs[si], v);
160
+ if (def.summaryFields[si].function === 'count') {
161
+ // For count, feed the raw count
162
+ for (let c = 0; c < accs[si].count; c++)
163
+ feedAccumulator(rowAccs[si], 1);
164
+ }
165
+ if (def.summaryFields[si].function === 'distinctCount') {
166
+ for (const dv of accs[si].distinctValues)
167
+ feedAccumulator(rowAccs[si], dv);
168
+ }
169
+ // Feed column accumulator
170
+ for (const v of accs[si].values)
171
+ feedAccumulator(colAccumulators[ci][si], v);
172
+ if (def.summaryFields[si].function === 'count') {
173
+ for (let c = 0; c < accs[si].count; c++)
174
+ feedAccumulator(colAccumulators[ci][si], 1);
175
+ }
176
+ if (def.summaryFields[si].function === 'distinctCount') {
177
+ for (const dv of accs[si].distinctValues)
178
+ colAccumulators[ci][si].distinctValues.add(dv);
179
+ }
180
+ // Feed grand accumulator
181
+ for (const v of accs[si].values)
182
+ feedAccumulator(grandAccumulators[si], v);
183
+ if (def.summaryFields[si].function === 'count') {
184
+ for (let c = 0; c < accs[si].count; c++)
185
+ feedAccumulator(grandAccumulators[si], 1);
186
+ }
187
+ if (def.summaryFields[si].function === 'distinctCount') {
188
+ for (const dv of accs[si].distinctValues)
189
+ grandAccumulators[si].distinctValues.add(dv);
190
+ }
191
+ }
192
+ rowCells.push(cellValues);
193
+ }
194
+ else {
195
+ rowCells.push(def.summaryFields.map(() => null));
196
+ }
197
+ }
198
+ cells.push(rowCells);
199
+ }
200
+ // ─── Step 4: Compute totals from accumulators ───────────────
201
+ for (let ri = 0; ri < rowKeys.length; ri++) {
202
+ rowTotals.push(def.summaryFields.map((sf, si) => resolveAccumulator(rowAccumulators[ri][si], sf.function)));
203
+ }
204
+ for (let ci = 0; ci < columnKeys.length; ci++) {
205
+ columnTotals[ci] = def.summaryFields.map((sf, si) => resolveAccumulator(colAccumulators[ci][si], sf.function));
206
+ }
207
+ const grandTotals = def.summaryFields.map((sf, si) => resolveAccumulator(grandAccumulators[si], sf.function));
208
+ // ─── Step 5: Suppress empty rows/columns ────────────────────
209
+ let finalRowKeys = rowKeys;
210
+ let finalCells = cells;
211
+ let finalRowTotals = rowTotals;
212
+ let finalColumnKeys = columnKeys;
213
+ let finalColumnTotals = columnTotals;
214
+ if (def.suppressEmptyRows) {
215
+ const nonEmptyRowIndices = [];
216
+ for (let ri = 0; ri < finalRowKeys.length; ri++) {
217
+ const hasData = finalCells[ri].some((col) => col.some((v) => v !== null && v !== 0));
218
+ if (hasData)
219
+ nonEmptyRowIndices.push(ri);
220
+ }
221
+ finalRowKeys = nonEmptyRowIndices.map((i) => finalRowKeys[i]);
222
+ finalCells = nonEmptyRowIndices.map((i) => finalCells[i]);
223
+ finalRowTotals = nonEmptyRowIndices.map((i) => finalRowTotals[i]);
224
+ }
225
+ if (def.suppressEmptyColumns) {
226
+ const nonEmptyColIndices = [];
227
+ for (let ci = 0; ci < finalColumnKeys.length; ci++) {
228
+ const hasData = finalCells.some((row) => row[ci] && row[ci].some((v) => v !== null && v !== 0));
229
+ if (hasData)
230
+ nonEmptyColIndices.push(ci);
231
+ }
232
+ finalColumnKeys = nonEmptyColIndices.map((i) => finalColumnKeys[i]);
233
+ finalCells = finalCells.map((row) => nonEmptyColIndices.map((i) => row[i]));
234
+ finalColumnTotals = nonEmptyColIndices.map((i) => finalColumnTotals[i]);
235
+ }
236
+ // ─── Step 6: Convert to percentages if requested ────────────
237
+ if (def.showAsPercentage) {
238
+ for (let ri = 0; ri < finalCells.length; ri++) {
239
+ for (let ci = 0; ci < finalCells[ri].length; ci++) {
240
+ for (let si = 0; si < summaryCount; si++) {
241
+ const val = finalCells[ri][ci][si];
242
+ if (val !== null && grandTotals[si] !== 0) {
243
+ finalCells[ri][ci][si] = (val / grandTotals[si]) * 100;
244
+ }
245
+ }
246
+ }
247
+ }
248
+ // Also convert row/column totals to percentages
249
+ for (let ri = 0; ri < finalRowTotals.length; ri++) {
250
+ for (let si = 0; si < summaryCount; si++) {
251
+ if (grandTotals[si] !== 0) {
252
+ finalRowTotals[ri][si] =
253
+ (finalRowTotals[ri][si] / grandTotals[si]) * 100;
254
+ }
255
+ }
256
+ }
257
+ for (let ci = 0; ci < finalColumnTotals.length; ci++) {
258
+ for (let si = 0; si < summaryCount; si++) {
259
+ if (grandTotals[si] !== 0) {
260
+ finalColumnTotals[ci][si] =
261
+ (finalColumnTotals[ci][si] / grandTotals[si]) * 100;
262
+ }
263
+ }
264
+ }
265
+ // Grand totals become 100%
266
+ for (let si = 0; si < summaryCount; si++) {
267
+ grandTotals[si] = grandTotals[si] !== 0 ? 100 : 0;
268
+ }
269
+ }
270
+ return {
271
+ rowKeys: finalRowKeys,
272
+ columnKeys: finalColumnKeys,
273
+ cells: finalCells,
274
+ rowTotals: finalRowTotals,
275
+ columnTotals: finalColumnTotals,
276
+ grandTotals,
277
+ };
278
+ }
279
+ // ─── Sort Helper ───────────────────────────────────────────────────
280
+ function sortKeys(keys, direction) {
281
+ return keys.sort((a, b) => {
282
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
283
+ const va = a[i] ?? '';
284
+ const vb = b[i] ?? '';
285
+ // Try numeric comparison
286
+ const na = Number(va);
287
+ const nb = Number(vb);
288
+ if (!isNaN(na) && !isNaN(nb)) {
289
+ if (na !== nb)
290
+ return direction === 'asc' ? na - nb : nb - na;
291
+ }
292
+ else {
293
+ const cmp = va.localeCompare(vb);
294
+ if (cmp !== 0)
295
+ return direction === 'asc' ? cmp : -cmp;
296
+ }
297
+ }
298
+ return 0;
299
+ });
300
+ }
301
+ // ─── HTML Renderer ─────────────────────────────────────────────────
302
+ /**
303
+ * Render a CrossTabResult as an HTML table.
304
+ */
305
+ export function renderCrossTabHtml(def, result, prefix = 'zr') {
306
+ const { rowKeys, columnKeys, cells, rowTotals, columnTotals, grandTotals } = result;
307
+ const summaryCount = def.summaryFields.length;
308
+ const rowFieldCount = def.rowFields.length;
309
+ if (rowKeys.length === 0 && columnKeys.length === 0) {
310
+ return `<div class="${prefix}-crosstab-empty">No data</div>`;
311
+ }
312
+ const headerCss = styleToCssInline(def.headerStyle);
313
+ const dataCss = styleToCssInline(def.dataStyle);
314
+ const totalCss = styleToCssInline(def.totalStyle);
315
+ let html = `<table class="${prefix}-crosstab" data-crosstab-id="${escapeAttr(def.id)}" style="border-collapse:collapse;width:100%;">`;
316
+ // ─── Column header rows ──────────────────────────────────────
317
+ // For multi-level column fields, we render one header row per level
318
+ for (let level = 0; level < def.columnFields.length; level++) {
319
+ html += '<tr>';
320
+ // Empty corner cells (one per row field)
321
+ if (level === 0) {
322
+ for (let rf = 0; rf < rowFieldCount; rf++) {
323
+ const label = def.rowFields[rf].label || def.rowFields[rf].field;
324
+ html += `<th class="${prefix}-ct-corner" rowspan="${def.columnFields.length}" style="${headerCss}border:1px solid #ccc;padding:4px 8px;">${escapeHtml(label)}</th>`;
325
+ }
326
+ }
327
+ // Column headers at this level
328
+ if (def.columnFields.length === 1) {
329
+ // Single level: one header per column * summaryCount
330
+ for (const ck of columnKeys) {
331
+ const colSpan = summaryCount > 1 ? ` colspan="${summaryCount}"` : '';
332
+ html += `<th class="${prefix}-ct-col-header"${colSpan} style="${headerCss}border:1px solid #ccc;padding:4px 8px;text-align:center;">${escapeHtml(ck[level])}</th>`;
333
+ }
334
+ }
335
+ else {
336
+ // Multi-level: group consecutive identical values at this level
337
+ let i = 0;
338
+ while (i < columnKeys.length) {
339
+ const val = columnKeys[i][level];
340
+ let span = 1;
341
+ while (i + span < columnKeys.length &&
342
+ columnKeys[i + span][level] === val) {
343
+ span++;
344
+ }
345
+ const colSpan = span * (level === def.columnFields.length - 1 ? summaryCount : 1);
346
+ const cs = colSpan > 1 ? ` colspan="${colSpan}"` : '';
347
+ html += `<th class="${prefix}-ct-col-header"${cs} style="${headerCss}border:1px solid #ccc;padding:4px 8px;text-align:center;">${escapeHtml(val)}</th>`;
348
+ i += span;
349
+ }
350
+ }
351
+ // Row total header
352
+ if (def.showRowTotals && level === 0) {
353
+ const rs = def.columnFields.length > 1
354
+ ? ` rowspan="${def.columnFields.length}"`
355
+ : '';
356
+ const cs = summaryCount > 1 ? ` colspan="${summaryCount}"` : '';
357
+ html += `<th class="${prefix}-ct-total-header"${rs}${cs} style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:center;font-weight:bold;">Total</th>`;
358
+ }
359
+ html += '</tr>';
360
+ }
361
+ // Summary label row (if multiple summaries)
362
+ if (summaryCount > 1) {
363
+ html += '<tr>';
364
+ // Empty cells for row field columns
365
+ for (let rf = 0; rf < rowFieldCount; rf++) {
366
+ html += `<th style="${headerCss}border:1px solid #ccc;padding:4px 8px;"></th>`;
367
+ }
368
+ for (let ci = 0; ci < columnKeys.length; ci++) {
369
+ for (const sf of def.summaryFields) {
370
+ const label = sf.label || `${sf.function}(${sf.field})`;
371
+ html += `<th class="${prefix}-ct-summary-header" style="${headerCss}border:1px solid #ccc;padding:4px 8px;text-align:center;font-size:0.9em;">${escapeHtml(label)}</th>`;
372
+ }
373
+ }
374
+ if (def.showRowTotals) {
375
+ for (const sf of def.summaryFields) {
376
+ const label = sf.label || `${sf.function}(${sf.field})`;
377
+ html += `<th class="${prefix}-ct-summary-header" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:center;font-size:0.9em;">${escapeHtml(label)}</th>`;
378
+ }
379
+ }
380
+ html += '</tr>';
381
+ }
382
+ // ─── Data rows ───────────────────────────────────────────────
383
+ for (let ri = 0; ri < rowKeys.length; ri++) {
384
+ html += '<tr>';
385
+ // Row header cells (multi-level: merge consecutive identical values)
386
+ for (let rf = 0; rf < rowFieldCount; rf++) {
387
+ // Check if this cell should be merged with the one above
388
+ if (ri > 0 &&
389
+ rowKeys[ri][rf] === rowKeys[ri - 1][rf] &&
390
+ // Only merge if all parent levels also match
391
+ rowKeys[ri].slice(0, rf).every((v, idx) => v === rowKeys[ri - 1][idx])) {
392
+ continue; // Skipped — merged with rowspan above
393
+ }
394
+ // Count how many consecutive rows have the same value (and same parent keys)
395
+ let rowSpan = 1;
396
+ while (ri + rowSpan < rowKeys.length) {
397
+ const next = rowKeys[ri + rowSpan];
398
+ if (next[rf] !== rowKeys[ri][rf])
399
+ break;
400
+ // Check parent levels match
401
+ const parentsMatch = rowKeys[ri]
402
+ .slice(0, rf)
403
+ .every((v, idx) => v === next[idx]);
404
+ if (!parentsMatch)
405
+ break;
406
+ rowSpan++;
407
+ }
408
+ const rs = rowSpan > 1 ? ` rowspan="${rowSpan}"` : '';
409
+ html += `<th class="${prefix}-ct-row-header"${rs} style="${headerCss}border:1px solid #ccc;padding:4px 8px;text-align:left;">${escapeHtml(rowKeys[ri][rf])}</th>`;
410
+ }
411
+ // Data cells
412
+ for (let ci = 0; ci < columnKeys.length; ci++) {
413
+ for (let si = 0; si < summaryCount; si++) {
414
+ const val = cells[ri]?.[ci]?.[si];
415
+ const formatted = formatCellValue(val, def.summaryFields[si], def.showAsPercentage);
416
+ html += `<td class="${prefix}-ct-cell" style="${dataCss}border:1px solid #ccc;padding:4px 8px;text-align:right;">${formatted}</td>`;
417
+ }
418
+ }
419
+ // Row totals
420
+ if (def.showRowTotals) {
421
+ for (let si = 0; si < summaryCount; si++) {
422
+ const val = rowTotals[ri]?.[si] ?? 0;
423
+ const formatted = formatCellValue(val, def.summaryFields[si], def.showAsPercentage);
424
+ html += `<td class="${prefix}-ct-row-total" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:right;font-weight:bold;">${formatted}</td>`;
425
+ }
426
+ }
427
+ html += '</tr>';
428
+ }
429
+ // ─── Column totals row ───────────────────────────────────────
430
+ if (def.showColumnTotals) {
431
+ html += '<tr>';
432
+ // "Total" label spanning all row field columns
433
+ html += `<th class="${prefix}-ct-col-total-label" colspan="${rowFieldCount}" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:left;font-weight:bold;">Total</th>`;
434
+ for (let ci = 0; ci < columnKeys.length; ci++) {
435
+ for (let si = 0; si < summaryCount; si++) {
436
+ const val = columnTotals[ci]?.[si] ?? 0;
437
+ const formatted = formatCellValue(val, def.summaryFields[si], def.showAsPercentage);
438
+ html += `<td class="${prefix}-ct-col-total" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:right;font-weight:bold;">${formatted}</td>`;
439
+ }
440
+ }
441
+ // Grand total
442
+ if (def.showRowTotals && def.showGrandTotal) {
443
+ for (let si = 0; si < summaryCount; si++) {
444
+ const formatted = formatCellValue(grandTotals[si], def.summaryFields[si], def.showAsPercentage);
445
+ html += `<td class="${prefix}-ct-grand-total" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:right;font-weight:bold;">${formatted}</td>`;
446
+ }
447
+ }
448
+ html += '</tr>';
449
+ }
450
+ else if (def.showGrandTotal && def.showRowTotals) {
451
+ // Grand total row even without column totals
452
+ html += '<tr>';
453
+ html += `<th class="${prefix}-ct-grand-label" colspan="${rowFieldCount + columnKeys.length * summaryCount}" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:right;font-weight:bold;">Grand Total</th>`;
454
+ for (let si = 0; si < summaryCount; si++) {
455
+ const formatted = formatCellValue(grandTotals[si], def.summaryFields[si], def.showAsPercentage);
456
+ html += `<td class="${prefix}-ct-grand-total" style="${totalCss}border:1px solid #ccc;padding:4px 8px;text-align:right;font-weight:bold;">${formatted}</td>`;
457
+ }
458
+ html += '</tr>';
459
+ }
460
+ html += '</table>';
461
+ return html;
462
+ }
463
+ // ─── Formatting ────────────────────────────────────────────────────
464
+ function formatCellValue(value, summary, isPercentage) {
465
+ if (value === null)
466
+ return '';
467
+ if (isPercentage) {
468
+ return value.toFixed(1) + '%';
469
+ }
470
+ if (summary.format) {
471
+ return applyFormat(value, summary.format);
472
+ }
473
+ // Default formatting based on function type
474
+ switch (summary.function) {
475
+ case 'count':
476
+ case 'distinctCount':
477
+ return String(Math.round(value));
478
+ case 'avg':
479
+ return value.toFixed(2);
480
+ default:
481
+ // For sum/min/max — use locale formatting if it looks like currency
482
+ return Number.isInteger(value) ? String(value) : value.toFixed(2);
483
+ }
484
+ }
485
+ function applyFormat(value, format) {
486
+ if (format.startsWith('$')) {
487
+ const decimals = (format.match(/\.(\d+)/)?.[1] || '2').length;
488
+ const prefix = format.charAt(0);
489
+ return (prefix +
490
+ value.toLocaleString(undefined, {
491
+ minimumFractionDigits: decimals,
492
+ maximumFractionDigits: decimals,
493
+ }));
494
+ }
495
+ if (format === 'percent') {
496
+ return (value * 100).toFixed(1) + '%';
497
+ }
498
+ if (format.includes('#') || format.includes('0')) {
499
+ const decimals = (format.split('.')[1] || '').length;
500
+ return value.toLocaleString(undefined, {
501
+ minimumFractionDigits: decimals,
502
+ maximumFractionDigits: decimals,
503
+ });
504
+ }
505
+ return String(value);
506
+ }
507
+ // ─── Style Helpers ─────────────────────────────────────────────────
508
+ function styleToCssInline(style) {
509
+ if (!style)
510
+ return '';
511
+ const parts = [];
512
+ if (style.fontFamily)
513
+ parts.push(`font-family:${style.fontFamily}`);
514
+ if (style.fontSize)
515
+ parts.push(`font-size:${style.fontSize}px`);
516
+ if (style.fontWeight)
517
+ parts.push(`font-weight:${style.fontWeight}`);
518
+ if (style.fontStyle)
519
+ parts.push(`font-style:${style.fontStyle}`);
520
+ if (style.textDecoration)
521
+ parts.push(`text-decoration:${style.textDecoration}`);
522
+ if (style.textAlign)
523
+ parts.push(`text-align:${style.textAlign}`);
524
+ if (style.color)
525
+ parts.push(`color:${style.color}`);
526
+ if (style.backgroundColor)
527
+ parts.push(`background-color:${style.backgroundColor}`);
528
+ if (style.padding !== undefined) {
529
+ parts.push(`padding:${typeof style.padding === 'number' ? style.padding + 'px' : style.padding}`);
530
+ }
531
+ return parts.length > 0 ? parts.join(';') + ';' : '';
532
+ }
533
+ // ─── Utilities ─────────────────────────────────────────────────────
534
+ function escapeHtml(str) {
535
+ return str
536
+ .replace(/&/g, '&amp;')
537
+ .replace(/</g, '&lt;')
538
+ .replace(/>/g, '&gt;')
539
+ .replace(/"/g, '&quot;');
540
+ }
541
+ function escapeAttr(str) {
542
+ return str
543
+ .replace(/&/g, '&amp;')
544
+ .replace(/"/g, '&quot;')
545
+ .replace(/'/g, '&#39;')
546
+ .replace(/</g, '&lt;')
547
+ .replace(/>/g, '&gt;');
548
+ }
549
+ //# sourceMappingURL=cross-tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-tab.js","sourceRoot":"","sources":["../../src/engine/cross-tab.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,56 @@
1
1
  import type { BindingContext } from './data-binding.js';
2
+ interface PrintState {
3
+ recordNumber: number;
4
+ groupNumber: number;
5
+ pageNumber: number;
6
+ totalPageCount: number;
7
+ isFirstRecord: boolean;
8
+ isLastRecord: boolean;
9
+ inRepeatedGroupHeader: boolean;
10
+ previousRow?: Record<string, unknown>;
11
+ nextRow?: Record<string, unknown>;
12
+ }
13
+ /** Reset all report variables (call before a new render) */
14
+ export declare function resetReportVariables(): void;
2
15
  /**
3
16
  * Evaluate an expression string with context.
4
17
  *
5
18
  * Supports:
6
19
  * - Field references: {fieldName} or {dataSource.field}
7
20
  * - Function calls: =SUM({qty}), =IF({status}=="paid","PAID","PENDING")
8
- * - Arithmetic: =qty*price
21
+ * - Arithmetic: =qty*price, ={qty}*{price}
22
+ * - String concatenation: ={firstName} & " " & {lastName}
23
+ * - Comparison: ={total} > 1000
24
+ * - Logical: ={active} AND {verified}
25
+ * - Nested calls: =IF({total} > 1000, FORMATCURRENCY({total}, "$", 2), "N/A")
9
26
  * - Aggregate over group: =SUM_GROUP(detail, total)
27
+ * - Variables: =SETVAR("runningTotal", GETVAR("runningTotal") + {amount})
10
28
  */
11
- export declare function evaluateExpression(expr: string, ctx: BindingContext): unknown;
29
+ export declare function evaluateExpression(expr: string, ctx: BindingContext, printState?: Partial<PrintState>): unknown;
30
+ /**
31
+ * Evaluate an expression and return the result as a string.
32
+ * Convenience wrapper for display purposes.
33
+ */
34
+ export declare function evaluateExpressionAsString(expr: string, ctx: BindingContext, printState?: Partial<PrintState>): string;
35
+ /**
36
+ * Validate an expression without evaluating it.
37
+ * Returns null if valid, or an error message if invalid.
38
+ */
39
+ export declare function validateExpression(expr: string): string | null;
40
+ /**
41
+ * Get a list of all field references used in an expression.
42
+ * Useful for dependency analysis and validation in the designer.
43
+ */
44
+ export declare function getExpressionFields(expr: string): string[];
45
+ /**
46
+ * Get a list of all functions used in an expression.
47
+ * Useful for validation in the designer.
48
+ */
49
+ export declare function getExpressionFunctions(expr: string): string[];
50
+ /**
51
+ * Get the full list of available function names.
52
+ * Useful for autocomplete in the designer.
53
+ */
54
+ export declare function getAvailableFunctions(): string[];
55
+ export {};
12
56
  //# sourceMappingURL=expression.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../src/engine/expression.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6DxD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,GAClB,OAAO,CAoDT"}
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../src/engine/expression.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA8YxD,UAAU,UAAU;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAMD,4DAA4D;AAC5D,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAu3BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,EACnB,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC/B,OAAO,CA4BT;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,EACnB,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC/B,MAAM,CAKR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc9D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAU1D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAc7D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD"}