@quillsql/react 2.16.20 → 2.16.22
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/index.cjs +2591 -179
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +2588 -158
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -263,6 +263,9 @@ var init_valueFormatter = __esm({
|
|
|
263
263
|
maximumFractionDigits: 2
|
|
264
264
|
});
|
|
265
265
|
formatPercent = (value) => {
|
|
266
|
+
if (typeof value === "string" && /^\s*[+-]?(?:\d+(?:\.\d+)?|\.\d+)\s*%\s*$/.test(value)) {
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
266
269
|
return formatterPercent.format(Number(value));
|
|
267
270
|
};
|
|
268
271
|
_getUTCDateHelper = (value, fmt) => {
|
|
@@ -1537,6 +1540,7 @@ var init_dateRangePickerUtils = __esm({
|
|
|
1537
1540
|
}
|
|
1538
1541
|
});
|
|
1539
1542
|
const defaultCustomIntervals = defaultIntervals.flatMap((interval2) => {
|
|
1543
|
+
const normalizedLabel = interval2.label?.toLowerCase().trim();
|
|
1540
1544
|
let createdIntervals = [];
|
|
1541
1545
|
if (interval2.label === "This week") {
|
|
1542
1546
|
createdIntervals = [
|
|
@@ -1686,13 +1690,13 @@ var init_dateRangePickerUtils = __esm({
|
|
|
1686
1690
|
unit: "months"
|
|
1687
1691
|
}
|
|
1688
1692
|
];
|
|
1689
|
-
} else if (
|
|
1693
|
+
} else if (normalizedLabel === "last month") {
|
|
1690
1694
|
createdIntervals = [
|
|
1691
1695
|
{
|
|
1692
1696
|
type: "previous_month"
|
|
1693
1697
|
}
|
|
1694
1698
|
];
|
|
1695
|
-
} else if (
|
|
1699
|
+
} else if (normalizedLabel === "previous quarter" || normalizedLabel === "last quarter") {
|
|
1696
1700
|
createdIntervals = [
|
|
1697
1701
|
{
|
|
1698
1702
|
type: "previous_quarter"
|
|
@@ -2086,13 +2090,13 @@ var init_Filter = __esm({
|
|
|
2086
2090
|
TimeUnit2[TimeUnit2["Hour"] = HOUR] = "Hour";
|
|
2087
2091
|
return TimeUnit2;
|
|
2088
2092
|
})(TimeUnit || {});
|
|
2089
|
-
FieldType = /* @__PURE__ */ ((
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
return
|
|
2093
|
+
FieldType = /* @__PURE__ */ ((FieldType3) => {
|
|
2094
|
+
FieldType3[FieldType3["String"] = STRING] = "String";
|
|
2095
|
+
FieldType3[FieldType3["Number"] = NUMBER] = "Number";
|
|
2096
|
+
FieldType3[FieldType3["Date"] = DATE] = "Date";
|
|
2097
|
+
FieldType3[FieldType3["Null"] = NULL] = "Null";
|
|
2098
|
+
FieldType3[FieldType3["Boolean"] = BOOLEAN] = "Boolean";
|
|
2099
|
+
return FieldType3;
|
|
2096
2100
|
})(FieldType || {});
|
|
2097
2101
|
InternalFilterType = /* @__PURE__ */ ((InternalFilterType2) => {
|
|
2098
2102
|
InternalFilterType2["StringFilter"] = "string-filter";
|
|
@@ -2238,7 +2242,7 @@ var init_Filter = __esm({
|
|
|
2238
2242
|
fieldType = FieldType.Boolean;
|
|
2239
2243
|
operator = filter.operator;
|
|
2240
2244
|
field = filter.field;
|
|
2241
|
-
value =
|
|
2245
|
+
value = filter.value;
|
|
2242
2246
|
table = filter.table;
|
|
2243
2247
|
return {
|
|
2244
2248
|
filterType,
|
|
@@ -2249,7 +2253,7 @@ var init_Filter = __esm({
|
|
|
2249
2253
|
operator
|
|
2250
2254
|
};
|
|
2251
2255
|
case "date" /* Date */:
|
|
2252
|
-
if (typeof filter.value === "object" && filter.value && "
|
|
2256
|
+
if (typeof filter.value === "object" && filter.value && "unit" in filter.value) {
|
|
2253
2257
|
if (filter.value.value && typeof filter.value.value !== "number" || typeof filter.value.unit !== "string") {
|
|
2254
2258
|
throw new Error(
|
|
2255
2259
|
`Invalid value for DateFilter, expected { value: number, unit: string }, got ${filter.value}`
|
|
@@ -2305,7 +2309,7 @@ var init_Filter = __esm({
|
|
|
2305
2309
|
table = filter.table;
|
|
2306
2310
|
} else {
|
|
2307
2311
|
throw new Error(
|
|
2308
|
-
`Invalid value for DateFilter, expected { value
|
|
2312
|
+
`Invalid value for DateFilter, expected { value?: number, unit: string }, { startDate: string, endDate: string}, or string, got ${filter.value}`
|
|
2309
2313
|
);
|
|
2310
2314
|
}
|
|
2311
2315
|
return {
|
|
@@ -15908,7 +15912,7 @@ var init_dataProcessing = __esm({
|
|
|
15908
15912
|
} else {
|
|
15909
15913
|
if (data.dateField && data.dateField.field) {
|
|
15910
15914
|
const dateField = data.dateField.field.replaceAll('"', "");
|
|
15911
|
-
const
|
|
15915
|
+
const maxDate2 = new Date(
|
|
15912
15916
|
data.rows.reduce((acc, row) => {
|
|
15913
15917
|
const rowValue = row[dateField];
|
|
15914
15918
|
if (rowValue) {
|
|
@@ -15917,7 +15921,7 @@ var init_dataProcessing = __esm({
|
|
|
15917
15921
|
return Math.max(acc, 0);
|
|
15918
15922
|
}, 0)
|
|
15919
15923
|
);
|
|
15920
|
-
const
|
|
15924
|
+
const minDate2 = new Date(
|
|
15921
15925
|
data.rows.reduce((acc, row) => {
|
|
15922
15926
|
const rowValue = row[dateField];
|
|
15923
15927
|
if (rowValue) {
|
|
@@ -15927,16 +15931,16 @@ var init_dataProcessing = __esm({
|
|
|
15927
15931
|
}, (/* @__PURE__ */ new Date("3022-01-01")).getTime())
|
|
15928
15932
|
);
|
|
15929
15933
|
const dateBucket = getDateBucketFromRange({
|
|
15930
|
-
start:
|
|
15931
|
-
end:
|
|
15934
|
+
start: minDate2,
|
|
15935
|
+
end: maxDate2
|
|
15932
15936
|
});
|
|
15933
15937
|
const minDateBucket = getDateString(
|
|
15934
|
-
|
|
15938
|
+
minDate2.toISOString(),
|
|
15935
15939
|
void 0,
|
|
15936
15940
|
dateBucket
|
|
15937
15941
|
);
|
|
15938
15942
|
const maxDateBucket = getDateString(
|
|
15939
|
-
|
|
15943
|
+
maxDate2.toISOString(),
|
|
15940
15944
|
void 0,
|
|
15941
15945
|
dateBucket
|
|
15942
15946
|
);
|
|
@@ -16053,8 +16057,9 @@ async function generatePivotWithSQL({
|
|
|
16053
16057
|
getPivotRowCount = true,
|
|
16054
16058
|
caller,
|
|
16055
16059
|
getToken,
|
|
16056
|
-
reportBuilderState
|
|
16060
|
+
reportBuilderState,
|
|
16057
16061
|
// Add reportBuilderState parameter
|
|
16062
|
+
overwriteCache = false
|
|
16058
16063
|
}) {
|
|
16059
16064
|
const databaseType = client.databaseType || "postgresql";
|
|
16060
16065
|
if (!pivot.aggregations?.length && pivot.aggregationType) {
|
|
@@ -16103,7 +16108,8 @@ async function generatePivotWithSQL({
|
|
|
16103
16108
|
})),
|
|
16104
16109
|
// Only pass dashboard filters in Dashboard context, not ReportBuilder
|
|
16105
16110
|
tenants,
|
|
16106
|
-
additionalProcessing
|
|
16111
|
+
additionalProcessing,
|
|
16112
|
+
overwriteCache
|
|
16107
16113
|
},
|
|
16108
16114
|
getToken
|
|
16109
16115
|
});
|
|
@@ -16277,8 +16283,9 @@ async function generatePivotTable({
|
|
|
16277
16283
|
additionalProcessing,
|
|
16278
16284
|
caller,
|
|
16279
16285
|
pivotQuery,
|
|
16280
|
-
reportBuilderState
|
|
16286
|
+
reportBuilderState,
|
|
16281
16287
|
// Add reportBuilderState parameter
|
|
16288
|
+
overwriteCache
|
|
16282
16289
|
}) {
|
|
16283
16290
|
try {
|
|
16284
16291
|
if (report && client) {
|
|
@@ -16295,8 +16302,9 @@ async function generatePivotTable({
|
|
|
16295
16302
|
additionalProcessing,
|
|
16296
16303
|
caller,
|
|
16297
16304
|
getToken,
|
|
16298
|
-
reportBuilderState
|
|
16305
|
+
reportBuilderState,
|
|
16299
16306
|
// Pass reportBuilderState
|
|
16307
|
+
overwriteCache
|
|
16300
16308
|
});
|
|
16301
16309
|
return pivotTable;
|
|
16302
16310
|
}
|
|
@@ -18182,7 +18190,7 @@ var init_tableProcessing = __esm({
|
|
|
18182
18190
|
try {
|
|
18183
18191
|
let data;
|
|
18184
18192
|
if (reportBuilderState) {
|
|
18185
|
-
|
|
18193
|
+
({ data } = await quillFetch({
|
|
18186
18194
|
client,
|
|
18187
18195
|
task: "report-builder-counts",
|
|
18188
18196
|
metadata: {
|
|
@@ -18196,9 +18204,9 @@ var init_tableProcessing = __esm({
|
|
|
18196
18204
|
tenants
|
|
18197
18205
|
},
|
|
18198
18206
|
getToken
|
|
18199
|
-
});
|
|
18207
|
+
}));
|
|
18200
18208
|
} else {
|
|
18201
|
-
|
|
18209
|
+
({ data } = await quillFetch({
|
|
18202
18210
|
client,
|
|
18203
18211
|
task: "query",
|
|
18204
18212
|
metadata: {
|
|
@@ -18212,7 +18220,7 @@ var init_tableProcessing = __esm({
|
|
|
18212
18220
|
},
|
|
18213
18221
|
urlParameters: `caller=getCounts&task=query`,
|
|
18214
18222
|
getToken
|
|
18215
|
-
});
|
|
18223
|
+
}));
|
|
18216
18224
|
}
|
|
18217
18225
|
if (data.errorMessage) {
|
|
18218
18226
|
return { filteredColumns: columns, exceededColumns: void 0 };
|
|
@@ -19202,9 +19210,9 @@ var init_dataFetcher = __esm({
|
|
|
19202
19210
|
return { error: "Failed to fetch data" };
|
|
19203
19211
|
}
|
|
19204
19212
|
};
|
|
19205
|
-
parseFetchResponse = async (client, task, response, getToken) => {
|
|
19213
|
+
parseFetchResponse = async (client, task, response, getToken, useInMemory = false) => {
|
|
19206
19214
|
try {
|
|
19207
|
-
if (response.status === "error" || response.data?.error) {
|
|
19215
|
+
if (response.status === "error" || response.data?.error && !useInMemory) {
|
|
19208
19216
|
let errorPrefix = "Error: ";
|
|
19209
19217
|
let errorMessage = "Failed to fetch report: " + (response.error || response.data?.error);
|
|
19210
19218
|
if (task === "query" || task === "report-builder") {
|
|
@@ -19817,7 +19825,8 @@ async function cleanDashboardItem({
|
|
|
19817
19825
|
additionalProcessing,
|
|
19818
19826
|
customFields,
|
|
19819
19827
|
skipPivotFetch,
|
|
19820
|
-
tenants
|
|
19828
|
+
tenants,
|
|
19829
|
+
overwriteCache
|
|
19821
19830
|
}) {
|
|
19822
19831
|
if (!item) return defaultDashboardItem;
|
|
19823
19832
|
if (!item.rows) {
|
|
@@ -19873,11 +19882,12 @@ async function cleanDashboardItem({
|
|
|
19873
19882
|
page: DEFAULT_PAGINATION
|
|
19874
19883
|
};
|
|
19875
19884
|
if (item.pivot && skipPivotFetch && item.rows && item.fields) {
|
|
19885
|
+
const pivotSourceRows = item.rows.map((row) => ({ ...row }));
|
|
19876
19886
|
const dateFilter = dashboardFilters?.find(
|
|
19877
19887
|
(filter) => filter.filterType === "date_range"
|
|
19878
19888
|
);
|
|
19879
19889
|
pivotTable = processPivotData({
|
|
19880
|
-
rows:
|
|
19890
|
+
rows: pivotSourceRows,
|
|
19881
19891
|
fields: item.fields,
|
|
19882
19892
|
pivot: {
|
|
19883
19893
|
...item.pivot,
|
|
@@ -19921,7 +19931,8 @@ async function cleanDashboardItem({
|
|
|
19921
19931
|
dateBucket,
|
|
19922
19932
|
shouldPaginatePivotAsTable ? additionalProcessing : pivotChartProcessing,
|
|
19923
19933
|
tenants,
|
|
19924
|
-
customFields
|
|
19934
|
+
customFields,
|
|
19935
|
+
overwriteCache
|
|
19925
19936
|
);
|
|
19926
19937
|
}
|
|
19927
19938
|
} catch (e) {
|
|
@@ -20026,7 +20037,7 @@ async function cleanDashboardItem({
|
|
|
20026
20037
|
referenceLines: item.referenceLines
|
|
20027
20038
|
};
|
|
20028
20039
|
}
|
|
20029
|
-
async function getPivotTable(report, dashboardFilters, dashboardName, getToken, client, eventTracking, dateBucketInitial, additionalProcessing, tenants, customFields) {
|
|
20040
|
+
async function getPivotTable(report, dashboardFilters, dashboardName, getToken, client, eventTracking, dateBucketInitial, additionalProcessing, tenants, customFields, overwriteCache) {
|
|
20030
20041
|
if (!report) return void 0;
|
|
20031
20042
|
const dateFilter = Object.values(dashboardFilters ?? {}).find(
|
|
20032
20043
|
(filter) => filter.filterType === "date_range" || filter.operator === "BETWEEN"
|
|
@@ -20094,7 +20105,8 @@ async function getPivotTable(report, dashboardFilters, dashboardName, getToken,
|
|
|
20094
20105
|
dashboardFilters,
|
|
20095
20106
|
tenants,
|
|
20096
20107
|
additionalProcessing,
|
|
20097
|
-
getToken
|
|
20108
|
+
getToken,
|
|
20109
|
+
overwriteCache
|
|
20098
20110
|
});
|
|
20099
20111
|
return pivotTable;
|
|
20100
20112
|
} catch (e) {
|
|
@@ -20342,7 +20354,8 @@ async function fetchReportRows({
|
|
|
20342
20354
|
filters = [],
|
|
20343
20355
|
getToken,
|
|
20344
20356
|
abortSignal,
|
|
20345
|
-
additionalProcessing
|
|
20357
|
+
additionalProcessing,
|
|
20358
|
+
overwriteCache = false
|
|
20346
20359
|
}) {
|
|
20347
20360
|
const fetchResp = await quillFetch({
|
|
20348
20361
|
client,
|
|
@@ -20354,7 +20367,8 @@ async function fetchReportRows({
|
|
|
20354
20367
|
filters: filters.map((filter) => ({ ...filter, options: void 0 })),
|
|
20355
20368
|
useNewNodeSql: true,
|
|
20356
20369
|
tenants,
|
|
20357
|
-
additionalProcessing
|
|
20370
|
+
additionalProcessing,
|
|
20371
|
+
overwriteCache
|
|
20358
20372
|
},
|
|
20359
20373
|
abortSignal,
|
|
20360
20374
|
getToken
|
|
@@ -20385,7 +20399,8 @@ async function fetchReport({
|
|
|
20385
20399
|
abortSignal,
|
|
20386
20400
|
getToken,
|
|
20387
20401
|
eventTracking,
|
|
20388
|
-
usePivotTask = false
|
|
20402
|
+
usePivotTask = false,
|
|
20403
|
+
overwriteCache = false
|
|
20389
20404
|
}) {
|
|
20390
20405
|
let reportInfo = void 0;
|
|
20391
20406
|
let errorMessage = void 0;
|
|
@@ -20405,7 +20420,8 @@ async function fetchReport({
|
|
|
20405
20420
|
rowsOnly,
|
|
20406
20421
|
rowCountOnly,
|
|
20407
20422
|
tenants,
|
|
20408
|
-
flags
|
|
20423
|
+
flags,
|
|
20424
|
+
overwriteCache
|
|
20409
20425
|
},
|
|
20410
20426
|
abortSignal,
|
|
20411
20427
|
getToken
|
|
@@ -20426,7 +20442,9 @@ async function fetchReport({
|
|
|
20426
20442
|
getToken,
|
|
20427
20443
|
eventTracking,
|
|
20428
20444
|
tenants,
|
|
20429
|
-
|
|
20445
|
+
// When not using pivot-template, avoid fallback pivot-template fetches.
|
|
20446
|
+
skipPivotFetch: !usePivotTask,
|
|
20447
|
+
overwriteCache
|
|
20430
20448
|
});
|
|
20431
20449
|
} catch (error) {
|
|
20432
20450
|
if (error instanceof Error && error.name === "AbortError") {
|
|
@@ -20476,7 +20494,8 @@ async function processReportResponse({
|
|
|
20476
20494
|
getToken,
|
|
20477
20495
|
eventTracking,
|
|
20478
20496
|
tenants,
|
|
20479
|
-
skipPivotFetch = false
|
|
20497
|
+
skipPivotFetch = false,
|
|
20498
|
+
overwriteCache
|
|
20480
20499
|
}) {
|
|
20481
20500
|
const shouldSkipPivotFetch = skipPivotFetch || !!resp?.pivotRows && !!resp?.fields;
|
|
20482
20501
|
const dashboardItem = {
|
|
@@ -20509,7 +20528,8 @@ async function processReportResponse({
|
|
|
20509
20528
|
getToken,
|
|
20510
20529
|
tenants,
|
|
20511
20530
|
eventTracking,
|
|
20512
|
-
skipPivotFetch: shouldSkipPivotFetch
|
|
20531
|
+
skipPivotFetch: shouldSkipPivotFetch,
|
|
20532
|
+
overwriteCache
|
|
20513
20533
|
});
|
|
20514
20534
|
if (additionalProcessing) {
|
|
20515
20535
|
reportInfo.pagination = additionalProcessing.page;
|
|
@@ -21586,6 +21606,1934 @@ async function getClientTenantIds({
|
|
|
21586
21606
|
|
|
21587
21607
|
// src/Context.tsx
|
|
21588
21608
|
init_columnProcessing();
|
|
21609
|
+
|
|
21610
|
+
// src/utils/cacheCab.ts
|
|
21611
|
+
init_dataFetcher();
|
|
21612
|
+
|
|
21613
|
+
// src/utils/inMemoryFilterEngine.ts
|
|
21614
|
+
init_Filter();
|
|
21615
|
+
var import_date_fns8 = require("date-fns");
|
|
21616
|
+
init_dateRangePickerUtils();
|
|
21617
|
+
var UNSET = Symbol("unset");
|
|
21618
|
+
var isFilter = (f) => {
|
|
21619
|
+
return f && typeof f === "object" && "filterType" in f && !("id" in f);
|
|
21620
|
+
};
|
|
21621
|
+
var isDashboardFilterUpdate = (f) => {
|
|
21622
|
+
return f && typeof f === "object" && "label" in f;
|
|
21623
|
+
};
|
|
21624
|
+
var normalizeFilterString = (value) => value.replaceAll("%", "").toLowerCase();
|
|
21625
|
+
var normalizeRowString = (value) => value.toLowerCase();
|
|
21626
|
+
var resolveFieldKeys = (field, table, resolver) => {
|
|
21627
|
+
if (!field) return [];
|
|
21628
|
+
const resolved = resolver?.(field, table);
|
|
21629
|
+
if (Array.isArray(resolved)) return resolved;
|
|
21630
|
+
if (typeof resolved === "string") return [resolved];
|
|
21631
|
+
return [field];
|
|
21632
|
+
};
|
|
21633
|
+
var getRowValue = (row, fieldKeys, cache) => {
|
|
21634
|
+
if (fieldKeys.length === 0) return void 0;
|
|
21635
|
+
const cacheKey = fieldKeys.join("|");
|
|
21636
|
+
if (Object.prototype.hasOwnProperty.call(cache, cacheKey)) {
|
|
21637
|
+
return cache[cacheKey];
|
|
21638
|
+
}
|
|
21639
|
+
for (const key of fieldKeys) {
|
|
21640
|
+
if (Object.prototype.hasOwnProperty.call(row, key)) {
|
|
21641
|
+
cache[cacheKey] = row[key];
|
|
21642
|
+
return row[key];
|
|
21643
|
+
}
|
|
21644
|
+
}
|
|
21645
|
+
cache[cacheKey] = void 0;
|
|
21646
|
+
return void 0;
|
|
21647
|
+
};
|
|
21648
|
+
var coerceNumber = (value) => {
|
|
21649
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
21650
|
+
if (typeof value === "string" && value !== "") {
|
|
21651
|
+
const parsed = Number(value);
|
|
21652
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
21653
|
+
}
|
|
21654
|
+
return null;
|
|
21655
|
+
};
|
|
21656
|
+
var coerceBoolean = (value) => {
|
|
21657
|
+
if (typeof value === "boolean") return value;
|
|
21658
|
+
if (typeof value === "number") return value !== 0;
|
|
21659
|
+
if (typeof value === "string") {
|
|
21660
|
+
const normalized = value.toLowerCase();
|
|
21661
|
+
if (normalized === "true" || normalized === "1") return true;
|
|
21662
|
+
if (normalized === "false" || normalized === "0") return false;
|
|
21663
|
+
}
|
|
21664
|
+
return null;
|
|
21665
|
+
};
|
|
21666
|
+
var toDateMs = (value) => {
|
|
21667
|
+
if (value instanceof Date) {
|
|
21668
|
+
return (0, import_date_fns8.isValid)(value) ? value.getTime() : null;
|
|
21669
|
+
}
|
|
21670
|
+
if (typeof value === "number") {
|
|
21671
|
+
const date = new Date(value);
|
|
21672
|
+
return (0, import_date_fns8.isValid)(date) ? date.getTime() : null;
|
|
21673
|
+
}
|
|
21674
|
+
if (typeof value === "string") {
|
|
21675
|
+
const date = new Date(value);
|
|
21676
|
+
return (0, import_date_fns8.isValid)(date) ? date.getTime() : null;
|
|
21677
|
+
}
|
|
21678
|
+
return null;
|
|
21679
|
+
};
|
|
21680
|
+
var buildColumnTypeMap = (columns) => {
|
|
21681
|
+
if (!columns?.length) return null;
|
|
21682
|
+
const map = /* @__PURE__ */ Object.create(null);
|
|
21683
|
+
for (const column of columns) {
|
|
21684
|
+
map[column.field] = column.jsType;
|
|
21685
|
+
}
|
|
21686
|
+
return map;
|
|
21687
|
+
};
|
|
21688
|
+
var resolveDashboardField = (filter, options) => {
|
|
21689
|
+
const mapped = options.filterMap?.[filter.label];
|
|
21690
|
+
if (mapped?.field) {
|
|
21691
|
+
return { field: mapped.field, table: mapped.table };
|
|
21692
|
+
}
|
|
21693
|
+
if (filter.filterType === "date_range" /* Date */ && options.dateField?.field) {
|
|
21694
|
+
return { field: options.dateField.field, table: options.dateField.table };
|
|
21695
|
+
}
|
|
21696
|
+
if (filter.field) {
|
|
21697
|
+
return { field: filter.field, table: filter.table };
|
|
21698
|
+
}
|
|
21699
|
+
return null;
|
|
21700
|
+
};
|
|
21701
|
+
var buildRelativeDateRange = (operator, value, now2, weekStartsOn) => {
|
|
21702
|
+
const amount = value.value || 1;
|
|
21703
|
+
const unit = value.unit;
|
|
21704
|
+
const currentStart = (() => {
|
|
21705
|
+
switch (unit) {
|
|
21706
|
+
case TimeUnit.Hour:
|
|
21707
|
+
return (0, import_date_fns8.startOfHour)(now2);
|
|
21708
|
+
case TimeUnit.Day:
|
|
21709
|
+
return (0, import_date_fns8.startOfDay)(now2);
|
|
21710
|
+
case TimeUnit.Week:
|
|
21711
|
+
return (0, import_date_fns8.startOfWeek)(now2, { weekStartsOn });
|
|
21712
|
+
case TimeUnit.Month:
|
|
21713
|
+
return (0, import_date_fns8.startOfMonth)(now2);
|
|
21714
|
+
case TimeUnit.Quarter:
|
|
21715
|
+
return (0, import_date_fns8.startOfQuarter)(now2);
|
|
21716
|
+
case TimeUnit.Year:
|
|
21717
|
+
return (0, import_date_fns8.startOfYear)(now2);
|
|
21718
|
+
default:
|
|
21719
|
+
return (0, import_date_fns8.startOfDay)(now2);
|
|
21720
|
+
}
|
|
21721
|
+
})();
|
|
21722
|
+
const addUnit = (base, multiplier) => {
|
|
21723
|
+
switch (unit) {
|
|
21724
|
+
case TimeUnit.Hour:
|
|
21725
|
+
return (0, import_date_fns8.addHours)(base, multiplier);
|
|
21726
|
+
case TimeUnit.Day:
|
|
21727
|
+
return (0, import_date_fns8.addDays)(base, multiplier);
|
|
21728
|
+
case TimeUnit.Week:
|
|
21729
|
+
return (0, import_date_fns8.addWeeks)(base, multiplier);
|
|
21730
|
+
case TimeUnit.Month:
|
|
21731
|
+
return (0, import_date_fns8.addMonths)(base, multiplier);
|
|
21732
|
+
case TimeUnit.Quarter:
|
|
21733
|
+
return (0, import_date_fns8.addMonths)(base, multiplier * 3);
|
|
21734
|
+
case TimeUnit.Year:
|
|
21735
|
+
return (0, import_date_fns8.addYears)(base, multiplier);
|
|
21736
|
+
default:
|
|
21737
|
+
return (0, import_date_fns8.addDays)(base, multiplier);
|
|
21738
|
+
}
|
|
21739
|
+
};
|
|
21740
|
+
const subUnit = (base, multiplier) => {
|
|
21741
|
+
switch (unit) {
|
|
21742
|
+
case TimeUnit.Hour:
|
|
21743
|
+
return (0, import_date_fns8.subHours)(base, multiplier);
|
|
21744
|
+
case TimeUnit.Day:
|
|
21745
|
+
return (0, import_date_fns8.subDays)(base, multiplier);
|
|
21746
|
+
case TimeUnit.Week:
|
|
21747
|
+
return (0, import_date_fns8.subWeeks)(base, multiplier);
|
|
21748
|
+
case TimeUnit.Month:
|
|
21749
|
+
return (0, import_date_fns8.subMonths)(base, multiplier);
|
|
21750
|
+
case TimeUnit.Quarter:
|
|
21751
|
+
return (0, import_date_fns8.subMonths)(base, multiplier * 3);
|
|
21752
|
+
case TimeUnit.Year:
|
|
21753
|
+
return (0, import_date_fns8.subYears)(base, multiplier);
|
|
21754
|
+
default:
|
|
21755
|
+
return (0, import_date_fns8.subDays)(base, multiplier);
|
|
21756
|
+
}
|
|
21757
|
+
};
|
|
21758
|
+
switch (operator) {
|
|
21759
|
+
case DateOperator.InTheLast: {
|
|
21760
|
+
const start2 = subUnit(now2, amount);
|
|
21761
|
+
return { start: start2.getTime() };
|
|
21762
|
+
}
|
|
21763
|
+
case DateOperator.InThePrevious: {
|
|
21764
|
+
const start2 = subUnit(currentStart, amount);
|
|
21765
|
+
return { start: start2.getTime(), end: currentStart.getTime(), endExclusive: true };
|
|
21766
|
+
}
|
|
21767
|
+
case DateOperator.InTheCurrent: {
|
|
21768
|
+
const end = addUnit(currentStart, 1);
|
|
21769
|
+
return {
|
|
21770
|
+
start: currentStart.getTime(),
|
|
21771
|
+
end: end.getTime(),
|
|
21772
|
+
endExclusive: true
|
|
21773
|
+
};
|
|
21774
|
+
}
|
|
21775
|
+
default:
|
|
21776
|
+
return null;
|
|
21777
|
+
}
|
|
21778
|
+
};
|
|
21779
|
+
var buildStringPredicate = (operator, value, fieldKeys) => {
|
|
21780
|
+
if (value === void 0 || value === null) return null;
|
|
21781
|
+
const normalizedValue = Array.isArray(value) ? value.map((v) => normalizeFilterString(String(v))) : normalizeFilterString(String(value));
|
|
21782
|
+
if (Array.isArray(normalizedValue)) {
|
|
21783
|
+
if (normalizedValue.length === 0) return null;
|
|
21784
|
+
} else if (normalizedValue === "") {
|
|
21785
|
+
return null;
|
|
21786
|
+
}
|
|
21787
|
+
if (operator === StringOperator.Is || operator === StringOperator.IsNot) {
|
|
21788
|
+
const values = Array.isArray(normalizedValue) ? normalizedValue : [normalizedValue];
|
|
21789
|
+
const valueSet = new Set(values);
|
|
21790
|
+
return (row, cache) => {
|
|
21791
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21792
|
+
if (rowValue === null || rowValue === void 0) return false;
|
|
21793
|
+
const normalized = normalizeRowString(String(rowValue));
|
|
21794
|
+
const hasValue = valueSet.has(normalized);
|
|
21795
|
+
return operator === StringOperator.Is ? hasValue : !hasValue;
|
|
21796
|
+
};
|
|
21797
|
+
}
|
|
21798
|
+
if (Array.isArray(normalizedValue)) {
|
|
21799
|
+
return null;
|
|
21800
|
+
}
|
|
21801
|
+
return (row, cache) => {
|
|
21802
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21803
|
+
if (rowValue === null || rowValue === void 0) return false;
|
|
21804
|
+
const normalizedRow = normalizeRowString(String(rowValue));
|
|
21805
|
+
switch (operator) {
|
|
21806
|
+
case StringOperator.IsExactly:
|
|
21807
|
+
return normalizedRow === normalizedValue;
|
|
21808
|
+
case StringOperator.IsNotExactly:
|
|
21809
|
+
return normalizedRow !== normalizedValue;
|
|
21810
|
+
case StringOperator.Contains:
|
|
21811
|
+
return normalizedRow.includes(normalizedValue);
|
|
21812
|
+
default:
|
|
21813
|
+
return false;
|
|
21814
|
+
}
|
|
21815
|
+
};
|
|
21816
|
+
};
|
|
21817
|
+
var buildNumericPredicate = (operator, value, fieldKeys) => {
|
|
21818
|
+
const filterValue = coerceNumber(value);
|
|
21819
|
+
if (filterValue === null) return null;
|
|
21820
|
+
return (row, cache) => {
|
|
21821
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21822
|
+
const parsed = coerceNumber(rowValue);
|
|
21823
|
+
if (parsed === null) return false;
|
|
21824
|
+
switch (operator) {
|
|
21825
|
+
case NumberOperator.EqualTo:
|
|
21826
|
+
return parsed === filterValue;
|
|
21827
|
+
case NumberOperator.NotEqualTo:
|
|
21828
|
+
return parsed !== filterValue;
|
|
21829
|
+
case NumberOperator.GreaterThan:
|
|
21830
|
+
return parsed > filterValue;
|
|
21831
|
+
case NumberOperator.LessThan:
|
|
21832
|
+
return parsed < filterValue;
|
|
21833
|
+
case NumberOperator.GreaterThanOrEqualTo:
|
|
21834
|
+
return parsed >= filterValue;
|
|
21835
|
+
case NumberOperator.LessThanOrEqualTo:
|
|
21836
|
+
return parsed <= filterValue;
|
|
21837
|
+
default:
|
|
21838
|
+
return false;
|
|
21839
|
+
}
|
|
21840
|
+
};
|
|
21841
|
+
};
|
|
21842
|
+
var buildNullPredicate = (operator, fieldKeys) => {
|
|
21843
|
+
return (row, cache) => {
|
|
21844
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21845
|
+
const isNullish = rowValue === null || rowValue === void 0;
|
|
21846
|
+
return operator === NullOperator.IsNull ? isNullish : !isNullish;
|
|
21847
|
+
};
|
|
21848
|
+
};
|
|
21849
|
+
var buildBooleanPredicate = (operator, value, fieldKeys) => {
|
|
21850
|
+
const filterValue = coerceBoolean(value);
|
|
21851
|
+
if (filterValue === null) return null;
|
|
21852
|
+
return (row, cache) => {
|
|
21853
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21854
|
+
const parsed = coerceBoolean(rowValue);
|
|
21855
|
+
if (parsed === null) return false;
|
|
21856
|
+
return operator === BoolOperator.EqualTo ? parsed === filterValue : parsed !== filterValue;
|
|
21857
|
+
};
|
|
21858
|
+
};
|
|
21859
|
+
var buildDateComparisonPredicate = (operator, value, fieldKeys) => {
|
|
21860
|
+
const filterDate = toDateMs(value);
|
|
21861
|
+
if (filterDate === null) return null;
|
|
21862
|
+
return (row, cache) => {
|
|
21863
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21864
|
+
const rowDate = toDateMs(rowValue);
|
|
21865
|
+
if (rowDate === null) return false;
|
|
21866
|
+
switch (operator) {
|
|
21867
|
+
case DateOperator.EqualTo:
|
|
21868
|
+
return rowDate === filterDate;
|
|
21869
|
+
case DateOperator.NotEqualTo:
|
|
21870
|
+
return rowDate !== filterDate;
|
|
21871
|
+
case DateOperator.GreaterThan:
|
|
21872
|
+
return rowDate > filterDate;
|
|
21873
|
+
case DateOperator.LessThan:
|
|
21874
|
+
return rowDate < filterDate;
|
|
21875
|
+
case DateOperator.GreaterThanOrEqualTo:
|
|
21876
|
+
return rowDate >= filterDate;
|
|
21877
|
+
case DateOperator.LessThanOrEqualTo:
|
|
21878
|
+
return rowDate <= filterDate;
|
|
21879
|
+
default:
|
|
21880
|
+
return false;
|
|
21881
|
+
}
|
|
21882
|
+
};
|
|
21883
|
+
};
|
|
21884
|
+
var buildDateRangePredicate = (range, fieldKeys) => {
|
|
21885
|
+
if (range.start === void 0 && range.end === void 0) return null;
|
|
21886
|
+
return (row, cache) => {
|
|
21887
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
21888
|
+
const rowDate = toDateMs(rowValue);
|
|
21889
|
+
if (rowDate === null) return false;
|
|
21890
|
+
if (range.start !== void 0 && rowDate < range.start) return false;
|
|
21891
|
+
if (range.end !== void 0) {
|
|
21892
|
+
if (range.endExclusive) {
|
|
21893
|
+
return rowDate < range.end;
|
|
21894
|
+
}
|
|
21895
|
+
return rowDate <= range.end;
|
|
21896
|
+
}
|
|
21897
|
+
return true;
|
|
21898
|
+
};
|
|
21899
|
+
};
|
|
21900
|
+
var buildCustomDatePredicate = (value, fieldKeys) => {
|
|
21901
|
+
const start2 = value.startDate ? toDateMs(value.startDate) : null;
|
|
21902
|
+
const end = value.endDate ? toDateMs(value.endDate) : null;
|
|
21903
|
+
if (start2 === null && end === null) return null;
|
|
21904
|
+
return buildDateRangePredicate(
|
|
21905
|
+
{
|
|
21906
|
+
start: start2 ?? void 0,
|
|
21907
|
+
end: end ?? void 0,
|
|
21908
|
+
endExclusive: false
|
|
21909
|
+
},
|
|
21910
|
+
fieldKeys
|
|
21911
|
+
);
|
|
21912
|
+
};
|
|
21913
|
+
var compileCustomFilter = (filter, options) => {
|
|
21914
|
+
const fieldKeys = resolveFieldKeys(
|
|
21915
|
+
filter.field,
|
|
21916
|
+
filter.table,
|
|
21917
|
+
options.fieldKeyResolver
|
|
21918
|
+
);
|
|
21919
|
+
if (fieldKeys.length === 0) return null;
|
|
21920
|
+
switch (filter.filterType) {
|
|
21921
|
+
case "string-filter" /* StringFilter */:
|
|
21922
|
+
case "string-in-filter" /* StringInFilter */:
|
|
21923
|
+
return buildStringPredicate(
|
|
21924
|
+
filter.operator,
|
|
21925
|
+
filter.value,
|
|
21926
|
+
fieldKeys
|
|
21927
|
+
);
|
|
21928
|
+
case "numeric-filter" /* NumericFilter */:
|
|
21929
|
+
return buildNumericPredicate(
|
|
21930
|
+
filter.operator,
|
|
21931
|
+
filter.value,
|
|
21932
|
+
fieldKeys
|
|
21933
|
+
);
|
|
21934
|
+
case "null-filter" /* NullFilter */:
|
|
21935
|
+
return buildNullPredicate(
|
|
21936
|
+
filter.operator,
|
|
21937
|
+
fieldKeys
|
|
21938
|
+
);
|
|
21939
|
+
case "boolean-filter" /* BooleanFilter */:
|
|
21940
|
+
return buildBooleanPredicate(
|
|
21941
|
+
filter.operator,
|
|
21942
|
+
filter.value,
|
|
21943
|
+
fieldKeys
|
|
21944
|
+
);
|
|
21945
|
+
case "date-custom-filter" /* DateCustomFilter */:
|
|
21946
|
+
return buildCustomDatePredicate(
|
|
21947
|
+
filter.value,
|
|
21948
|
+
fieldKeys
|
|
21949
|
+
);
|
|
21950
|
+
case "date-comparison-filter" /* DateComparisonFilter */:
|
|
21951
|
+
return buildDateComparisonPredicate(
|
|
21952
|
+
filter.operator,
|
|
21953
|
+
filter.value,
|
|
21954
|
+
fieldKeys
|
|
21955
|
+
);
|
|
21956
|
+
case "date-filter" /* DateFilter */: {
|
|
21957
|
+
const value = filter.value;
|
|
21958
|
+
if (!value?.unit) return null;
|
|
21959
|
+
const now2 = options.now ?? /* @__PURE__ */ new Date();
|
|
21960
|
+
const range = buildRelativeDateRange(
|
|
21961
|
+
filter.operator,
|
|
21962
|
+
value,
|
|
21963
|
+
now2,
|
|
21964
|
+
options.weekStartsOn ?? 0
|
|
21965
|
+
);
|
|
21966
|
+
if (!range) return null;
|
|
21967
|
+
return buildDateRangePredicate(range, fieldKeys);
|
|
21968
|
+
}
|
|
21969
|
+
default:
|
|
21970
|
+
return null;
|
|
21971
|
+
}
|
|
21972
|
+
};
|
|
21973
|
+
var compileDashboardFilter = (filter, options, columnTypeMap) => {
|
|
21974
|
+
const resolved = resolveDashboardField(filter, options);
|
|
21975
|
+
if (!resolved?.field) return null;
|
|
21976
|
+
const fieldKeys = resolveFieldKeys(
|
|
21977
|
+
resolved.field,
|
|
21978
|
+
resolved.table,
|
|
21979
|
+
options.fieldKeyResolver
|
|
21980
|
+
);
|
|
21981
|
+
if (fieldKeys.length === 0) return null;
|
|
21982
|
+
switch (filter.filterType) {
|
|
21983
|
+
case "string" /* String */: {
|
|
21984
|
+
const stringFilter = filter;
|
|
21985
|
+
if (stringFilter.stringFilterType === "multiselect" /* Multiselect */) {
|
|
21986
|
+
if (!stringFilter.values || stringFilter.values.length === 0) {
|
|
21987
|
+
return null;
|
|
21988
|
+
}
|
|
21989
|
+
return buildStringPredicate(
|
|
21990
|
+
StringOperator.Is,
|
|
21991
|
+
stringFilter.values,
|
|
21992
|
+
fieldKeys
|
|
21993
|
+
);
|
|
21994
|
+
}
|
|
21995
|
+
if (!stringFilter.selectedValue) return null;
|
|
21996
|
+
return buildStringPredicate(
|
|
21997
|
+
StringOperator.IsExactly,
|
|
21998
|
+
stringFilter.selectedValue,
|
|
21999
|
+
fieldKeys
|
|
22000
|
+
);
|
|
22001
|
+
}
|
|
22002
|
+
case "date_range" /* Date */: {
|
|
22003
|
+
const dateFilter = filter;
|
|
22004
|
+
const start2 = dateFilter.startDate ? dateFilter.startDate.getTime() : void 0;
|
|
22005
|
+
const end = dateFilter.endDate ? dateFilter.endDate.getTime() : void 0;
|
|
22006
|
+
return buildDateRangePredicate(
|
|
22007
|
+
{ start: start2, end, endExclusive: false },
|
|
22008
|
+
fieldKeys
|
|
22009
|
+
);
|
|
22010
|
+
}
|
|
22011
|
+
case "tenant" /* Tenant */: {
|
|
22012
|
+
const tenantFilter = filter;
|
|
22013
|
+
if (!tenantFilter.values || tenantFilter.values.length === 0) {
|
|
22014
|
+
return null;
|
|
22015
|
+
}
|
|
22016
|
+
const normalizedValues = tenantFilter.values.map(
|
|
22017
|
+
(v) => normalizeFilterString(String(v))
|
|
22018
|
+
);
|
|
22019
|
+
const valueSet = new Set(normalizedValues);
|
|
22020
|
+
const fieldType = columnTypeMap?.[resolved.field] ?? "string";
|
|
22021
|
+
return (row, cache) => {
|
|
22022
|
+
const rowValue = getRowValue(row, fieldKeys, cache);
|
|
22023
|
+
if (rowValue === null || rowValue === void 0) return false;
|
|
22024
|
+
if (fieldType === "number") {
|
|
22025
|
+
const numeric = coerceNumber(rowValue);
|
|
22026
|
+
return numeric !== null && valueSet.has(normalizeFilterString(String(numeric)));
|
|
22027
|
+
}
|
|
22028
|
+
return valueSet.has(normalizeRowString(String(rowValue)));
|
|
22029
|
+
};
|
|
22030
|
+
}
|
|
22031
|
+
default:
|
|
22032
|
+
return null;
|
|
22033
|
+
}
|
|
22034
|
+
};
|
|
22035
|
+
var updateDashboardFilters = (filtersToUpdate, dashboardFilters) => {
|
|
22036
|
+
return dashboardFilters.map((filter) => {
|
|
22037
|
+
const update = filtersToUpdate.find((u) => u.label === filter.label);
|
|
22038
|
+
if (!update) return filter;
|
|
22039
|
+
if (filter.filterType === "string" /* String */) {
|
|
22040
|
+
if (filter.stringFilterType === "multiselect" /* Multiselect */) {
|
|
22041
|
+
return {
|
|
22042
|
+
...filter,
|
|
22043
|
+
values: update.value
|
|
22044
|
+
};
|
|
22045
|
+
}
|
|
22046
|
+
return {
|
|
22047
|
+
...filter,
|
|
22048
|
+
selectedValue: update.value
|
|
22049
|
+
};
|
|
22050
|
+
}
|
|
22051
|
+
if (filter.filterType === "date_range" /* Date */) {
|
|
22052
|
+
const presetOptions = convertPresetOptionsToSelectableList(
|
|
22053
|
+
filter.presetOptions ?? [],
|
|
22054
|
+
filter.defaultPresetRanges ?? []
|
|
22055
|
+
);
|
|
22056
|
+
const value = update.value;
|
|
22057
|
+
const preset = presetOptions.find((p) => {
|
|
22058
|
+
const pStart = p.startDate ? new Date(p.startDate).toISOString() : void 0;
|
|
22059
|
+
const vStart = value.startDate ? new Date(value.startDate).toISOString() : void 0;
|
|
22060
|
+
const pEnd = p.endDate ? new Date(p.endDate).toISOString() : void 0;
|
|
22061
|
+
const vEnd = value.endDate ? new Date(value.endDate).toISOString() : void 0;
|
|
22062
|
+
return pStart === vStart && pEnd === vEnd;
|
|
22063
|
+
});
|
|
22064
|
+
if (!preset) {
|
|
22065
|
+
return { ...filter, startDate: value.startDate, endDate: value.endDate };
|
|
22066
|
+
}
|
|
22067
|
+
return {
|
|
22068
|
+
...filter,
|
|
22069
|
+
preset,
|
|
22070
|
+
startDate: value.startDate,
|
|
22071
|
+
endDate: value.endDate
|
|
22072
|
+
};
|
|
22073
|
+
}
|
|
22074
|
+
if (filter.filterType === "tenant" /* Tenant */) {
|
|
22075
|
+
const value = update.value;
|
|
22076
|
+
let values;
|
|
22077
|
+
if (Array.isArray(value)) {
|
|
22078
|
+
values = value;
|
|
22079
|
+
} else if (typeof value === "string") {
|
|
22080
|
+
values = [value];
|
|
22081
|
+
} else {
|
|
22082
|
+
values = [];
|
|
22083
|
+
}
|
|
22084
|
+
return {
|
|
22085
|
+
...filter,
|
|
22086
|
+
values
|
|
22087
|
+
};
|
|
22088
|
+
}
|
|
22089
|
+
return filter;
|
|
22090
|
+
});
|
|
22091
|
+
};
|
|
22092
|
+
var compileApplyFiltersPredicate = (filters, options) => {
|
|
22093
|
+
const dashboardUpdates = filters.filter(isDashboardFilterUpdate);
|
|
22094
|
+
const customFilters = filters.filter(isFilter);
|
|
22095
|
+
const internalCustomFilters = customFilters.map((filter) => {
|
|
22096
|
+
try {
|
|
22097
|
+
return convertCustomFilter(filter);
|
|
22098
|
+
} catch (error) {
|
|
22099
|
+
return null;
|
|
22100
|
+
}
|
|
22101
|
+
}).concat(options.customFilters ?? []).filter((filter) => filter !== null && filter !== void 0);
|
|
22102
|
+
const dashboardFilters = options.dashboardFilters ?? [];
|
|
22103
|
+
const updatedDashboardFilters = dashboardUpdates.length ? updateDashboardFilters(dashboardUpdates, dashboardFilters) : dashboardFilters;
|
|
22104
|
+
const columnTypeMap = buildColumnTypeMap(options.columns);
|
|
22105
|
+
const predicates = [];
|
|
22106
|
+
for (const filter of internalCustomFilters) {
|
|
22107
|
+
const predicate = compileCustomFilter(filter, options);
|
|
22108
|
+
if (predicate) predicates.push(predicate);
|
|
22109
|
+
}
|
|
22110
|
+
for (const filter of updatedDashboardFilters) {
|
|
22111
|
+
const predicate = compileDashboardFilter(
|
|
22112
|
+
filter,
|
|
22113
|
+
options,
|
|
22114
|
+
columnTypeMap
|
|
22115
|
+
);
|
|
22116
|
+
if (predicate) predicates.push(predicate);
|
|
22117
|
+
}
|
|
22118
|
+
if (predicates.length === 0) {
|
|
22119
|
+
return { predicate: () => true, hasPredicates: false };
|
|
22120
|
+
}
|
|
22121
|
+
return {
|
|
22122
|
+
predicate: (row) => {
|
|
22123
|
+
const cache = /* @__PURE__ */ Object.create(null);
|
|
22124
|
+
for (const predicate of predicates) {
|
|
22125
|
+
if (!predicate(row, cache)) return false;
|
|
22126
|
+
}
|
|
22127
|
+
return true;
|
|
22128
|
+
},
|
|
22129
|
+
hasPredicates: true
|
|
22130
|
+
};
|
|
22131
|
+
};
|
|
22132
|
+
var applyFiltersInMemory = (rows, filters, options) => {
|
|
22133
|
+
if (!rows.length) return rows;
|
|
22134
|
+
const { predicate, hasPredicates } = compileApplyFiltersPredicate(
|
|
22135
|
+
filters,
|
|
22136
|
+
options
|
|
22137
|
+
);
|
|
22138
|
+
if (!hasPredicates) return rows;
|
|
22139
|
+
const results = [];
|
|
22140
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
22141
|
+
const row = rows[i];
|
|
22142
|
+
if (predicate(row)) {
|
|
22143
|
+
results.push(row);
|
|
22144
|
+
}
|
|
22145
|
+
}
|
|
22146
|
+
return results;
|
|
22147
|
+
};
|
|
22148
|
+
|
|
22149
|
+
// src/utils/inMemoryPivotEngine.ts
|
|
22150
|
+
init_columnType();
|
|
22151
|
+
var MS_IN_DAY = 24 * 60 * 60 * 1e3;
|
|
22152
|
+
var MONTHS = [
|
|
22153
|
+
"Jan",
|
|
22154
|
+
"Feb",
|
|
22155
|
+
"Mar",
|
|
22156
|
+
"Apr",
|
|
22157
|
+
"May",
|
|
22158
|
+
"Jun",
|
|
22159
|
+
"Jul",
|
|
22160
|
+
"Aug",
|
|
22161
|
+
"Sep",
|
|
22162
|
+
"Oct",
|
|
22163
|
+
"Nov",
|
|
22164
|
+
"Dec"
|
|
22165
|
+
];
|
|
22166
|
+
var INVALID_DATE_KEY = "-2026";
|
|
22167
|
+
function singleAggToMultiAgg(pivot) {
|
|
22168
|
+
if (pivot.aggregations) {
|
|
22169
|
+
return pivot;
|
|
22170
|
+
}
|
|
22171
|
+
const newPivot = { ...pivot };
|
|
22172
|
+
const newAgg = { aggregationType: pivot.aggregationType };
|
|
22173
|
+
const fieldsToCopy = [
|
|
22174
|
+
"valueField",
|
|
22175
|
+
"valueFieldType",
|
|
22176
|
+
"valueField2",
|
|
22177
|
+
"valueField2Type"
|
|
22178
|
+
];
|
|
22179
|
+
fieldsToCopy.forEach((x) => {
|
|
22180
|
+
if (pivot[x]) {
|
|
22181
|
+
newAgg[x] = pivot[x];
|
|
22182
|
+
delete newPivot[x];
|
|
22183
|
+
}
|
|
22184
|
+
});
|
|
22185
|
+
newPivot.aggregations = [newAgg];
|
|
22186
|
+
return newPivot;
|
|
22187
|
+
}
|
|
22188
|
+
function isDateFormat2(xAxisFormat) {
|
|
22189
|
+
const DATE_FORMATS = [
|
|
22190
|
+
"yyyy",
|
|
22191
|
+
"mmm_dd",
|
|
22192
|
+
"mmm_yyyy",
|
|
22193
|
+
"mmm_dd_yyyy",
|
|
22194
|
+
"hh_ap_pm",
|
|
22195
|
+
"mmm_dd-mmm_dd",
|
|
22196
|
+
"mmm_dd_hh:mm_ap_pm",
|
|
22197
|
+
"wo, yyyy"
|
|
22198
|
+
];
|
|
22199
|
+
const isDate = DATE_FORMATS.includes(xAxisFormat.toLowerCase());
|
|
22200
|
+
return isDate;
|
|
22201
|
+
}
|
|
22202
|
+
function isValidDate3(date) {
|
|
22203
|
+
try {
|
|
22204
|
+
return date instanceof Date && !isNaN(date.getTime());
|
|
22205
|
+
} catch {
|
|
22206
|
+
return false;
|
|
22207
|
+
}
|
|
22208
|
+
}
|
|
22209
|
+
function isDateLikeType(fieldType) {
|
|
22210
|
+
if (!fieldType) {
|
|
22211
|
+
return false;
|
|
22212
|
+
}
|
|
22213
|
+
return isDateType(fieldType) || isDateFormat2(fieldType);
|
|
22214
|
+
}
|
|
22215
|
+
function inferDateBucketFromFilters(pivot, filters) {
|
|
22216
|
+
if (!pivot?.rowFieldType) {
|
|
22217
|
+
return void 0;
|
|
22218
|
+
}
|
|
22219
|
+
const normalizedType = String(pivot.rowFieldType).toLowerCase();
|
|
22220
|
+
if (isDateFormat2(normalizedType)) {
|
|
22221
|
+
switch (normalizedType) {
|
|
22222
|
+
case "mmm_dd-mmm_dd":
|
|
22223
|
+
return "week";
|
|
22224
|
+
case "yyyy":
|
|
22225
|
+
case "wo, yyyy":
|
|
22226
|
+
return "year";
|
|
22227
|
+
case "mmm_dd_hh:mm_ap_pm":
|
|
22228
|
+
case "hh_ap_pm":
|
|
22229
|
+
return "day";
|
|
22230
|
+
default:
|
|
22231
|
+
return "month";
|
|
22232
|
+
}
|
|
22233
|
+
}
|
|
22234
|
+
const isDateLike = isDateType(normalizedType);
|
|
22235
|
+
if (!isDateLike) {
|
|
22236
|
+
return void 0;
|
|
22237
|
+
}
|
|
22238
|
+
let earliest;
|
|
22239
|
+
let latest;
|
|
22240
|
+
const extractTimestamp = (value) => {
|
|
22241
|
+
if (!value) {
|
|
22242
|
+
return void 0;
|
|
22243
|
+
}
|
|
22244
|
+
if (value instanceof Date) {
|
|
22245
|
+
return value.getTime();
|
|
22246
|
+
}
|
|
22247
|
+
const parsed = Date.parse(value);
|
|
22248
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
22249
|
+
};
|
|
22250
|
+
(Array.isArray(filters) ? filters : []).forEach((filter) => {
|
|
22251
|
+
if (!filter || filter.filterType !== "date_range") {
|
|
22252
|
+
return;
|
|
22253
|
+
}
|
|
22254
|
+
if (filter.primaryRange?.value === "ALL_TIME") {
|
|
22255
|
+
earliest = -1;
|
|
22256
|
+
return;
|
|
22257
|
+
}
|
|
22258
|
+
const possibleStarts = [
|
|
22259
|
+
filter.startDate,
|
|
22260
|
+
filter.start,
|
|
22261
|
+
filter.primaryRange?.startDate,
|
|
22262
|
+
filter.primaryRange?.start,
|
|
22263
|
+
filter.range?.startDate,
|
|
22264
|
+
filter.range?.start
|
|
22265
|
+
];
|
|
22266
|
+
const possibleEnds = [
|
|
22267
|
+
filter.endDate,
|
|
22268
|
+
filter.end,
|
|
22269
|
+
filter.primaryRange?.endDate,
|
|
22270
|
+
filter.primaryRange?.end,
|
|
22271
|
+
filter.range?.endDate,
|
|
22272
|
+
filter.range?.end
|
|
22273
|
+
];
|
|
22274
|
+
possibleStarts.forEach((value) => {
|
|
22275
|
+
const timestamp = extractTimestamp(value);
|
|
22276
|
+
if (timestamp === void 0) {
|
|
22277
|
+
return;
|
|
22278
|
+
}
|
|
22279
|
+
earliest = earliest === void 0 ? timestamp : Math.min(earliest, timestamp);
|
|
22280
|
+
});
|
|
22281
|
+
possibleEnds.forEach((value) => {
|
|
22282
|
+
const timestamp = extractTimestamp(value);
|
|
22283
|
+
if (timestamp === void 0) {
|
|
22284
|
+
return;
|
|
22285
|
+
}
|
|
22286
|
+
latest = latest === void 0 ? timestamp : Math.max(latest, timestamp);
|
|
22287
|
+
});
|
|
22288
|
+
});
|
|
22289
|
+
if (earliest === -1) {
|
|
22290
|
+
return "month";
|
|
22291
|
+
}
|
|
22292
|
+
if (earliest === void 0 || latest === void 0) {
|
|
22293
|
+
return void 0;
|
|
22294
|
+
}
|
|
22295
|
+
if (latest < earliest) {
|
|
22296
|
+
[earliest, latest] = [latest, earliest];
|
|
22297
|
+
}
|
|
22298
|
+
const diffInDays = Math.max(1, Math.round((latest - earliest) / MS_IN_DAY));
|
|
22299
|
+
if (diffInDays < 20) {
|
|
22300
|
+
return "day";
|
|
22301
|
+
}
|
|
22302
|
+
if (diffInDays <= 59) {
|
|
22303
|
+
return "week";
|
|
22304
|
+
}
|
|
22305
|
+
if (diffInDays <= 400) {
|
|
22306
|
+
return "month";
|
|
22307
|
+
}
|
|
22308
|
+
return "year";
|
|
22309
|
+
}
|
|
22310
|
+
function getDateRangeFromFilters(filters) {
|
|
22311
|
+
let earliest;
|
|
22312
|
+
let latest;
|
|
22313
|
+
const extractTimestamp = (value) => {
|
|
22314
|
+
if (!value) return void 0;
|
|
22315
|
+
if (value instanceof Date) return value.getTime();
|
|
22316
|
+
const parsed = Date.parse(value);
|
|
22317
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
22318
|
+
};
|
|
22319
|
+
(Array.isArray(filters) ? filters : []).forEach((filter) => {
|
|
22320
|
+
if (!filter || filter.filterType !== "date_range") return;
|
|
22321
|
+
if (filter.primaryRange?.value === "ALL_TIME") return;
|
|
22322
|
+
const possibleStarts = [
|
|
22323
|
+
filter.startDate,
|
|
22324
|
+
filter.start,
|
|
22325
|
+
filter.primaryRange?.startDate,
|
|
22326
|
+
filter.primaryRange?.start,
|
|
22327
|
+
filter.range?.startDate,
|
|
22328
|
+
filter.range?.start
|
|
22329
|
+
];
|
|
22330
|
+
const possibleEnds = [
|
|
22331
|
+
filter.endDate,
|
|
22332
|
+
filter.end,
|
|
22333
|
+
filter.primaryRange?.endDate,
|
|
22334
|
+
filter.primaryRange?.end,
|
|
22335
|
+
filter.range?.endDate,
|
|
22336
|
+
filter.range?.end
|
|
22337
|
+
];
|
|
22338
|
+
possibleStarts.forEach((v) => {
|
|
22339
|
+
const ts = extractTimestamp(v);
|
|
22340
|
+
if (ts === void 0) return;
|
|
22341
|
+
earliest = earliest === void 0 ? ts : Math.min(earliest, ts);
|
|
22342
|
+
});
|
|
22343
|
+
possibleEnds.forEach((v) => {
|
|
22344
|
+
const ts = extractTimestamp(v);
|
|
22345
|
+
if (ts === void 0) return;
|
|
22346
|
+
latest = latest === void 0 ? ts : Math.max(latest, ts);
|
|
22347
|
+
});
|
|
22348
|
+
});
|
|
22349
|
+
if (earliest === void 0 || latest === void 0) return void 0;
|
|
22350
|
+
if (latest < earliest) [earliest, latest] = [latest, earliest];
|
|
22351
|
+
return {
|
|
22352
|
+
start: new Date(earliest),
|
|
22353
|
+
end: new Date(latest)
|
|
22354
|
+
};
|
|
22355
|
+
}
|
|
22356
|
+
function generateBucketKeys(start2, end, bucket) {
|
|
22357
|
+
const keys = /* @__PURE__ */ new Set();
|
|
22358
|
+
const startDay = new Date(
|
|
22359
|
+
Date.UTC(start2.getUTCFullYear(), start2.getUTCMonth(), start2.getUTCDate())
|
|
22360
|
+
);
|
|
22361
|
+
const endDay = new Date(
|
|
22362
|
+
Date.UTC(end.getUTCFullYear(), end.getUTCMonth(), end.getUTCDate())
|
|
22363
|
+
);
|
|
22364
|
+
const cur = new Date(startDay);
|
|
22365
|
+
while (cur <= endDay) {
|
|
22366
|
+
keys.add(getDateKey(cur, bucket));
|
|
22367
|
+
cur.setUTCDate(cur.getUTCDate() + 1);
|
|
22368
|
+
}
|
|
22369
|
+
return Array.from(keys).sort((a, b) => parseInt(a) - parseInt(b));
|
|
22370
|
+
}
|
|
22371
|
+
function buildEmptyAggRow(aggregations) {
|
|
22372
|
+
const multiAgg = aggregations.length > 1;
|
|
22373
|
+
const empty = {};
|
|
22374
|
+
aggregations.forEach((agg) => {
|
|
22375
|
+
const { aggregationType: type, valueField } = agg;
|
|
22376
|
+
const key = !valueField ? `${type}` + (multiAgg ? `_${type}` : "") : `${valueField}` + (multiAgg ? `_${type}` : "");
|
|
22377
|
+
empty[key] = 0;
|
|
22378
|
+
});
|
|
22379
|
+
return empty;
|
|
22380
|
+
}
|
|
22381
|
+
function getBucketRange(dateKey, bucket) {
|
|
22382
|
+
const d = new Date(parseInt(dateKey, 10));
|
|
22383
|
+
let start2 = new Date(d);
|
|
22384
|
+
let end = new Date(d);
|
|
22385
|
+
switch (bucket) {
|
|
22386
|
+
case "day":
|
|
22387
|
+
start2 = new Date(
|
|
22388
|
+
Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())
|
|
22389
|
+
);
|
|
22390
|
+
end = new Date(start2);
|
|
22391
|
+
break;
|
|
22392
|
+
case "week":
|
|
22393
|
+
start2 = new Date(d);
|
|
22394
|
+
end = new Date(start2);
|
|
22395
|
+
end.setUTCDate(start2.getUTCDate() + 6);
|
|
22396
|
+
break;
|
|
22397
|
+
case "month":
|
|
22398
|
+
start2 = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1));
|
|
22399
|
+
end = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0));
|
|
22400
|
+
break;
|
|
22401
|
+
case "year":
|
|
22402
|
+
start2 = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
|
22403
|
+
end = new Date(Date.UTC(d.getUTCFullYear(), 11, 31));
|
|
22404
|
+
break;
|
|
22405
|
+
}
|
|
22406
|
+
return { start: start2, end };
|
|
22407
|
+
}
|
|
22408
|
+
function formatBucketNameFromRange(start2, end, bucket) {
|
|
22409
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
22410
|
+
switch (bucket) {
|
|
22411
|
+
case "day":
|
|
22412
|
+
return `${pad(start2.getUTCDate())} ${MONTHS[start2.getUTCMonth()]} ${start2.getUTCFullYear()}`;
|
|
22413
|
+
case "week": {
|
|
22414
|
+
const sameMonth = start2.getUTCMonth() === end.getUTCMonth();
|
|
22415
|
+
return sameMonth ? `${MONTHS[start2.getUTCMonth()]} ${start2.getUTCDate()} - ${end.getUTCDate()}` : `${MONTHS[start2.getUTCMonth()]} ${start2.getUTCDate()} - ${MONTHS[end.getUTCMonth()]} ${end.getUTCDate()}`;
|
|
22416
|
+
}
|
|
22417
|
+
case "month":
|
|
22418
|
+
return `${MONTHS[start2.getUTCMonth()]} ${start2.getUTCFullYear()}`;
|
|
22419
|
+
case "year":
|
|
22420
|
+
return `${start2.getUTCFullYear()}`;
|
|
22421
|
+
default:
|
|
22422
|
+
return "";
|
|
22423
|
+
}
|
|
22424
|
+
}
|
|
22425
|
+
function getDateKey(date, bucket) {
|
|
22426
|
+
if (!isValidDate3(date)) {
|
|
22427
|
+
return INVALID_DATE_KEY;
|
|
22428
|
+
}
|
|
22429
|
+
switch (bucket) {
|
|
22430
|
+
case "day":
|
|
22431
|
+
return Date.UTC(
|
|
22432
|
+
date.getUTCFullYear(),
|
|
22433
|
+
date.getUTCMonth(),
|
|
22434
|
+
date.getUTCDate()
|
|
22435
|
+
).toString();
|
|
22436
|
+
case "week": {
|
|
22437
|
+
const day = date.getUTCDay();
|
|
22438
|
+
const mondayUtc = Date.UTC(
|
|
22439
|
+
date.getUTCFullYear(),
|
|
22440
|
+
date.getUTCMonth(),
|
|
22441
|
+
date.getUTCDate() - (day + 6) % 7
|
|
22442
|
+
);
|
|
22443
|
+
return mondayUtc.toString();
|
|
22444
|
+
}
|
|
22445
|
+
case "month":
|
|
22446
|
+
return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1).toString();
|
|
22447
|
+
case "year":
|
|
22448
|
+
return Date.UTC(date.getUTCFullYear(), 0, 1).toString();
|
|
22449
|
+
default:
|
|
22450
|
+
return INVALID_DATE_KEY;
|
|
22451
|
+
}
|
|
22452
|
+
}
|
|
22453
|
+
function sortRows(rows, pivot) {
|
|
22454
|
+
try {
|
|
22455
|
+
const { sort, sortField, sortFieldType, sortDirection } = pivot;
|
|
22456
|
+
if (!sort || sortField == null || sortFieldType == null) return rows;
|
|
22457
|
+
const sortFunc = isBoolType(sortFieldType) ? (a, b) => a === b ? 0 : a ? 1 : -1 : isDateType(sortFieldType) ? (a, b) => {
|
|
22458
|
+
const ta = new Date(a), tb = new Date(b);
|
|
22459
|
+
const aValid = isValidDate3(ta), bValid = isValidDate3(tb);
|
|
22460
|
+
if (!aValid && !bValid) return 0;
|
|
22461
|
+
if (!aValid) return 1;
|
|
22462
|
+
if (!bValid) return -1;
|
|
22463
|
+
return ta.getTime() - tb.getTime();
|
|
22464
|
+
} : isStringType(sortFieldType) ? (a, b) => a.localeCompare(b) : (a, b) => a - b;
|
|
22465
|
+
const dir = sortDirection === "ASC" ? 1 : -1;
|
|
22466
|
+
rows.sort((a, b) => {
|
|
22467
|
+
const av = a[sortField], bv = b[sortField];
|
|
22468
|
+
if (av == null && bv == null) return 0;
|
|
22469
|
+
if (av == null) return 1;
|
|
22470
|
+
if (bv == null) return -1;
|
|
22471
|
+
return dir * sortFunc(av, bv);
|
|
22472
|
+
});
|
|
22473
|
+
} catch {
|
|
22474
|
+
console.warn(`Sorting failed.`);
|
|
22475
|
+
}
|
|
22476
|
+
return rows;
|
|
22477
|
+
}
|
|
22478
|
+
function assembleFinalRows(seen, rowKey, dateBucket, dateRange) {
|
|
22479
|
+
const allColumns = /* @__PURE__ */ new Set();
|
|
22480
|
+
Object.keys(seen).forEach((rowKeyVal) => {
|
|
22481
|
+
Object.keys(seen[rowKeyVal]).forEach((col) => {
|
|
22482
|
+
allColumns.add(col);
|
|
22483
|
+
});
|
|
22484
|
+
});
|
|
22485
|
+
const filled = {};
|
|
22486
|
+
Object.keys(seen).forEach((rowKeyVal) => {
|
|
22487
|
+
filled[rowKeyVal] = {};
|
|
22488
|
+
allColumns.forEach((col) => {
|
|
22489
|
+
const value = seen[rowKeyVal][col];
|
|
22490
|
+
filled[rowKeyVal][col] = value ?? 0;
|
|
22491
|
+
});
|
|
22492
|
+
});
|
|
22493
|
+
if (dateBucket) {
|
|
22494
|
+
return Object.keys(filled).sort((a, b) => parseInt(a) - parseInt(b)).map((k) => {
|
|
22495
|
+
if (k === INVALID_DATE_KEY) {
|
|
22496
|
+
return { [rowKey]: "Invalid Date", ...filled[k], __quillRawDate: 0 };
|
|
22497
|
+
}
|
|
22498
|
+
const { start: start2, end } = getBucketRange(k, dateBucket);
|
|
22499
|
+
let bucketStart = start2;
|
|
22500
|
+
let bucketEnd = end;
|
|
22501
|
+
if (dateRange) {
|
|
22502
|
+
if (bucketStart < dateRange.start) bucketStart = dateRange.start;
|
|
22503
|
+
if (bucketEnd > dateRange.end) bucketEnd = dateRange.end;
|
|
22504
|
+
}
|
|
22505
|
+
return {
|
|
22506
|
+
[rowKey]: formatBucketNameFromRange(
|
|
22507
|
+
bucketStart,
|
|
22508
|
+
bucketEnd,
|
|
22509
|
+
dateBucket
|
|
22510
|
+
),
|
|
22511
|
+
...filled[k],
|
|
22512
|
+
__quillRawDate: bucketStart.toISOString()
|
|
22513
|
+
};
|
|
22514
|
+
});
|
|
22515
|
+
}
|
|
22516
|
+
return Object.keys(filled).sort().map((k) => ({ [rowKey]: k, ...filled[k] }));
|
|
22517
|
+
}
|
|
22518
|
+
function anyToNum(valueFieldType, obj) {
|
|
22519
|
+
if (!valueFieldType) {
|
|
22520
|
+
if (typeof obj === "number") return obj;
|
|
22521
|
+
if (typeof obj === "string" && !isNaN(Number(obj))) return Number(obj);
|
|
22522
|
+
return obj ? 1 : 0;
|
|
22523
|
+
}
|
|
22524
|
+
if (isNumberType(valueFieldType)) {
|
|
22525
|
+
return Number(obj);
|
|
22526
|
+
}
|
|
22527
|
+
return obj ? 1 : 0;
|
|
22528
|
+
}
|
|
22529
|
+
function updateAccumulator(acc, row, agg, isOneRow) {
|
|
22530
|
+
const {
|
|
22531
|
+
aggregationType: type,
|
|
22532
|
+
valueField,
|
|
22533
|
+
valueFieldType,
|
|
22534
|
+
valueField2,
|
|
22535
|
+
valueField2Type
|
|
22536
|
+
} = agg;
|
|
22537
|
+
if (!valueField) return;
|
|
22538
|
+
const distinctDenom = !!valueField2 && !!valueField2Type && valueField !== valueField2;
|
|
22539
|
+
const rawVal = row[valueField];
|
|
22540
|
+
if (valueFieldType && (type === "min" || type === "max") && (isDateType(valueFieldType) || isDateFormat2(valueFieldType))) {
|
|
22541
|
+
const dateVal = rawVal instanceof Date ? rawVal : new Date(rawVal);
|
|
22542
|
+
if (!isNaN(dateVal.getTime())) {
|
|
22543
|
+
if (type === "min") {
|
|
22544
|
+
acc.minDate = acc.minDate && acc.minDate.getTime() < dateVal.getTime() ? acc.minDate : dateVal;
|
|
22545
|
+
} else {
|
|
22546
|
+
acc.maxDate = acc.maxDate && acc.maxDate.getTime() > dateVal.getTime() ? acc.maxDate : dateVal;
|
|
22547
|
+
}
|
|
22548
|
+
}
|
|
22549
|
+
return;
|
|
22550
|
+
}
|
|
22551
|
+
const numVal = anyToNum(valueFieldType, rawVal);
|
|
22552
|
+
switch (type) {
|
|
22553
|
+
case "sum":
|
|
22554
|
+
acc.sum += numVal;
|
|
22555
|
+
break;
|
|
22556
|
+
case "average":
|
|
22557
|
+
case "avg":
|
|
22558
|
+
acc.sum += numVal;
|
|
22559
|
+
acc.count++;
|
|
22560
|
+
break;
|
|
22561
|
+
case "min":
|
|
22562
|
+
acc.min = acc.hasVal ? Math.min(acc.min, numVal) : numVal;
|
|
22563
|
+
acc.hasVal = true;
|
|
22564
|
+
break;
|
|
22565
|
+
case "max":
|
|
22566
|
+
acc.max = acc.hasVal ? Math.max(acc.max, numVal) : numVal;
|
|
22567
|
+
acc.hasVal = true;
|
|
22568
|
+
break;
|
|
22569
|
+
case "count":
|
|
22570
|
+
acc.count += numVal;
|
|
22571
|
+
break;
|
|
22572
|
+
case "percentage":
|
|
22573
|
+
acc.sum += numVal;
|
|
22574
|
+
acc.count += distinctDenom ? anyToNum(valueField2Type, row[valueField2]) : isOneRow ? 1 : numVal;
|
|
22575
|
+
break;
|
|
22576
|
+
}
|
|
22577
|
+
}
|
|
22578
|
+
function getFinalAggregationValue({
|
|
22579
|
+
type,
|
|
22580
|
+
valueFieldType,
|
|
22581
|
+
valueField,
|
|
22582
|
+
acc,
|
|
22583
|
+
distinctDenom = false,
|
|
22584
|
+
sumOfDenom,
|
|
22585
|
+
rowsLength,
|
|
22586
|
+
totalRowsForCount
|
|
22587
|
+
}) {
|
|
22588
|
+
if (valueFieldType && (type === "min" || type === "max") && (isDateType(valueFieldType) || isDateFormat2(valueFieldType))) {
|
|
22589
|
+
const dateVal = type === "min" ? acc.minDate : acc.maxDate;
|
|
22590
|
+
return dateVal?.toISOString() ?? "";
|
|
22591
|
+
}
|
|
22592
|
+
if (type === "count") {
|
|
22593
|
+
return totalRowsForCount ?? acc.count;
|
|
22594
|
+
}
|
|
22595
|
+
let final;
|
|
22596
|
+
if (!valueField && type === "percentage" && rowsLength !== void 0) {
|
|
22597
|
+
final = rowsLength ? (totalRowsForCount ?? 0) / rowsLength : 0;
|
|
22598
|
+
} else {
|
|
22599
|
+
switch (type) {
|
|
22600
|
+
case "sum":
|
|
22601
|
+
final = acc.sum;
|
|
22602
|
+
break;
|
|
22603
|
+
case "average":
|
|
22604
|
+
case "avg":
|
|
22605
|
+
final = acc.count ? acc.sum / acc.count : 0;
|
|
22606
|
+
break;
|
|
22607
|
+
case "min":
|
|
22608
|
+
final = acc.hasVal ? acc.min : 0;
|
|
22609
|
+
break;
|
|
22610
|
+
case "max":
|
|
22611
|
+
final = acc.hasVal ? acc.max : 0;
|
|
22612
|
+
break;
|
|
22613
|
+
case "percentage": {
|
|
22614
|
+
const denom = distinctDenom ? acc.count : sumOfDenom ?? acc.count;
|
|
22615
|
+
final = denom ? acc.sum / denom : 0;
|
|
22616
|
+
break;
|
|
22617
|
+
}
|
|
22618
|
+
default:
|
|
22619
|
+
final = 0;
|
|
22620
|
+
}
|
|
22621
|
+
}
|
|
22622
|
+
return final;
|
|
22623
|
+
}
|
|
22624
|
+
function aggregateToOneRow(rows, aggregations) {
|
|
22625
|
+
const multiAgg = aggregations.length > 1;
|
|
22626
|
+
const resultArray = aggregations.map((agg) => {
|
|
22627
|
+
const { aggregationType: type, valueField, valueFieldType } = agg;
|
|
22628
|
+
if (!valueField) {
|
|
22629
|
+
if (type !== "count") {
|
|
22630
|
+
return {};
|
|
22631
|
+
}
|
|
22632
|
+
const finalKey2 = "count" + (multiAgg ? "_count" : "");
|
|
22633
|
+
return { [finalKey2]: rows.length };
|
|
22634
|
+
}
|
|
22635
|
+
const finalKey = `${valueField}` + (multiAgg ? `_${type}` : "");
|
|
22636
|
+
const acc = {
|
|
22637
|
+
sum: 0,
|
|
22638
|
+
count: 0,
|
|
22639
|
+
min: Infinity,
|
|
22640
|
+
max: -Infinity,
|
|
22641
|
+
hasVal: false,
|
|
22642
|
+
minDate: null,
|
|
22643
|
+
maxDate: null
|
|
22644
|
+
};
|
|
22645
|
+
for (const row of rows) {
|
|
22646
|
+
updateAccumulator(acc, row, agg, true);
|
|
22647
|
+
}
|
|
22648
|
+
return {
|
|
22649
|
+
[finalKey]: getFinalAggregationValue({
|
|
22650
|
+
type,
|
|
22651
|
+
valueFieldType,
|
|
22652
|
+
valueField,
|
|
22653
|
+
acc,
|
|
22654
|
+
totalRowsForCount: acc.count
|
|
22655
|
+
})
|
|
22656
|
+
};
|
|
22657
|
+
});
|
|
22658
|
+
return [
|
|
22659
|
+
resultArray.reduce((acc, current) => {
|
|
22660
|
+
return { ...acc, ...current };
|
|
22661
|
+
}, {})
|
|
22662
|
+
];
|
|
22663
|
+
}
|
|
22664
|
+
function aggregateWithColumn(rows, colKey, aggregations, getGroupKey) {
|
|
22665
|
+
if (!colKey) return;
|
|
22666
|
+
const seen = {};
|
|
22667
|
+
const multiAgg = aggregations.length > 1;
|
|
22668
|
+
aggregations.forEach((agg) => {
|
|
22669
|
+
const {
|
|
22670
|
+
aggregationType: type,
|
|
22671
|
+
valueField,
|
|
22672
|
+
valueFieldType,
|
|
22673
|
+
valueField2,
|
|
22674
|
+
valueField2Type
|
|
22675
|
+
} = agg;
|
|
22676
|
+
if (!valueField) {
|
|
22677
|
+
if (type !== "count" && type !== "percentage") return;
|
|
22678
|
+
}
|
|
22679
|
+
const distinctDenom = !!valueField2 && !!valueField2Type && valueField !== valueField2;
|
|
22680
|
+
const accs = {};
|
|
22681
|
+
rows.forEach((row) => {
|
|
22682
|
+
const groupKey = getGroupKey(row);
|
|
22683
|
+
const colVal = row[colKey];
|
|
22684
|
+
if (!accs[groupKey]) accs[groupKey] = {};
|
|
22685
|
+
if (!accs[groupKey][colVal]) {
|
|
22686
|
+
accs[groupKey][colVal] = {
|
|
22687
|
+
sum: 0,
|
|
22688
|
+
count: 0,
|
|
22689
|
+
min: Infinity,
|
|
22690
|
+
max: -Infinity,
|
|
22691
|
+
hasVal: false,
|
|
22692
|
+
minDate: null,
|
|
22693
|
+
maxDate: null,
|
|
22694
|
+
totalRows: 0
|
|
22695
|
+
};
|
|
22696
|
+
}
|
|
22697
|
+
const acc = accs[groupKey][colVal];
|
|
22698
|
+
acc.totalRows += 1;
|
|
22699
|
+
if (!valueField) {
|
|
22700
|
+
if (type === "count") acc.count += 1;
|
|
22701
|
+
else if (type === "percentage") acc.sum += 1;
|
|
22702
|
+
return;
|
|
22703
|
+
}
|
|
22704
|
+
updateAccumulator(acc, row, agg, false);
|
|
22705
|
+
});
|
|
22706
|
+
Object.keys(accs).forEach((groupKey) => {
|
|
22707
|
+
if (!seen[groupKey]) seen[groupKey] = {};
|
|
22708
|
+
const sumOfDenom = Object.values(accs[groupKey]).reduce(
|
|
22709
|
+
(t, a) => t + a.count,
|
|
22710
|
+
0
|
|
22711
|
+
);
|
|
22712
|
+
Object.keys(accs[groupKey]).forEach((colVal) => {
|
|
22713
|
+
const acc = accs[groupKey][colVal];
|
|
22714
|
+
const finalKey = `${colVal}` + (multiAgg ? `_${type}` : "");
|
|
22715
|
+
seen[groupKey][finalKey] = getFinalAggregationValue({
|
|
22716
|
+
type,
|
|
22717
|
+
valueFieldType,
|
|
22718
|
+
valueField,
|
|
22719
|
+
acc,
|
|
22720
|
+
distinctDenom,
|
|
22721
|
+
sumOfDenom,
|
|
22722
|
+
totalRowsForCount: acc.totalRows
|
|
22723
|
+
});
|
|
22724
|
+
});
|
|
22725
|
+
});
|
|
22726
|
+
});
|
|
22727
|
+
return seen;
|
|
22728
|
+
}
|
|
22729
|
+
function aggregateWithoutColumn(rows, aggregations, getGroupKey) {
|
|
22730
|
+
const seen = {};
|
|
22731
|
+
const multiAgg = aggregations.length > 1;
|
|
22732
|
+
aggregations.forEach((agg) => {
|
|
22733
|
+
const {
|
|
22734
|
+
aggregationType: type,
|
|
22735
|
+
valueField,
|
|
22736
|
+
valueFieldType,
|
|
22737
|
+
valueField2,
|
|
22738
|
+
valueField2Type
|
|
22739
|
+
} = agg;
|
|
22740
|
+
if (!valueField) {
|
|
22741
|
+
if (type !== "count" && type !== "percentage") return;
|
|
22742
|
+
}
|
|
22743
|
+
const finalKey = !valueField ? `${type}` + (multiAgg ? `_${type}` : "") : `${valueField}` + (multiAgg ? `_${type}` : "");
|
|
22744
|
+
const distinctDenom = !!valueField2 && !!valueField2Type && valueField !== valueField2;
|
|
22745
|
+
const accs = {};
|
|
22746
|
+
rows.forEach((row) => {
|
|
22747
|
+
const key = getGroupKey(row);
|
|
22748
|
+
if (!seen[key]) seen[key] = {};
|
|
22749
|
+
if (!accs[key]) {
|
|
22750
|
+
accs[key] = {
|
|
22751
|
+
sum: 0,
|
|
22752
|
+
count: 0,
|
|
22753
|
+
min: Infinity,
|
|
22754
|
+
max: -Infinity,
|
|
22755
|
+
hasVal: false,
|
|
22756
|
+
minDate: null,
|
|
22757
|
+
maxDate: null,
|
|
22758
|
+
totalRows: 0
|
|
22759
|
+
};
|
|
22760
|
+
}
|
|
22761
|
+
const acc = accs[key];
|
|
22762
|
+
acc.totalRows += 1;
|
|
22763
|
+
if (!valueField) {
|
|
22764
|
+
if (type === "count") acc.count += 1;
|
|
22765
|
+
else if (type === "percentage") acc.sum += 1;
|
|
22766
|
+
return;
|
|
22767
|
+
}
|
|
22768
|
+
updateAccumulator(acc, row, agg, false);
|
|
22769
|
+
});
|
|
22770
|
+
const sumOfDenom = Object.values(accs).reduce(
|
|
22771
|
+
(t, a) => t + a.count,
|
|
22772
|
+
0
|
|
22773
|
+
);
|
|
22774
|
+
Object.keys(accs).forEach((k) => {
|
|
22775
|
+
const acc = accs[k];
|
|
22776
|
+
seen[k][finalKey] = getFinalAggregationValue({
|
|
22777
|
+
type,
|
|
22778
|
+
valueFieldType,
|
|
22779
|
+
valueField,
|
|
22780
|
+
acc,
|
|
22781
|
+
distinctDenom,
|
|
22782
|
+
sumOfDenom,
|
|
22783
|
+
rowsLength: rows.length,
|
|
22784
|
+
totalRowsForCount: acc.totalRows
|
|
22785
|
+
});
|
|
22786
|
+
});
|
|
22787
|
+
});
|
|
22788
|
+
return seen;
|
|
22789
|
+
}
|
|
22790
|
+
function applyPivotInMemory(rows, pivot, filters) {
|
|
22791
|
+
if (!pivot) return rows;
|
|
22792
|
+
const multiAggPivot = pivot.aggregations ? pivot : singleAggToMultiAgg(pivot);
|
|
22793
|
+
if (multiAggPivot.rowField === void 0) {
|
|
22794
|
+
return aggregateToOneRow(rows, multiAggPivot.aggregations);
|
|
22795
|
+
}
|
|
22796
|
+
const { rowField, columnField, aggregations } = multiAggPivot;
|
|
22797
|
+
const dateBucket = inferDateBucketFromFilters(pivot, filters);
|
|
22798
|
+
const dateRange = dateBucket ? getDateRangeFromFilters(filters) : void 0;
|
|
22799
|
+
const getRowKey = dateBucket ? (row) => {
|
|
22800
|
+
const rawValue = row[rowField];
|
|
22801
|
+
const rawDateFromQuill = row.__quillRawDate;
|
|
22802
|
+
const rawDateValue = rawDateFromQuill ?? (rawValue !== null && typeof rawValue === "object" && rawValue.value ? rawValue.value : rawValue);
|
|
22803
|
+
return getDateKey(new Date(rawDateValue), dateBucket);
|
|
22804
|
+
} : (row) => row[rowField];
|
|
22805
|
+
const aggregated = columnField ? aggregateWithColumn(rows, columnField, aggregations, getRowKey) : aggregateWithoutColumn(rows, aggregations, getRowKey);
|
|
22806
|
+
const aggregatedRows = aggregated || {};
|
|
22807
|
+
if (rows.length === 0 && dateBucket && dateRange && !columnField) {
|
|
22808
|
+
const bucketKeys = generateBucketKeys(
|
|
22809
|
+
dateRange.start,
|
|
22810
|
+
dateRange.end,
|
|
22811
|
+
dateBucket
|
|
22812
|
+
);
|
|
22813
|
+
const emptyAgg = buildEmptyAggRow(aggregations);
|
|
22814
|
+
bucketKeys.forEach((k) => {
|
|
22815
|
+
aggregatedRows[k] = { ...emptyAgg };
|
|
22816
|
+
});
|
|
22817
|
+
}
|
|
22818
|
+
const finalRows = assembleFinalRows(
|
|
22819
|
+
aggregatedRows,
|
|
22820
|
+
rowField,
|
|
22821
|
+
dateBucket,
|
|
22822
|
+
rows.length === 0 ? dateRange : void 0
|
|
22823
|
+
);
|
|
22824
|
+
const sorted = sortRows(finalRows, pivot);
|
|
22825
|
+
if (pivot.rowLimit) {
|
|
22826
|
+
return sorted.slice(0, pivot.rowLimit);
|
|
22827
|
+
}
|
|
22828
|
+
return sorted;
|
|
22829
|
+
}
|
|
22830
|
+
function generatePivotColumnsInMemory({
|
|
22831
|
+
pivot,
|
|
22832
|
+
pivotRows,
|
|
22833
|
+
sourceColumns
|
|
22834
|
+
}) {
|
|
22835
|
+
if (!pivot?.rowField || !Array.isArray(pivotRows) || pivotRows.length === 0) {
|
|
22836
|
+
return void 0;
|
|
22837
|
+
}
|
|
22838
|
+
const columns = Array.isArray(sourceColumns) ? sourceColumns : [];
|
|
22839
|
+
const rowSource = columns.find((col) => col.field === pivot.rowField);
|
|
22840
|
+
const isRowFieldDate = isDateLikeType(pivot.rowFieldType);
|
|
22841
|
+
const rowFieldType = rowSource?.fieldType ?? pivot.rowFieldType ?? "string";
|
|
22842
|
+
const rowColumn = {
|
|
22843
|
+
field: pivot.rowField,
|
|
22844
|
+
label: rowSource?.label ?? pivot.rowField,
|
|
22845
|
+
format: isRowFieldDate ? "string" : rowSource?.format ?? "string",
|
|
22846
|
+
fieldType: rowFieldType,
|
|
22847
|
+
dataTypeID: rowSource?.dataTypeID ?? 1043,
|
|
22848
|
+
jsType: rowSource?.jsType ?? (isRowFieldDate ? "date" : "string")
|
|
22849
|
+
};
|
|
22850
|
+
const valueFieldFormat = (valueField) => columns.find((col) => col.field === valueField)?.format ?? "whole_number";
|
|
22851
|
+
const multiAgg = (pivot.aggregations?.length ?? 0) > 1;
|
|
22852
|
+
const aggregationBySuffix = new Map(
|
|
22853
|
+
(pivot.aggregations ?? []).map((agg) => [
|
|
22854
|
+
multiAgg ? `_${agg.aggregationType}` : "",
|
|
22855
|
+
agg
|
|
22856
|
+
])
|
|
22857
|
+
);
|
|
22858
|
+
const valueKeys = Array.from(
|
|
22859
|
+
new Set(
|
|
22860
|
+
pivotRows.flatMap(
|
|
22861
|
+
(row) => Object.keys(row).filter(
|
|
22862
|
+
(key) => key !== pivot.rowField && key !== "__quillRawDate"
|
|
22863
|
+
)
|
|
22864
|
+
)
|
|
22865
|
+
)
|
|
22866
|
+
);
|
|
22867
|
+
const valueColumns = valueKeys.map((key) => {
|
|
22868
|
+
const matchingSuffix = Array.from(aggregationBySuffix.keys()).find(
|
|
22869
|
+
(suffix) => suffix && key.endsWith(suffix)
|
|
22870
|
+
);
|
|
22871
|
+
const matchedAgg = matchingSuffix ? aggregationBySuffix.get(matchingSuffix) : pivot.aggregations?.[0];
|
|
22872
|
+
const format9 = matchedAgg?.aggregationType === "percentage" ? "percent" : valueFieldFormat(matchedAgg?.valueField);
|
|
22873
|
+
const valueFieldType = matchedAgg?.valueFieldType ?? "number";
|
|
22874
|
+
return {
|
|
22875
|
+
field: key,
|
|
22876
|
+
label: key,
|
|
22877
|
+
format: format9,
|
|
22878
|
+
fieldType: valueFieldType,
|
|
22879
|
+
jsType: valueFieldType,
|
|
22880
|
+
dataTypeID: columns.find((col) => col.field === matchedAgg?.valueField)?.dataTypeID ?? 20
|
|
22881
|
+
};
|
|
22882
|
+
});
|
|
22883
|
+
return [rowColumn, ...valueColumns];
|
|
22884
|
+
}
|
|
22885
|
+
|
|
22886
|
+
// src/utils/cacheCab.ts
|
|
22887
|
+
var import_idb = require("idb");
|
|
22888
|
+
var import_date_fns9 = require("date-fns");
|
|
22889
|
+
var import_date_fns_tz2 = require("date-fns-tz");
|
|
22890
|
+
var TZ = "America/Los_Angeles";
|
|
22891
|
+
var CacheCab = class {
|
|
22892
|
+
fetchedRange = {};
|
|
22893
|
+
cachedReportIds = [];
|
|
22894
|
+
uncacheableReportIDs = [];
|
|
22895
|
+
uncacheableInFlight = /* @__PURE__ */ new Map();
|
|
22896
|
+
storage;
|
|
22897
|
+
META_KEY = "cachecab:meta";
|
|
22898
|
+
DATA_PREFIX = "cachecab:data:";
|
|
22899
|
+
UNCACHEABLE_PREFIX = "cachecab:uncacheable:";
|
|
22900
|
+
constructor({
|
|
22901
|
+
storageType = "memory"
|
|
22902
|
+
} = {}) {
|
|
22903
|
+
this.storage = storageType !== "idb" ? new MemoryStorage() : new IdbStorage();
|
|
22904
|
+
void this.loadMetaFromStorage();
|
|
22905
|
+
}
|
|
22906
|
+
async get(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, pageSize, getToken, eventTracking, forceRefresh) {
|
|
22907
|
+
if (this.isCached(reportId, tenants) && !forceRefresh) {
|
|
22908
|
+
return this.getFromCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking);
|
|
22909
|
+
} else {
|
|
22910
|
+
return this.addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, true, forceRefresh);
|
|
22911
|
+
}
|
|
22912
|
+
}
|
|
22913
|
+
isCached(reportId, tenants) {
|
|
22914
|
+
return this.cachedReportIds.includes(this.getCacheKey(reportId, tenants));
|
|
22915
|
+
}
|
|
22916
|
+
isCacheable(reportId) {
|
|
22917
|
+
return !this.uncacheableReportIDs.includes(reportId);
|
|
22918
|
+
}
|
|
22919
|
+
async getUncacheableResult(reportId, client, tenants, flags, filters, additionalProcessing, pivot) {
|
|
22920
|
+
const key = this.getUncacheableRequestKey(
|
|
22921
|
+
reportId,
|
|
22922
|
+
client,
|
|
22923
|
+
tenants,
|
|
22924
|
+
flags,
|
|
22925
|
+
filters,
|
|
22926
|
+
additionalProcessing,
|
|
22927
|
+
pivot
|
|
22928
|
+
);
|
|
22929
|
+
try {
|
|
22930
|
+
const raw = await this.storage.getItem(key);
|
|
22931
|
+
return raw ? JSON.parse(raw) : null;
|
|
22932
|
+
} catch {
|
|
22933
|
+
return null;
|
|
22934
|
+
}
|
|
22935
|
+
}
|
|
22936
|
+
async setUncacheableResult(reportId, client, tenants, flags, filters, additionalProcessing, pivot, report) {
|
|
22937
|
+
const key = this.getUncacheableRequestKey(
|
|
22938
|
+
reportId,
|
|
22939
|
+
client,
|
|
22940
|
+
tenants,
|
|
22941
|
+
flags,
|
|
22942
|
+
filters,
|
|
22943
|
+
additionalProcessing,
|
|
22944
|
+
pivot
|
|
22945
|
+
);
|
|
22946
|
+
try {
|
|
22947
|
+
await this.storage.setItem(key, JSON.stringify(report));
|
|
22948
|
+
} catch {
|
|
22949
|
+
}
|
|
22950
|
+
}
|
|
22951
|
+
async getOrFetchUncacheableResult(reportId, client, tenants, flags, filters, additionalProcessing, pivot, fetcher, forceRefresh = false) {
|
|
22952
|
+
const key = this.getUncacheableRequestKey(
|
|
22953
|
+
reportId,
|
|
22954
|
+
client,
|
|
22955
|
+
tenants,
|
|
22956
|
+
flags,
|
|
22957
|
+
filters,
|
|
22958
|
+
additionalProcessing,
|
|
22959
|
+
pivot
|
|
22960
|
+
);
|
|
22961
|
+
if (!forceRefresh) {
|
|
22962
|
+
const raw = await this.storage.getItem(key);
|
|
22963
|
+
if (raw) {
|
|
22964
|
+
return { report: JSON.parse(raw), fromCache: true };
|
|
22965
|
+
}
|
|
22966
|
+
const inFlight = this.uncacheableInFlight.get(key);
|
|
22967
|
+
if (inFlight) {
|
|
22968
|
+
const report = await inFlight;
|
|
22969
|
+
return { report, fromCache: false };
|
|
22970
|
+
}
|
|
22971
|
+
}
|
|
22972
|
+
const requestPromise = (async () => {
|
|
22973
|
+
const report = await fetcher();
|
|
22974
|
+
try {
|
|
22975
|
+
await this.storage.setItem(key, JSON.stringify(report));
|
|
22976
|
+
} catch {
|
|
22977
|
+
}
|
|
22978
|
+
return report;
|
|
22979
|
+
})();
|
|
22980
|
+
this.uncacheableInFlight.set(key, requestPromise);
|
|
22981
|
+
try {
|
|
22982
|
+
const report = await requestPromise;
|
|
22983
|
+
return { report, fromCache: false };
|
|
22984
|
+
} finally {
|
|
22985
|
+
this.uncacheableInFlight.delete(key);
|
|
22986
|
+
}
|
|
22987
|
+
}
|
|
22988
|
+
async addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, firstTime = true, forceRefresh = false) {
|
|
22989
|
+
const tenantPart = tenants ? JSON.stringify(tenants) : "";
|
|
22990
|
+
const cacheKey = this.getCacheKey(reportId, tenants);
|
|
22991
|
+
if (firstTime) {
|
|
22992
|
+
const result = await this.fetchInitialReport({ reportId, client, tenants, flags, filters: dashboardFilters, getToken, eventTracking, forceRefresh });
|
|
22993
|
+
try {
|
|
22994
|
+
await this.storage.setItem(this.DATA_PREFIX + cacheKey, JSON.stringify(result));
|
|
22995
|
+
this.cachedReportIds.push(cacheKey);
|
|
22996
|
+
await this.persistMetaToStorage();
|
|
22997
|
+
} catch {
|
|
22998
|
+
console.warn(`Failed to cache report: ${reportId}. Cache full?`);
|
|
22999
|
+
}
|
|
23000
|
+
const newRows = await this.applyPivotsAndFilters(result, dashboardFilters, customFilters, pivot, tenantPart, false);
|
|
23001
|
+
if (pivot) {
|
|
23002
|
+
const pivotColumns = generatePivotColumnsInMemory({
|
|
23003
|
+
pivot,
|
|
23004
|
+
pivotRows: newRows,
|
|
23005
|
+
sourceColumns: result.columnInternal ?? result.columns
|
|
23006
|
+
});
|
|
23007
|
+
return { ...result, pivotRows: newRows, pivotColumns: pivotColumns ?? result.pivotColumns, pivotRowCount: newRows.length };
|
|
23008
|
+
}
|
|
23009
|
+
return { ...result, rows: newRows, rowCount: newRows.length };
|
|
23010
|
+
} else {
|
|
23011
|
+
const dbDateFilter = dashboardFilters.find((x) => x.filterType === "date_range");
|
|
23012
|
+
const { start: requestedStart, end: requestedEnd } = normalizePSTRanges(
|
|
23013
|
+
dbDateFilter?.startDate ? new Date(dbDateFilter.startDate) : void 0,
|
|
23014
|
+
dbDateFilter?.endDate ? new Date(dbDateFilter.endDate) : void 0
|
|
23015
|
+
);
|
|
23016
|
+
if (!requestedStart || !requestedEnd) {
|
|
23017
|
+
return this.addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, true);
|
|
23018
|
+
}
|
|
23019
|
+
const currentRange = this.fetchedRange[cacheKey];
|
|
23020
|
+
const rangeStart = currentRange?.start ?? requestedStart;
|
|
23021
|
+
const rangeEnd = currentRange?.end ?? endOfDayPST(/* @__PURE__ */ new Date());
|
|
23022
|
+
const existingRaw = await this.storage.getItem(this.DATA_PREFIX + cacheKey);
|
|
23023
|
+
let existing;
|
|
23024
|
+
let fetchedRows = [];
|
|
23025
|
+
try {
|
|
23026
|
+
existing = JSON.parse(existingRaw);
|
|
23027
|
+
if (!existing.rows) {
|
|
23028
|
+
throw new Error("Invalid Cache!");
|
|
23029
|
+
}
|
|
23030
|
+
if (requestedStart < rangeStart) {
|
|
23031
|
+
const olderReport = await this.fetchReport({
|
|
23032
|
+
reportId,
|
|
23033
|
+
client,
|
|
23034
|
+
tenants,
|
|
23035
|
+
flags,
|
|
23036
|
+
filters: dashboardFilters,
|
|
23037
|
+
getToken,
|
|
23038
|
+
eventTracking,
|
|
23039
|
+
start: requestedStart,
|
|
23040
|
+
end: rangeStart
|
|
23041
|
+
});
|
|
23042
|
+
fetchedRows = olderReport.rows;
|
|
23043
|
+
}
|
|
23044
|
+
if (requestedEnd && requestedEnd > rangeEnd) {
|
|
23045
|
+
const newerReport = await this.fetchReport({
|
|
23046
|
+
reportId,
|
|
23047
|
+
client,
|
|
23048
|
+
tenants,
|
|
23049
|
+
flags,
|
|
23050
|
+
filters: dashboardFilters,
|
|
23051
|
+
getToken,
|
|
23052
|
+
eventTracking,
|
|
23053
|
+
start: rangeEnd,
|
|
23054
|
+
end: requestedEnd
|
|
23055
|
+
});
|
|
23056
|
+
fetchedRows = fetchedRows.concat(newerReport.rows);
|
|
23057
|
+
}
|
|
23058
|
+
} catch {
|
|
23059
|
+
existing = await this.fetchReport({
|
|
23060
|
+
reportId,
|
|
23061
|
+
client,
|
|
23062
|
+
tenants,
|
|
23063
|
+
flags,
|
|
23064
|
+
filters: dashboardFilters,
|
|
23065
|
+
getToken,
|
|
23066
|
+
eventTracking,
|
|
23067
|
+
start: requestedStart,
|
|
23068
|
+
end: requestedEnd
|
|
23069
|
+
});
|
|
23070
|
+
fetchedRows = existing.rows;
|
|
23071
|
+
}
|
|
23072
|
+
const dateKey = existing.dateField?.field ? removeQuotes(existing.dateField.field) : void 0;
|
|
23073
|
+
let mergedRows;
|
|
23074
|
+
if (dateKey) {
|
|
23075
|
+
const startMs = rangeStart.getTime();
|
|
23076
|
+
const endMs = rangeEnd.getTime();
|
|
23077
|
+
const boundaryRows = existing.rows.filter((row) => {
|
|
23078
|
+
const raw = row[dateKey];
|
|
23079
|
+
if (!raw) return false;
|
|
23080
|
+
const t = new Date(raw).getTime();
|
|
23081
|
+
return Math.abs(t - startMs) <= MS_IN_DAY || Math.abs(t - endMs) <= MS_IN_DAY;
|
|
23082
|
+
});
|
|
23083
|
+
const filteredNew = filterNewRows(boundaryRows, fetchedRows);
|
|
23084
|
+
mergedRows = filteredNew.concat(existing.rows);
|
|
23085
|
+
} else {
|
|
23086
|
+
mergedRows = filterNewRows(existing.rows, fetchedRows).concat(existing.rows);
|
|
23087
|
+
}
|
|
23088
|
+
const merged = { ...existing, rows: mergedRows };
|
|
23089
|
+
await this.storage.setItem(this.DATA_PREFIX + cacheKey, JSON.stringify(merged));
|
|
23090
|
+
await this.persistMetaToStorage();
|
|
23091
|
+
const newRows = await this.applyPivotsAndFilters(merged, dashboardFilters, customFilters, pivot, tenantPart, false);
|
|
23092
|
+
if (pivot) {
|
|
23093
|
+
const pivotColumns = generatePivotColumnsInMemory({
|
|
23094
|
+
pivot,
|
|
23095
|
+
pivotRows: newRows,
|
|
23096
|
+
sourceColumns: merged.columnInternal ?? merged.columns
|
|
23097
|
+
});
|
|
23098
|
+
return { ...merged, pivotRows: newRows, pivotColumns: pivotColumns ?? merged.pivotColumns, pivotRowCount: newRows.length };
|
|
23099
|
+
}
|
|
23100
|
+
return { ...merged, rows: newRows, rowCount: newRows.length };
|
|
23101
|
+
}
|
|
23102
|
+
}
|
|
23103
|
+
/**
|
|
23104
|
+
* Returns cache entry (or re-queries if stale)
|
|
23105
|
+
*/
|
|
23106
|
+
async getFromCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking) {
|
|
23107
|
+
const dateRangeFilter = dashboardFilters.find((x) => x.filterType === "date_range");
|
|
23108
|
+
const cacheKey = this.getCacheKey(reportId, tenants);
|
|
23109
|
+
if (!dateRangeFilter || dateRangeFilter?.primaryRange.value === "ALL_TIME") {
|
|
23110
|
+
const fetchInfo = this.fetchedRange[cacheKey];
|
|
23111
|
+
if (!fetchInfo || fetchInfo?.allTimeDoneBefore === false || Date.now() - fetchInfo.fetchedAtUTCMS >= MS_IN_DAY) {
|
|
23112
|
+
return this.addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, true);
|
|
23113
|
+
}
|
|
23114
|
+
} else if (this.weShouldReQuery(cacheKey, dateRangeFilter)) {
|
|
23115
|
+
return this.addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, false);
|
|
23116
|
+
}
|
|
23117
|
+
try {
|
|
23118
|
+
const raw = await this.storage.getItem(this.DATA_PREFIX + cacheKey);
|
|
23119
|
+
if (!raw) {
|
|
23120
|
+
throw new Error("Invalid Cache!");
|
|
23121
|
+
}
|
|
23122
|
+
const parsed = JSON.parse(raw);
|
|
23123
|
+
const tenantPart = tenants ? JSON.stringify(tenants) : "";
|
|
23124
|
+
const newRows = await this.applyPivotsAndFilters(parsed, dashboardFilters, customFilters, pivot, tenantPart);
|
|
23125
|
+
if (pivot) {
|
|
23126
|
+
const pivotColumns = generatePivotColumnsInMemory({
|
|
23127
|
+
pivot,
|
|
23128
|
+
pivotRows: newRows,
|
|
23129
|
+
sourceColumns: parsed.columnInternal ?? parsed.columns
|
|
23130
|
+
});
|
|
23131
|
+
return { ...parsed, pivotRows: newRows, pivotColumns: pivotColumns ?? parsed.pivotColumns, pivotRowCount: newRows.length };
|
|
23132
|
+
}
|
|
23133
|
+
return { ...parsed, rows: newRows, rowCount: newRows.length };
|
|
23134
|
+
} catch (err) {
|
|
23135
|
+
console.error(err);
|
|
23136
|
+
return this.addToCache(reportId, dashboardFilters, customFilters, pivot, client, tenants, flags, getToken, eventTracking, false);
|
|
23137
|
+
}
|
|
23138
|
+
}
|
|
23139
|
+
weShouldReQuery(cacheKey, dateRangeFilter) {
|
|
23140
|
+
const start2 = dateRangeFilter.startDate;
|
|
23141
|
+
const end = dateRangeFilter.endDate;
|
|
23142
|
+
const range = this.fetchedRange[cacheKey];
|
|
23143
|
+
const { start: s, end: e } = normalizePSTRanges(
|
|
23144
|
+
start2 ? new Date(start2) : void 0,
|
|
23145
|
+
end ? new Date(end) : void 0
|
|
23146
|
+
);
|
|
23147
|
+
return !range || !s || !e || range.start > s || range.end < e;
|
|
23148
|
+
}
|
|
23149
|
+
async fetchInitialReport({
|
|
23150
|
+
reportId,
|
|
23151
|
+
client,
|
|
23152
|
+
tenants,
|
|
23153
|
+
flags,
|
|
23154
|
+
filters = [],
|
|
23155
|
+
getToken,
|
|
23156
|
+
eventTracking,
|
|
23157
|
+
forceRefresh
|
|
23158
|
+
}) {
|
|
23159
|
+
let start2;
|
|
23160
|
+
let end;
|
|
23161
|
+
const dateRangeFilter = filters.find((x) => x.filterType === "date_range");
|
|
23162
|
+
const cacheRange = dateRangeFilter?.initialCacheDateRange;
|
|
23163
|
+
if (cacheRange && cacheRange.startDate) {
|
|
23164
|
+
const startDate = dateRangeFilter?.startDate;
|
|
23165
|
+
start2 = startDate ? (0, import_date_fns9.min)([new Date(cacheRange.startDate), new Date(startDate)]) : new Date(cacheRange.startDate);
|
|
23166
|
+
end = endOfDayPST(/* @__PURE__ */ new Date());
|
|
23167
|
+
} else {
|
|
23168
|
+
const endDate = dateRangeFilter?.endDate ? new Date(dateRangeFilter.endDate) : void 0;
|
|
23169
|
+
const currentDay = endOfDayPST(/* @__PURE__ */ new Date());
|
|
23170
|
+
end = endDate ? (0, import_date_fns9.max)([currentDay, endDate]) : currentDay;
|
|
23171
|
+
start2 = (0, import_date_fns9.subMonths)(end, 7);
|
|
23172
|
+
}
|
|
23173
|
+
const normalized = normalizePSTRanges(start2, end);
|
|
23174
|
+
return this.fetchReport({
|
|
23175
|
+
reportId,
|
|
23176
|
+
client,
|
|
23177
|
+
tenants,
|
|
23178
|
+
flags,
|
|
23179
|
+
filters,
|
|
23180
|
+
getToken,
|
|
23181
|
+
eventTracking,
|
|
23182
|
+
start: normalized.start,
|
|
23183
|
+
end: normalized.end,
|
|
23184
|
+
forceRefresh
|
|
23185
|
+
});
|
|
23186
|
+
}
|
|
23187
|
+
async fetchReport({
|
|
23188
|
+
reportId,
|
|
23189
|
+
client,
|
|
23190
|
+
tenants,
|
|
23191
|
+
flags,
|
|
23192
|
+
filters = [],
|
|
23193
|
+
getToken,
|
|
23194
|
+
eventTracking,
|
|
23195
|
+
start: start2,
|
|
23196
|
+
end,
|
|
23197
|
+
forceRefresh
|
|
23198
|
+
}) {
|
|
23199
|
+
let reportInfo = void 0;
|
|
23200
|
+
try {
|
|
23201
|
+
const { start: s, end: e } = normalizePSTRanges(start2, end);
|
|
23202
|
+
const adjusted = [...filters].map((x) => {
|
|
23203
|
+
return { ...x, options: void 0 };
|
|
23204
|
+
});
|
|
23205
|
+
const dateFilterIndex = adjusted.findIndex((x) => x.filterType === "date_range");
|
|
23206
|
+
const isAllTime = dateFilterIndex !== -1 && adjusted[dateFilterIndex].primaryRange?.value === "ALL_TIME";
|
|
23207
|
+
if (!isAllTime) {
|
|
23208
|
+
const dateFilter = adjusted[dateFilterIndex];
|
|
23209
|
+
if (dateFilter && dateFilter.startDate && dateFilter.endDate) {
|
|
23210
|
+
adjusted[dateFilterIndex] = { ...dateFilter, startDate: s, endDate: e };
|
|
23211
|
+
}
|
|
23212
|
+
}
|
|
23213
|
+
const fetchResp = await quillFetch({
|
|
23214
|
+
client,
|
|
23215
|
+
task: "report",
|
|
23216
|
+
metadata: {
|
|
23217
|
+
reportId,
|
|
23218
|
+
clientId: client.publicKey,
|
|
23219
|
+
databaseType: client.databaseType,
|
|
23220
|
+
filters: adjusted,
|
|
23221
|
+
additionalProcessing: { page: { rowsPerPage: 1e3, rowsPerRequest: 1e5 } },
|
|
23222
|
+
useNewNodeSql: true,
|
|
23223
|
+
tenants,
|
|
23224
|
+
flags,
|
|
23225
|
+
overwriteCache: forceRefresh ?? false
|
|
23226
|
+
},
|
|
23227
|
+
getToken
|
|
23228
|
+
});
|
|
23229
|
+
const resp = await parseFetchResponse(
|
|
23230
|
+
client,
|
|
23231
|
+
"report",
|
|
23232
|
+
fetchResp,
|
|
23233
|
+
getToken,
|
|
23234
|
+
true
|
|
23235
|
+
);
|
|
23236
|
+
reportInfo = await processReportResponse({
|
|
23237
|
+
resp,
|
|
23238
|
+
client,
|
|
23239
|
+
filters: adjusted,
|
|
23240
|
+
dateBucket: resp?.dateBucket,
|
|
23241
|
+
additionalProcessing: { page: { rowsPerPage: 1e3, rowsPerRequest: 1e5 } },
|
|
23242
|
+
getToken,
|
|
23243
|
+
eventTracking,
|
|
23244
|
+
tenants,
|
|
23245
|
+
// CacheCab fetches with task: 'report'; keep pivot processing local.
|
|
23246
|
+
skipPivotFetch: true,
|
|
23247
|
+
overwriteCache: forceRefresh ?? false
|
|
23248
|
+
});
|
|
23249
|
+
const dateField = reportInfo.dateField?.field;
|
|
23250
|
+
if (!isAllTime && dateField !== void 0 && reportInfo.rows.length > 0) {
|
|
23251
|
+
const cleanedDateField = removeQuotes(dateField);
|
|
23252
|
+
const missingDateFieldCount = reportInfo.rows.some((row) => row[cleanedDateField] === void 0);
|
|
23253
|
+
if (missingDateFieldCount) {
|
|
23254
|
+
this.uncacheableReportIDs.push(reportId);
|
|
23255
|
+
return EMPTY_INTERNAL_REPORT;
|
|
23256
|
+
}
|
|
23257
|
+
}
|
|
23258
|
+
const requiredFilterFields = adjusted.flatMap((x, idx) => {
|
|
23259
|
+
if (idx === dateFilterIndex || !x.values && !x.selectedValue) return [];
|
|
23260
|
+
return removeQuotes(x.field);
|
|
23261
|
+
});
|
|
23262
|
+
const missingFields = [...new Set(requiredFilterFields.filter(
|
|
23263
|
+
(field) => reportInfo?.rows.some((row) => row[field] === void 0)
|
|
23264
|
+
))];
|
|
23265
|
+
if (missingFields.length > 0) {
|
|
23266
|
+
this.uncacheableReportIDs.push(reportId);
|
|
23267
|
+
return EMPTY_INTERNAL_REPORT;
|
|
23268
|
+
}
|
|
23269
|
+
const cacheKey = this.getCacheKey(reportId, tenants);
|
|
23270
|
+
if (isAllTime) {
|
|
23271
|
+
this.fetchedRange[cacheKey] = { start: /* @__PURE__ */ new Date(0), end: /* @__PURE__ */ new Date(), fetchedAtUTCMS: Date.now(), allTimeDoneBefore: true };
|
|
23272
|
+
} else {
|
|
23273
|
+
const existing = this.fetchedRange[cacheKey];
|
|
23274
|
+
if (existing && !forceRefresh) {
|
|
23275
|
+
const oldStart = existing.start;
|
|
23276
|
+
const oldEnd = existing.end;
|
|
23277
|
+
this.fetchedRange[cacheKey] = { start: getMinDate(oldStart, s), end: getMaxDate(oldEnd, e), fetchedAtUTCMS: Date.now(), allTimeDoneBefore: false };
|
|
23278
|
+
} else {
|
|
23279
|
+
this.fetchedRange[cacheKey] = { start: s, end: e, fetchedAtUTCMS: Date.now(), allTimeDoneBefore: false };
|
|
23280
|
+
}
|
|
23281
|
+
}
|
|
23282
|
+
} catch (error) {
|
|
23283
|
+
console.warn(error);
|
|
23284
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
23285
|
+
throw error;
|
|
23286
|
+
}
|
|
23287
|
+
}
|
|
23288
|
+
return reportInfo || EMPTY_INTERNAL_REPORT;
|
|
23289
|
+
}
|
|
23290
|
+
async applyPivotsAndFilters(report, dashboardFilters, customFilters, pivot, tenantPart, useCache = true) {
|
|
23291
|
+
const datasetVersion = this.fetchedRange[report.id + tenantPart]?.fetchedAtUTCMS ?? 0;
|
|
23292
|
+
const keyParts = [
|
|
23293
|
+
report.queryString,
|
|
23294
|
+
tenantPart,
|
|
23295
|
+
datasetVersion,
|
|
23296
|
+
// prevents fetching stale filters on hard refresh
|
|
23297
|
+
hashString(stableStringify(dashboardFilters)),
|
|
23298
|
+
hashString(stableStringify(customFilters))
|
|
23299
|
+
];
|
|
23300
|
+
const queryKey = this.DATA_PREFIX + keyParts.join("|");
|
|
23301
|
+
let filtersApplied;
|
|
23302
|
+
if (useCache) {
|
|
23303
|
+
try {
|
|
23304
|
+
const cache = await this.storage.getItem(queryKey);
|
|
23305
|
+
if (cache) {
|
|
23306
|
+
filtersApplied = JSON.parse(cache);
|
|
23307
|
+
}
|
|
23308
|
+
} catch {
|
|
23309
|
+
}
|
|
23310
|
+
}
|
|
23311
|
+
if (!filtersApplied) {
|
|
23312
|
+
const dateIndex = dashboardFilters.findIndex((x) => x.filterType === "date_range");
|
|
23313
|
+
const requiredFilterFields = dashboardFilters.flatMap((x, idx) => {
|
|
23314
|
+
if (idx === dateIndex || !x.values?.length && !x.selectedValue) return [];
|
|
23315
|
+
return removeQuotes(x.field);
|
|
23316
|
+
});
|
|
23317
|
+
const missingFields = [...new Set(requiredFilterFields.filter(
|
|
23318
|
+
(field) => report.rows.some((row) => row[field] === void 0)
|
|
23319
|
+
))];
|
|
23320
|
+
if (missingFields.length > 0) {
|
|
23321
|
+
this.uncacheableReportIDs.push(report.id);
|
|
23322
|
+
return [];
|
|
23323
|
+
}
|
|
23324
|
+
const dbDateFilter = dashboardFilters.find((x) => x.filterType === "date_range");
|
|
23325
|
+
if (report.dateField && dbDateFilter?.startDate) {
|
|
23326
|
+
const { start: startDate, end: endDate } = normalizePSTRanges(
|
|
23327
|
+
new Date(dbDateFilter.startDate),
|
|
23328
|
+
dbDateFilter.endDate ? new Date(dbDateFilter.endDate) : void 0
|
|
23329
|
+
);
|
|
23330
|
+
const fieldToUse = report.rows[0] && report.rows[0]["__quillRawDate"] ? "__quillRawDate" : removeQuotes(report.dateField.field);
|
|
23331
|
+
const dateFilteredRows = report.rows.filter((x) => {
|
|
23332
|
+
const rowDate = new Date(x[fieldToUse]);
|
|
23333
|
+
return startDate <= rowDate && (endDate ? rowDate <= endDate : true);
|
|
23334
|
+
});
|
|
23335
|
+
filtersApplied = applyFiltersInMemory(dateFilteredRows, [], { dashboardFilters, customFilters });
|
|
23336
|
+
} else {
|
|
23337
|
+
filtersApplied = applyFiltersInMemory(report.rows, [], { dashboardFilters, customFilters });
|
|
23338
|
+
}
|
|
23339
|
+
}
|
|
23340
|
+
try {
|
|
23341
|
+
await this.storage.setItem(queryKey, JSON.stringify(filtersApplied));
|
|
23342
|
+
} catch {
|
|
23343
|
+
}
|
|
23344
|
+
const withPivot = applyPivotInMemory(filtersApplied, pivot, dashboardFilters.concat(customFilters));
|
|
23345
|
+
return withPivot;
|
|
23346
|
+
}
|
|
23347
|
+
getCacheKey(reportId, tenants) {
|
|
23348
|
+
const tenantPart = tenants ? JSON.stringify(tenants) : "";
|
|
23349
|
+
return reportId + tenantPart;
|
|
23350
|
+
}
|
|
23351
|
+
getUncacheableRequestKey(reportId, client, tenants, flags, filters, additionalProcessing, pivot) {
|
|
23352
|
+
const canonicalFilters = filters.map(
|
|
23353
|
+
(f) => canonicalizeFilterForUncacheableKey(f)
|
|
23354
|
+
);
|
|
23355
|
+
const keyParts = [
|
|
23356
|
+
reportId,
|
|
23357
|
+
client.publicKey,
|
|
23358
|
+
client.databaseType,
|
|
23359
|
+
hashString(stableStringify(canonicalizeForKey(tenants ?? null))),
|
|
23360
|
+
hashString(stableStringify(canonicalizeForKey(flags ?? null))),
|
|
23361
|
+
hashString(stableStringify(canonicalFilters)),
|
|
23362
|
+
hashString(stableStringify(canonicalizeForKey(additionalProcessing ?? null))),
|
|
23363
|
+
hashString(stableStringify(canonicalizeForKey(pivot ?? null)))
|
|
23364
|
+
];
|
|
23365
|
+
return this.UNCACHEABLE_PREFIX + keyParts.join("|");
|
|
23366
|
+
}
|
|
23367
|
+
async loadMetaFromStorage() {
|
|
23368
|
+
const meta = await this.storage.getItem(this.META_KEY);
|
|
23369
|
+
if (!meta) return;
|
|
23370
|
+
try {
|
|
23371
|
+
const parsed = JSON.parse(meta);
|
|
23372
|
+
this.cachedReportIds = parsed.cached || [];
|
|
23373
|
+
this.uncacheableReportIDs = parsed.cannotBeCached;
|
|
23374
|
+
this.fetchedRange = Object.fromEntries(
|
|
23375
|
+
Object.entries(parsed.fetchedRange || {}).map(([id2, range]) => [
|
|
23376
|
+
id2,
|
|
23377
|
+
{ ...range, start: new Date(range.start), end: new Date(range.end) }
|
|
23378
|
+
])
|
|
23379
|
+
);
|
|
23380
|
+
} catch (err) {
|
|
23381
|
+
console.warn("CacheCab: could not parse meta from storage", err);
|
|
23382
|
+
}
|
|
23383
|
+
}
|
|
23384
|
+
async persistMetaToStorage() {
|
|
23385
|
+
const serializableRange = Object.fromEntries(
|
|
23386
|
+
Object.entries(this.fetchedRange).map(([id2, range]) => [
|
|
23387
|
+
id2,
|
|
23388
|
+
{ ...range }
|
|
23389
|
+
])
|
|
23390
|
+
);
|
|
23391
|
+
await this.storage.setItem(
|
|
23392
|
+
this.META_KEY,
|
|
23393
|
+
JSON.stringify({
|
|
23394
|
+
fetchedRange: serializableRange,
|
|
23395
|
+
cached: this.cachedReportIds,
|
|
23396
|
+
cannotBeCached: this.uncacheableReportIDs
|
|
23397
|
+
})
|
|
23398
|
+
);
|
|
23399
|
+
}
|
|
23400
|
+
};
|
|
23401
|
+
var MemoryStorage = class {
|
|
23402
|
+
store = /* @__PURE__ */ new Map();
|
|
23403
|
+
async getItem(key) {
|
|
23404
|
+
return this.store.get(key) ?? null;
|
|
23405
|
+
}
|
|
23406
|
+
async setItem(key, value) {
|
|
23407
|
+
this.store.set(key, value);
|
|
23408
|
+
}
|
|
23409
|
+
};
|
|
23410
|
+
var DB_NAME = "quill.cachecab";
|
|
23411
|
+
var STORE_NAME = "kv";
|
|
23412
|
+
var IdbStorage = class {
|
|
23413
|
+
dbPromise;
|
|
23414
|
+
constructor() {
|
|
23415
|
+
this.dbPromise = (0, import_idb.openDB)(DB_NAME, 1, {
|
|
23416
|
+
upgrade(db) {
|
|
23417
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
23418
|
+
db.createObjectStore(STORE_NAME);
|
|
23419
|
+
}
|
|
23420
|
+
}
|
|
23421
|
+
});
|
|
23422
|
+
}
|
|
23423
|
+
async getItem(key) {
|
|
23424
|
+
const db = await this.dbPromise;
|
|
23425
|
+
return await db.get(STORE_NAME, key) ?? null;
|
|
23426
|
+
}
|
|
23427
|
+
async setItem(key, value) {
|
|
23428
|
+
const db = await this.dbPromise;
|
|
23429
|
+
await db.put(STORE_NAME, value, key);
|
|
23430
|
+
}
|
|
23431
|
+
};
|
|
23432
|
+
function removeQuotes(str) {
|
|
23433
|
+
return str.replace(/^['"]|['"]$/g, "");
|
|
23434
|
+
}
|
|
23435
|
+
function getMaxDate(d1, d2) {
|
|
23436
|
+
return d1 > d2 ? d1 : d2;
|
|
23437
|
+
}
|
|
23438
|
+
function getMinDate(d1, d2) {
|
|
23439
|
+
return d2 > d1 ? d1 : d2;
|
|
23440
|
+
}
|
|
23441
|
+
function hashString(str) {
|
|
23442
|
+
let h1 = 3735928559 ^ 0, h2 = 1103547991 ^ 0;
|
|
23443
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
23444
|
+
ch = str.charCodeAt(i);
|
|
23445
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
23446
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
23447
|
+
}
|
|
23448
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
23449
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
23450
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
|
|
23451
|
+
}
|
|
23452
|
+
function filterNewRows(existingRows, newRows) {
|
|
23453
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23454
|
+
const getKey = (row) => stableStringify(row);
|
|
23455
|
+
existingRows.forEach((row) => seen.add(getKey(row)));
|
|
23456
|
+
return newRows.filter((row) => {
|
|
23457
|
+
const k = getKey(row);
|
|
23458
|
+
if (seen.has(k)) return false;
|
|
23459
|
+
seen.add(k);
|
|
23460
|
+
return true;
|
|
23461
|
+
});
|
|
23462
|
+
}
|
|
23463
|
+
function stableStringify(obj) {
|
|
23464
|
+
if (obj === null || typeof obj !== "object") return JSON.stringify(obj);
|
|
23465
|
+
if (Array.isArray(obj)) {
|
|
23466
|
+
return `[${obj.map(stableStringify).join(",")}]`;
|
|
23467
|
+
}
|
|
23468
|
+
const keys = Object.keys(obj).sort();
|
|
23469
|
+
return `{${keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",")}}`;
|
|
23470
|
+
}
|
|
23471
|
+
function canonicalizeForKey(value) {
|
|
23472
|
+
if (value instanceof Date) {
|
|
23473
|
+
return value.toISOString();
|
|
23474
|
+
}
|
|
23475
|
+
if (Array.isArray(value)) {
|
|
23476
|
+
return value.map(canonicalizeForKey);
|
|
23477
|
+
}
|
|
23478
|
+
if (value && typeof value === "object") {
|
|
23479
|
+
const out = {};
|
|
23480
|
+
Object.keys(value).sort().forEach((key) => {
|
|
23481
|
+
if (value[key] !== void 0) {
|
|
23482
|
+
out[key] = canonicalizeForKey(value[key]);
|
|
23483
|
+
}
|
|
23484
|
+
});
|
|
23485
|
+
return out;
|
|
23486
|
+
}
|
|
23487
|
+
return value;
|
|
23488
|
+
}
|
|
23489
|
+
function canonicalizeFilterForUncacheableKey(filter) {
|
|
23490
|
+
const raw = canonicalizeForKey(filter) ?? {};
|
|
23491
|
+
const base = {
|
|
23492
|
+
filterType: raw.filterType,
|
|
23493
|
+
field: raw.field,
|
|
23494
|
+
table: raw.table,
|
|
23495
|
+
label: raw.label,
|
|
23496
|
+
operator: raw.operator
|
|
23497
|
+
};
|
|
23498
|
+
if (raw.selectedValue !== void 0) {
|
|
23499
|
+
base.selectedValue = raw.selectedValue;
|
|
23500
|
+
}
|
|
23501
|
+
if (Array.isArray(raw.values)) {
|
|
23502
|
+
base.values = [...raw.values].map(canonicalizeForKey).sort();
|
|
23503
|
+
}
|
|
23504
|
+
if (raw.value !== void 0) {
|
|
23505
|
+
base.value = canonicalizeForKey(raw.value);
|
|
23506
|
+
}
|
|
23507
|
+
if (raw.filterType === "date_range") {
|
|
23508
|
+
const { start: start2, end } = normalizePSTRanges(
|
|
23509
|
+
raw.startDate ? new Date(raw.startDate) : void 0,
|
|
23510
|
+
raw.endDate ? new Date(raw.endDate) : void 0
|
|
23511
|
+
);
|
|
23512
|
+
base.startDate = start2 ? start2.toISOString() : void 0;
|
|
23513
|
+
base.endDate = end ? end.toISOString() : void 0;
|
|
23514
|
+
base.primaryRange = raw.primaryRange?.value;
|
|
23515
|
+
base.comparisonRange = raw.comparisonRange?.value;
|
|
23516
|
+
}
|
|
23517
|
+
return canonicalizeForKey(base);
|
|
23518
|
+
}
|
|
23519
|
+
function startOfDayPST(date) {
|
|
23520
|
+
const pstDate = (0, import_date_fns_tz2.utcToZonedTime)(date, TZ);
|
|
23521
|
+
const startPst = (0, import_date_fns9.startOfDay)(pstDate);
|
|
23522
|
+
return (0, import_date_fns_tz2.zonedTimeToUtc)(startPst, TZ);
|
|
23523
|
+
}
|
|
23524
|
+
function endOfDayPST(date) {
|
|
23525
|
+
const pstDate = (0, import_date_fns_tz2.utcToZonedTime)(date, TZ);
|
|
23526
|
+
const endPst = (0, import_date_fns9.endOfDay)(pstDate);
|
|
23527
|
+
return (0, import_date_fns_tz2.zonedTimeToUtc)(endPst, TZ);
|
|
23528
|
+
}
|
|
23529
|
+
function normalizePSTRanges(start2, end) {
|
|
23530
|
+
return {
|
|
23531
|
+
start: start2 ? startOfDayPST(start2) : void 0,
|
|
23532
|
+
end: end ? endOfDayPST(end) : void 0
|
|
23533
|
+
};
|
|
23534
|
+
}
|
|
23535
|
+
|
|
23536
|
+
// src/Context.tsx
|
|
21589
23537
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
21590
23538
|
var dummySetter = () => {
|
|
21591
23539
|
};
|
|
@@ -21917,7 +23865,9 @@ var ReportFiltersContext = (0, import_react.createContext)({
|
|
|
21917
23865
|
loadFiltersForReport: async () => {
|
|
21918
23866
|
},
|
|
21919
23867
|
abortLoadingFilters: () => {
|
|
21920
|
-
}
|
|
23868
|
+
},
|
|
23869
|
+
customFiltersLoaded: false,
|
|
23870
|
+
setCustomFiltersLoaded: dummySetter
|
|
21921
23871
|
});
|
|
21922
23872
|
var customDashboardFiltersReducer = (state, action) => {
|
|
21923
23873
|
switch (action.type) {
|
|
@@ -22007,6 +23957,9 @@ var FetchContext = (0, import_react.createContext)({
|
|
|
22007
23957
|
var EventTrackingContext = (0, import_react.createContext)({
|
|
22008
23958
|
eventTracking: null
|
|
22009
23959
|
});
|
|
23960
|
+
var CacheCabContext = (0, import_react.createContext)({
|
|
23961
|
+
getCacheCab: (storageType) => new CacheCab({ storageType })
|
|
23962
|
+
});
|
|
22010
23963
|
var ContextProvider = ({
|
|
22011
23964
|
children,
|
|
22012
23965
|
initialTheme,
|
|
@@ -22020,6 +23973,14 @@ var ContextProvider = ({
|
|
|
22020
23973
|
getAuthorizationToken = async () => "",
|
|
22021
23974
|
eventTracking = null
|
|
22022
23975
|
}) => {
|
|
23976
|
+
const cacheCabByTypeRef = (0, import_react.useRef)({});
|
|
23977
|
+
const getCacheCab = (0, import_react.useCallback)((storageType) => {
|
|
23978
|
+
const key = storageType === "idb" ? "idb" : "memory";
|
|
23979
|
+
if (!cacheCabByTypeRef.current[key]) {
|
|
23980
|
+
cacheCabByTypeRef.current[key] = new CacheCab({ storageType: key });
|
|
23981
|
+
}
|
|
23982
|
+
return cacheCabByTypeRef.current[key];
|
|
23983
|
+
}, []);
|
|
22023
23984
|
const [client, setClient] = (0, import_react.useState)(
|
|
22024
23985
|
typeof window !== "undefined" && sessionStorage ? JSON.parse(sessionStorage.getItem("quill-client") ?? "null") : null
|
|
22025
23986
|
);
|
|
@@ -22082,6 +24043,7 @@ var ContextProvider = ({
|
|
|
22082
24043
|
reportFiltersReducer,
|
|
22083
24044
|
{}
|
|
22084
24045
|
);
|
|
24046
|
+
const [customFiltersLoaded, setCustomFiltersLoaded] = (0, import_react.useState)(false);
|
|
22085
24047
|
const reportFilterOptionsAbortControllers = (0, import_react.useRef)({});
|
|
22086
24048
|
const [reports, reportsDispatch] = (0, import_react.useReducer)(reportsReducer, {});
|
|
22087
24049
|
const [reportsLoadingState, reportsLoadingStateDispatch] = (0, import_react.useReducer)(
|
|
@@ -22105,6 +24067,11 @@ var ContextProvider = ({
|
|
|
22105
24067
|
const viewerTenantsByOwnerRequests = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
22106
24068
|
const mappedTenantsRequests = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
22107
24069
|
const loadDashboardProcessId = (0, import_react.useRef)({});
|
|
24070
|
+
(0, import_react.useEffect)(() => {
|
|
24071
|
+
if (Object.keys(customReportFilters).length) {
|
|
24072
|
+
setCustomFiltersLoaded(true);
|
|
24073
|
+
}
|
|
24074
|
+
}, [customReportFilters]);
|
|
22108
24075
|
(0, import_react.useEffect)(() => {
|
|
22109
24076
|
if (!theme) {
|
|
22110
24077
|
const populatedTheme = {
|
|
@@ -22873,6 +24840,7 @@ var ContextProvider = ({
|
|
|
22873
24840
|
...dashboard2,
|
|
22874
24841
|
dateFilter: dashboard2.dateFilter ? {
|
|
22875
24842
|
...dashboard2.dateFilter,
|
|
24843
|
+
initialCacheDateRange: dashboard2.initialCacheDateRange ? { ...dashboard2.initialCacheDateRange } : void 0,
|
|
22876
24844
|
presetOptions: dashboard2.dateFilter.presetOptions?.map(
|
|
22877
24845
|
(preset) => ({
|
|
22878
24846
|
...preset,
|
|
@@ -23215,6 +25183,7 @@ var ContextProvider = ({
|
|
|
23215
25183
|
...dashboard2,
|
|
23216
25184
|
dateFilter: dashboard2.dateFilter ? {
|
|
23217
25185
|
...dashboard2.dateFilter,
|
|
25186
|
+
initialCacheDateRange: dashboard2.initialCacheDateRange ? { ...dashboard2.initialCacheDateRange } : void 0,
|
|
23218
25187
|
presetOptions: dashboard2.dateFilter.presetOptions?.map(
|
|
23219
25188
|
(preset) => ({
|
|
23220
25189
|
...preset,
|
|
@@ -23259,6 +25228,7 @@ var ContextProvider = ({
|
|
|
23259
25228
|
if (dashboard2.dateFilter) {
|
|
23260
25229
|
dashboard2.dateFilter = {
|
|
23261
25230
|
...dashboard2.dateFilter,
|
|
25231
|
+
initialCacheDateRange: dashboard2.initialCacheDateRange ? { ...dashboard2.initialCacheDateRange } : void 0,
|
|
23262
25232
|
startDate: presetOptions.find(
|
|
23263
25233
|
(elem) => elem.value === dashboard2.dateFilter.primaryRange?.value
|
|
23264
25234
|
)?.startDate,
|
|
@@ -23527,7 +25497,7 @@ var ContextProvider = ({
|
|
|
23527
25497
|
if (!theme) {
|
|
23528
25498
|
return null;
|
|
23529
25499
|
}
|
|
23530
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CacheCabContext.Provider, { value: { getCacheCab }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
23531
25501
|
ClientContext.Provider,
|
|
23532
25502
|
{
|
|
23533
25503
|
value: [
|
|
@@ -23568,7 +25538,9 @@ var ContextProvider = ({
|
|
|
23568
25538
|
reportFiltersDispatch,
|
|
23569
25539
|
customReportFiltersDispatch,
|
|
23570
25540
|
loadFiltersForReport,
|
|
23571
|
-
abortLoadingFilters
|
|
25541
|
+
abortLoadingFilters,
|
|
25542
|
+
customFiltersLoaded,
|
|
25543
|
+
setCustomFiltersLoaded
|
|
23572
25544
|
},
|
|
23573
25545
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
23574
25546
|
ReportsContext.Provider,
|
|
@@ -23611,7 +25583,7 @@ var ContextProvider = ({
|
|
|
23611
25583
|
}
|
|
23612
25584
|
) })
|
|
23613
25585
|
}
|
|
23614
|
-
);
|
|
25586
|
+
) });
|
|
23615
25587
|
};
|
|
23616
25588
|
|
|
23617
25589
|
// src/hooks/useExport.tsx
|
|
@@ -23627,9 +25599,9 @@ init_Filter();
|
|
|
23627
25599
|
init_filterProcessing();
|
|
23628
25600
|
|
|
23629
25601
|
// src/utils/merge.ts
|
|
23630
|
-
var
|
|
25602
|
+
var import_date_fns10 = require("date-fns");
|
|
23631
25603
|
init_columnType();
|
|
23632
|
-
var
|
|
25604
|
+
var import_date_fns_tz3 = require("date-fns-tz");
|
|
23633
25605
|
function mergeComparisonRange(resp) {
|
|
23634
25606
|
if (resp.chartType === "table") return resp;
|
|
23635
25607
|
const compRows = resp.compareRows;
|
|
@@ -23672,6 +25644,18 @@ var useDashboardInternal = (dashboardName, customFilters) => {
|
|
|
23672
25644
|
(f) => f.filter
|
|
23673
25645
|
) : null;
|
|
23674
25646
|
}, [dashboardFilters, dashboardName]);
|
|
25647
|
+
const getExistingDateFilter = (0, import_react2.useMemo)(
|
|
25648
|
+
() => (name2) => {
|
|
25649
|
+
if (!name2) return void 0;
|
|
25650
|
+
const filtersForDashboard = dashboardFilters[name2];
|
|
25651
|
+
if (!filtersForDashboard) return void 0;
|
|
25652
|
+
const entry = Object.values(filtersForDashboard).find(
|
|
25653
|
+
(f) => f?.filter?.filterType === "date_range" /* Date */
|
|
25654
|
+
);
|
|
25655
|
+
return entry?.filter;
|
|
25656
|
+
},
|
|
25657
|
+
[dashboardFilters]
|
|
25658
|
+
);
|
|
23675
25659
|
(0, import_react2.useEffect)(() => {
|
|
23676
25660
|
if (!dashboardName) return;
|
|
23677
25661
|
if (backfilledDashboards.current.has(dashboardName)) return;
|
|
@@ -23709,7 +25693,7 @@ var useDashboardInternal = (dashboardName, customFilters) => {
|
|
|
23709
25693
|
customFilters
|
|
23710
25694
|
);
|
|
23711
25695
|
}, [dashboardName, loading, dashboardConfig, dashboardFilters]);
|
|
23712
|
-
const handleReload = async (overrideDashboardName, fetchFromServer = false, reportAction, overrideFilters) => {
|
|
25696
|
+
const handleReload = async (overrideDashboardName, fetchFromServer = false, reportAction, overrideFilters, options) => {
|
|
23713
25697
|
if (!dashboardName) return;
|
|
23714
25698
|
if (overrideFilters) {
|
|
23715
25699
|
const dateFilter2 = overrideFilters.filters.find(
|
|
@@ -23762,10 +25746,19 @@ var useDashboardInternal = (dashboardName, customFilters) => {
|
|
|
23762
25746
|
Object.values(dashboard?.sections ?? {}).flat(),
|
|
23763
25747
|
dashboardName
|
|
23764
25748
|
) : void 0;
|
|
25749
|
+
const existingDateFilter = options?.preserveExistingDateFilter ? getExistingDateFilter(dashboardName) : void 0;
|
|
25750
|
+
const mergedDateFilter = dateFilter && existingDateFilter ? {
|
|
25751
|
+
...dateFilter,
|
|
25752
|
+
startDate: existingDateFilter.startDate ?? dateFilter.startDate,
|
|
25753
|
+
endDate: existingDateFilter.endDate ?? dateFilter.endDate,
|
|
25754
|
+
preset: existingDateFilter.preset ?? dateFilter.preset,
|
|
25755
|
+
primaryRange: existingDateFilter.primaryRange ?? dateFilter.primaryRange,
|
|
25756
|
+
comparisonRange: existingDateFilter.comparisonRange ?? dateFilter.comparisonRange
|
|
25757
|
+
} : dateFilter ?? existingDateFilter;
|
|
23765
25758
|
loadFiltersForDashboard(
|
|
23766
25759
|
dashboardName,
|
|
23767
25760
|
[
|
|
23768
|
-
...
|
|
25761
|
+
...mergedDateFilter ? [mergedDateFilter] : [],
|
|
23769
25762
|
...updatedDashboard?.filters?.map((filter) => ({
|
|
23770
25763
|
...filter,
|
|
23771
25764
|
query: void 0
|
|
@@ -24050,7 +26043,8 @@ var useDashboards = () => {
|
|
|
24050
26043
|
tenantFilters,
|
|
24051
26044
|
dateFilter,
|
|
24052
26045
|
customFilters,
|
|
24053
|
-
tenantKeys
|
|
26046
|
+
tenantKeys,
|
|
26047
|
+
initialCacheDateRange
|
|
24054
26048
|
}) => {
|
|
24055
26049
|
if (!client) return;
|
|
24056
26050
|
if (tenantKeys?.some((key) => !key)) {
|
|
@@ -24071,6 +26065,7 @@ var useDashboards = () => {
|
|
|
24071
26065
|
filters,
|
|
24072
26066
|
tenantFilters,
|
|
24073
26067
|
dateFilter: dateFilter ?? null,
|
|
26068
|
+
initialCacheDateRange,
|
|
24074
26069
|
name: name2.trim(),
|
|
24075
26070
|
task: "edit-dashboard",
|
|
24076
26071
|
clientId: client.clientId,
|
|
@@ -24282,7 +26277,9 @@ var useDashboards = () => {
|
|
|
24282
26277
|
};
|
|
24283
26278
|
};
|
|
24284
26279
|
var useDashboard = (dashboardName, config) => {
|
|
26280
|
+
const logCacheStatistics = config?.showCacheLogs || false;
|
|
24285
26281
|
const { data, dashboardFilters, reload, isLoading } = useDashboardInternal(dashboardName);
|
|
26282
|
+
const [lastUpdated, setLastUpdated] = (0, import_react2.useState)(0);
|
|
24286
26283
|
const { customFilterDispatch } = (0, import_react2.useContext)(DashboardFiltersContext);
|
|
24287
26284
|
const { reportsDispatch, reportsLoadingStateDispatch } = (0, import_react2.useContext)(ReportsContext);
|
|
24288
26285
|
const initialLoad = (0, import_react2.useRef)(true);
|
|
@@ -24291,15 +26288,19 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24291
26288
|
const [client] = (0, import_react2.useContext)(ClientContext);
|
|
24292
26289
|
const { tenants, flags } = (0, import_react2.useContext)(TenantContext);
|
|
24293
26290
|
const { getToken } = (0, import_react2.useContext)(FetchContext);
|
|
24294
|
-
const { customReportFilters } = (0, import_react2.useContext)(ReportFiltersContext);
|
|
26291
|
+
const { customReportFilters, customFiltersLoaded, setCustomFiltersLoaded } = (0, import_react2.useContext)(ReportFiltersContext);
|
|
24295
26292
|
const { eventTracking } = (0, import_react2.useContext)(EventTrackingContext);
|
|
24296
|
-
const
|
|
26293
|
+
const { getCacheCab } = (0, import_react2.useContext)(CacheCabContext);
|
|
24297
26294
|
const reportRequestIds = (0, import_react2.useRef)({});
|
|
24298
26295
|
const lastDashboardName = (0, import_react2.useRef)(null);
|
|
24299
26296
|
const pendingNameChangeReload = (0, import_react2.useRef)(false);
|
|
24300
|
-
(0, import_react2.
|
|
24301
|
-
|
|
24302
|
-
|
|
26297
|
+
const [loadedDashes, setLoadedDashes] = (0, import_react2.useState)([]);
|
|
26298
|
+
const [lastUpdatedDict, setLastUpdatedDict] = (0, import_react2.useState)({});
|
|
26299
|
+
const cacheEnabled = config?.cacheEnabled ?? true;
|
|
26300
|
+
const cacheCab = (0, import_react2.useMemo)(
|
|
26301
|
+
() => getCacheCab(config?.cacheType),
|
|
26302
|
+
[getCacheCab, config?.cacheType]
|
|
26303
|
+
);
|
|
24303
26304
|
(0, import_react2.useEffect)(() => {
|
|
24304
26305
|
const nameChanged = dashboardName !== lastDashboardName.current;
|
|
24305
26306
|
if (nameChanged) {
|
|
@@ -24309,19 +26310,29 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24309
26310
|
backfilledDashboards.current = false;
|
|
24310
26311
|
reportRequestIds.current = {};
|
|
24311
26312
|
pendingNameChangeReload.current = true;
|
|
26313
|
+
if (customFiltersLoaded && !loadedDashes.includes(dashboardName)) {
|
|
26314
|
+
setCustomFiltersLoaded(false);
|
|
26315
|
+
}
|
|
26316
|
+
setLastUpdated(lastUpdatedDict[dashboardName] || 0);
|
|
24312
26317
|
}
|
|
24313
26318
|
if (!dashboardName) return;
|
|
24314
26319
|
if (pendingNameChangeReload.current && data) {
|
|
24315
26320
|
pendingNameChangeReload.current = false;
|
|
24316
26321
|
initialLoad.current = false;
|
|
26322
|
+
fetchedInitialReports.current = false;
|
|
24317
26323
|
return;
|
|
24318
26324
|
}
|
|
24319
26325
|
if (pendingNameChangeReload.current && !isLoading && !data && initialLoad.current) {
|
|
24320
26326
|
initialLoad.current = false;
|
|
24321
26327
|
pendingNameChangeReload.current = false;
|
|
24322
|
-
reload(
|
|
26328
|
+
reload(dashboardName, false, void 0, void 0, {
|
|
26329
|
+
preserveExistingDateFilter: true
|
|
26330
|
+
});
|
|
24323
26331
|
}
|
|
24324
26332
|
}, [isLoading, data, dashboardName]);
|
|
26333
|
+
(0, import_react2.useEffect)(() => {
|
|
26334
|
+
setLastUpdated(lastUpdatedDict[dashboardName] || 0);
|
|
26335
|
+
}, [lastUpdatedDict, dashboardName]);
|
|
24325
26336
|
(0, import_react2.useEffect)(() => {
|
|
24326
26337
|
if (backfilledDashboards.current) return;
|
|
24327
26338
|
if (isLoading || !data) return;
|
|
@@ -24330,7 +26341,9 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24330
26341
|
);
|
|
24331
26342
|
if (!needsBackfill) return;
|
|
24332
26343
|
backfilledDashboards.current = true;
|
|
24333
|
-
reload(dashboardName, false
|
|
26344
|
+
reload(dashboardName, false, void 0, void 0, {
|
|
26345
|
+
preserveExistingDateFilter: true
|
|
26346
|
+
});
|
|
24334
26347
|
}, [isLoading, data, dashboardFilters, dashboardName]);
|
|
24335
26348
|
const { allReportsById } = useAllReports();
|
|
24336
26349
|
const sections = (0, import_react2.useMemo)(() => {
|
|
@@ -24354,7 +26367,13 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24354
26367
|
fetchedInitialReports.current = true;
|
|
24355
26368
|
fetchReports([], dashboardFilters ?? [], config?.pageSize);
|
|
24356
26369
|
}
|
|
24357
|
-
}, [fetchedInitialReports, data, dashboardFilters]);
|
|
26370
|
+
}, [fetchedInitialReports, data, dashboardFilters, customFiltersLoaded]);
|
|
26371
|
+
(0, import_react2.useEffect)(() => {
|
|
26372
|
+
if (customFiltersLoaded && data && dashboardFilters !== null) {
|
|
26373
|
+
fetchedInitialReports.current = true;
|
|
26374
|
+
fetchReports([], dashboardFilters ?? [], config?.pageSize);
|
|
26375
|
+
}
|
|
26376
|
+
}, [customFiltersLoaded]);
|
|
24358
26377
|
const applyDashboardFilters = (filtersToUpdate) => {
|
|
24359
26378
|
const newFilters = (dashboardFilters ?? []).map((f) => {
|
|
24360
26379
|
const update = filtersToUpdate.find((u) => u.label === f.label);
|
|
@@ -24433,7 +26452,7 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24433
26452
|
});
|
|
24434
26453
|
return internalFilters;
|
|
24435
26454
|
};
|
|
24436
|
-
const
|
|
26455
|
+
const isFilter2 = (f) => {
|
|
24437
26456
|
return f && typeof f === "object" && "filterType" in f && !("id" in f);
|
|
24438
26457
|
};
|
|
24439
26458
|
const isDashboardFilter = (f) => {
|
|
@@ -24441,29 +26460,22 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24441
26460
|
};
|
|
24442
26461
|
const applyFilters = (filters2) => {
|
|
24443
26462
|
const dashboardFilters2 = filters2.filter(isDashboardFilter);
|
|
24444
|
-
const customFilters = filters2.filter(
|
|
26463
|
+
const customFilters = filters2.filter(isFilter2);
|
|
24445
26464
|
const newCustomFilters = applyCustomFilters(customFilters);
|
|
24446
26465
|
const newDashboardFilters = applyDashboardFilters(dashboardFilters2);
|
|
24447
26466
|
fetchReports(newCustomFilters, newDashboardFilters);
|
|
24448
26467
|
};
|
|
24449
|
-
const
|
|
24450
|
-
|
|
24451
|
-
|
|
24452
|
-
while (attempts < maxAttempts) {
|
|
24453
|
-
const filters2 = customFiltersRef.current[reportId];
|
|
24454
|
-
if (filters2 && filters2.length > 0) {
|
|
24455
|
-
return filters2;
|
|
24456
|
-
}
|
|
24457
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
24458
|
-
attempts++;
|
|
24459
|
-
}
|
|
24460
|
-
return [];
|
|
26468
|
+
const forceCacheRefresh = () => {
|
|
26469
|
+
if (!cacheEnabled) return;
|
|
26470
|
+
fetchReports([], dashboardFilters ?? [], config?.pageSize, true);
|
|
24461
26471
|
};
|
|
24462
|
-
const fetchReports = async (customFilters, dashboardFilters2, pageSize) => {
|
|
26472
|
+
const fetchReports = async (customFilters, dashboardFilters2, pageSize, forceCacheToRefresh = false) => {
|
|
24463
26473
|
if (!client || !sections) return;
|
|
24464
26474
|
const allReports = Object.values(sections).flat();
|
|
26475
|
+
const fetchStartTime = Date.now();
|
|
26476
|
+
let totalCached = 0;
|
|
24465
26477
|
await Promise.all(
|
|
24466
|
-
allReports.map(async (reportInfo) => {
|
|
26478
|
+
allReports.map(async (reportInfo, idx) => {
|
|
24467
26479
|
const reportId = reportInfo.id;
|
|
24468
26480
|
const requestId = (reportRequestIds.current[reportId] ?? 0) + 1;
|
|
24469
26481
|
reportRequestIds.current[reportId] = requestId;
|
|
@@ -24472,7 +26484,7 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24472
26484
|
id: reportId,
|
|
24473
26485
|
data: true
|
|
24474
26486
|
});
|
|
24475
|
-
const customReportFiltersArray =
|
|
26487
|
+
const customReportFiltersArray = customReportFilters[reportId] ?? [];
|
|
24476
26488
|
let rowsPerRequest = pageSize || 600;
|
|
24477
26489
|
if (!pageSize && (reportInfo.chartType === "table" || reportInfo.chartType === "metric")) {
|
|
24478
26490
|
rowsPerRequest = 10;
|
|
@@ -24484,17 +26496,162 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24484
26496
|
const additionalProcessing = {
|
|
24485
26497
|
page: pagination
|
|
24486
26498
|
};
|
|
24487
|
-
const usePivotTask = !!reportInfo.pivot;
|
|
26499
|
+
const usePivotTask = !cacheEnabled && !!reportInfo.pivot;
|
|
26500
|
+
const allFilters = dashboardFilters2.concat(customFilters).concat(customReportFiltersArray);
|
|
26501
|
+
const applyInMemoryPivotIfNeeded = (report2) => {
|
|
26502
|
+
const pivotToApply = reportInfo.pivot ?? report2.pivot;
|
|
26503
|
+
if (!pivotToApply || usePivotTask) {
|
|
26504
|
+
return report2;
|
|
26505
|
+
}
|
|
26506
|
+
const pivotRows = applyPivotInMemory(
|
|
26507
|
+
report2.rows ?? [],
|
|
26508
|
+
pivotToApply,
|
|
26509
|
+
allFilters
|
|
26510
|
+
);
|
|
26511
|
+
const pivotColumns = generatePivotColumnsInMemory({
|
|
26512
|
+
pivot: pivotToApply,
|
|
26513
|
+
pivotRows,
|
|
26514
|
+
sourceColumns: report2.columnInternal ?? report2.columns
|
|
26515
|
+
});
|
|
26516
|
+
return {
|
|
26517
|
+
...report2,
|
|
26518
|
+
pivot: pivotToApply,
|
|
26519
|
+
pivotRows,
|
|
26520
|
+
pivotColumns: pivotColumns ?? report2.pivotColumns,
|
|
26521
|
+
pivotRowCount: pivotRows.length
|
|
26522
|
+
};
|
|
26523
|
+
};
|
|
26524
|
+
if (cacheEnabled && cacheCab.isCacheable(reportId)) {
|
|
26525
|
+
const report2 = await cacheCab.get(reportId, dashboardFilters2, customFilters.concat(customReportFiltersArray), reportInfo.pivot, client, tenants, flags, pageSize, getToken, eventTracking, forceCacheToRefresh);
|
|
26526
|
+
if (reportRequestIds.current[reportId] !== requestId) {
|
|
26527
|
+
return null;
|
|
26528
|
+
}
|
|
26529
|
+
if (cacheCab.isCacheable(reportId)) {
|
|
26530
|
+
reportsDispatch({
|
|
26531
|
+
type: "UPDATE_REPORT",
|
|
26532
|
+
id: reportId,
|
|
26533
|
+
data: {
|
|
26534
|
+
...report2,
|
|
26535
|
+
pagination,
|
|
26536
|
+
triggerReload: false
|
|
26537
|
+
}
|
|
26538
|
+
});
|
|
26539
|
+
reportsLoadingStateDispatch({
|
|
26540
|
+
type: "SET_REPORT_LOADING",
|
|
26541
|
+
id: reportId,
|
|
26542
|
+
data: false
|
|
26543
|
+
});
|
|
26544
|
+
totalCached += 1;
|
|
26545
|
+
return report2;
|
|
26546
|
+
}
|
|
26547
|
+
}
|
|
26548
|
+
if (cacheEnabled && !cacheCab.isCacheable(reportId)) {
|
|
26549
|
+
try {
|
|
26550
|
+
const { report: uncacheableReport, fromCache } = await cacheCab.getOrFetchUncacheableResult(
|
|
26551
|
+
reportId,
|
|
26552
|
+
client,
|
|
26553
|
+
tenants,
|
|
26554
|
+
flags,
|
|
26555
|
+
allFilters,
|
|
26556
|
+
additionalProcessing,
|
|
26557
|
+
reportInfo.pivot,
|
|
26558
|
+
async () => {
|
|
26559
|
+
const { report: report2, error: error2 } = await fetchReport({
|
|
26560
|
+
reportId,
|
|
26561
|
+
client,
|
|
26562
|
+
tenants,
|
|
26563
|
+
flags,
|
|
26564
|
+
additionalProcessing,
|
|
26565
|
+
filters: allFilters,
|
|
26566
|
+
getToken,
|
|
26567
|
+
eventTracking,
|
|
26568
|
+
usePivotTask,
|
|
26569
|
+
overwriteCache: forceCacheToRefresh
|
|
26570
|
+
});
|
|
26571
|
+
if (error2 || !report2) {
|
|
26572
|
+
throw error2 ?? new Error("Failed to fetch uncacheable report");
|
|
26573
|
+
}
|
|
26574
|
+
return report2;
|
|
26575
|
+
},
|
|
26576
|
+
forceCacheToRefresh
|
|
26577
|
+
);
|
|
26578
|
+
if (reportRequestIds.current[reportId] !== requestId) {
|
|
26579
|
+
return null;
|
|
26580
|
+
}
|
|
26581
|
+
const uncacheableReportWithPivot = applyInMemoryPivotIfNeeded(uncacheableReport);
|
|
26582
|
+
reportsDispatch({
|
|
26583
|
+
type: "UPDATE_REPORT",
|
|
26584
|
+
id: reportId,
|
|
26585
|
+
data: {
|
|
26586
|
+
...uncacheableReportWithPivot,
|
|
26587
|
+
pagination,
|
|
26588
|
+
triggerReload: false
|
|
26589
|
+
}
|
|
26590
|
+
});
|
|
26591
|
+
reportsLoadingStateDispatch({
|
|
26592
|
+
type: "SET_REPORT_LOADING",
|
|
26593
|
+
id: reportId,
|
|
26594
|
+
data: false
|
|
26595
|
+
});
|
|
26596
|
+
if (fromCache) {
|
|
26597
|
+
totalCached += 1;
|
|
26598
|
+
}
|
|
26599
|
+
if (usePivotTask) {
|
|
26600
|
+
fetchReportRows({
|
|
26601
|
+
reportId,
|
|
26602
|
+
client,
|
|
26603
|
+
tenants,
|
|
26604
|
+
filters: allFilters,
|
|
26605
|
+
getToken,
|
|
26606
|
+
additionalProcessing,
|
|
26607
|
+
overwriteCache: forceCacheToRefresh
|
|
26608
|
+
}).then(({ rows, rowCount, columns, fields }) => {
|
|
26609
|
+
if (reportRequestIds.current[reportId] !== requestId) {
|
|
26610
|
+
return;
|
|
26611
|
+
}
|
|
26612
|
+
reportsDispatch({
|
|
26613
|
+
type: "UPDATE_REPORT",
|
|
26614
|
+
id: reportId,
|
|
26615
|
+
data: {
|
|
26616
|
+
rows,
|
|
26617
|
+
rowCount,
|
|
26618
|
+
columnInternal: columns,
|
|
26619
|
+
columns: columns.map((col) => ({
|
|
26620
|
+
field: col.field,
|
|
26621
|
+
format: col.format,
|
|
26622
|
+
label: col.label,
|
|
26623
|
+
inferFormat: col.inferFormat
|
|
26624
|
+
})),
|
|
26625
|
+
// @ts-ignore fields is not typed on QuillReportInternal
|
|
26626
|
+
fields,
|
|
26627
|
+
triggerReload: false
|
|
26628
|
+
}
|
|
26629
|
+
});
|
|
26630
|
+
}).catch((e) => {
|
|
26631
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
26632
|
+
return;
|
|
26633
|
+
}
|
|
26634
|
+
console.error("Failed to fetch background rows", e);
|
|
26635
|
+
});
|
|
26636
|
+
}
|
|
26637
|
+
return uncacheableReportWithPivot;
|
|
26638
|
+
} catch (error2) {
|
|
26639
|
+
console.error(error2);
|
|
26640
|
+
return null;
|
|
26641
|
+
}
|
|
26642
|
+
}
|
|
24488
26643
|
const { report, error } = await fetchReport({
|
|
24489
26644
|
reportId,
|
|
24490
26645
|
client,
|
|
24491
26646
|
tenants,
|
|
24492
26647
|
flags,
|
|
24493
26648
|
additionalProcessing,
|
|
24494
|
-
filters:
|
|
26649
|
+
filters: allFilters,
|
|
24495
26650
|
getToken,
|
|
24496
26651
|
eventTracking,
|
|
24497
|
-
usePivotTask
|
|
26652
|
+
usePivotTask,
|
|
26653
|
+
overwriteCache: forceCacheToRefresh
|
|
26654
|
+
// usePivotTask: false,
|
|
24498
26655
|
});
|
|
24499
26656
|
if (error) {
|
|
24500
26657
|
console.error(error);
|
|
@@ -24522,9 +26679,10 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24522
26679
|
reportId,
|
|
24523
26680
|
client,
|
|
24524
26681
|
tenants,
|
|
24525
|
-
filters:
|
|
26682
|
+
filters: allFilters,
|
|
24526
26683
|
getToken,
|
|
24527
|
-
additionalProcessing
|
|
26684
|
+
additionalProcessing,
|
|
26685
|
+
overwriteCache: forceCacheToRefresh
|
|
24528
26686
|
}).then(({ rows, rowCount, columns, fields }) => {
|
|
24529
26687
|
if (reportRequestIds.current[reportId] !== requestId) {
|
|
24530
26688
|
return;
|
|
@@ -24548,19 +26706,30 @@ var useDashboard = (dashboardName, config) => {
|
|
|
24548
26706
|
}
|
|
24549
26707
|
});
|
|
24550
26708
|
}).catch((e) => {
|
|
24551
|
-
if (e instanceof Error && e.name === "AbortError")
|
|
26709
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
26710
|
+
return;
|
|
26711
|
+
}
|
|
24552
26712
|
console.error("Failed to fetch background rows", e);
|
|
24553
26713
|
});
|
|
24554
26714
|
}
|
|
24555
26715
|
return report;
|
|
24556
26716
|
})
|
|
24557
26717
|
);
|
|
26718
|
+
if (!loadedDashes.includes(dashboardName) || !cacheEnabled || forceCacheToRefresh) {
|
|
26719
|
+
setLoadedDashes((prev) => prev.includes(dashboardName) ? prev : [...prev, dashboardName]);
|
|
26720
|
+
setLastUpdatedDict((prev) => ({ ...prev, [dashboardName]: Date.now() }));
|
|
26721
|
+
}
|
|
26722
|
+
if (logCacheStatistics) {
|
|
26723
|
+
console.log(`Dashboard "${dashboardName}": Cache Rate: ${(100 * totalCached / allReports.length).toFixed(1)}%, load time: ${((Date.now() - fetchStartTime) / 1e3).toFixed(2)} secs`);
|
|
26724
|
+
}
|
|
24558
26725
|
};
|
|
24559
26726
|
return {
|
|
24560
26727
|
isLoading: !!isLoading || !sections,
|
|
24561
26728
|
sections: isLoading ? null : sections,
|
|
24562
26729
|
filters,
|
|
24563
|
-
applyFilters
|
|
26730
|
+
applyFilters,
|
|
26731
|
+
lastUpdated,
|
|
26732
|
+
forceCacheRefresh
|
|
24564
26733
|
};
|
|
24565
26734
|
};
|
|
24566
26735
|
var useDashboardReportInternal = (reportId, config) => {
|
|
@@ -24584,15 +26753,6 @@ var useDashboardReportInternal = (reportId, config) => {
|
|
|
24584
26753
|
} = useDashboardInternal(reports[reportId]?.dashboardName ?? null);
|
|
24585
26754
|
const [pageLoading, setPageLoading] = (0, import_react2.useState)(false);
|
|
24586
26755
|
const [maxPage, setMaxPage] = (0, import_react2.useState)(0);
|
|
24587
|
-
(0, import_react2.useEffect)(() => {
|
|
24588
|
-
if (config?.initialFilters) {
|
|
24589
|
-
customReportFiltersDispatch({
|
|
24590
|
-
type: "ADD_CUSTOM_REPORT_FILTERS",
|
|
24591
|
-
reportId,
|
|
24592
|
-
data: config.initialFilters.map(convertCustomFilter)
|
|
24593
|
-
});
|
|
24594
|
-
}
|
|
24595
|
-
}, []);
|
|
24596
26756
|
const processedReport = (0, import_react2.useMemo)(() => {
|
|
24597
26757
|
if (!reports[reportId]) return null;
|
|
24598
26758
|
const dashboardName = reports[reportId].dashboardName;
|
|
@@ -24797,6 +26957,7 @@ var useDashboardReportInternal = (reportId, config) => {
|
|
|
24797
26957
|
};
|
|
24798
26958
|
var useDashboardReport = (reportId, config) => {
|
|
24799
26959
|
const { report, loading, applyFilters, deleteReport, nextPage } = useDashboardReportInternal(reportId, config);
|
|
26960
|
+
const { customReportFiltersDispatch } = (0, import_react2.useContext)(ReportFiltersContext);
|
|
24800
26961
|
const fetchingRef = (0, import_react2.useRef)(false);
|
|
24801
26962
|
const fetchNextPage = async () => {
|
|
24802
26963
|
if (fetchingRef.current) {
|
|
@@ -24811,6 +26972,15 @@ var useDashboardReport = (reportId, config) => {
|
|
|
24811
26972
|
fetchingRef.current = false;
|
|
24812
26973
|
}
|
|
24813
26974
|
};
|
|
26975
|
+
(0, import_react2.useEffect)(() => {
|
|
26976
|
+
if (config?.initialFilters) {
|
|
26977
|
+
customReportFiltersDispatch({
|
|
26978
|
+
type: "ADD_CUSTOM_REPORT_FILTERS",
|
|
26979
|
+
reportId,
|
|
26980
|
+
data: config.initialFilters.map(convertCustomFilter)
|
|
26981
|
+
});
|
|
26982
|
+
}
|
|
26983
|
+
}, []);
|
|
24814
26984
|
return {
|
|
24815
26985
|
report,
|
|
24816
26986
|
isLoading: loading || fetchingRef.current,
|
|
@@ -25275,7 +27445,7 @@ function QuillCustomDocumentComponent({
|
|
|
25275
27445
|
}
|
|
25276
27446
|
|
|
25277
27447
|
// src/Chart.tsx
|
|
25278
|
-
var
|
|
27448
|
+
var import_date_fns14 = require("date-fns");
|
|
25279
27449
|
|
|
25280
27450
|
// src/components/Chart/BarList.tsx
|
|
25281
27451
|
var import_react4 = __toESM(require("react"), 1);
|
|
@@ -27964,19 +30134,23 @@ var RenderLegend = ({
|
|
|
27964
30134
|
const seeAllMeasureRef = (0, import_react12.useRef)(null);
|
|
27965
30135
|
const seeAllTriggerRef = (0, import_react12.useRef)(null);
|
|
27966
30136
|
const itemRefs = (0, import_react12.useRef)([]);
|
|
27967
|
-
|
|
27968
|
-
const maxItems = limit ??
|
|
30137
|
+
const safePayload = payload ?? [];
|
|
30138
|
+
const maxItems = limit ?? safePayload.length;
|
|
27969
30139
|
const measuredLimit = visibleCount ?? maxItems;
|
|
27970
|
-
const visiblePayload =
|
|
30140
|
+
const visiblePayload = safePayload.slice(0, Math.min(maxItems, measuredLimit));
|
|
27971
30141
|
const handleOpen = () => setIsOpen(true);
|
|
27972
30142
|
const handleClose = () => setIsOpen(false);
|
|
27973
30143
|
(0, import_react12.useLayoutEffect)(() => {
|
|
27974
30144
|
if (!containerRef.current) return;
|
|
27975
|
-
if (!
|
|
30145
|
+
if (!safePayload.length) {
|
|
30146
|
+
setShowSeeAll(false);
|
|
30147
|
+
setVisibleCount(null);
|
|
30148
|
+
return;
|
|
30149
|
+
}
|
|
27976
30150
|
const updateVisibleCount = () => {
|
|
27977
30151
|
const containerWidth = containerRef.current?.offsetWidth ?? 0;
|
|
27978
30152
|
if (!containerWidth) return;
|
|
27979
|
-
const maxCount = Math.min(maxItems,
|
|
30153
|
+
const maxCount = Math.min(maxItems, safePayload.length);
|
|
27980
30154
|
const seeAllWidth = getOuterWidth(seeAllMeasureRef.current);
|
|
27981
30155
|
const computeCount = (reserveSeeAll) => {
|
|
27982
30156
|
const availableWidth = containerWidth - (reserveSeeAll ? seeAllWidth : 0);
|
|
@@ -27992,7 +30166,7 @@ var RenderLegend = ({
|
|
|
27992
30166
|
return Math.max(1, nextCount);
|
|
27993
30167
|
};
|
|
27994
30168
|
const countWithSeeAll = computeCount(true);
|
|
27995
|
-
const shouldShowSeeAll =
|
|
30169
|
+
const shouldShowSeeAll = safePayload.length > countWithSeeAll;
|
|
27996
30170
|
const finalCount = shouldShowSeeAll ? countWithSeeAll : computeCount(false);
|
|
27997
30171
|
setShowSeeAll(shouldShowSeeAll);
|
|
27998
30172
|
setVisibleCount(finalCount);
|
|
@@ -28001,7 +30175,8 @@ var RenderLegend = ({
|
|
|
28001
30175
|
const observer = new ResizeObserver(updateVisibleCount);
|
|
28002
30176
|
observer.observe(containerRef.current);
|
|
28003
30177
|
return () => observer.disconnect();
|
|
28004
|
-
}, [
|
|
30178
|
+
}, [safePayload.length, maxItems]);
|
|
30179
|
+
if (!safePayload.length) return null;
|
|
28005
30180
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
28006
30181
|
"div",
|
|
28007
30182
|
{
|
|
@@ -28041,7 +30216,7 @@ var RenderLegend = ({
|
|
|
28041
30216
|
justifyContent: "flex-start",
|
|
28042
30217
|
flexWrap: "nowrap"
|
|
28043
30218
|
},
|
|
28044
|
-
children:
|
|
30219
|
+
children: safePayload.slice(0, maxItems).map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
28045
30220
|
"div",
|
|
28046
30221
|
{
|
|
28047
30222
|
ref: (element) => {
|
|
@@ -28130,7 +30305,7 @@ var RenderLegend = ({
|
|
|
28130
30305
|
maxWidth: 520,
|
|
28131
30306
|
gap: "0.5rem"
|
|
28132
30307
|
},
|
|
28133
|
-
children:
|
|
30308
|
+
children: safePayload.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
28134
30309
|
LegendItem,
|
|
28135
30310
|
{
|
|
28136
30311
|
entry,
|
|
@@ -28480,8 +30655,8 @@ var PieChartWrapper = import_react13.default.forwardRef(
|
|
|
28480
30655
|
cy: "50%",
|
|
28481
30656
|
startAngle: 90,
|
|
28482
30657
|
endAngle: -270,
|
|
28483
|
-
innerRadius: isDonut ?
|
|
28484
|
-
outerRadius:
|
|
30658
|
+
innerRadius: isDonut ? "70%" : "0%",
|
|
30659
|
+
outerRadius: "100%",
|
|
28485
30660
|
paddingAngle: 0,
|
|
28486
30661
|
dataKey: category,
|
|
28487
30662
|
nameKey: index,
|
|
@@ -29074,8 +31249,8 @@ var import_recharts2 = require("recharts");
|
|
|
29074
31249
|
init_valueFormatter();
|
|
29075
31250
|
|
|
29076
31251
|
// src/utils/axisFormatter.ts
|
|
29077
|
-
var
|
|
29078
|
-
var
|
|
31252
|
+
var import_date_fns11 = require("date-fns");
|
|
31253
|
+
var import_date_fns_tz4 = require("date-fns-tz");
|
|
29079
31254
|
var axisFormatter = ({ value, field, fields }) => {
|
|
29080
31255
|
if (field === void 0 || field === null) return "";
|
|
29081
31256
|
if (value === void 0 || value === null) return "";
|
|
@@ -29191,9 +31366,9 @@ var formatPercent2 = (value) => {
|
|
|
29191
31366
|
return formatter.format(Number(value));
|
|
29192
31367
|
};
|
|
29193
31368
|
var _getUTCDateHelper2 = (value, fmt) => {
|
|
29194
|
-
const utcDate = (0,
|
|
29195
|
-
if (!(0,
|
|
29196
|
-
return (0,
|
|
31369
|
+
const utcDate = (0, import_date_fns_tz4.utcToZonedTime)(new Date(value), "UTC");
|
|
31370
|
+
if (!(0, import_date_fns11.isValid)(utcDate)) return "Invalid date";
|
|
31371
|
+
return (0, import_date_fns11.format)(utcDate, fmt);
|
|
29197
31372
|
};
|
|
29198
31373
|
var format_YYYY2 = (value) => _getUTCDateHelper2(value, "yyyy");
|
|
29199
31374
|
var format_MMM_dd = (value) => _getUTCDateHelper2(value, "dd MMM");
|
|
@@ -29201,31 +31376,31 @@ var format_MMM_yyyy2 = (value) => _getUTCDateHelper2(value, "MMM yyyy");
|
|
|
29201
31376
|
var format_hh_ap_pm2 = (value) => _getUTCDateHelper2(value, "hh:mm aa");
|
|
29202
31377
|
var format_MMM_dd_yyyy2 = (value) => _getUTCDateHelper2(value, "dd MMM yyyy");
|
|
29203
31378
|
var format_MMM_dd_MMM_dd = (value) => {
|
|
29204
|
-
const utcDate = (0,
|
|
29205
|
-
if (!(0,
|
|
29206
|
-
const monday = (0,
|
|
29207
|
-
const sunday = (0,
|
|
29208
|
-
if ((0,
|
|
29209
|
-
return `${(0,
|
|
31379
|
+
const utcDate = (0, import_date_fns_tz4.utcToZonedTime)(new Date(value), "UTC");
|
|
31380
|
+
if (!(0, import_date_fns11.isValid)(utcDate)) return "Invalid date";
|
|
31381
|
+
const monday = (0, import_date_fns11.startOfWeek)(utcDate, { weekStartsOn: 1 });
|
|
31382
|
+
const sunday = (0, import_date_fns11.endOfWeek)(utcDate, { weekStartsOn: 1 });
|
|
31383
|
+
if ((0, import_date_fns11.format)(monday, "MMM") === (0, import_date_fns11.format)(sunday, "MMM")) {
|
|
31384
|
+
return `${(0, import_date_fns11.format)(monday, "MMM dd")} - ${(0, import_date_fns11.format)(sunday, "dd")}`;
|
|
29210
31385
|
} else {
|
|
29211
|
-
return `${(0,
|
|
31386
|
+
return `${(0, import_date_fns11.format)(monday, "MMM dd")} - ${(0, import_date_fns11.format)(sunday, "MMM dd")}`;
|
|
29212
31387
|
}
|
|
29213
31388
|
};
|
|
29214
31389
|
var format_MMM_dd_hh_mm_ap_pm2 = (value) => {
|
|
29215
|
-
const utcDate = (0,
|
|
29216
|
-
if (!(0,
|
|
31390
|
+
const utcDate = (0, import_date_fns_tz4.utcToZonedTime)(new Date(value), "UTC");
|
|
31391
|
+
if (!(0, import_date_fns11.isValid)(utcDate)) return "Invalid date";
|
|
29217
31392
|
const formatStr = utcDate.getMinutes() === 0 ? "MMM do h a" : "MMM do h:mm a";
|
|
29218
|
-
const res = (0,
|
|
31393
|
+
const res = (0, import_date_fns11.format)(utcDate, formatStr);
|
|
29219
31394
|
return res.slice(0, -2) + res.slice(-2).toLowerCase();
|
|
29220
31395
|
};
|
|
29221
31396
|
var format_wo_yyyy2 = (value) => {
|
|
29222
|
-
const utcDate = (0,
|
|
29223
|
-
if (!(0,
|
|
29224
|
-
return `${(0,
|
|
31397
|
+
const utcDate = (0, import_date_fns_tz4.utcToZonedTime)(new Date(value), "UTC");
|
|
31398
|
+
if (!(0, import_date_fns11.isValid)(utcDate)) return "Invalid date";
|
|
31399
|
+
return `${(0, import_date_fns11.getWeek)(utcDate)},${utcDate.getFullYear()}`;
|
|
29225
31400
|
};
|
|
29226
31401
|
|
|
29227
31402
|
// src/components/Chart/ChartTooltip.tsx
|
|
29228
|
-
var
|
|
31403
|
+
var import_date_fns12 = require("date-fns");
|
|
29229
31404
|
|
|
29230
31405
|
// src/components/Chart/ChartTooltipFrame.tsx
|
|
29231
31406
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
@@ -29420,7 +31595,7 @@ var ChartTooltipPrimary = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.js
|
|
|
29420
31595
|
paddingTop: 2,
|
|
29421
31596
|
paddingBottom: 2
|
|
29422
31597
|
},
|
|
29423
|
-
children: !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0,
|
|
31598
|
+
children: !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : props.label
|
|
29424
31599
|
}
|
|
29425
31600
|
)
|
|
29426
31601
|
}
|
|
@@ -29469,8 +31644,8 @@ function reformatComparisonPayload(props, primaryLabel, comparisonLabel) {
|
|
|
29469
31644
|
const nameKey = isComparison ? `comparison_${props.xAxisField}` : props.xAxisField;
|
|
29470
31645
|
const days = LABEL_TO_DAYS[primaryLabel] ?? 0;
|
|
29471
31646
|
const primaryDate = item.payload[props.xAxisField] ?? 0;
|
|
29472
|
-
const compDate = (0,
|
|
29473
|
-
const date = item.payload[nameKey] ?? (0,
|
|
31647
|
+
const compDate = (0, import_date_fns12.subDays)(new Date(primaryDate), days + 1);
|
|
31648
|
+
const date = item.payload[nameKey] ?? (0, import_date_fns12.format)(compDate, props.xAxisFormat);
|
|
29474
31649
|
const name2 = props.dateFormatter(date);
|
|
29475
31650
|
const color2 = item.color;
|
|
29476
31651
|
const value = props.valueFormatter(item.value, item.name);
|
|
@@ -29503,7 +31678,7 @@ function reformatComparisonPayload(props, primaryLabel, comparisonLabel) {
|
|
|
29503
31678
|
return columnsByKey;
|
|
29504
31679
|
}
|
|
29505
31680
|
function getTooltipLabel(props, altTooltipLabel, isDateXAxis) {
|
|
29506
|
-
return props.payload.length <= 2 && altTooltipLabel && isDateXAxis ? !isNaN(new Date(altTooltipLabel)) && props.dateFormatter ? props.dateFormatter(altTooltipLabel) : !isNaN(new Date(altTooltipLabel)) ? (0,
|
|
31681
|
+
return props.payload.length <= 2 && altTooltipLabel && isDateXAxis ? !isNaN(new Date(altTooltipLabel)) && props.dateFormatter ? props.dateFormatter(altTooltipLabel) : !isNaN(new Date(altTooltipLabel)) ? (0, import_date_fns12.format)(new Date(altTooltipLabel), "MMM yyyy") : altTooltipLabel : !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : props.label;
|
|
29507
31682
|
}
|
|
29508
31683
|
function ChartTooltipComparison(props) {
|
|
29509
31684
|
const isDateXAxis = isDateFormat(props.xAxisFormat);
|
|
@@ -30519,7 +32694,7 @@ init_dateRangePickerUtils();
|
|
|
30519
32694
|
|
|
30520
32695
|
// src/DateRangePicker/QuillDateRangePicker.tsx
|
|
30521
32696
|
var import_react20 = require("react");
|
|
30522
|
-
var
|
|
32697
|
+
var import_date_fns13 = require("date-fns");
|
|
30523
32698
|
|
|
30524
32699
|
// src/components/QuillSelect.tsx
|
|
30525
32700
|
var import_react19 = require("react");
|
|
@@ -30965,9 +33140,9 @@ function QuillDateRangePicker({
|
|
|
30965
33140
|
]
|
|
30966
33141
|
}
|
|
30967
33142
|
),
|
|
30968
|
-
localStartDate && (0,
|
|
33143
|
+
localStartDate && (0, import_date_fns13.format)(localStartDate, "MMM dd, yyyy"),
|
|
30969
33144
|
localStartDate ? " - " : "Pick a date",
|
|
30970
|
-
localEndDate && (0,
|
|
33145
|
+
localEndDate && (0, import_date_fns13.format)(localEndDate, "MMM dd, yyyy")
|
|
30971
33146
|
]
|
|
30972
33147
|
}
|
|
30973
33148
|
),
|
|
@@ -31034,21 +33209,21 @@ function CalendarRow({
|
|
|
31034
33209
|
updateDateFilter,
|
|
31035
33210
|
setLocalPreset
|
|
31036
33211
|
}) {
|
|
31037
|
-
const firstMonthDisplayedDates = (0,
|
|
31038
|
-
start: (0,
|
|
31039
|
-
end: (0,
|
|
33212
|
+
const firstMonthDisplayedDates = (0, import_date_fns13.eachDayOfInterval)({
|
|
33213
|
+
start: (0, import_date_fns13.startOfWeek)(anchorStartDate),
|
|
33214
|
+
end: (0, import_date_fns13.endOfWeek)((0, import_date_fns13.endOfMonth)(anchorStartDate))
|
|
31040
33215
|
});
|
|
31041
|
-
const secondMonthDisplayedDates = (0,
|
|
31042
|
-
start: (0,
|
|
31043
|
-
end: (0,
|
|
33216
|
+
const secondMonthDisplayedDates = (0, import_date_fns13.eachDayOfInterval)({
|
|
33217
|
+
start: (0, import_date_fns13.startOfWeek)((0, import_date_fns13.startOfMonth)(anchorEndDate)),
|
|
33218
|
+
end: (0, import_date_fns13.endOfWeek)(anchorEndDate)
|
|
31044
33219
|
});
|
|
31045
33220
|
const incrementAnchorDates = () => {
|
|
31046
|
-
setAnchorStartDate((0,
|
|
31047
|
-
setAnchorEndDate((0,
|
|
33221
|
+
setAnchorStartDate((0, import_date_fns13.startOfMonth)((0, import_date_fns13.addMonths)(anchorStartDate, 1)));
|
|
33222
|
+
setAnchorEndDate((0, import_date_fns13.endOfMonth)((0, import_date_fns13.addMonths)(anchorEndDate, 1)));
|
|
31048
33223
|
};
|
|
31049
33224
|
const decrementAnchorDates = () => {
|
|
31050
|
-
setAnchorStartDate((0,
|
|
31051
|
-
setAnchorEndDate((0,
|
|
33225
|
+
setAnchorStartDate((0, import_date_fns13.startOfMonth)((0, import_date_fns13.subMonths)(anchorStartDate, 1)));
|
|
33226
|
+
setAnchorEndDate((0, import_date_fns13.endOfMonth)((0, import_date_fns13.subMonths)(anchorEndDate, 1)));
|
|
31052
33227
|
};
|
|
31053
33228
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { style: { position: "absolute", zIndex: 100, marginTop: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
31054
33229
|
"div",
|
|
@@ -31144,7 +33319,7 @@ function CalendarRow({
|
|
|
31144
33319
|
color: theme.primaryTextColor,
|
|
31145
33320
|
fontWeight: 600
|
|
31146
33321
|
},
|
|
31147
|
-
children: (0,
|
|
33322
|
+
children: (0, import_date_fns13.format)(anchorStartDate, "MMM yyyy")
|
|
31148
33323
|
}
|
|
31149
33324
|
)
|
|
31150
33325
|
]
|
|
@@ -31208,7 +33383,7 @@ function CalendarRow({
|
|
|
31208
33383
|
color: theme.primaryTextColor,
|
|
31209
33384
|
fontWeight: 600
|
|
31210
33385
|
},
|
|
31211
|
-
children: (0,
|
|
33386
|
+
children: (0, import_date_fns13.format)(anchorEndDate, "MMM yyyy")
|
|
31212
33387
|
}
|
|
31213
33388
|
),
|
|
31214
33389
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
@@ -31302,11 +33477,11 @@ function DayPicker({
|
|
|
31302
33477
|
setLocalPreset,
|
|
31303
33478
|
theme
|
|
31304
33479
|
}) {
|
|
31305
|
-
const isStartDate = (0,
|
|
31306
|
-
const isEndDate = (0,
|
|
31307
|
-
const isBetweenStartAndEnd = (0,
|
|
31308
|
-
const isBeginningOfWeek = (0,
|
|
31309
|
-
const isEndOfWeek = (0,
|
|
33480
|
+
const isStartDate = (0, import_date_fns13.differenceInDays)((0, import_date_fns13.startOfDay)(date), (0, import_date_fns13.startOfDay)(localStartDate || 0)) === 0;
|
|
33481
|
+
const isEndDate = (0, import_date_fns13.differenceInDays)((0, import_date_fns13.startOfDay)(date), (0, import_date_fns13.startOfDay)(localEndDate || 0)) === 0;
|
|
33482
|
+
const isBetweenStartAndEnd = (0, import_date_fns13.isBefore)(date, localEndDate || 0) && (0, import_date_fns13.isAfter)(date, localStartDate || 0);
|
|
33483
|
+
const isBeginningOfWeek = (0, import_date_fns13.differenceInDays)((0, import_date_fns13.startOfWeek)(date), date) === 0;
|
|
33484
|
+
const isEndOfWeek = (0, import_date_fns13.differenceInDays)((0, import_date_fns13.endOfWeek)(date), date) === 0;
|
|
31310
33485
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
31311
33486
|
"button",
|
|
31312
33487
|
{
|
|
@@ -31338,7 +33513,7 @@ function DayPicker({
|
|
|
31338
33513
|
});
|
|
31339
33514
|
setLocalPreset("");
|
|
31340
33515
|
}
|
|
31341
|
-
if (localStartDate && localEndDate && (0,
|
|
33516
|
+
if (localStartDate && localEndDate && (0, import_date_fns13.isAfter)(date, localStartDate)) {
|
|
31342
33517
|
setLocalEndDate(date);
|
|
31343
33518
|
updateDateFilter({
|
|
31344
33519
|
startDate: localStartDate,
|
|
@@ -31346,7 +33521,7 @@ function DayPicker({
|
|
|
31346
33521
|
});
|
|
31347
33522
|
setLocalPreset("");
|
|
31348
33523
|
}
|
|
31349
|
-
if (localStartDate && localEndDate && (0,
|
|
33524
|
+
if (localStartDate && localEndDate && (0, import_date_fns13.isBefore)(date, localStartDate)) {
|
|
31350
33525
|
setLocalStartDate(date);
|
|
31351
33526
|
updateDateFilter({
|
|
31352
33527
|
startDate: date,
|
|
@@ -31354,42 +33529,42 @@ function DayPicker({
|
|
|
31354
33529
|
});
|
|
31355
33530
|
setLocalPreset("");
|
|
31356
33531
|
}
|
|
31357
|
-
if (localStartDate && localEndDate && (0,
|
|
33532
|
+
if (localStartDate && localEndDate && (0, import_date_fns13.differenceInDays)((0, import_date_fns13.startOfDay)(date), (0, import_date_fns13.startOfDay)(localStartDate)) === 0) {
|
|
31358
33533
|
setLocalStartDate(void 0);
|
|
31359
33534
|
setLocalEndDate(void 0);
|
|
31360
33535
|
}
|
|
31361
33536
|
},
|
|
31362
|
-
children: (0,
|
|
33537
|
+
children: (0, import_date_fns13.format)(date, "d")
|
|
31363
33538
|
}
|
|
31364
33539
|
);
|
|
31365
33540
|
}
|
|
31366
33541
|
function getAnchorStartDate(startDate, endDate) {
|
|
31367
33542
|
if (!startDate && !endDate) {
|
|
31368
|
-
return (0,
|
|
33543
|
+
return (0, import_date_fns13.startOfMonth)((0, import_date_fns13.subMonths)(/* @__PURE__ */ new Date(), 1));
|
|
31369
33544
|
}
|
|
31370
33545
|
if (startDate && !endDate) {
|
|
31371
|
-
return (0,
|
|
33546
|
+
return (0, import_date_fns13.startOfMonth)(startDate);
|
|
31372
33547
|
}
|
|
31373
33548
|
if (!startDate && endDate) {
|
|
31374
|
-
return (0,
|
|
33549
|
+
return (0, import_date_fns13.startOfMonth)((0, import_date_fns13.subMonths)(endDate, 1));
|
|
31375
33550
|
}
|
|
31376
33551
|
if (startDate && endDate) {
|
|
31377
|
-
return (0,
|
|
33552
|
+
return (0, import_date_fns13.startOfMonth)(startDate);
|
|
31378
33553
|
}
|
|
31379
33554
|
return /* @__PURE__ */ new Date();
|
|
31380
33555
|
}
|
|
31381
33556
|
function getAnchorEndDate(startDate, endDate) {
|
|
31382
33557
|
if (!startDate && !endDate) {
|
|
31383
|
-
return (0,
|
|
33558
|
+
return (0, import_date_fns13.endOfMonth)(/* @__PURE__ */ new Date());
|
|
31384
33559
|
}
|
|
31385
33560
|
if (startDate && !endDate) {
|
|
31386
|
-
return (0,
|
|
33561
|
+
return (0, import_date_fns13.endOfMonth)((0, import_date_fns13.addMonths)(startDate, 1));
|
|
31387
33562
|
}
|
|
31388
33563
|
if (!startDate && endDate) {
|
|
31389
|
-
return (0,
|
|
33564
|
+
return (0, import_date_fns13.endOfMonth)(endDate);
|
|
31390
33565
|
}
|
|
31391
33566
|
if (startDate && endDate) {
|
|
31392
|
-
return (0,
|
|
33567
|
+
return (0, import_date_fns13.endOfMonth)((0, import_date_fns13.addMonths)(startDate, 1));
|
|
31393
33568
|
}
|
|
31394
33569
|
return /* @__PURE__ */ new Date();
|
|
31395
33570
|
}
|
|
@@ -32573,6 +34748,164 @@ function DashboardFilter2({
|
|
|
32573
34748
|
// src/Chart.tsx
|
|
32574
34749
|
init_paginationProcessing();
|
|
32575
34750
|
|
|
34751
|
+
// src/utils/cloudCacheValidation.ts
|
|
34752
|
+
var LIMIT_CLAUSE_REGEX = /^limit\b\s+(?:all|\d+|\$\d+|:[a-zA-Z_][a-zA-Z0-9_]*|\?)/i;
|
|
34753
|
+
var SQL_CONTENT_TO_IGNORE_REGEX = /'(?:''|[^'])*'|"(?:[^"]|"")*"|`[^`]*`|\[[^\]]*\]|--[^\n]*|\/\*[\s\S]*?\*\//g;
|
|
34754
|
+
function isWordChar(char) {
|
|
34755
|
+
if (!char) {
|
|
34756
|
+
return false;
|
|
34757
|
+
}
|
|
34758
|
+
return /[A-Za-z0-9_]/.test(char);
|
|
34759
|
+
}
|
|
34760
|
+
function getFinalSqlStatement(query) {
|
|
34761
|
+
const statements = query.split(";").map((statement) => statement.trim()).filter((statement) => statement.length > 0);
|
|
34762
|
+
return statements[statements.length - 1] ?? "";
|
|
34763
|
+
}
|
|
34764
|
+
function hasTopLevelLimitClause(statement) {
|
|
34765
|
+
let depth = 0;
|
|
34766
|
+
for (let i = 0; i < statement.length; i += 1) {
|
|
34767
|
+
const char = statement[i];
|
|
34768
|
+
if (char === "(") {
|
|
34769
|
+
depth += 1;
|
|
34770
|
+
continue;
|
|
34771
|
+
}
|
|
34772
|
+
if (char === ")") {
|
|
34773
|
+
depth = Math.max(0, depth - 1);
|
|
34774
|
+
continue;
|
|
34775
|
+
}
|
|
34776
|
+
if (depth !== 0) {
|
|
34777
|
+
continue;
|
|
34778
|
+
}
|
|
34779
|
+
const previousChar = i > 0 ? statement[i - 1] : void 0;
|
|
34780
|
+
if (isWordChar(previousChar)) {
|
|
34781
|
+
continue;
|
|
34782
|
+
}
|
|
34783
|
+
if (!LIMIT_CLAUSE_REGEX.test(statement.slice(i))) {
|
|
34784
|
+
continue;
|
|
34785
|
+
}
|
|
34786
|
+
return true;
|
|
34787
|
+
}
|
|
34788
|
+
return false;
|
|
34789
|
+
}
|
|
34790
|
+
function unwrapIdentifier(identifier) {
|
|
34791
|
+
if (!identifier) {
|
|
34792
|
+
return "";
|
|
34793
|
+
}
|
|
34794
|
+
const trimmed = identifier.trim();
|
|
34795
|
+
if (trimmed.length < 2) {
|
|
34796
|
+
return trimmed;
|
|
34797
|
+
}
|
|
34798
|
+
const startsAndEndsWithDoubleQuote = trimmed.startsWith('"') && trimmed.endsWith('"');
|
|
34799
|
+
const startsAndEndsWithSingleQuote = trimmed.startsWith("'") && trimmed.endsWith("'");
|
|
34800
|
+
const startsAndEndsWithBackticks = trimmed.startsWith("`") && trimmed.endsWith("`");
|
|
34801
|
+
const startsAndEndsWithBrackets = trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
34802
|
+
if (startsAndEndsWithDoubleQuote || startsAndEndsWithSingleQuote || startsAndEndsWithBackticks || startsAndEndsWithBrackets) {
|
|
34803
|
+
return trimmed.slice(1, -1);
|
|
34804
|
+
}
|
|
34805
|
+
return trimmed;
|
|
34806
|
+
}
|
|
34807
|
+
function normalizeIdentifier(identifier) {
|
|
34808
|
+
return unwrapIdentifier(identifier).toLowerCase();
|
|
34809
|
+
}
|
|
34810
|
+
function hasRowFieldWithIdentifier(row, normalizedField) {
|
|
34811
|
+
if (!row || !normalizedField) {
|
|
34812
|
+
return false;
|
|
34813
|
+
}
|
|
34814
|
+
return Object.keys(row).some(
|
|
34815
|
+
(fieldName) => normalizeIdentifier(fieldName) === normalizedField
|
|
34816
|
+
);
|
|
34817
|
+
}
|
|
34818
|
+
function reportReferencesField(report, field, table) {
|
|
34819
|
+
const normalizedField = normalizeIdentifier(field);
|
|
34820
|
+
if (!normalizedField) {
|
|
34821
|
+
return false;
|
|
34822
|
+
}
|
|
34823
|
+
const referencedColumns = report?.referencedColumns ?? {};
|
|
34824
|
+
let entries = Object.entries(referencedColumns);
|
|
34825
|
+
if (entries.length === 0) {
|
|
34826
|
+
return false;
|
|
34827
|
+
}
|
|
34828
|
+
const normalizedTable = normalizeIdentifier(table);
|
|
34829
|
+
if (normalizedTable) {
|
|
34830
|
+
entries = entries.filter(
|
|
34831
|
+
([tableName]) => normalizeIdentifier(tableName) === normalizedTable
|
|
34832
|
+
);
|
|
34833
|
+
}
|
|
34834
|
+
const referencedFields = entries.flatMap(([, fields]) => fields ?? []);
|
|
34835
|
+
if (referencedFields.length === 0) {
|
|
34836
|
+
return false;
|
|
34837
|
+
}
|
|
34838
|
+
return referencedFields.some((referencedField) => {
|
|
34839
|
+
const normalizedReferencedField = normalizeIdentifier(referencedField);
|
|
34840
|
+
return normalizedReferencedField === normalizedField || normalizedReferencedField === "*";
|
|
34841
|
+
});
|
|
34842
|
+
}
|
|
34843
|
+
function isDateFieldMissingInReport(report) {
|
|
34844
|
+
if (!report?.dateField?.field || !report.dateField.table) {
|
|
34845
|
+
return false;
|
|
34846
|
+
}
|
|
34847
|
+
const dateField = report.dateField;
|
|
34848
|
+
if (!reportReferencesField(report, dateField.field, dateField.table)) {
|
|
34849
|
+
return true;
|
|
34850
|
+
}
|
|
34851
|
+
const firstRow = report.rows?.[0];
|
|
34852
|
+
if (!firstRow) {
|
|
34853
|
+
return false;
|
|
34854
|
+
}
|
|
34855
|
+
const normalizedDateField = normalizeIdentifier(dateField.field);
|
|
34856
|
+
const dateFieldExistsInFirstRow = hasRowFieldWithIdentifier(
|
|
34857
|
+
firstRow,
|
|
34858
|
+
normalizedDateField
|
|
34859
|
+
);
|
|
34860
|
+
return !dateFieldExistsInFirstRow;
|
|
34861
|
+
}
|
|
34862
|
+
function hasLimitClause(query) {
|
|
34863
|
+
if (!query) {
|
|
34864
|
+
return false;
|
|
34865
|
+
}
|
|
34866
|
+
const sanitizedQuery = query.replace(SQL_CONTENT_TO_IGNORE_REGEX, " ");
|
|
34867
|
+
const finalStatement = getFinalSqlStatement(sanitizedQuery);
|
|
34868
|
+
if (!finalStatement) {
|
|
34869
|
+
return false;
|
|
34870
|
+
}
|
|
34871
|
+
return hasTopLevelLimitClause(finalStatement);
|
|
34872
|
+
}
|
|
34873
|
+
function reportUsesLimitClause(report) {
|
|
34874
|
+
const queriesToInspect = report?.itemQuery && report.itemQuery.length > 0 ? report.itemQuery : report?.queryString ? [report.queryString] : [];
|
|
34875
|
+
return queriesToInspect.some(hasLimitClause);
|
|
34876
|
+
}
|
|
34877
|
+
function getMissingDashboardFilterFields({
|
|
34878
|
+
rows = [],
|
|
34879
|
+
dashboardFilters = []
|
|
34880
|
+
}) {
|
|
34881
|
+
const dateIndex = dashboardFilters.findIndex(
|
|
34882
|
+
(filter) => filter.filterType === "date_range"
|
|
34883
|
+
);
|
|
34884
|
+
const requiredFields = dashboardFilters.flatMap((filter, index) => {
|
|
34885
|
+
if (index === dateIndex || !filter.field) {
|
|
34886
|
+
return [];
|
|
34887
|
+
}
|
|
34888
|
+
const normalizedField = normalizeIdentifier(filter.field);
|
|
34889
|
+
if (!normalizedField) {
|
|
34890
|
+
return [];
|
|
34891
|
+
}
|
|
34892
|
+
return [
|
|
34893
|
+
{
|
|
34894
|
+
displayField: unwrapIdentifier(filter.field),
|
|
34895
|
+
normalizedField
|
|
34896
|
+
}
|
|
34897
|
+
];
|
|
34898
|
+
});
|
|
34899
|
+
const dedupedRequiredFields = requiredFields.filter(
|
|
34900
|
+
(field, index, fields) => fields.findIndex(
|
|
34901
|
+
(candidate) => candidate.normalizedField === field.normalizedField
|
|
34902
|
+
) === index
|
|
34903
|
+
);
|
|
34904
|
+
return dedupedRequiredFields.filter(
|
|
34905
|
+
({ normalizedField }) => rows.some((row) => !hasRowFieldWithIdentifier(row, normalizedField))
|
|
34906
|
+
).map(({ displayField }) => displayField);
|
|
34907
|
+
}
|
|
34908
|
+
|
|
32576
34909
|
// src/components/Dashboard/MetricComponent.tsx
|
|
32577
34910
|
var import_react24 = require("react");
|
|
32578
34911
|
init_dateRangePickerUtils();
|
|
@@ -32680,7 +35013,7 @@ function QuillMetricComponent({
|
|
|
32680
35013
|
width: "100%"
|
|
32681
35014
|
}
|
|
32682
35015
|
}
|
|
32683
|
-
) : !report?.rows || report?.rows?.length === 0
|
|
35016
|
+
) : !report?.rows || report?.rows?.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
32684
35017
|
"div",
|
|
32685
35018
|
{
|
|
32686
35019
|
style: {
|
|
@@ -36194,6 +38527,7 @@ function QuillTableDashboardComponent({
|
|
|
36194
38527
|
}
|
|
36195
38528
|
|
|
36196
38529
|
// src/Chart.tsx
|
|
38530
|
+
init_valueFormatter();
|
|
36197
38531
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
36198
38532
|
var MAX_ROWS_FOR_GENERIC_TABLE = 500;
|
|
36199
38533
|
function sumByKey(arr, key) {
|
|
@@ -36230,7 +38564,8 @@ function Chart({
|
|
|
36230
38564
|
filters,
|
|
36231
38565
|
onClickChartElement,
|
|
36232
38566
|
dateBucket,
|
|
36233
|
-
propagateChanges
|
|
38567
|
+
propagateChanges,
|
|
38568
|
+
isAdmin = false
|
|
36234
38569
|
}) {
|
|
36235
38570
|
const [schemaData] = (0, import_react30.useContext)(SchemaDataContext);
|
|
36236
38571
|
const { reload } = useReportInternal(reportId);
|
|
@@ -36352,6 +38687,25 @@ function Chart({
|
|
|
36352
38687
|
}
|
|
36353
38688
|
}, [report, theme]);
|
|
36354
38689
|
const [client, clientLoading] = (0, import_react30.useContext)(ClientContext);
|
|
38690
|
+
const cloudCacheEnabled = (0, import_react30.useMemo)(() => {
|
|
38691
|
+
return !!client?.features?.cloudCache;
|
|
38692
|
+
}, [client]);
|
|
38693
|
+
const shouldShowCloudCacheValidationErrors = isAdmin && cloudCacheEnabled;
|
|
38694
|
+
const isMissingDateField = (0, import_react30.useMemo)(() => {
|
|
38695
|
+
if (!shouldShowCloudCacheValidationErrors) return false;
|
|
38696
|
+
return isDateFieldMissingInReport(report);
|
|
38697
|
+
}, [report, shouldShowCloudCacheValidationErrors]);
|
|
38698
|
+
const usesLimitInQuery = (0, import_react30.useMemo)(() => {
|
|
38699
|
+
if (!shouldShowCloudCacheValidationErrors) return false;
|
|
38700
|
+
return reportUsesLimitClause(report);
|
|
38701
|
+
}, [report, shouldShowCloudCacheValidationErrors]);
|
|
38702
|
+
const missingDashboardFilterFields = (0, import_react30.useMemo)(() => {
|
|
38703
|
+
if (!shouldShowCloudCacheValidationErrors || !report) return [];
|
|
38704
|
+
return getMissingDashboardFilterFields({
|
|
38705
|
+
rows: report.rows,
|
|
38706
|
+
dashboardFilters
|
|
38707
|
+
});
|
|
38708
|
+
}, [report, dashboardFilters, shouldShowCloudCacheValidationErrors]);
|
|
36355
38709
|
const [error, setError] = (0, import_react30.useState)(void 0);
|
|
36356
38710
|
const updateFilter = (filter, value, comparison) => {
|
|
36357
38711
|
let filterValue = {};
|
|
@@ -36492,6 +38846,30 @@ function Chart({
|
|
|
36492
38846
|
if (report?.error || error) {
|
|
36493
38847
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: containerStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChartError, { errorMessage: report?.error ?? error }) });
|
|
36494
38848
|
}
|
|
38849
|
+
if (isMissingDateField) {
|
|
38850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: containerStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
38851
|
+
ChartError,
|
|
38852
|
+
{
|
|
38853
|
+
errorMessage: `The query for this report is missing dashboard date filter field ${report?.dateField?.field}, which is necessary for date filtering on this dashboard when the cache is enabled.`
|
|
38854
|
+
}
|
|
38855
|
+
) });
|
|
38856
|
+
}
|
|
38857
|
+
if (usesLimitInQuery) {
|
|
38858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: containerStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
38859
|
+
ChartError,
|
|
38860
|
+
{
|
|
38861
|
+
errorMessage: `The query for this report uses the LIMIT keyword, which is not supported when the cache is enabled.`
|
|
38862
|
+
}
|
|
38863
|
+
) });
|
|
38864
|
+
}
|
|
38865
|
+
if (missingDashboardFilterFields.length) {
|
|
38866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: containerStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
38867
|
+
ChartError,
|
|
38868
|
+
{
|
|
38869
|
+
errorMessage: `The query for this report is missing dashboard filter fields: ${missingDashboardFilterFields.join(", ")}`
|
|
38870
|
+
}
|
|
38871
|
+
) });
|
|
38872
|
+
}
|
|
36495
38873
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
36496
38874
|
"div",
|
|
36497
38875
|
{
|
|
@@ -36822,7 +39200,7 @@ var ChartDisplay = ({
|
|
|
36822
39200
|
);
|
|
36823
39201
|
}
|
|
36824
39202
|
if (config?.chartType?.toLowerCase() === "metric") {
|
|
36825
|
-
if (!config?.rows || config?.rows?.length === 0
|
|
39203
|
+
if (!config?.rows || config?.rows?.length === 0) {
|
|
36826
39204
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
36827
39205
|
"div",
|
|
36828
39206
|
{
|
|
@@ -36860,6 +39238,36 @@ var ChartDisplay = ({
|
|
|
36860
39238
|
}
|
|
36861
39239
|
);
|
|
36862
39240
|
}
|
|
39241
|
+
if (config?.pivotRows && config?.pivotRows?.length > 0) {
|
|
39242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
39243
|
+
"div",
|
|
39244
|
+
{
|
|
39245
|
+
style: {
|
|
39246
|
+
fontFamily: theme?.fontFamily,
|
|
39247
|
+
fontSize: 32,
|
|
39248
|
+
color: theme?.primaryTextColor,
|
|
39249
|
+
fontWeight: "600",
|
|
39250
|
+
textOverflow: "ellipsis",
|
|
39251
|
+
margin: 0,
|
|
39252
|
+
whiteSpace: "nowrap",
|
|
39253
|
+
boxSizing: "content-box",
|
|
39254
|
+
maxWidth: "100%",
|
|
39255
|
+
textAlign: "left",
|
|
39256
|
+
overflow: "hidden",
|
|
39257
|
+
height: containerStyle?.height || "100%",
|
|
39258
|
+
display: "flex",
|
|
39259
|
+
width: "100%",
|
|
39260
|
+
flexDirection: "row",
|
|
39261
|
+
...containerStyle
|
|
39262
|
+
},
|
|
39263
|
+
className,
|
|
39264
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(QuillMetricComponent, { report: config ?? EMPTY_REPORT, children: quillFormat({
|
|
39265
|
+
value: config?.pivotRows?.[0]?.[config?.xAxisField],
|
|
39266
|
+
format: config?.xAxisFormat
|
|
39267
|
+
}) ?? "No results" })
|
|
39268
|
+
}
|
|
39269
|
+
);
|
|
39270
|
+
}
|
|
36863
39271
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
36864
39272
|
"div",
|
|
36865
39273
|
{
|
|
@@ -37799,7 +40207,7 @@ var FilterPopoverWrapper = ({
|
|
|
37799
40207
|
// src/components/ReportBuilder/FilterModal.tsx
|
|
37800
40208
|
var import_react35 = require("react");
|
|
37801
40209
|
init_Filter();
|
|
37802
|
-
var
|
|
40210
|
+
var import_date_fns15 = require("date-fns");
|
|
37803
40211
|
init_textProcessing();
|
|
37804
40212
|
init_filterProcessing();
|
|
37805
40213
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
@@ -37833,10 +40241,10 @@ function FilterModal({
|
|
|
37833
40241
|
const [unit, setUnit] = (0, import_react35.useState)("");
|
|
37834
40242
|
const [unitOptions, setUnitOptions] = (0, import_react35.useState)([]);
|
|
37835
40243
|
const [startDate, setStartDate] = (0, import_react35.useState)(
|
|
37836
|
-
(0,
|
|
40244
|
+
(0, import_date_fns15.startOfToday)().toISOString().substring(0, 10)
|
|
37837
40245
|
);
|
|
37838
40246
|
const [endDate, setEndDate] = (0, import_react35.useState)(
|
|
37839
|
-
(0,
|
|
40247
|
+
(0, import_date_fns15.startOfToday)().toISOString().substring(0, 10)
|
|
37840
40248
|
);
|
|
37841
40249
|
const [filterInitialized, setFilterInitialized] = (0, import_react35.useState)(false);
|
|
37842
40250
|
const [table, setTable] = (0, import_react35.useState)(void 0);
|
|
@@ -37904,10 +40312,10 @@ function FilterModal({
|
|
|
37904
40312
|
onOperatorChange(filter.operator);
|
|
37905
40313
|
setUnit(filter.filterType === "date-filter" ? filter.value.unit : "");
|
|
37906
40314
|
setStartDate(
|
|
37907
|
-
filter.value?.startDate ? filter.value.startDate.substring(0, 10) : (0,
|
|
40315
|
+
filter.value?.startDate ? filter.value.startDate.substring(0, 10) : (0, import_date_fns15.startOfToday)().toISOString().substring(0, 10)
|
|
37908
40316
|
);
|
|
37909
40317
|
setEndDate(
|
|
37910
|
-
filter.value?.endDate ? filter.value.endDate.substring(0, 10) : (0,
|
|
40318
|
+
filter.value?.endDate ? filter.value.endDate.substring(0, 10) : (0, import_date_fns15.startOfToday)().toISOString().substring(0, 10)
|
|
37911
40319
|
);
|
|
37912
40320
|
if (filter.filterType === "string-in-filter") {
|
|
37913
40321
|
setSelectedOptions(
|
|
@@ -38002,8 +40410,8 @@ function FilterModal({
|
|
|
38002
40410
|
DateOperator.LessThan,
|
|
38003
40411
|
DateOperator.LessThanOrEqualTo,
|
|
38004
40412
|
DateOperator.NotEqualTo
|
|
38005
|
-
].includes(operator2) && !(0,
|
|
38006
|
-
setValue((0,
|
|
40413
|
+
].includes(operator2) && !(0, import_date_fns15.isValid)((0, import_date_fns15.parse)(value, "yyyy-mm-dd", /* @__PURE__ */ new Date())) && (filterInitialized || !filter)) {
|
|
40414
|
+
setValue((0, import_date_fns15.startOfToday)().toISOString().substring(0, 10));
|
|
38007
40415
|
} else if (type === FieldType.Date && [
|
|
38008
40416
|
DateOperator.InTheLast,
|
|
38009
40417
|
DateOperator.InTheCurrent,
|
|
@@ -38191,12 +40599,12 @@ function FilterModal({
|
|
|
38191
40599
|
case DateOperator.LessThan:
|
|
38192
40600
|
case DateOperator.GreaterThanOrEqualTo:
|
|
38193
40601
|
case DateOperator.LessThanOrEqualTo: {
|
|
38194
|
-
const parsedDate = (0,
|
|
38195
|
-
if (!(0,
|
|
40602
|
+
const parsedDate = (0, import_date_fns15.parse)(value, "yyyy-mm-dd", /* @__PURE__ */ new Date());
|
|
40603
|
+
if (!(0, import_date_fns15.isValid)(parsedDate)) {
|
|
38196
40604
|
alert("Please specify a valid date in yyyy-mm-dd");
|
|
38197
40605
|
return;
|
|
38198
40606
|
}
|
|
38199
|
-
const normalizedDate = (0,
|
|
40607
|
+
const normalizedDate = (0, import_date_fns15.format)(parsedDate, "yyyy-mm-dd");
|
|
38200
40608
|
onSubmitFilter({
|
|
38201
40609
|
field,
|
|
38202
40610
|
filterType: "date-comparison-filter" /* DateComparisonFilter */,
|
|
@@ -38492,8 +40900,8 @@ function FilterModal({
|
|
|
38492
40900
|
QuillDateRangePicker,
|
|
38493
40901
|
{
|
|
38494
40902
|
dateRange: {
|
|
38495
|
-
startDate: startDate ? /* @__PURE__ */ new Date(startDate + "T00:00:00") : (0,
|
|
38496
|
-
endDate: endDate ? /* @__PURE__ */ new Date(endDate + "T00:00:00") : (0,
|
|
40903
|
+
startDate: startDate ? /* @__PURE__ */ new Date(startDate + "T00:00:00") : (0, import_date_fns15.startOfToday)(),
|
|
40904
|
+
endDate: endDate ? /* @__PURE__ */ new Date(endDate + "T00:00:00") : (0, import_date_fns15.startOfToday)()
|
|
38497
40905
|
},
|
|
38498
40906
|
preset: "",
|
|
38499
40907
|
presetOptions: [],
|
|
@@ -38720,6 +41128,9 @@ function validateTemplatesAgainstFilters(filters, templates) {
|
|
|
38720
41128
|
}
|
|
38721
41129
|
async function addTemplatesToDashboard(name2, newTemplates, client, dashboardData, getToken, eventTracking) {
|
|
38722
41130
|
try {
|
|
41131
|
+
if (!newTemplates?.length) {
|
|
41132
|
+
return null;
|
|
41133
|
+
}
|
|
38723
41134
|
const { publicKey, tenants } = client;
|
|
38724
41135
|
if (tenants) {
|
|
38725
41136
|
throw new Error("Adding from template not yet supported for tenants");
|
|
@@ -38772,6 +41183,7 @@ async function addTemplatesToDashboard(name2, newTemplates, client, dashboardDat
|
|
|
38772
41183
|
function: "addTemplatesToDashboard"
|
|
38773
41184
|
}
|
|
38774
41185
|
});
|
|
41186
|
+
return null;
|
|
38775
41187
|
}
|
|
38776
41188
|
}
|
|
38777
41189
|
|
|
@@ -40649,7 +43061,7 @@ var PivotList = ({
|
|
|
40649
43061
|
};
|
|
40650
43062
|
|
|
40651
43063
|
// src/internals/ReportBuilder/PivotModal.tsx
|
|
40652
|
-
var
|
|
43064
|
+
var import_date_fns16 = require("date-fns");
|
|
40653
43065
|
init_textProcessing();
|
|
40654
43066
|
init_pivotProcessing();
|
|
40655
43067
|
init_tableProcessing();
|
|
@@ -42477,7 +44889,7 @@ var validateReport = (formData, dashboardData, defaultDateFilter, allTables) =>
|
|
|
42477
44889
|
|
|
42478
44890
|
// src/components/Chart/InternalChart.tsx
|
|
42479
44891
|
var import_react42 = require("react");
|
|
42480
|
-
var
|
|
44892
|
+
var import_date_fns17 = require("date-fns");
|
|
42481
44893
|
init_Filter();
|
|
42482
44894
|
init_filterProcessing();
|
|
42483
44895
|
init_dateRangePickerUtils();
|
|
@@ -44317,7 +46729,7 @@ function ChartBuilder({
|
|
|
44317
46729
|
template: true,
|
|
44318
46730
|
referenceLines: []
|
|
44319
46731
|
};
|
|
44320
|
-
const
|
|
46732
|
+
const updateDashboardFilters2 = async (dashboardName) => {
|
|
44321
46733
|
if (dashboardConfig && dashboardConfig[dashboardName]) {
|
|
44322
46734
|
return dashboardConfig[dashboardName];
|
|
44323
46735
|
}
|
|
@@ -44639,7 +47051,7 @@ function ChartBuilder({
|
|
|
44639
47051
|
if (destinationDashboardName) {
|
|
44640
47052
|
dashboardName = destinationDashboardName;
|
|
44641
47053
|
}
|
|
44642
|
-
const curDashboard = await
|
|
47054
|
+
const curDashboard = await updateDashboardFilters2(dashboardName);
|
|
44643
47055
|
setDashboardOptions(dashboardOptions2);
|
|
44644
47056
|
curFormData.dashboardName = dashboardName;
|
|
44645
47057
|
const curSchemaData = schemaData.schemaWithCustomFields;
|
|
@@ -45926,7 +48338,7 @@ function ChartBuilder({
|
|
|
45926
48338
|
value: formData.dashboardName || "",
|
|
45927
48339
|
onChange: async (e) => {
|
|
45928
48340
|
handleChange(e.target.value, "dashboardName");
|
|
45929
|
-
await
|
|
48341
|
+
await updateDashboardFilters2(e.target.value);
|
|
45930
48342
|
},
|
|
45931
48343
|
options: dashboardOptions.map((elem) => ({
|
|
45932
48344
|
label: elem.label,
|
|
@@ -54257,7 +56669,7 @@ function StaticChart(props) {
|
|
|
54257
56669
|
pageLoading,
|
|
54258
56670
|
nextPage,
|
|
54259
56671
|
prevPage,
|
|
54260
|
-
sortRows
|
|
56672
|
+
sortRows: sortRows2
|
|
54261
56673
|
} = useDashboardReportInternal(reportId);
|
|
54262
56674
|
const baseStyle = report?.chartType && CHART_TYPE_STYLES[report.chartType] ? CHART_TYPE_STYLES[report.chartType] : DEFAULT_STYLE;
|
|
54263
56675
|
const mergedStyle = className ? { ...containerStyle ?? {} } : { ...baseStyle, ...containerStyle ?? {} };
|
|
@@ -54277,7 +56689,7 @@ function StaticChart(props) {
|
|
|
54277
56689
|
}
|
|
54278
56690
|
};
|
|
54279
56691
|
const onSortChange = (sort) => {
|
|
54280
|
-
|
|
56692
|
+
sortRows2({
|
|
54281
56693
|
field: sort.field,
|
|
54282
56694
|
direction: sort.direction
|
|
54283
56695
|
});
|