@harbortouch/skytab-analytics-report-utils 0.18.0 → 0.20.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/chunk-7NXZJEGU.js +3340 -0
- package/dist/exporters/exportBuilder.cjs +3503 -0
- package/dist/exporters/exportBuilder.d.cts +56 -0
- package/dist/exporters/exportBuilder.d.ts +56 -0
- package/dist/exporters/exportBuilder.js +246 -0
- package/dist/index.cjs +1557 -9
- package/dist/index.d.cts +5 -1260
- package/dist/index.d.ts +5 -1260
- package/dist/index.js +41 -1750
- package/dist/report-BOL9p86o.d.cts +1291 -0
- package/dist/report-BOL9p86o.d.ts +1291 -0
- package/package.json +9 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { R as ReportType, A as AnalyticsField } from '../report-BOL9p86o.cjs';
|
|
2
|
+
import { E as ExportTable, a as ExportFilter } from '../types-BzLsgnfc.cjs';
|
|
3
|
+
|
|
4
|
+
interface ReportDocumentSection {
|
|
5
|
+
sheetName: string;
|
|
6
|
+
table?: ExportTable;
|
|
7
|
+
filters?: ExportFilter[];
|
|
8
|
+
}
|
|
9
|
+
interface ReportLocation {
|
|
10
|
+
id: number;
|
|
11
|
+
name: string;
|
|
12
|
+
timezone: string;
|
|
13
|
+
language: string;
|
|
14
|
+
currency: string;
|
|
15
|
+
countryCode: string;
|
|
16
|
+
merchantId: string;
|
|
17
|
+
}
|
|
18
|
+
interface ReportParameters {
|
|
19
|
+
compareToLastWeek?: boolean;
|
|
20
|
+
compareToLastYear?: boolean;
|
|
21
|
+
cols?: string[];
|
|
22
|
+
secondGroupBy?: AnalyticsField;
|
|
23
|
+
startDate: string | Date;
|
|
24
|
+
endDate: string | Date;
|
|
25
|
+
groupBy?: AnalyticsField;
|
|
26
|
+
order?: string;
|
|
27
|
+
}
|
|
28
|
+
type ReportData = SingleReportData | Record<string, SingleReportData>;
|
|
29
|
+
type SingleReportData = Record<string, unknown>[];
|
|
30
|
+
declare class ExportBuilder {
|
|
31
|
+
private readonly reportType;
|
|
32
|
+
private readonly locations;
|
|
33
|
+
private readonly locale;
|
|
34
|
+
constructor(reportType: ReportType, locations: ReportLocation[], locale: string);
|
|
35
|
+
private getFormattingConfig;
|
|
36
|
+
private getConfig;
|
|
37
|
+
private getConfigSectionName;
|
|
38
|
+
private translate;
|
|
39
|
+
private buildColumnPrefix;
|
|
40
|
+
private sortAndPrependPrefix;
|
|
41
|
+
private resolveColumns;
|
|
42
|
+
private getColumnHeader;
|
|
43
|
+
private resolveColumnsAndHeaders;
|
|
44
|
+
private formatField;
|
|
45
|
+
private formatRow;
|
|
46
|
+
private resolveLabelField;
|
|
47
|
+
private buildTotalsRow;
|
|
48
|
+
private getExtraFooterRows;
|
|
49
|
+
private renderTableContent;
|
|
50
|
+
private getDataForConfig;
|
|
51
|
+
private formatMaybeDate;
|
|
52
|
+
private buildMetadata;
|
|
53
|
+
getContent(reportData: ReportData, parameters: ReportParameters, name: string): ReportDocumentSection[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { ExportBuilder, type ReportData, type ReportDocumentSection, type ReportLocation, type ReportParameters, type SingleReportData };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { R as ReportType, A as AnalyticsField } from '../report-BOL9p86o.js';
|
|
2
|
+
import { E as ExportTable, a as ExportFilter } from '../types-BzLsgnfc.js';
|
|
3
|
+
|
|
4
|
+
interface ReportDocumentSection {
|
|
5
|
+
sheetName: string;
|
|
6
|
+
table?: ExportTable;
|
|
7
|
+
filters?: ExportFilter[];
|
|
8
|
+
}
|
|
9
|
+
interface ReportLocation {
|
|
10
|
+
id: number;
|
|
11
|
+
name: string;
|
|
12
|
+
timezone: string;
|
|
13
|
+
language: string;
|
|
14
|
+
currency: string;
|
|
15
|
+
countryCode: string;
|
|
16
|
+
merchantId: string;
|
|
17
|
+
}
|
|
18
|
+
interface ReportParameters {
|
|
19
|
+
compareToLastWeek?: boolean;
|
|
20
|
+
compareToLastYear?: boolean;
|
|
21
|
+
cols?: string[];
|
|
22
|
+
secondGroupBy?: AnalyticsField;
|
|
23
|
+
startDate: string | Date;
|
|
24
|
+
endDate: string | Date;
|
|
25
|
+
groupBy?: AnalyticsField;
|
|
26
|
+
order?: string;
|
|
27
|
+
}
|
|
28
|
+
type ReportData = SingleReportData | Record<string, SingleReportData>;
|
|
29
|
+
type SingleReportData = Record<string, unknown>[];
|
|
30
|
+
declare class ExportBuilder {
|
|
31
|
+
private readonly reportType;
|
|
32
|
+
private readonly locations;
|
|
33
|
+
private readonly locale;
|
|
34
|
+
constructor(reportType: ReportType, locations: ReportLocation[], locale: string);
|
|
35
|
+
private getFormattingConfig;
|
|
36
|
+
private getConfig;
|
|
37
|
+
private getConfigSectionName;
|
|
38
|
+
private translate;
|
|
39
|
+
private buildColumnPrefix;
|
|
40
|
+
private sortAndPrependPrefix;
|
|
41
|
+
private resolveColumns;
|
|
42
|
+
private getColumnHeader;
|
|
43
|
+
private resolveColumnsAndHeaders;
|
|
44
|
+
private formatField;
|
|
45
|
+
private formatRow;
|
|
46
|
+
private resolveLabelField;
|
|
47
|
+
private buildTotalsRow;
|
|
48
|
+
private getExtraFooterRows;
|
|
49
|
+
private renderTableContent;
|
|
50
|
+
private getDataForConfig;
|
|
51
|
+
private formatMaybeDate;
|
|
52
|
+
private buildMetadata;
|
|
53
|
+
getContent(reportData: ReportData, parameters: ReportParameters, name: string): ReportDocumentSection[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { ExportBuilder, type ReportData, type ReportDocumentSection, type ReportLocation, type ReportParameters, type SingleReportData };
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import {
|
|
2
|
+
calculateReportTotals,
|
|
3
|
+
en_US_default,
|
|
4
|
+
formatFieldValue,
|
|
5
|
+
getColumnExportHeaderLabel,
|
|
6
|
+
getColumnMetadata,
|
|
7
|
+
getReportConfig,
|
|
8
|
+
getReportFormattingLocaleOptions,
|
|
9
|
+
resolveTranslate
|
|
10
|
+
} from "../chunk-7NXZJEGU.js";
|
|
11
|
+
|
|
12
|
+
// src/exporters/exportBuilder.ts
|
|
13
|
+
import { format, isValid, parseISO } from "date-fns";
|
|
14
|
+
var ExportBuilder = class {
|
|
15
|
+
constructor(reportType, locations, locale) {
|
|
16
|
+
this.reportType = reportType;
|
|
17
|
+
this.locations = locations;
|
|
18
|
+
this.locale = locale;
|
|
19
|
+
}
|
|
20
|
+
getFormattingConfig() {
|
|
21
|
+
const configs = getReportFormattingLocaleOptions(this.locations);
|
|
22
|
+
return configs[0];
|
|
23
|
+
}
|
|
24
|
+
getConfig() {
|
|
25
|
+
return getReportConfig(this.reportType);
|
|
26
|
+
}
|
|
27
|
+
getConfigSectionName(config) {
|
|
28
|
+
return config.sectionName ? this.translate(config.sectionName) : "Unknown section";
|
|
29
|
+
}
|
|
30
|
+
translate(messageKey) {
|
|
31
|
+
return resolveTranslate(messageKey, this.locale);
|
|
32
|
+
}
|
|
33
|
+
buildColumnPrefix(config, parameters) {
|
|
34
|
+
const prefix = [];
|
|
35
|
+
if ("groupByName" in config.fields) {
|
|
36
|
+
prefix.push("groupByName");
|
|
37
|
+
}
|
|
38
|
+
if (parameters.secondGroupBy && "groupByName2" in config.fields) {
|
|
39
|
+
prefix.push("groupByName2");
|
|
40
|
+
}
|
|
41
|
+
return prefix;
|
|
42
|
+
}
|
|
43
|
+
sortAndPrependPrefix(config, parameters, collected) {
|
|
44
|
+
const orderMap = new Map(config.availableColumns.map((col, i) => [col, i]));
|
|
45
|
+
const sorted = [...collected].sort((a, b) => (orderMap.get(a) ?? Infinity) - (orderMap.get(b) ?? Infinity));
|
|
46
|
+
return [...this.buildColumnPrefix(config, parameters), ...sorted];
|
|
47
|
+
}
|
|
48
|
+
resolveColumns(config, parameters) {
|
|
49
|
+
const selectedGroupIds = Array.isArray(parameters.cols) ? parameters.cols : null;
|
|
50
|
+
const compareToLastWeek = parameters.compareToLastWeek === true;
|
|
51
|
+
const compareToLastYear = parameters.compareToLastYear === true;
|
|
52
|
+
if (selectedGroupIds !== null && selectedGroupIds.length === 0) {
|
|
53
|
+
return this.buildColumnPrefix(config, parameters);
|
|
54
|
+
}
|
|
55
|
+
if (selectedGroupIds?.length && config.columnGroups?.length) {
|
|
56
|
+
const collected = [];
|
|
57
|
+
for (const groupId of selectedGroupIds) {
|
|
58
|
+
const group = config.columnGroups.find((g) => g.id === groupId);
|
|
59
|
+
if (!group) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
collected.push(...group.baseFields);
|
|
63
|
+
if (compareToLastWeek && group.lastWeekFields) {
|
|
64
|
+
collected.push(...group.lastWeekFields);
|
|
65
|
+
}
|
|
66
|
+
if (compareToLastYear && group.lastYearFields) {
|
|
67
|
+
collected.push(...group.lastYearFields);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return this.sortAndPrependPrefix(config, parameters, collected);
|
|
71
|
+
}
|
|
72
|
+
if (!selectedGroupIds && config.columnGroups?.length && (compareToLastWeek || compareToLastYear)) {
|
|
73
|
+
const collected = [];
|
|
74
|
+
for (const col of config.defaultVisibleColumns) {
|
|
75
|
+
collected.push(col);
|
|
76
|
+
const group = config.columnGroups.find((g) => g.baseFields.includes(col));
|
|
77
|
+
if (group) {
|
|
78
|
+
if (compareToLastWeek && group.lastWeekFields) {
|
|
79
|
+
collected.push(...group.lastWeekFields);
|
|
80
|
+
}
|
|
81
|
+
if (compareToLastYear && group.lastYearFields) {
|
|
82
|
+
collected.push(...group.lastYearFields);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return this.sortAndPrependPrefix(config, parameters, collected);
|
|
87
|
+
}
|
|
88
|
+
const metricCols = selectedGroupIds?.length ? config.availableColumns.filter((c) => selectedGroupIds.includes(c)) : config.defaultVisibleColumns;
|
|
89
|
+
return [...this.buildColumnPrefix(config, parameters), ...metricCols];
|
|
90
|
+
}
|
|
91
|
+
getColumnHeader(fieldName, config) {
|
|
92
|
+
const columnKey = config.fields[fieldName]?.columnKey;
|
|
93
|
+
const titleKey = columnKey ? getColumnMetadata(columnKey)?.shortTitleKey : void 0;
|
|
94
|
+
const colHeader = titleKey ? this.translate(titleKey) : fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()).trim();
|
|
95
|
+
const group = config.columnGroups?.find(
|
|
96
|
+
(g) => g.baseFields.includes(fieldName) || (g.lastWeekFields?.includes(fieldName) ?? false) || (g.lastYearFields?.includes(fieldName) ?? false)
|
|
97
|
+
);
|
|
98
|
+
return group ? getColumnExportHeaderLabel(colHeader, this.translate(group.headerTranslationKey)) : colHeader;
|
|
99
|
+
}
|
|
100
|
+
resolveColumnsAndHeaders(parameters, config) {
|
|
101
|
+
const columns = this.resolveColumns(config, parameters);
|
|
102
|
+
const headers = columns.map((col) => {
|
|
103
|
+
if (col === "groupByName2" && parameters.secondGroupBy) {
|
|
104
|
+
return this.translate(`analytics.field.${parameters.secondGroupBy}`);
|
|
105
|
+
}
|
|
106
|
+
return this.getColumnHeader(col, config);
|
|
107
|
+
});
|
|
108
|
+
const columnTypes = columns.map((col) => config.fields[col]);
|
|
109
|
+
return { columns, headers, columnTypes };
|
|
110
|
+
}
|
|
111
|
+
formatField(value, config, localeOption, fullRecord) {
|
|
112
|
+
if (!config || value === void 0 || value === null) {
|
|
113
|
+
return "";
|
|
114
|
+
}
|
|
115
|
+
const formatted = formatFieldValue(value, config.type, localeOption, fullRecord, config);
|
|
116
|
+
return typeof formatted === "string" && formatted in en_US_default ? this.translate(formatted) : formatted;
|
|
117
|
+
}
|
|
118
|
+
formatRow(raw, columns, columnTypes, localeConfig, fullRecord) {
|
|
119
|
+
const formatted = {};
|
|
120
|
+
columns.forEach((col, i) => {
|
|
121
|
+
formatted[col] = this.formatField(raw[col], columnTypes[i], localeConfig, fullRecord);
|
|
122
|
+
});
|
|
123
|
+
return formatted;
|
|
124
|
+
}
|
|
125
|
+
resolveLabelField(config, columns) {
|
|
126
|
+
if ("groupByName" in config.fields) {
|
|
127
|
+
return "groupByName";
|
|
128
|
+
}
|
|
129
|
+
const firstStringCol = columns.find((col) => {
|
|
130
|
+
const field = config.fields[col];
|
|
131
|
+
return field?.type === "string" && !field.footerCalculation;
|
|
132
|
+
});
|
|
133
|
+
return firstStringCol ?? columns[0] ?? "groupByName";
|
|
134
|
+
}
|
|
135
|
+
buildTotalsRow(data, config, columns) {
|
|
136
|
+
if (data.length === 0) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const labelField = this.resolveLabelField(config, columns);
|
|
140
|
+
const label = config.totalsLabel ? this.translate(config.totalsLabel) : this.translate("table.total");
|
|
141
|
+
return calculateReportTotals(data, config.fields, { labelField, label });
|
|
142
|
+
}
|
|
143
|
+
getExtraFooterRows(data, config, sectionData, columns) {
|
|
144
|
+
if (config.extraFooterRowsKey) {
|
|
145
|
+
if (!Array.isArray(data)) {
|
|
146
|
+
const rows = data[config.extraFooterRowsKey];
|
|
147
|
+
if (Array.isArray(rows)) {
|
|
148
|
+
return rows;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (config.extraFooterFields?.length && sectionData.length > 0) {
|
|
153
|
+
const labelField = this.resolveLabelField(config, columns);
|
|
154
|
+
const totals = calculateReportTotals(sectionData, config.fields, {
|
|
155
|
+
labelField,
|
|
156
|
+
label: this.translate("table.total")
|
|
157
|
+
});
|
|
158
|
+
const row = { [labelField]: totals[labelField] };
|
|
159
|
+
for (const field of config.extraFooterFields) {
|
|
160
|
+
row[field] = totals[field];
|
|
161
|
+
}
|
|
162
|
+
return [row];
|
|
163
|
+
}
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
renderTableContent(config, reportData, parameters) {
|
|
167
|
+
const localeConfig = this.getFormattingConfig();
|
|
168
|
+
const data = this.getDataForConfig(reportData, config);
|
|
169
|
+
const { columns, headers, columnTypes } = this.resolveColumnsAndHeaders(parameters, config);
|
|
170
|
+
const tableColumns = columns.map((col, i) => ({ header: headers[i], key: col }));
|
|
171
|
+
const rows = data.filter((row) => typeof row === "object" && row !== null).map((row) => this.formatRow(row, columns, columnTypes, localeConfig, row));
|
|
172
|
+
if (config.hasFooter) {
|
|
173
|
+
const totalsRow = this.buildTotalsRow(data, config, columns);
|
|
174
|
+
if (totalsRow) {
|
|
175
|
+
rows.push(this.formatRow(totalsRow, columns, columnTypes, localeConfig, null));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const extraRow of this.getExtraFooterRows(reportData, config, data, columns)) {
|
|
179
|
+
rows.push(this.formatRow(extraRow, columns, columnTypes, localeConfig, extraRow));
|
|
180
|
+
}
|
|
181
|
+
return { table: { columns: tableColumns, rows } };
|
|
182
|
+
}
|
|
183
|
+
getDataForConfig(data, config) {
|
|
184
|
+
if (Array.isArray(data)) {
|
|
185
|
+
return data;
|
|
186
|
+
}
|
|
187
|
+
return config.dataAccessKey ? data[config.dataAccessKey] ?? [] : [];
|
|
188
|
+
}
|
|
189
|
+
formatMaybeDate(value) {
|
|
190
|
+
const date = typeof value === "string" ? parseISO(value) : value;
|
|
191
|
+
if (!isValid(date)) {
|
|
192
|
+
return "";
|
|
193
|
+
}
|
|
194
|
+
return format(date, "yyyy-MM-dd");
|
|
195
|
+
}
|
|
196
|
+
buildMetadata(parameters) {
|
|
197
|
+
const rows = [];
|
|
198
|
+
rows.push([
|
|
199
|
+
this.translate("scheduled-reports.period"),
|
|
200
|
+
`${this.formatMaybeDate(parameters.startDate)} - ${this.formatMaybeDate(parameters.endDate)}`
|
|
201
|
+
]);
|
|
202
|
+
if (parameters.groupBy) {
|
|
203
|
+
rows.push([
|
|
204
|
+
this.translate("components.form.field.group-by"),
|
|
205
|
+
this.translate(`analytics.field.${parameters.groupBy}`)
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
208
|
+
const locationNames = this.locations.map((l) => l.name);
|
|
209
|
+
if (locationNames.length > 0) {
|
|
210
|
+
rows.push([this.translate("common.labels.locations"), locationNames.join(", ")]);
|
|
211
|
+
}
|
|
212
|
+
if (parameters.compareToLastWeek === true) {
|
|
213
|
+
rows.push([this.translate("components.form.field.last-week"), this.translate("common.labels.yes")]);
|
|
214
|
+
}
|
|
215
|
+
if (parameters.compareToLastYear === true) {
|
|
216
|
+
rows.push([this.translate("components.form.field.last-year"), this.translate("common.labels.yes")]);
|
|
217
|
+
}
|
|
218
|
+
return rows;
|
|
219
|
+
}
|
|
220
|
+
getContent(reportData, parameters, name) {
|
|
221
|
+
const rawConfig = this.getConfig();
|
|
222
|
+
if (!rawConfig) {
|
|
223
|
+
throw new Error("Missing report config");
|
|
224
|
+
}
|
|
225
|
+
let sections;
|
|
226
|
+
if (Array.isArray(rawConfig)) {
|
|
227
|
+
sections = rawConfig.map((config) => ({
|
|
228
|
+
sheetName: this.getConfigSectionName(config),
|
|
229
|
+
...this.renderTableContent(config, reportData, parameters)
|
|
230
|
+
}));
|
|
231
|
+
} else {
|
|
232
|
+
const metadata = this.buildMetadata(parameters);
|
|
233
|
+
sections = [
|
|
234
|
+
{
|
|
235
|
+
sheetName: name,
|
|
236
|
+
filters: metadata.map(([label, value]) => ({ label, value })),
|
|
237
|
+
...this.renderTableContent(rawConfig, reportData, parameters)
|
|
238
|
+
}
|
|
239
|
+
];
|
|
240
|
+
}
|
|
241
|
+
return sections;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
export {
|
|
245
|
+
ExportBuilder
|
|
246
|
+
};
|