@harbortouch/skytab-analytics-report-utils 0.41.11 → 0.41.13
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/{chunk-UUKHJDV3.js → chunk-7CBVZY3Y.js} +6 -6
- package/dist/exporters/excel/index.d.cts +2 -2
- package/dist/exporters/excel/index.d.ts +2 -2
- package/dist/exporters/exportBuilder.cjs +10 -7
- package/dist/exporters/exportBuilder.d.cts +1 -1
- package/dist/exporters/exportBuilder.d.ts +1 -1
- package/dist/exporters/exportBuilder.js +5 -2
- package/dist/exporters/pdf/index.cjs +74 -38
- package/dist/exporters/pdf/index.d.cts +2 -1
- package/dist/exporters/pdf/index.d.ts +2 -1
- package/dist/exporters/pdf/index.js +74 -38
- package/dist/index.cjs +6 -6
- package/dist/index.js +1 -1
- package/dist/{types-JAEAu4KX.d.cts → types-D3IyO__4.d.cts} +1 -0
- package/dist/{types-JAEAu4KX.d.ts → types-D3IyO__4.d.ts} +1 -0
- package/package.json +1 -1
|
@@ -2523,16 +2523,16 @@ var FIELDS11 = {
|
|
|
2523
2523
|
groupByName: { type: "string" },
|
|
2524
2524
|
rowType: { type: "string" },
|
|
2525
2525
|
locationName: { type: "string", size: 220, columnKey: "locationName" },
|
|
2526
|
-
employeeName: {
|
|
2527
|
-
empId: {
|
|
2526
|
+
employeeName: {
|
|
2528
2527
|
type: "string",
|
|
2529
|
-
size:
|
|
2530
|
-
columnKey: "
|
|
2528
|
+
size: 220,
|
|
2529
|
+
columnKey: "employeeName",
|
|
2531
2530
|
footerCalculation: { type: "label", label: "table.total" }
|
|
2532
2531
|
},
|
|
2532
|
+
empId: { type: "string", size: 160, columnKey: "employeeId" },
|
|
2533
2533
|
payrollId: { type: "string", size: 160, columnKey: "payrollId" },
|
|
2534
2534
|
jobName: { type: "string", size: 160, columnKey: "employeeJob" },
|
|
2535
|
-
paidNormalHours: { type: "
|
|
2535
|
+
paidNormalHours: { type: "fixedNumber", columnKey: "paidNormalHours", footerCalculation: { type: "sum" } },
|
|
2536
2536
|
normalPay: { type: "money", columnKey: "normalPay", footerCalculation: { type: "sum" } },
|
|
2537
2537
|
overtimePay: { type: "money", columnKey: "overtimePay", footerCalculation: { type: "sum" } },
|
|
2538
2538
|
doubleOvertimePay: { type: "money", columnKey: "doubleOvertimePay", footerCalculation: { type: "sum" } },
|
|
@@ -2569,7 +2569,7 @@ var VISIBLE_COLUMNS3 = [
|
|
|
2569
2569
|
"minimumWageAdjustment",
|
|
2570
2570
|
"totalPay"
|
|
2571
2571
|
];
|
|
2572
|
-
var AVAILABLE_COLUMNS3 = [
|
|
2572
|
+
var AVAILABLE_COLUMNS3 = [...VISIBLE_COLUMNS3];
|
|
2573
2573
|
var payrollConfig = {
|
|
2574
2574
|
fields: FIELDS11,
|
|
2575
2575
|
availableColumns: AVAILABLE_COLUMNS3,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ExportSection } from '../../types-
|
|
2
|
-
export { E as XlsxFilter, b as XlsxTable, c as XlsxTableColumn } from '../../types-
|
|
1
|
+
import { a as ExportSection } from '../../types-D3IyO__4.cjs';
|
|
2
|
+
export { E as XlsxFilter, b as XlsxTable, c as XlsxTableColumn } from '../../types-D3IyO__4.cjs';
|
|
3
3
|
|
|
4
4
|
declare class ExcelExporter {
|
|
5
5
|
generate(content: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ExportSection } from '../../types-
|
|
2
|
-
export { E as XlsxFilter, b as XlsxTable, c as XlsxTableColumn } from '../../types-
|
|
1
|
+
import { a as ExportSection } from '../../types-D3IyO__4.js';
|
|
2
|
+
export { E as XlsxFilter, b as XlsxTable, c as XlsxTableColumn } from '../../types-D3IyO__4.js';
|
|
3
3
|
|
|
4
4
|
declare class ExcelExporter {
|
|
5
5
|
generate(content: {
|
|
@@ -2693,16 +2693,16 @@ var FIELDS11 = {
|
|
|
2693
2693
|
groupByName: { type: "string" },
|
|
2694
2694
|
rowType: { type: "string" },
|
|
2695
2695
|
locationName: { type: "string", size: 220, columnKey: "locationName" },
|
|
2696
|
-
employeeName: {
|
|
2697
|
-
empId: {
|
|
2696
|
+
employeeName: {
|
|
2698
2697
|
type: "string",
|
|
2699
|
-
size:
|
|
2700
|
-
columnKey: "
|
|
2698
|
+
size: 220,
|
|
2699
|
+
columnKey: "employeeName",
|
|
2701
2700
|
footerCalculation: { type: "label", label: "table.total" }
|
|
2702
2701
|
},
|
|
2702
|
+
empId: { type: "string", size: 160, columnKey: "employeeId" },
|
|
2703
2703
|
payrollId: { type: "string", size: 160, columnKey: "payrollId" },
|
|
2704
2704
|
jobName: { type: "string", size: 160, columnKey: "employeeJob" },
|
|
2705
|
-
paidNormalHours: { type: "
|
|
2705
|
+
paidNormalHours: { type: "fixedNumber", columnKey: "paidNormalHours", footerCalculation: { type: "sum" } },
|
|
2706
2706
|
normalPay: { type: "money", columnKey: "normalPay", footerCalculation: { type: "sum" } },
|
|
2707
2707
|
overtimePay: { type: "money", columnKey: "overtimePay", footerCalculation: { type: "sum" } },
|
|
2708
2708
|
doubleOvertimePay: { type: "money", columnKey: "doubleOvertimePay", footerCalculation: { type: "sum" } },
|
|
@@ -2739,7 +2739,7 @@ var VISIBLE_COLUMNS3 = [
|
|
|
2739
2739
|
"minimumWageAdjustment",
|
|
2740
2740
|
"totalPay"
|
|
2741
2741
|
];
|
|
2742
|
-
var AVAILABLE_COLUMNS3 = [
|
|
2742
|
+
var AVAILABLE_COLUMNS3 = [...VISIBLE_COLUMNS3];
|
|
2743
2743
|
var payrollConfig = {
|
|
2744
2744
|
fields: FIELDS11,
|
|
2745
2745
|
availableColumns: AVAILABLE_COLUMNS3,
|
|
@@ -4146,7 +4146,10 @@ var ExportBuilder = class {
|
|
|
4146
4146
|
renderTableContent(config, reportData, parameters) {
|
|
4147
4147
|
const data = this.getDataForConfig(reportData, config);
|
|
4148
4148
|
const { columns, headers, columnTypes } = this.resolveColumnsAndHeaders(parameters, config);
|
|
4149
|
-
const tableColumns = columns.map((col, i) =>
|
|
4149
|
+
const tableColumns = columns.map((col, i) => {
|
|
4150
|
+
const size = config.fields[col]?.size;
|
|
4151
|
+
return { header: headers[i], key: col, ...size !== void 0 ? { size } : {} };
|
|
4152
|
+
});
|
|
4150
4153
|
const rows = data.filter((row) => typeof row === "object" && row !== null).map((row) => this.formatRow(row, columns, columnTypes, row));
|
|
4151
4154
|
if (config.hasFooter) {
|
|
4152
4155
|
const totalsRow = this.buildTotalsRow(data, config);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { R as ReportType, A as AnalyticsField } from '../report-Dj8UU5d_.cjs';
|
|
2
|
-
import { E as ExportFilter, R as ReportMetadata, a as ExportSection } from '../types-
|
|
2
|
+
import { E as ExportFilter, R as ReportMetadata, a as ExportSection } from '../types-D3IyO__4.cjs';
|
|
3
3
|
|
|
4
4
|
declare function resolveRawFiltersToExportFilters(rawFilters: Record<string, (string | number)[] | undefined>, locale: string, reportType?: ReportType): ExportFilter[];
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { R as ReportType, A as AnalyticsField } from '../report-Dj8UU5d_.js';
|
|
2
|
-
import { E as ExportFilter, R as ReportMetadata, a as ExportSection } from '../types-
|
|
2
|
+
import { E as ExportFilter, R as ReportMetadata, a as ExportSection } from '../types-D3IyO__4.js';
|
|
3
3
|
|
|
4
4
|
declare function resolveRawFiltersToExportFilters(rawFilters: Record<string, (string | number)[] | undefined>, locale: string, reportType?: ReportType): ExportFilter[];
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getReportFormattingLocaleOptions,
|
|
9
9
|
getReportName,
|
|
10
10
|
resolveTranslate
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-7CBVZY3Y.js";
|
|
12
12
|
|
|
13
13
|
// src/utils/filter-resolver.ts
|
|
14
14
|
var ANALYTICS_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -197,7 +197,10 @@ var ExportBuilder = class {
|
|
|
197
197
|
renderTableContent(config, reportData, parameters) {
|
|
198
198
|
const data = this.getDataForConfig(reportData, config);
|
|
199
199
|
const { columns, headers, columnTypes } = this.resolveColumnsAndHeaders(parameters, config);
|
|
200
|
-
const tableColumns = columns.map((col, i) =>
|
|
200
|
+
const tableColumns = columns.map((col, i) => {
|
|
201
|
+
const size = config.fields[col]?.size;
|
|
202
|
+
return { header: headers[i], key: col, ...size !== void 0 ? { size } : {} };
|
|
203
|
+
});
|
|
201
204
|
const rows = data.filter((row) => typeof row === "object" && row !== null).map((row) => this.formatRow(row, columns, columnTypes, row));
|
|
202
205
|
if (config.hasFooter) {
|
|
203
206
|
const totalsRow = this.buildTotalsRow(data, config);
|
|
@@ -207,7 +207,14 @@ var PdfExporter = class {
|
|
|
207
207
|
const dataFontSize = columnCount > 13 ? 5 : columnCount > 10 ? 6 : columnCount > 7 ? 7 : 8;
|
|
208
208
|
const headerWidthSlack = 2;
|
|
209
209
|
const headerMinWidths = /* @__PURE__ */ new Map();
|
|
210
|
+
const cssPixelsToPoints = 0.75;
|
|
211
|
+
const boundedColumns = /* @__PURE__ */ new Set();
|
|
210
212
|
columns.forEach((col) => {
|
|
213
|
+
if (col.size !== void 0 && Number.isFinite(col.size) && col.size > 0) {
|
|
214
|
+
col.width = col.size * cssPixelsToPoints;
|
|
215
|
+
boundedColumns.add(col);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
211
218
|
doc.font(FONT_BOLD).fontSize(headerFontSize);
|
|
212
219
|
const headerTextWidth = doc.widthOfString(col.header);
|
|
213
220
|
const headerMinWidth = Math.max(...col.header.split(" ").map((w) => doc.widthOfString(w)));
|
|
@@ -226,49 +233,50 @@ var PdfExporter = class {
|
|
|
226
233
|
headerMinWidths.set(col, headerMinWidth + TABLE_CELL_PADDING * 2 + headerWidthSlack);
|
|
227
234
|
});
|
|
228
235
|
const usableWidth = doc.page.width - doc.page.margins.left - doc.page.margins.right;
|
|
236
|
+
const minimumColumnWidth = Math.min(MIN_COLUMN_WIDTH, usableWidth / columnCount);
|
|
229
237
|
const totalColumnWidth = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
230
238
|
if (totalColumnWidth > usableWidth) {
|
|
231
239
|
const scale = usableWidth / totalColumnWidth;
|
|
232
240
|
columns.forEach((c) => {
|
|
233
|
-
const
|
|
234
|
-
|
|
241
|
+
const width = c.width ?? MIN_COLUMN_WIDTH;
|
|
242
|
+
const headerMin = headerMinWidths.get(c) ?? minimumColumnWidth;
|
|
243
|
+
const minimumWidth = Math.min(width, Math.max(headerMin, minimumColumnWidth));
|
|
244
|
+
c.width = Math.max(Math.floor(width * scale), minimumWidth);
|
|
235
245
|
});
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
246
|
+
const excess = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0) - usableWidth;
|
|
247
|
+
if (excess > 0) {
|
|
248
|
+
const reducibleWidth = columns.reduce(
|
|
249
|
+
(sum, c) => sum + Math.max((c.width ?? MIN_COLUMN_WIDTH) - minimumColumnWidth, 0),
|
|
250
|
+
0
|
|
251
|
+
);
|
|
252
|
+
if (reducibleWidth > 0) {
|
|
253
|
+
columns.forEach((c) => {
|
|
254
|
+
const width = c.width ?? MIN_COLUMN_WIDTH;
|
|
255
|
+
const available = Math.max(width - minimumColumnWidth, 0);
|
|
256
|
+
c.width = width - excess * (available / reducibleWidth);
|
|
257
|
+
});
|
|
244
258
|
}
|
|
245
259
|
}
|
|
246
260
|
} else if (totalColumnWidth < usableWidth) {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
261
|
+
const expandableColumns = columns.filter((c) => !boundedColumns.has(c));
|
|
262
|
+
const expandableWidth = expandableColumns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
263
|
+
if (expandableWidth > 0) {
|
|
264
|
+
const scale = (expandableWidth + usableWidth - totalColumnWidth) / expandableWidth;
|
|
265
|
+
expandableColumns.forEach((c) => {
|
|
266
|
+
c.width = Math.floor((c.width ?? MIN_COLUMN_WIDTH) * scale);
|
|
267
|
+
});
|
|
268
|
+
const expanded = columns.reduce((sum, c) => sum + (c.width ?? 0), 0);
|
|
269
|
+
const lastExpandableColumn = expandableColumns[expandableColumns.length - 1];
|
|
270
|
+
lastExpandableColumn.width = (lastExpandableColumn.width ?? 0) + (usableWidth - expanded);
|
|
271
|
+
}
|
|
253
272
|
}
|
|
254
273
|
const tableWidth = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
255
274
|
const pageBottom = doc.page.height - doc.page.margins.bottom;
|
|
256
|
-
const calculateRowHeight = (
|
|
257
|
-
|
|
258
|
-
doc.
|
|
259
|
-
let maxLines = 1;
|
|
260
|
-
columns.forEach((col) => {
|
|
261
|
-
const cellValue = isHeader ? col.header : row?.[col.key] !== void 0 ? String(row[col.key]) : "";
|
|
262
|
-
const textWidth = doc.widthOfString(cellValue);
|
|
263
|
-
const availableWidth = (col.width ?? MIN_COLUMN_WIDTH) - TABLE_CELL_PADDING * 2;
|
|
264
|
-
const lines = Math.ceil(textWidth / availableWidth);
|
|
265
|
-
if (lines > maxLines) {
|
|
266
|
-
maxLines = lines;
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
return Math.max(maxLines * (fontSize + 2) + TABLE_CELL_PADDING * 2, DEFAULT_ROW_HEIGHT);
|
|
275
|
+
const calculateRowHeight = (isHeader = false) => {
|
|
276
|
+
doc.font(isHeader ? FONT_BOLD : FONT_REGULAR).fontSize(isHeader ? headerFontSize : dataFontSize);
|
|
277
|
+
return Math.max(doc.currentLineHeight(true) + TABLE_CELL_PADDING * 2, DEFAULT_ROW_HEIGHT);
|
|
270
278
|
};
|
|
271
|
-
const headerHeight = calculateRowHeight(
|
|
279
|
+
const headerHeight = calculateRowHeight(true);
|
|
272
280
|
const drawTableHeader = (y) => this.drawHeader(doc, columns, y, tableWidth, headerHeight, TABLE_CELL_PADDING, headerFontSize, MIN_COLUMN_WIDTH);
|
|
273
281
|
let tableStartY = startY;
|
|
274
282
|
if (tableStartY + headerHeight > pageBottom) {
|
|
@@ -278,7 +286,7 @@ var PdfExporter = class {
|
|
|
278
286
|
let currentY = drawTableHeader(tableStartY);
|
|
279
287
|
doc.font(FONT_REGULAR).fontSize(dataFontSize);
|
|
280
288
|
rows.forEach((row, rowIndex) => {
|
|
281
|
-
const currentRowHeight = calculateRowHeight(
|
|
289
|
+
const currentRowHeight = calculateRowHeight();
|
|
282
290
|
if (currentY + currentRowHeight > pageBottom) {
|
|
283
291
|
doc.addPage();
|
|
284
292
|
currentY = drawTableHeader(doc.page.margins.top);
|
|
@@ -301,6 +309,28 @@ var PdfExporter = class {
|
|
|
301
309
|
doc.strokeColor(HEADER_RULE_COLOR).lineWidth(HEADER_RULE_WIDTH).moveTo(left, closingRuleY).lineTo(left + tableWidth, closingRuleY).stroke();
|
|
302
310
|
return closingRuleY;
|
|
303
311
|
}
|
|
312
|
+
truncateTextToWidth(doc, text, availableWidth) {
|
|
313
|
+
if (doc.widthOfString(text) <= availableWidth) {
|
|
314
|
+
return text;
|
|
315
|
+
}
|
|
316
|
+
const ellipsis = "\u2026";
|
|
317
|
+
if (doc.widthOfString(ellipsis) > availableWidth) {
|
|
318
|
+
return "";
|
|
319
|
+
}
|
|
320
|
+
const characters = Array.from(text);
|
|
321
|
+
let low = 0;
|
|
322
|
+
let high = characters.length;
|
|
323
|
+
while (low < high) {
|
|
324
|
+
const middle = Math.ceil((low + high) / 2);
|
|
325
|
+
const candidate = `${characters.slice(0, middle).join("").trimEnd()}${ellipsis}`;
|
|
326
|
+
if (doc.widthOfString(candidate) <= availableWidth) {
|
|
327
|
+
low = middle;
|
|
328
|
+
} else {
|
|
329
|
+
high = middle - 1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return `${characters.slice(0, low).join("").trimEnd()}${ellipsis}`;
|
|
333
|
+
}
|
|
304
334
|
drawHeader(doc, columns, startY, tableWidth, headerHeight, cellPadding, headerFontSize, minColumnWidth) {
|
|
305
335
|
const left = doc.page.margins.left;
|
|
306
336
|
doc.rect(left, startY, tableWidth, headerHeight).fill(HEADER_BACKGROUND_COLOR);
|
|
@@ -310,12 +340,15 @@ var PdfExporter = class {
|
|
|
310
340
|
const headerLineHeight = doc.currentLineHeight(true);
|
|
311
341
|
const headerTextY = startY + Math.max((headerHeight - headerLineHeight) / 2, 0);
|
|
312
342
|
columns.forEach((col) => {
|
|
313
|
-
|
|
314
|
-
|
|
343
|
+
const innerWidth = (col.width ?? minColumnWidth) - cellPadding * 2;
|
|
344
|
+
const bounded = col.size !== void 0 && Number.isFinite(col.size) && col.size > 0;
|
|
345
|
+
const headerText = bounded ? this.truncateTextToWidth(doc, col.header, innerWidth) : col.header;
|
|
346
|
+
doc.text(headerText, xPosition + cellPadding, headerTextY, {
|
|
347
|
+
width: innerWidth,
|
|
315
348
|
height: headerLineHeight,
|
|
316
349
|
align: "left",
|
|
317
350
|
lineBreak: false,
|
|
318
|
-
ellipsis:
|
|
351
|
+
ellipsis: !bounded
|
|
319
352
|
});
|
|
320
353
|
xPosition += col.width ?? minColumnWidth;
|
|
321
354
|
});
|
|
@@ -336,12 +369,15 @@ var PdfExporter = class {
|
|
|
336
369
|
const rawValue = row[col.key];
|
|
337
370
|
const cellValue = typeof rawValue === "string" || typeof rawValue === "number" || typeof rawValue === "boolean" ? String(rawValue) : "";
|
|
338
371
|
const isNumeric = typeof rawValue === "number" || typeof rawValue === "string" && rawValue !== "" && !isNaN(Number(rawValue));
|
|
339
|
-
|
|
340
|
-
|
|
372
|
+
const innerWidth = (col.width ?? minColumnWidth) - cellPadding * 2;
|
|
373
|
+
const bounded = col.size !== void 0 && Number.isFinite(col.size) && col.size > 0;
|
|
374
|
+
const rowText = bounded ? this.truncateTextToWidth(doc, cellValue, innerWidth) : cellValue;
|
|
375
|
+
doc.text(rowText, xPosition + cellPadding, dataTextY, {
|
|
376
|
+
width: innerWidth,
|
|
341
377
|
height: dataLineHeight,
|
|
342
378
|
align: isNumeric ? "right" : "left",
|
|
343
379
|
lineBreak: false,
|
|
344
|
-
ellipsis:
|
|
380
|
+
ellipsis: !bounded
|
|
345
381
|
});
|
|
346
382
|
xPosition += col.width ?? minColumnWidth;
|
|
347
383
|
if (i < columns.length - 1) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ExportSection, E as ExportFilter, b as ExportTable, c as ExportTableColumn } from '../../types-
|
|
1
|
+
import { a as ExportSection, E as ExportFilter, b as ExportTable, c as ExportTableColumn } from '../../types-D3IyO__4.cjs';
|
|
2
2
|
|
|
3
3
|
type MetaDataValue = ExportFilter[] | string;
|
|
4
4
|
declare class PdfExporter {
|
|
@@ -10,6 +10,7 @@ declare class PdfExporter {
|
|
|
10
10
|
drawSectionTitle(doc: PDFKit.PDFDocument, title: string, startY: number): number;
|
|
11
11
|
drawMetaData(doc: PDFKit.PDFDocument, metaData: Record<string, MetaDataValue>, startY: number): number;
|
|
12
12
|
drawTable(doc: PDFKit.PDFDocument, table: ExportTable, startY: number): number;
|
|
13
|
+
private truncateTextToWidth;
|
|
13
14
|
drawHeader(doc: PDFKit.PDFDocument, columns: ExportTableColumn[], startY: number, tableWidth: number, headerHeight: number, cellPadding: number, headerFontSize: number, minColumnWidth: number): number;
|
|
14
15
|
drawRow(doc: PDFKit.PDFDocument, row: Record<string, unknown>, columns: ExportTableColumn[], currentY: number, rowHeight: number, cellPadding: number, dataFontSize: number, minColumnWidth: number, rowIndex?: number): number;
|
|
15
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ExportSection, E as ExportFilter, b as ExportTable, c as ExportTableColumn } from '../../types-
|
|
1
|
+
import { a as ExportSection, E as ExportFilter, b as ExportTable, c as ExportTableColumn } from '../../types-D3IyO__4.js';
|
|
2
2
|
|
|
3
3
|
type MetaDataValue = ExportFilter[] | string;
|
|
4
4
|
declare class PdfExporter {
|
|
@@ -10,6 +10,7 @@ declare class PdfExporter {
|
|
|
10
10
|
drawSectionTitle(doc: PDFKit.PDFDocument, title: string, startY: number): number;
|
|
11
11
|
drawMetaData(doc: PDFKit.PDFDocument, metaData: Record<string, MetaDataValue>, startY: number): number;
|
|
12
12
|
drawTable(doc: PDFKit.PDFDocument, table: ExportTable, startY: number): number;
|
|
13
|
+
private truncateTextToWidth;
|
|
13
14
|
drawHeader(doc: PDFKit.PDFDocument, columns: ExportTableColumn[], startY: number, tableWidth: number, headerHeight: number, cellPadding: number, headerFontSize: number, minColumnWidth: number): number;
|
|
14
15
|
drawRow(doc: PDFKit.PDFDocument, row: Record<string, unknown>, columns: ExportTableColumn[], currentY: number, rowHeight: number, cellPadding: number, dataFontSize: number, minColumnWidth: number, rowIndex?: number): number;
|
|
15
16
|
}
|
|
@@ -167,7 +167,14 @@ var PdfExporter = class {
|
|
|
167
167
|
const dataFontSize = columnCount > 13 ? 5 : columnCount > 10 ? 6 : columnCount > 7 ? 7 : 8;
|
|
168
168
|
const headerWidthSlack = 2;
|
|
169
169
|
const headerMinWidths = /* @__PURE__ */ new Map();
|
|
170
|
+
const cssPixelsToPoints = 0.75;
|
|
171
|
+
const boundedColumns = /* @__PURE__ */ new Set();
|
|
170
172
|
columns.forEach((col) => {
|
|
173
|
+
if (col.size !== void 0 && Number.isFinite(col.size) && col.size > 0) {
|
|
174
|
+
col.width = col.size * cssPixelsToPoints;
|
|
175
|
+
boundedColumns.add(col);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
171
178
|
doc.font(FONT_BOLD).fontSize(headerFontSize);
|
|
172
179
|
const headerTextWidth = doc.widthOfString(col.header);
|
|
173
180
|
const headerMinWidth = Math.max(...col.header.split(" ").map((w) => doc.widthOfString(w)));
|
|
@@ -186,49 +193,50 @@ var PdfExporter = class {
|
|
|
186
193
|
headerMinWidths.set(col, headerMinWidth + TABLE_CELL_PADDING * 2 + headerWidthSlack);
|
|
187
194
|
});
|
|
188
195
|
const usableWidth = doc.page.width - doc.page.margins.left - doc.page.margins.right;
|
|
196
|
+
const minimumColumnWidth = Math.min(MIN_COLUMN_WIDTH, usableWidth / columnCount);
|
|
189
197
|
const totalColumnWidth = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
190
198
|
if (totalColumnWidth > usableWidth) {
|
|
191
199
|
const scale = usableWidth / totalColumnWidth;
|
|
192
200
|
columns.forEach((c) => {
|
|
193
|
-
const
|
|
194
|
-
|
|
201
|
+
const width = c.width ?? MIN_COLUMN_WIDTH;
|
|
202
|
+
const headerMin = headerMinWidths.get(c) ?? minimumColumnWidth;
|
|
203
|
+
const minimumWidth = Math.min(width, Math.max(headerMin, minimumColumnWidth));
|
|
204
|
+
c.width = Math.max(Math.floor(width * scale), minimumWidth);
|
|
195
205
|
});
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
const excess = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0) - usableWidth;
|
|
207
|
+
if (excess > 0) {
|
|
208
|
+
const reducibleWidth = columns.reduce(
|
|
209
|
+
(sum, c) => sum + Math.max((c.width ?? MIN_COLUMN_WIDTH) - minimumColumnWidth, 0),
|
|
210
|
+
0
|
|
211
|
+
);
|
|
212
|
+
if (reducibleWidth > 0) {
|
|
213
|
+
columns.forEach((c) => {
|
|
214
|
+
const width = c.width ?? MIN_COLUMN_WIDTH;
|
|
215
|
+
const available = Math.max(width - minimumColumnWidth, 0);
|
|
216
|
+
c.width = width - excess * (available / reducibleWidth);
|
|
217
|
+
});
|
|
204
218
|
}
|
|
205
219
|
}
|
|
206
220
|
} else if (totalColumnWidth < usableWidth) {
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
221
|
+
const expandableColumns = columns.filter((c) => !boundedColumns.has(c));
|
|
222
|
+
const expandableWidth = expandableColumns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
223
|
+
if (expandableWidth > 0) {
|
|
224
|
+
const scale = (expandableWidth + usableWidth - totalColumnWidth) / expandableWidth;
|
|
225
|
+
expandableColumns.forEach((c) => {
|
|
226
|
+
c.width = Math.floor((c.width ?? MIN_COLUMN_WIDTH) * scale);
|
|
227
|
+
});
|
|
228
|
+
const expanded = columns.reduce((sum, c) => sum + (c.width ?? 0), 0);
|
|
229
|
+
const lastExpandableColumn = expandableColumns[expandableColumns.length - 1];
|
|
230
|
+
lastExpandableColumn.width = (lastExpandableColumn.width ?? 0) + (usableWidth - expanded);
|
|
231
|
+
}
|
|
213
232
|
}
|
|
214
233
|
const tableWidth = columns.reduce((sum, c) => sum + (c.width ?? MIN_COLUMN_WIDTH), 0);
|
|
215
234
|
const pageBottom = doc.page.height - doc.page.margins.bottom;
|
|
216
|
-
const calculateRowHeight = (
|
|
217
|
-
|
|
218
|
-
doc.
|
|
219
|
-
let maxLines = 1;
|
|
220
|
-
columns.forEach((col) => {
|
|
221
|
-
const cellValue = isHeader ? col.header : row?.[col.key] !== void 0 ? String(row[col.key]) : "";
|
|
222
|
-
const textWidth = doc.widthOfString(cellValue);
|
|
223
|
-
const availableWidth = (col.width ?? MIN_COLUMN_WIDTH) - TABLE_CELL_PADDING * 2;
|
|
224
|
-
const lines = Math.ceil(textWidth / availableWidth);
|
|
225
|
-
if (lines > maxLines) {
|
|
226
|
-
maxLines = lines;
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
return Math.max(maxLines * (fontSize + 2) + TABLE_CELL_PADDING * 2, DEFAULT_ROW_HEIGHT);
|
|
235
|
+
const calculateRowHeight = (isHeader = false) => {
|
|
236
|
+
doc.font(isHeader ? FONT_BOLD : FONT_REGULAR).fontSize(isHeader ? headerFontSize : dataFontSize);
|
|
237
|
+
return Math.max(doc.currentLineHeight(true) + TABLE_CELL_PADDING * 2, DEFAULT_ROW_HEIGHT);
|
|
230
238
|
};
|
|
231
|
-
const headerHeight = calculateRowHeight(
|
|
239
|
+
const headerHeight = calculateRowHeight(true);
|
|
232
240
|
const drawTableHeader = (y) => this.drawHeader(doc, columns, y, tableWidth, headerHeight, TABLE_CELL_PADDING, headerFontSize, MIN_COLUMN_WIDTH);
|
|
233
241
|
let tableStartY = startY;
|
|
234
242
|
if (tableStartY + headerHeight > pageBottom) {
|
|
@@ -238,7 +246,7 @@ var PdfExporter = class {
|
|
|
238
246
|
let currentY = drawTableHeader(tableStartY);
|
|
239
247
|
doc.font(FONT_REGULAR).fontSize(dataFontSize);
|
|
240
248
|
rows.forEach((row, rowIndex) => {
|
|
241
|
-
const currentRowHeight = calculateRowHeight(
|
|
249
|
+
const currentRowHeight = calculateRowHeight();
|
|
242
250
|
if (currentY + currentRowHeight > pageBottom) {
|
|
243
251
|
doc.addPage();
|
|
244
252
|
currentY = drawTableHeader(doc.page.margins.top);
|
|
@@ -261,6 +269,28 @@ var PdfExporter = class {
|
|
|
261
269
|
doc.strokeColor(HEADER_RULE_COLOR).lineWidth(HEADER_RULE_WIDTH).moveTo(left, closingRuleY).lineTo(left + tableWidth, closingRuleY).stroke();
|
|
262
270
|
return closingRuleY;
|
|
263
271
|
}
|
|
272
|
+
truncateTextToWidth(doc, text, availableWidth) {
|
|
273
|
+
if (doc.widthOfString(text) <= availableWidth) {
|
|
274
|
+
return text;
|
|
275
|
+
}
|
|
276
|
+
const ellipsis = "\u2026";
|
|
277
|
+
if (doc.widthOfString(ellipsis) > availableWidth) {
|
|
278
|
+
return "";
|
|
279
|
+
}
|
|
280
|
+
const characters = Array.from(text);
|
|
281
|
+
let low = 0;
|
|
282
|
+
let high = characters.length;
|
|
283
|
+
while (low < high) {
|
|
284
|
+
const middle = Math.ceil((low + high) / 2);
|
|
285
|
+
const candidate = `${characters.slice(0, middle).join("").trimEnd()}${ellipsis}`;
|
|
286
|
+
if (doc.widthOfString(candidate) <= availableWidth) {
|
|
287
|
+
low = middle;
|
|
288
|
+
} else {
|
|
289
|
+
high = middle - 1;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return `${characters.slice(0, low).join("").trimEnd()}${ellipsis}`;
|
|
293
|
+
}
|
|
264
294
|
drawHeader(doc, columns, startY, tableWidth, headerHeight, cellPadding, headerFontSize, minColumnWidth) {
|
|
265
295
|
const left = doc.page.margins.left;
|
|
266
296
|
doc.rect(left, startY, tableWidth, headerHeight).fill(HEADER_BACKGROUND_COLOR);
|
|
@@ -270,12 +300,15 @@ var PdfExporter = class {
|
|
|
270
300
|
const headerLineHeight = doc.currentLineHeight(true);
|
|
271
301
|
const headerTextY = startY + Math.max((headerHeight - headerLineHeight) / 2, 0);
|
|
272
302
|
columns.forEach((col) => {
|
|
273
|
-
|
|
274
|
-
|
|
303
|
+
const innerWidth = (col.width ?? minColumnWidth) - cellPadding * 2;
|
|
304
|
+
const bounded = col.size !== void 0 && Number.isFinite(col.size) && col.size > 0;
|
|
305
|
+
const headerText = bounded ? this.truncateTextToWidth(doc, col.header, innerWidth) : col.header;
|
|
306
|
+
doc.text(headerText, xPosition + cellPadding, headerTextY, {
|
|
307
|
+
width: innerWidth,
|
|
275
308
|
height: headerLineHeight,
|
|
276
309
|
align: "left",
|
|
277
310
|
lineBreak: false,
|
|
278
|
-
ellipsis:
|
|
311
|
+
ellipsis: !bounded
|
|
279
312
|
});
|
|
280
313
|
xPosition += col.width ?? minColumnWidth;
|
|
281
314
|
});
|
|
@@ -296,12 +329,15 @@ var PdfExporter = class {
|
|
|
296
329
|
const rawValue = row[col.key];
|
|
297
330
|
const cellValue = typeof rawValue === "string" || typeof rawValue === "number" || typeof rawValue === "boolean" ? String(rawValue) : "";
|
|
298
331
|
const isNumeric = typeof rawValue === "number" || typeof rawValue === "string" && rawValue !== "" && !isNaN(Number(rawValue));
|
|
299
|
-
|
|
300
|
-
|
|
332
|
+
const innerWidth = (col.width ?? minColumnWidth) - cellPadding * 2;
|
|
333
|
+
const bounded = col.size !== void 0 && Number.isFinite(col.size) && col.size > 0;
|
|
334
|
+
const rowText = bounded ? this.truncateTextToWidth(doc, cellValue, innerWidth) : cellValue;
|
|
335
|
+
doc.text(rowText, xPosition + cellPadding, dataTextY, {
|
|
336
|
+
width: innerWidth,
|
|
301
337
|
height: dataLineHeight,
|
|
302
338
|
align: isNumeric ? "right" : "left",
|
|
303
339
|
lineBreak: false,
|
|
304
|
-
ellipsis:
|
|
340
|
+
ellipsis: !bounded
|
|
305
341
|
});
|
|
306
342
|
xPosition += col.width ?? minColumnWidth;
|
|
307
343
|
if (i < columns.length - 1) {
|
package/dist/index.cjs
CHANGED
|
@@ -2601,16 +2601,16 @@ var FIELDS11 = {
|
|
|
2601
2601
|
groupByName: { type: "string" },
|
|
2602
2602
|
rowType: { type: "string" },
|
|
2603
2603
|
locationName: { type: "string", size: 220, columnKey: "locationName" },
|
|
2604
|
-
employeeName: {
|
|
2605
|
-
empId: {
|
|
2604
|
+
employeeName: {
|
|
2606
2605
|
type: "string",
|
|
2607
|
-
size:
|
|
2608
|
-
columnKey: "
|
|
2606
|
+
size: 220,
|
|
2607
|
+
columnKey: "employeeName",
|
|
2609
2608
|
footerCalculation: { type: "label", label: "table.total" }
|
|
2610
2609
|
},
|
|
2610
|
+
empId: { type: "string", size: 160, columnKey: "employeeId" },
|
|
2611
2611
|
payrollId: { type: "string", size: 160, columnKey: "payrollId" },
|
|
2612
2612
|
jobName: { type: "string", size: 160, columnKey: "employeeJob" },
|
|
2613
|
-
paidNormalHours: { type: "
|
|
2613
|
+
paidNormalHours: { type: "fixedNumber", columnKey: "paidNormalHours", footerCalculation: { type: "sum" } },
|
|
2614
2614
|
normalPay: { type: "money", columnKey: "normalPay", footerCalculation: { type: "sum" } },
|
|
2615
2615
|
overtimePay: { type: "money", columnKey: "overtimePay", footerCalculation: { type: "sum" } },
|
|
2616
2616
|
doubleOvertimePay: { type: "money", columnKey: "doubleOvertimePay", footerCalculation: { type: "sum" } },
|
|
@@ -2647,7 +2647,7 @@ var VISIBLE_COLUMNS3 = [
|
|
|
2647
2647
|
"minimumWageAdjustment",
|
|
2648
2648
|
"totalPay"
|
|
2649
2649
|
];
|
|
2650
|
-
var AVAILABLE_COLUMNS3 = [
|
|
2650
|
+
var AVAILABLE_COLUMNS3 = [...VISIBLE_COLUMNS3];
|
|
2651
2651
|
var payrollConfig = {
|
|
2652
2652
|
fields: FIELDS11,
|
|
2653
2653
|
availableColumns: AVAILABLE_COLUMNS3,
|
package/dist/index.js
CHANGED