@quillsql/react 2.16.101 → 2.16.103
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 +446 -38
- package/dist/index.js +446 -38
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -23368,7 +23368,7 @@ async function fetchReportRows({
|
|
|
23368
23368
|
additionalProcessing,
|
|
23369
23369
|
overwriteCache = false
|
|
23370
23370
|
}) {
|
|
23371
|
-
const
|
|
23371
|
+
const startedAt2 = performance.now();
|
|
23372
23372
|
profileDashboard("raw-report-rows-fetch-start", { reportId });
|
|
23373
23373
|
const fetchResp = await quillFetch({
|
|
23374
23374
|
client,
|
|
@@ -23389,7 +23389,7 @@ async function fetchReportRows({
|
|
|
23389
23389
|
const resp = await parseFetchResponse(client, "report", fetchResp, getToken);
|
|
23390
23390
|
profileDashboard("raw-report-rows-fetch-finish", {
|
|
23391
23391
|
reportId,
|
|
23392
|
-
elapsedMs: Math.round(performance.now() -
|
|
23392
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23393
23393
|
rowCount: resp.rows?.length ?? 0
|
|
23394
23394
|
});
|
|
23395
23395
|
if (client.databaseType?.toLowerCase() === "bigquery") {
|
|
@@ -23427,7 +23427,7 @@ async function fetchReport({
|
|
|
23427
23427
|
}) {
|
|
23428
23428
|
let reportInfo = void 0;
|
|
23429
23429
|
let errorMessage = void 0;
|
|
23430
|
-
const
|
|
23430
|
+
const startedAt2 = performance.now();
|
|
23431
23431
|
try {
|
|
23432
23432
|
const task = usePivotTask ? "pivot-template" : useReportTask ? "report" : "item";
|
|
23433
23433
|
profileDashboard("fetch-report-start", {
|
|
@@ -23482,7 +23482,7 @@ async function fetchReport({
|
|
|
23482
23482
|
profileDashboard("fetch-report-response", {
|
|
23483
23483
|
reportId: reportId ?? null,
|
|
23484
23484
|
task,
|
|
23485
|
-
elapsedMs: Math.round(performance.now() -
|
|
23485
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23486
23486
|
hasRows: !!resp?.rows,
|
|
23487
23487
|
rowCount: resp?.rows?.length ?? 0,
|
|
23488
23488
|
hasFields: !!resp?.fields,
|
|
@@ -23507,7 +23507,7 @@ async function fetchReport({
|
|
|
23507
23507
|
profileDashboard("fetch-report-processed", {
|
|
23508
23508
|
reportId: reportId ?? null,
|
|
23509
23509
|
task,
|
|
23510
|
-
elapsedMs: Math.round(performance.now() -
|
|
23510
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23511
23511
|
rowCount: reportInfo.rows?.length ?? 0,
|
|
23512
23512
|
pivotRowCount: reportInfo.pivotRows?.length ?? 0
|
|
23513
23513
|
});
|
|
@@ -23736,6 +23736,15 @@ async function saveReport({
|
|
|
23736
23736
|
}
|
|
23737
23737
|
return data;
|
|
23738
23738
|
}
|
|
23739
|
+
function isPlainNumericCellValue(value) {
|
|
23740
|
+
if (value === null || value === void 0 || value === "") return true;
|
|
23741
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
23742
|
+
if (typeof value === "bigint") return true;
|
|
23743
|
+
if (typeof value !== "string") return false;
|
|
23744
|
+
const trimmed = value.trim();
|
|
23745
|
+
if (!trimmed) return true;
|
|
23746
|
+
return /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(trimmed);
|
|
23747
|
+
}
|
|
23739
23748
|
var formatRowsFromReport = (report, xAxisField, xAxisFormat) => {
|
|
23740
23749
|
if (!report.rows || !report.columns) {
|
|
23741
23750
|
return [];
|
|
@@ -23763,6 +23772,10 @@ var formatRowsFromReport = (report, xAxisField, xAxisFormat) => {
|
|
|
23763
23772
|
const formattedRow = {};
|
|
23764
23773
|
for (const column of resolvedColumns) {
|
|
23765
23774
|
const rawValue = row[column.field];
|
|
23775
|
+
if (NUMBER_FORMAT_TYPES.includes(String(column.format ?? "")) && !isPlainNumericCellValue(rawValue)) {
|
|
23776
|
+
formattedRow[column.field] = rawValue === null || rawValue === void 0 || rawValue === "" ? "-" : String(rawValue);
|
|
23777
|
+
continue;
|
|
23778
|
+
}
|
|
23766
23779
|
formattedRow[column.field] = column.inferFormat ? quillAutoFormat(rawValue) : getFormattedWithCache(column.format, rawValue);
|
|
23767
23780
|
}
|
|
23768
23781
|
return formattedRow;
|
|
@@ -39693,7 +39706,7 @@ var ChartDataLoader = ({
|
|
|
39693
39706
|
}
|
|
39694
39707
|
const fetchRowsRequestId = rowsRequestId.current + 1;
|
|
39695
39708
|
rowsRequestId.current = fetchRowsRequestId;
|
|
39696
|
-
const
|
|
39709
|
+
const startedAt2 = performance.now();
|
|
39697
39710
|
profileDashboard("chart-data-loader-fetch-start", {
|
|
39698
39711
|
reportId: item.id,
|
|
39699
39712
|
requestId: fetchRowsRequestId,
|
|
@@ -39839,7 +39852,7 @@ var ChartDataLoader = ({
|
|
|
39839
39852
|
reportId: item.id,
|
|
39840
39853
|
requestId: fetchRowsRequestId,
|
|
39841
39854
|
reason,
|
|
39842
|
-
elapsedMs: Math.round(performance.now() -
|
|
39855
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
39843
39856
|
isLatestRequest: fetchRowsRequestId === rowsRequestId.current,
|
|
39844
39857
|
startsBackgroundFetch: !!backgroundFetch
|
|
39845
39858
|
});
|
|
@@ -62391,6 +62404,345 @@ function resolveReportFromCacheCab({
|
|
|
62391
62404
|
|
|
62392
62405
|
// src/hooks/useForm.tsx
|
|
62393
62406
|
init_dashboardProfiler();
|
|
62407
|
+
|
|
62408
|
+
// src/hooks/useReport.nanPivotDiag.ts
|
|
62409
|
+
init_valueFormatter();
|
|
62410
|
+
var NAN_PIVOT_DEBUG_FLAG = "__QUILL_DEBUG_NAN_PIVOT__";
|
|
62411
|
+
var NAN_PIVOT_LOG_FLAG = "__QUILL_NAN_PIVOT_LOG__";
|
|
62412
|
+
var startedAt = Date.now();
|
|
62413
|
+
function globalRecord() {
|
|
62414
|
+
return globalThis;
|
|
62415
|
+
}
|
|
62416
|
+
function isNanPivotDebugEnabled() {
|
|
62417
|
+
const globalValue = globalRecord()[NAN_PIVOT_DEBUG_FLAG];
|
|
62418
|
+
if (globalValue === true) return true;
|
|
62419
|
+
if (typeof process !== "undefined" && typeof process.env !== "undefined") {
|
|
62420
|
+
const envValue = String(process.env.QUILL_DEBUG_NAN_PIVOT ?? "").trim().toLowerCase();
|
|
62421
|
+
return envValue === "1" || envValue === "true";
|
|
62422
|
+
}
|
|
62423
|
+
return false;
|
|
62424
|
+
}
|
|
62425
|
+
function getNanPivotLog() {
|
|
62426
|
+
const log = globalRecord()[NAN_PIVOT_LOG_FLAG];
|
|
62427
|
+
return Array.isArray(log) ? log : [];
|
|
62428
|
+
}
|
|
62429
|
+
function findNanValues(value, path = "root") {
|
|
62430
|
+
if (typeof value === "number" && Number.isNaN(value)) {
|
|
62431
|
+
return [`${path}=NaN`];
|
|
62432
|
+
}
|
|
62433
|
+
if (typeof value === "string" && /^[-+]?NaN(?:%|\s*)$/i.test(value.trim())) {
|
|
62434
|
+
return [`${path}=${JSON.stringify(value)}`];
|
|
62435
|
+
}
|
|
62436
|
+
if (Array.isArray(value)) {
|
|
62437
|
+
return value.flatMap(
|
|
62438
|
+
(entry, index) => findNanValues(entry, `${path}[${index}]`)
|
|
62439
|
+
);
|
|
62440
|
+
}
|
|
62441
|
+
if (value && typeof value === "object") {
|
|
62442
|
+
return Object.entries(value).flatMap(
|
|
62443
|
+
([key, entry]) => findNanValues(entry, `${path}.${key}`)
|
|
62444
|
+
);
|
|
62445
|
+
}
|
|
62446
|
+
return [];
|
|
62447
|
+
}
|
|
62448
|
+
function pivotKindOf(pivot) {
|
|
62449
|
+
if (pivot == null) return "none";
|
|
62450
|
+
if (typeof pivot !== "object") return "none";
|
|
62451
|
+
const value = pivot;
|
|
62452
|
+
const rowField = String(value.rowField ?? "").trim();
|
|
62453
|
+
const columnField = String(value.columnField ?? "").trim();
|
|
62454
|
+
const hasAggregation = Array.isArray(value.aggregations) && value.aggregations.length > 0 || Boolean(String(value.aggregationType ?? "").trim());
|
|
62455
|
+
if (rowField && columnField) return "2D";
|
|
62456
|
+
if (rowField || columnField) return "1D";
|
|
62457
|
+
if (hasAggregation) return "aggregation-only";
|
|
62458
|
+
return "empty-object";
|
|
62459
|
+
}
|
|
62460
|
+
function reportDetailSurfaceOf(chart) {
|
|
62461
|
+
if (!chart || typeof chart !== "object") return "none";
|
|
62462
|
+
const value = chart;
|
|
62463
|
+
const chartType = String(value.chartType ?? "").trim().toLowerCase();
|
|
62464
|
+
if (chartType !== "table") {
|
|
62465
|
+
return "chart-display-chart";
|
|
62466
|
+
}
|
|
62467
|
+
const isPivotTable = Boolean(value.pivot) && Array.isArray(value.columns) && value.columns.length > 0;
|
|
62468
|
+
return isPivotTable ? "chart-display-pivot-table" : "flat-table";
|
|
62469
|
+
}
|
|
62470
|
+
function columnFormats(columns) {
|
|
62471
|
+
if (!Array.isArray(columns)) return [];
|
|
62472
|
+
return columns.map((column) => {
|
|
62473
|
+
const value = column ?? {};
|
|
62474
|
+
return {
|
|
62475
|
+
field: String(value.field ?? ""),
|
|
62476
|
+
label: String(value.label ?? ""),
|
|
62477
|
+
format: String(value.format ?? "")
|
|
62478
|
+
};
|
|
62479
|
+
});
|
|
62480
|
+
}
|
|
62481
|
+
function sampleRows(rows, count = 2) {
|
|
62482
|
+
return Array.isArray(rows) ? rows.slice(0, count) : [];
|
|
62483
|
+
}
|
|
62484
|
+
function hitsFor(surface, value) {
|
|
62485
|
+
return findNanValues(value).map((path) => ({ surface, path }));
|
|
62486
|
+
}
|
|
62487
|
+
function looksNumeric(value) {
|
|
62488
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
62489
|
+
if (typeof value !== "string") return false;
|
|
62490
|
+
const trimmed = value.trim();
|
|
62491
|
+
if (!trimmed) return false;
|
|
62492
|
+
return Number.isFinite(Number(trimmed.replace(/,/g, "")));
|
|
62493
|
+
}
|
|
62494
|
+
function alreadyGroupedNumberString(value) {
|
|
62495
|
+
return typeof value === "string" && /^-?\d{1,3}(?:,\d{3})+(?:\.\d+)?$/.test(value.trim());
|
|
62496
|
+
}
|
|
62497
|
+
function formatRowsAsChartDisplay(chart, rows, columns) {
|
|
62498
|
+
if (!Array.isArray(rows) || rows.length === 0) return [];
|
|
62499
|
+
const value = chart ?? {};
|
|
62500
|
+
try {
|
|
62501
|
+
return formatRowsFromReport(
|
|
62502
|
+
{
|
|
62503
|
+
...value,
|
|
62504
|
+
rows,
|
|
62505
|
+
columns: Array.isArray(columns) ? columns : [],
|
|
62506
|
+
pivot: chart?.pivot
|
|
62507
|
+
},
|
|
62508
|
+
value.xAxisField,
|
|
62509
|
+
value.xAxisFormat
|
|
62510
|
+
);
|
|
62511
|
+
} catch {
|
|
62512
|
+
return [];
|
|
62513
|
+
}
|
|
62514
|
+
}
|
|
62515
|
+
function formatMismatchesFor(columns, rows) {
|
|
62516
|
+
if (!Array.isArray(rows) || rows.length === 0) return [];
|
|
62517
|
+
const mismatches = [];
|
|
62518
|
+
for (const column of columns) {
|
|
62519
|
+
if (!NUMBER_FORMAT_TYPES.includes(column.format)) continue;
|
|
62520
|
+
for (let index = 0; index < Math.min(rows.length, 8); index += 1) {
|
|
62521
|
+
const row = rows[index];
|
|
62522
|
+
if (!row || typeof row !== "object") continue;
|
|
62523
|
+
const cell = row[column.field];
|
|
62524
|
+
if (cell == null || cell === "") continue;
|
|
62525
|
+
if (looksNumeric(cell)) continue;
|
|
62526
|
+
mismatches.push(
|
|
62527
|
+
`${column.field} format=${column.format} row[${index}]=${JSON.stringify(cell)}`
|
|
62528
|
+
);
|
|
62529
|
+
break;
|
|
62530
|
+
}
|
|
62531
|
+
}
|
|
62532
|
+
return mismatches;
|
|
62533
|
+
}
|
|
62534
|
+
function chartDisplayRows(chart) {
|
|
62535
|
+
if (!chart || typeof chart !== "object") return [];
|
|
62536
|
+
const value = chart;
|
|
62537
|
+
if (String(value.chartType ?? "").toLowerCase() !== "table") {
|
|
62538
|
+
return Array.isArray(value.rows) ? value.rows : [];
|
|
62539
|
+
}
|
|
62540
|
+
const tableColumns = value.includeCustomFields && value.columnsWithCustomFields && !value.pivot ? value.columnsWithCustomFields : value.columns ?? value.yAxisFields ?? [];
|
|
62541
|
+
try {
|
|
62542
|
+
return formatRowsFromReport(
|
|
62543
|
+
{ ...value, rows: value.rows ?? [], columns: tableColumns },
|
|
62544
|
+
value.xAxisField,
|
|
62545
|
+
value.xAxisFormat
|
|
62546
|
+
);
|
|
62547
|
+
} catch {
|
|
62548
|
+
return [];
|
|
62549
|
+
}
|
|
62550
|
+
}
|
|
62551
|
+
function pivotFieldHits(pivot) {
|
|
62552
|
+
if (!pivot || typeof pivot !== "object") return [];
|
|
62553
|
+
return hitsFor("pivotFields", {
|
|
62554
|
+
rowField: pivot.rowField,
|
|
62555
|
+
columnField: pivot.columnField,
|
|
62556
|
+
rowFieldTable: pivot.rowFieldTable,
|
|
62557
|
+
columnFieldTable: pivot.columnFieldTable
|
|
62558
|
+
});
|
|
62559
|
+
}
|
|
62560
|
+
function jsonSafe(value) {
|
|
62561
|
+
try {
|
|
62562
|
+
return JSON.parse(
|
|
62563
|
+
JSON.stringify(value, (_key, current) => {
|
|
62564
|
+
if (typeof current === "number" && Number.isNaN(current)) {
|
|
62565
|
+
return "__NaN__";
|
|
62566
|
+
}
|
|
62567
|
+
if (current === void 0) return "__undefined__";
|
|
62568
|
+
return current;
|
|
62569
|
+
})
|
|
62570
|
+
);
|
|
62571
|
+
} catch {
|
|
62572
|
+
return value;
|
|
62573
|
+
}
|
|
62574
|
+
}
|
|
62575
|
+
function snapshotUseReportNanState(input) {
|
|
62576
|
+
const chart = input.chart ?? null;
|
|
62577
|
+
const table = input.table ?? null;
|
|
62578
|
+
const sourceReport = input.sourceReport ?? null;
|
|
62579
|
+
const chartType = String(chart?.chartType ?? input.chartType ?? "").trim();
|
|
62580
|
+
const tableColumns = columnFormats(table?.columns);
|
|
62581
|
+
const chartColumns = columnFormats(chart?.columns);
|
|
62582
|
+
const tableRows = Array.isArray(table?.rows) ? table.rows : [];
|
|
62583
|
+
const chartRows = Array.isArray(chart?.rows) ? chart.rows : [];
|
|
62584
|
+
const pivotRows = Array.isArray(chart?.pivotRows) ? chart.pivotRows : [];
|
|
62585
|
+
const sourceRows = Array.isArray(sourceReport?.rows) ? sourceReport.rows : [];
|
|
62586
|
+
const sourcePivotRows = Array.isArray(sourceReport?.pivotRows) ? sourceReport.pivotRows : [];
|
|
62587
|
+
const displayRows = chartDisplayRows(chart);
|
|
62588
|
+
const doubleFormatRows = formatRowsAsChartDisplay(
|
|
62589
|
+
chart,
|
|
62590
|
+
tableRows,
|
|
62591
|
+
table?.columns ?? chart?.columns
|
|
62592
|
+
);
|
|
62593
|
+
const formPivot = input.formPivot ?? null;
|
|
62594
|
+
const nextPivot = input.nextPivot ?? null;
|
|
62595
|
+
const sourcePivot = sourceReport?.pivot ?? null;
|
|
62596
|
+
const chartPivot = chart?.pivot ?? null;
|
|
62597
|
+
const kind = pivotKindOf(chartPivot ?? nextPivot ?? formPivot ?? sourcePivot);
|
|
62598
|
+
const groupRowsBy = String(input.groupRowsBy ?? "").trim() || null;
|
|
62599
|
+
const groupColumnsBy = String(input.groupColumnsBy ?? "").trim() || null;
|
|
62600
|
+
const hasFormPivotSelection = Boolean(
|
|
62601
|
+
groupRowsBy || groupColumnsBy || Array.isArray(input.aggregations) && input.aggregations.some((value) => String(value ?? "").trim())
|
|
62602
|
+
);
|
|
62603
|
+
const unexpectedPivot = !hasFormPivotSelection && (kind === "1D" || kind === "2D" || kind === "aggregation-only" || kind === "empty-object");
|
|
62604
|
+
const nanHits = [
|
|
62605
|
+
...hitsFor("useReport.table", tableRows),
|
|
62606
|
+
...hitsFor("useReport.chart.rows", chartRows),
|
|
62607
|
+
...hitsFor("useReport.chart.pivotRows", pivotRows),
|
|
62608
|
+
...hitsFor("sourceReport.rows", sourceRows),
|
|
62609
|
+
...hitsFor("sourceReport.pivotRows", sourcePivotRows),
|
|
62610
|
+
...hitsFor("chartDisplay.formattedRows", displayRows),
|
|
62611
|
+
...hitsFor("chartDisplay.doubleFormatTableRows", doubleFormatRows),
|
|
62612
|
+
...hitsFor("columnLabels", [
|
|
62613
|
+
...tableColumns.map((column) => column.label),
|
|
62614
|
+
...chartColumns.map((column) => column.label)
|
|
62615
|
+
]),
|
|
62616
|
+
...hitsFor("columnFields", [
|
|
62617
|
+
...tableColumns.map((column) => column.field),
|
|
62618
|
+
...chartColumns.map((column) => column.field)
|
|
62619
|
+
]),
|
|
62620
|
+
...pivotFieldHits(chartPivot),
|
|
62621
|
+
...pivotFieldHits(formPivot),
|
|
62622
|
+
...pivotFieldHits(sourcePivot)
|
|
62623
|
+
];
|
|
62624
|
+
return {
|
|
62625
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
62626
|
+
atMs: Date.now() - startedAt,
|
|
62627
|
+
source: input.source ?? "useReport",
|
|
62628
|
+
flow: input.flow,
|
|
62629
|
+
step: input.step,
|
|
62630
|
+
reportId: String(input.reportId ?? ""),
|
|
62631
|
+
datasources: Array.isArray(input.datasources) ? input.datasources.map((value) => String(value)) : [],
|
|
62632
|
+
chartType,
|
|
62633
|
+
chartLoading: Boolean(input.chartLoading),
|
|
62634
|
+
tableLoading: Boolean(input.tableLoading),
|
|
62635
|
+
loading: Boolean(input.loading),
|
|
62636
|
+
groupRowsBy,
|
|
62637
|
+
groupColumnsBy,
|
|
62638
|
+
aggregations: input.aggregations ?? [],
|
|
62639
|
+
formPivot,
|
|
62640
|
+
nextPivot,
|
|
62641
|
+
sourcePivot,
|
|
62642
|
+
chartPivot,
|
|
62643
|
+
pivotKind: kind,
|
|
62644
|
+
unexpectedPivot,
|
|
62645
|
+
isPivotTableChart: Boolean(input.isPivotTableChart),
|
|
62646
|
+
reportDetailSurface: reportDetailSurfaceOf(chart),
|
|
62647
|
+
tableColumnFormats: tableColumns,
|
|
62648
|
+
chartColumnFormats: chartColumns,
|
|
62649
|
+
tableRowCount: tableRows.length,
|
|
62650
|
+
chartRowCount: chartRows.length,
|
|
62651
|
+
pivotRowCount: pivotRows.length,
|
|
62652
|
+
tableSample: sampleRows(tableRows),
|
|
62653
|
+
chartRowSample: sampleRows(chartRows),
|
|
62654
|
+
pivotRowSample: sampleRows(pivotRows),
|
|
62655
|
+
chartDisplaySample: sampleRows(displayRows),
|
|
62656
|
+
doubleFormatSample: sampleRows(doubleFormatRows),
|
|
62657
|
+
formatMismatches: [
|
|
62658
|
+
...formatMismatchesFor(tableColumns, sourceRows.length ? sourceRows : tableRows),
|
|
62659
|
+
...formatMismatchesFor(chartColumns, chartRows.length ? chartRows : pivotRows),
|
|
62660
|
+
...tableRows.flatMap((row, index) => {
|
|
62661
|
+
if (!row || typeof row !== "object") return [];
|
|
62662
|
+
return tableColumns.filter(
|
|
62663
|
+
(column) => NUMBER_FORMAT_TYPES.includes(column.format) && alreadyGroupedNumberString(
|
|
62664
|
+
row[column.field]
|
|
62665
|
+
)
|
|
62666
|
+
).map(
|
|
62667
|
+
(column) => `already-formatted ${column.field} row[${index}]=${JSON.stringify(
|
|
62668
|
+
row[column.field]
|
|
62669
|
+
)}`
|
|
62670
|
+
);
|
|
62671
|
+
})
|
|
62672
|
+
],
|
|
62673
|
+
nanHits
|
|
62674
|
+
};
|
|
62675
|
+
}
|
|
62676
|
+
var lastSerializedBySource = /* @__PURE__ */ new Map();
|
|
62677
|
+
function recordUseReportNanPivotState(input) {
|
|
62678
|
+
if (!isNanPivotDebugEnabled()) return null;
|
|
62679
|
+
const snapshot = snapshotUseReportNanState(input);
|
|
62680
|
+
const key = `${snapshot.source}:${snapshot.flow ?? ""}:${snapshot.reportId}`;
|
|
62681
|
+
const serialized = JSON.stringify(jsonSafe(snapshot));
|
|
62682
|
+
if (lastSerializedBySource.get(key) === serialized) {
|
|
62683
|
+
return snapshot;
|
|
62684
|
+
}
|
|
62685
|
+
lastSerializedBySource.set(key, serialized);
|
|
62686
|
+
const log = getNanPivotLog();
|
|
62687
|
+
log.push(snapshot);
|
|
62688
|
+
globalRecord()[NAN_PIVOT_LOG_FLAG] = log;
|
|
62689
|
+
const liveHits = snapshot.nanHits.filter(
|
|
62690
|
+
(hit) => hit.surface !== "chartDisplay.doubleFormatTableRows"
|
|
62691
|
+
);
|
|
62692
|
+
const compact = {
|
|
62693
|
+
atMs: snapshot.atMs,
|
|
62694
|
+
source: snapshot.source,
|
|
62695
|
+
flow: snapshot.flow,
|
|
62696
|
+
step: snapshot.step,
|
|
62697
|
+
reportId: snapshot.reportId,
|
|
62698
|
+
datasources: snapshot.datasources,
|
|
62699
|
+
chartType: snapshot.chartType,
|
|
62700
|
+
loading: snapshot.loading,
|
|
62701
|
+
chartLoading: snapshot.chartLoading,
|
|
62702
|
+
tableLoading: snapshot.tableLoading,
|
|
62703
|
+
groupRowsBy: snapshot.groupRowsBy,
|
|
62704
|
+
groupColumnsBy: snapshot.groupColumnsBy,
|
|
62705
|
+
pivotKind: snapshot.pivotKind,
|
|
62706
|
+
unexpectedPivot: snapshot.unexpectedPivot,
|
|
62707
|
+
isPivotTableChart: snapshot.isPivotTableChart,
|
|
62708
|
+
reportDetailSurface: snapshot.reportDetailSurface,
|
|
62709
|
+
tableRowCount: snapshot.tableRowCount,
|
|
62710
|
+
chartRowCount: snapshot.chartRowCount,
|
|
62711
|
+
pivotRowCount: snapshot.pivotRowCount,
|
|
62712
|
+
formatMismatches: snapshot.formatMismatches.slice(0, 8),
|
|
62713
|
+
nanHits: snapshot.nanHits.slice(0, 12)
|
|
62714
|
+
};
|
|
62715
|
+
if (liveHits.length > 0 || snapshot.unexpectedPivot) {
|
|
62716
|
+
console.log(
|
|
62717
|
+
"[useReport][nan-pivot][hit]",
|
|
62718
|
+
JSON.stringify(
|
|
62719
|
+
jsonSafe({
|
|
62720
|
+
...compact,
|
|
62721
|
+
tableSample: snapshot.tableSample,
|
|
62722
|
+
chartRowSample: snapshot.chartRowSample,
|
|
62723
|
+
pivotRowSample: snapshot.pivotRowSample,
|
|
62724
|
+
chartDisplaySample: snapshot.chartDisplaySample,
|
|
62725
|
+
doubleFormatSample: snapshot.doubleFormatSample,
|
|
62726
|
+
formPivot: snapshot.formPivot,
|
|
62727
|
+
chartPivot: snapshot.chartPivot,
|
|
62728
|
+
sourcePivot: snapshot.sourcePivot
|
|
62729
|
+
}),
|
|
62730
|
+
null,
|
|
62731
|
+
2
|
|
62732
|
+
)
|
|
62733
|
+
);
|
|
62734
|
+
} else if (snapshot.nanHits.length > 0) {
|
|
62735
|
+
console.log(
|
|
62736
|
+
"[useReport][nan-pivot][double-format]",
|
|
62737
|
+
JSON.stringify(compact)
|
|
62738
|
+
);
|
|
62739
|
+
} else {
|
|
62740
|
+
console.log("[useReport][nan-pivot][state]", JSON.stringify(compact));
|
|
62741
|
+
}
|
|
62742
|
+
return snapshot;
|
|
62743
|
+
}
|
|
62744
|
+
|
|
62745
|
+
// src/hooks/useForm.tsx
|
|
62394
62746
|
init_reportRequestPool();
|
|
62395
62747
|
|
|
62396
62748
|
// src/hooks/useForm.queries.ts
|
|
@@ -63570,22 +63922,21 @@ function isPlaceholderAxisLabel(label, field) {
|
|
|
63570
63922
|
function resolvedAxisLabel(savedLabel, field, generatedLabel) {
|
|
63571
63923
|
return isPlaceholderAxisLabel(savedLabel, field) ? generatedLabel : savedLabel;
|
|
63572
63924
|
}
|
|
63925
|
+
function uniqueAxisFormat(formats) {
|
|
63926
|
+
const values = formats.map((format9) => String(format9 ?? "").trim()).filter(Boolean);
|
|
63927
|
+
if (values.length === 0) return void 0;
|
|
63928
|
+
return values.every((format9) => format9 === values[0]) ? values[0] : void 0;
|
|
63929
|
+
}
|
|
63573
63930
|
function resolveYAxisFormatForField(field, aggregation, saved, fallback) {
|
|
63574
63931
|
const formatByField = new Map(
|
|
63575
63932
|
saved.map((axis) => [String(axis.field ?? "").trim(), axis.format])
|
|
63576
63933
|
);
|
|
63934
|
+
const savedFormats = uniqueAxisFormat(saved.map((axis) => axis.format));
|
|
63577
63935
|
if (aggregation?.aggregationType === "count") {
|
|
63578
|
-
return formatByField.get(field) ?? formatByField.get("count") ??
|
|
63579
|
-
}
|
|
63580
|
-
if (aggregation?.aggregationType === "percentage") {
|
|
63581
|
-
const savedFormat = formatByField.get(field);
|
|
63582
|
-
if (savedFormat === "percent" || savedFormat === "percentage") {
|
|
63583
|
-
return savedFormat;
|
|
63584
|
-
}
|
|
63585
|
-
return "percentage";
|
|
63936
|
+
return formatByField.get(field) ?? formatByField.get("count") ?? savedFormats ?? "whole_number";
|
|
63586
63937
|
}
|
|
63587
63938
|
const aggType = aggregation?.aggregationType ? String(aggregation.aggregationType) : void 0;
|
|
63588
|
-
return formatByField.get(field) ?? formatByField.get(trimAggregationSuffix(field, aggType)) ?? (aggregation?.valueField ? formatByField.get(aggregation.valueField) : void 0) ?? fallback;
|
|
63939
|
+
return formatByField.get(field) ?? formatByField.get(trimAggregationSuffix(field, aggType)) ?? (aggregation?.valueField ? formatByField.get(aggregation.valueField) : void 0) ?? savedFormats ?? fallback;
|
|
63589
63940
|
}
|
|
63590
63941
|
function aggregationIdentityForField(field, aggregations) {
|
|
63591
63942
|
return getAggregationIdentityKey(
|
|
@@ -63656,6 +64007,7 @@ function applyYAxisEdits(measures, edits, aggregations) {
|
|
|
63656
64007
|
const base = (identity ? byIdentity.get(identity) : void 0) ?? byField.get(field);
|
|
63657
64008
|
const label = String(edit.label ?? "").trim();
|
|
63658
64009
|
if (!base) {
|
|
64010
|
+
if (aggregations.length > 0) continue;
|
|
63659
64011
|
next.push({
|
|
63660
64012
|
field,
|
|
63661
64013
|
label: label || toTitleCaseLabel(field),
|
|
@@ -63669,7 +64021,16 @@ function applyYAxisEdits(measures, edits, aggregations) {
|
|
|
63669
64021
|
format: toAxisFormat(edit.format, base.format)
|
|
63670
64022
|
});
|
|
63671
64023
|
}
|
|
63672
|
-
|
|
64024
|
+
if (next.length > 0) return next;
|
|
64025
|
+
if (aggregations.length > 0 && measures.length === 1 && edits.length === 1 && edits[0]?.format) {
|
|
64026
|
+
return [
|
|
64027
|
+
{
|
|
64028
|
+
...measures[0],
|
|
64029
|
+
format: toAxisFormat(edits[0].format, measures[0].format)
|
|
64030
|
+
}
|
|
64031
|
+
];
|
|
64032
|
+
}
|
|
64033
|
+
return measures;
|
|
63673
64034
|
}
|
|
63674
64035
|
function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
63675
64036
|
const saved = chart.yAxisFields ?? [];
|
|
@@ -63680,7 +64041,6 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63680
64041
|
const aggregations = getPivotAggregations(chart);
|
|
63681
64042
|
const hasMultipleAggregations = aggregations.length > 1;
|
|
63682
64043
|
const columnField = String(chart.pivot?.columnField ?? "").trim();
|
|
63683
|
-
const isAggregationOnlyPivot = !String(chart.pivot?.rowField ?? "").trim() && !columnField;
|
|
63684
64044
|
const fallback = saved[0]?.format ?? chart.xAxisFormat ?? "whole_number";
|
|
63685
64045
|
const valueKeys = pivotValueFieldKeys(chart);
|
|
63686
64046
|
const fallbackKeys = pivotFallbackValueKeys(chart);
|
|
@@ -63702,9 +64062,9 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63702
64062
|
measure.field
|
|
63703
64063
|
);
|
|
63704
64064
|
if (matchedKey) return [{ ...measure, field: matchedKey }];
|
|
63705
|
-
return
|
|
64065
|
+
return [measure];
|
|
63706
64066
|
});
|
|
63707
|
-
if (!columnField && measures.length === 0 && saved.length > 0) {
|
|
64067
|
+
if (!columnField && measures.length === 0 && saved.length > 0 && aggregations.length === 0) {
|
|
63708
64068
|
measures = saved;
|
|
63709
64069
|
}
|
|
63710
64070
|
measures = applyYAxisEdits(measures, edits, aggregations);
|
|
@@ -63731,7 +64091,12 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63731
64091
|
measureLabel,
|
|
63732
64092
|
hasMultipleAggregations
|
|
63733
64093
|
),
|
|
63734
|
-
format: measure?.format ?? resolveYAxisFormatForField(
|
|
64094
|
+
format: measure?.format ?? resolveYAxisFormatForField(
|
|
64095
|
+
field,
|
|
64096
|
+
aggregation,
|
|
64097
|
+
saved,
|
|
64098
|
+
fallback
|
|
64099
|
+
)
|
|
63735
64100
|
}
|
|
63736
64101
|
];
|
|
63737
64102
|
});
|
|
@@ -63771,7 +64136,11 @@ function normalizePivotChartForDisplay(chart) {
|
|
|
63771
64136
|
pivotRowFieldEarly,
|
|
63772
64137
|
String(rowColumn?.format ?? "")
|
|
63773
64138
|
) ? pivotRowFieldEarly : config.xAxisField;
|
|
63774
|
-
const withResolvedXAxis = resolvedXAxisField && resolvedXAxisField !== config.xAxisField ? {
|
|
64139
|
+
const withResolvedXAxis = resolvedXAxisField && resolvedXAxisField !== config.xAxisField ? {
|
|
64140
|
+
...config,
|
|
64141
|
+
xAxisField: resolvedXAxisField,
|
|
64142
|
+
xAxisFormat: toAxisFormat(rowColumn?.format, "string")
|
|
64143
|
+
} : config;
|
|
63775
64144
|
const isMetricOrGauge = ["metric", "gauge"].includes(
|
|
63776
64145
|
String(withResolvedXAxis.chartType ?? "").toLowerCase()
|
|
63777
64146
|
);
|
|
@@ -66598,7 +66967,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
66598
66967
|
pivot,
|
|
66599
66968
|
operation
|
|
66600
66969
|
}) => {
|
|
66601
|
-
const
|
|
66970
|
+
const startedAt2 = performance.now();
|
|
66602
66971
|
const snapshot = await cacheCab.getReportSnapshot(
|
|
66603
66972
|
effectiveReportId,
|
|
66604
66973
|
tenants
|
|
@@ -66617,7 +66986,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
66617
66986
|
)
|
|
66618
66987
|
});
|
|
66619
66988
|
const diagnostics = globalThis.__QUILL_CACHECAB_DIAGNOSTICS__;
|
|
66620
|
-
const durationMs = performance.now() -
|
|
66989
|
+
const durationMs = performance.now() - startedAt2;
|
|
66621
66990
|
const outcome = resolution.resolved ? "hit" : "fallback";
|
|
66622
66991
|
if (Array.isArray(diagnostics)) {
|
|
66623
66992
|
diagnostics.push({
|
|
@@ -69605,11 +69974,12 @@ function useReport(reportIdArg, options = {}) {
|
|
|
69605
69974
|
registerOption(column.field, column.label, column.format);
|
|
69606
69975
|
}
|
|
69607
69976
|
for (const yAxis2 of yAxisResolved.measures) {
|
|
69608
|
-
|
|
69977
|
+
const field = String(yAxis2.field ?? "").trim();
|
|
69978
|
+
registerOption(field, field, yAxis2.format);
|
|
69609
69979
|
if (yAxis2.format) {
|
|
69610
|
-
const existing = optionsByField.get(
|
|
69980
|
+
const existing = optionsByField.get(field);
|
|
69611
69981
|
if (existing) {
|
|
69612
|
-
optionsByField.set(
|
|
69982
|
+
optionsByField.set(field, {
|
|
69613
69983
|
...existing,
|
|
69614
69984
|
format: toAxisFormat(yAxis2.format, existing.format)
|
|
69615
69985
|
});
|
|
@@ -69686,12 +70056,17 @@ function useReport(reportIdArg, options = {}) {
|
|
|
69686
70056
|
];
|
|
69687
70057
|
}, [chartAxisOptions, yAxisResolved.measures]);
|
|
69688
70058
|
const yAxisOptions = (0, import_react63.useMemo)(
|
|
69689
|
-
() => yAxisMeasures.map((measure) =>
|
|
69690
|
-
|
|
69691
|
-
|
|
69692
|
-
|
|
69693
|
-
|
|
69694
|
-
|
|
70059
|
+
() => yAxisMeasures.map((measure) => {
|
|
70060
|
+
const field = String(measure.field ?? "").trim();
|
|
70061
|
+
const catalog = chartAxisOptionByField.get(field);
|
|
70062
|
+
if (catalog) return catalog;
|
|
70063
|
+
return {
|
|
70064
|
+
value: field,
|
|
70065
|
+
label: toTitleCaseLabel(field),
|
|
70066
|
+
format: toAxisFormat(measure.format, "string")
|
|
70067
|
+
};
|
|
70068
|
+
}),
|
|
70069
|
+
[chartAxisOptionByField, yAxisMeasures]
|
|
69695
70070
|
);
|
|
69696
70071
|
const normalizedChartYAxisOptions = (0, import_react63.useMemo)(() => {
|
|
69697
70072
|
return yAxisOptions.map((option) => ({
|
|
@@ -70031,11 +70406,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
70031
70406
|
);
|
|
70032
70407
|
const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(pivotState);
|
|
70033
70408
|
const pivotTableColumns = (0, import_react63.useMemo)(
|
|
70034
|
-
() => isPivotTableChart ? buildPivotTableColumns(
|
|
70035
|
-
pivotState,
|
|
70036
|
-
chart,
|
|
70037
|
-
resolveTableDisplayLabel
|
|
70038
|
-
) : null,
|
|
70409
|
+
() => isPivotTableChart ? buildPivotTableColumns(pivotState, chart, resolveTableDisplayLabel) : null,
|
|
70039
70410
|
[chart, isPivotTableChart, pivotState, resolveTableDisplayLabel]
|
|
70040
70411
|
);
|
|
70041
70412
|
const chartAxes = (0, import_react63.useMemo)(() => {
|
|
@@ -70686,6 +71057,43 @@ function useReport(reportIdArg, options = {}) {
|
|
|
70686
71057
|
tableRefreshQuery.isFetching,
|
|
70687
71058
|
tableRefreshQueryEnabled
|
|
70688
71059
|
]);
|
|
71060
|
+
(0, import_react63.useEffect)(() => {
|
|
71061
|
+
if (!isNanPivotDebugEnabled()) return;
|
|
71062
|
+
recordUseReportNanPivotState({
|
|
71063
|
+
source: "useReport",
|
|
71064
|
+
reportId: effectiveReportId,
|
|
71065
|
+
datasources,
|
|
71066
|
+
chartType: resolvedChartType,
|
|
71067
|
+
chartLoading,
|
|
71068
|
+
tableLoading,
|
|
71069
|
+
loading,
|
|
71070
|
+
groupRowsBy,
|
|
71071
|
+
groupColumnsBy,
|
|
71072
|
+
aggregations: aggregationValues,
|
|
71073
|
+
formPivot: pivotState,
|
|
71074
|
+
nextPivot,
|
|
71075
|
+
sourceReport,
|
|
71076
|
+
chart: chartWithSort,
|
|
71077
|
+
table,
|
|
71078
|
+
isPivotTableChart
|
|
71079
|
+
});
|
|
71080
|
+
}, [
|
|
71081
|
+
aggregationValues,
|
|
71082
|
+
chartLoading,
|
|
71083
|
+
chartWithSort,
|
|
71084
|
+
datasources,
|
|
71085
|
+
effectiveReportId,
|
|
71086
|
+
groupColumnsBy,
|
|
71087
|
+
groupRowsBy,
|
|
71088
|
+
isPivotTableChart,
|
|
71089
|
+
loading,
|
|
71090
|
+
nextPivot,
|
|
71091
|
+
pivotState,
|
|
71092
|
+
resolvedChartType,
|
|
71093
|
+
sourceReport,
|
|
71094
|
+
table,
|
|
71095
|
+
tableLoading
|
|
71096
|
+
]);
|
|
70689
71097
|
const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
|
|
70690
71098
|
const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
|
|
70691
71099
|
return normalizedNextIds.map((columnId) => {
|
package/dist/index.js
CHANGED
|
@@ -23350,7 +23350,7 @@ async function fetchReportRows({
|
|
|
23350
23350
|
additionalProcessing,
|
|
23351
23351
|
overwriteCache = false
|
|
23352
23352
|
}) {
|
|
23353
|
-
const
|
|
23353
|
+
const startedAt2 = performance.now();
|
|
23354
23354
|
profileDashboard("raw-report-rows-fetch-start", { reportId });
|
|
23355
23355
|
const fetchResp = await quillFetch({
|
|
23356
23356
|
client,
|
|
@@ -23371,7 +23371,7 @@ async function fetchReportRows({
|
|
|
23371
23371
|
const resp = await parseFetchResponse(client, "report", fetchResp, getToken);
|
|
23372
23372
|
profileDashboard("raw-report-rows-fetch-finish", {
|
|
23373
23373
|
reportId,
|
|
23374
|
-
elapsedMs: Math.round(performance.now() -
|
|
23374
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23375
23375
|
rowCount: resp.rows?.length ?? 0
|
|
23376
23376
|
});
|
|
23377
23377
|
if (client.databaseType?.toLowerCase() === "bigquery") {
|
|
@@ -23409,7 +23409,7 @@ async function fetchReport({
|
|
|
23409
23409
|
}) {
|
|
23410
23410
|
let reportInfo = void 0;
|
|
23411
23411
|
let errorMessage = void 0;
|
|
23412
|
-
const
|
|
23412
|
+
const startedAt2 = performance.now();
|
|
23413
23413
|
try {
|
|
23414
23414
|
const task = usePivotTask ? "pivot-template" : useReportTask ? "report" : "item";
|
|
23415
23415
|
profileDashboard("fetch-report-start", {
|
|
@@ -23464,7 +23464,7 @@ async function fetchReport({
|
|
|
23464
23464
|
profileDashboard("fetch-report-response", {
|
|
23465
23465
|
reportId: reportId ?? null,
|
|
23466
23466
|
task,
|
|
23467
|
-
elapsedMs: Math.round(performance.now() -
|
|
23467
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23468
23468
|
hasRows: !!resp?.rows,
|
|
23469
23469
|
rowCount: resp?.rows?.length ?? 0,
|
|
23470
23470
|
hasFields: !!resp?.fields,
|
|
@@ -23489,7 +23489,7 @@ async function fetchReport({
|
|
|
23489
23489
|
profileDashboard("fetch-report-processed", {
|
|
23490
23490
|
reportId: reportId ?? null,
|
|
23491
23491
|
task,
|
|
23492
|
-
elapsedMs: Math.round(performance.now() -
|
|
23492
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
23493
23493
|
rowCount: reportInfo.rows?.length ?? 0,
|
|
23494
23494
|
pivotRowCount: reportInfo.pivotRows?.length ?? 0
|
|
23495
23495
|
});
|
|
@@ -23718,6 +23718,15 @@ async function saveReport({
|
|
|
23718
23718
|
}
|
|
23719
23719
|
return data;
|
|
23720
23720
|
}
|
|
23721
|
+
function isPlainNumericCellValue(value) {
|
|
23722
|
+
if (value === null || value === void 0 || value === "") return true;
|
|
23723
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
23724
|
+
if (typeof value === "bigint") return true;
|
|
23725
|
+
if (typeof value !== "string") return false;
|
|
23726
|
+
const trimmed = value.trim();
|
|
23727
|
+
if (!trimmed) return true;
|
|
23728
|
+
return /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(trimmed);
|
|
23729
|
+
}
|
|
23721
23730
|
var formatRowsFromReport = (report, xAxisField, xAxisFormat) => {
|
|
23722
23731
|
if (!report.rows || !report.columns) {
|
|
23723
23732
|
return [];
|
|
@@ -23745,6 +23754,10 @@ var formatRowsFromReport = (report, xAxisField, xAxisFormat) => {
|
|
|
23745
23754
|
const formattedRow = {};
|
|
23746
23755
|
for (const column of resolvedColumns) {
|
|
23747
23756
|
const rawValue = row[column.field];
|
|
23757
|
+
if (NUMBER_FORMAT_TYPES.includes(String(column.format ?? "")) && !isPlainNumericCellValue(rawValue)) {
|
|
23758
|
+
formattedRow[column.field] = rawValue === null || rawValue === void 0 || rawValue === "" ? "-" : String(rawValue);
|
|
23759
|
+
continue;
|
|
23760
|
+
}
|
|
23748
23761
|
formattedRow[column.field] = column.inferFormat ? quillAutoFormat(rawValue) : getFormattedWithCache(column.format, rawValue);
|
|
23749
23762
|
}
|
|
23750
23763
|
return formattedRow;
|
|
@@ -39780,7 +39793,7 @@ var ChartDataLoader = ({
|
|
|
39780
39793
|
}
|
|
39781
39794
|
const fetchRowsRequestId = rowsRequestId.current + 1;
|
|
39782
39795
|
rowsRequestId.current = fetchRowsRequestId;
|
|
39783
|
-
const
|
|
39796
|
+
const startedAt2 = performance.now();
|
|
39784
39797
|
profileDashboard("chart-data-loader-fetch-start", {
|
|
39785
39798
|
reportId: item.id,
|
|
39786
39799
|
requestId: fetchRowsRequestId,
|
|
@@ -39926,7 +39939,7 @@ var ChartDataLoader = ({
|
|
|
39926
39939
|
reportId: item.id,
|
|
39927
39940
|
requestId: fetchRowsRequestId,
|
|
39928
39941
|
reason,
|
|
39929
|
-
elapsedMs: Math.round(performance.now() -
|
|
39942
|
+
elapsedMs: Math.round(performance.now() - startedAt2),
|
|
39930
39943
|
isLatestRequest: fetchRowsRequestId === rowsRequestId.current,
|
|
39931
39944
|
startsBackgroundFetch: !!backgroundFetch
|
|
39932
39945
|
});
|
|
@@ -62599,6 +62612,345 @@ function resolveReportFromCacheCab({
|
|
|
62599
62612
|
|
|
62600
62613
|
// src/hooks/useForm.tsx
|
|
62601
62614
|
init_dashboardProfiler();
|
|
62615
|
+
|
|
62616
|
+
// src/hooks/useReport.nanPivotDiag.ts
|
|
62617
|
+
init_valueFormatter();
|
|
62618
|
+
var NAN_PIVOT_DEBUG_FLAG = "__QUILL_DEBUG_NAN_PIVOT__";
|
|
62619
|
+
var NAN_PIVOT_LOG_FLAG = "__QUILL_NAN_PIVOT_LOG__";
|
|
62620
|
+
var startedAt = Date.now();
|
|
62621
|
+
function globalRecord() {
|
|
62622
|
+
return globalThis;
|
|
62623
|
+
}
|
|
62624
|
+
function isNanPivotDebugEnabled() {
|
|
62625
|
+
const globalValue = globalRecord()[NAN_PIVOT_DEBUG_FLAG];
|
|
62626
|
+
if (globalValue === true) return true;
|
|
62627
|
+
if (typeof process !== "undefined" && typeof process.env !== "undefined") {
|
|
62628
|
+
const envValue = String(process.env.QUILL_DEBUG_NAN_PIVOT ?? "").trim().toLowerCase();
|
|
62629
|
+
return envValue === "1" || envValue === "true";
|
|
62630
|
+
}
|
|
62631
|
+
return false;
|
|
62632
|
+
}
|
|
62633
|
+
function getNanPivotLog() {
|
|
62634
|
+
const log = globalRecord()[NAN_PIVOT_LOG_FLAG];
|
|
62635
|
+
return Array.isArray(log) ? log : [];
|
|
62636
|
+
}
|
|
62637
|
+
function findNanValues(value, path = "root") {
|
|
62638
|
+
if (typeof value === "number" && Number.isNaN(value)) {
|
|
62639
|
+
return [`${path}=NaN`];
|
|
62640
|
+
}
|
|
62641
|
+
if (typeof value === "string" && /^[-+]?NaN(?:%|\s*)$/i.test(value.trim())) {
|
|
62642
|
+
return [`${path}=${JSON.stringify(value)}`];
|
|
62643
|
+
}
|
|
62644
|
+
if (Array.isArray(value)) {
|
|
62645
|
+
return value.flatMap(
|
|
62646
|
+
(entry, index) => findNanValues(entry, `${path}[${index}]`)
|
|
62647
|
+
);
|
|
62648
|
+
}
|
|
62649
|
+
if (value && typeof value === "object") {
|
|
62650
|
+
return Object.entries(value).flatMap(
|
|
62651
|
+
([key, entry]) => findNanValues(entry, `${path}.${key}`)
|
|
62652
|
+
);
|
|
62653
|
+
}
|
|
62654
|
+
return [];
|
|
62655
|
+
}
|
|
62656
|
+
function pivotKindOf(pivot) {
|
|
62657
|
+
if (pivot == null) return "none";
|
|
62658
|
+
if (typeof pivot !== "object") return "none";
|
|
62659
|
+
const value = pivot;
|
|
62660
|
+
const rowField = String(value.rowField ?? "").trim();
|
|
62661
|
+
const columnField = String(value.columnField ?? "").trim();
|
|
62662
|
+
const hasAggregation = Array.isArray(value.aggregations) && value.aggregations.length > 0 || Boolean(String(value.aggregationType ?? "").trim());
|
|
62663
|
+
if (rowField && columnField) return "2D";
|
|
62664
|
+
if (rowField || columnField) return "1D";
|
|
62665
|
+
if (hasAggregation) return "aggregation-only";
|
|
62666
|
+
return "empty-object";
|
|
62667
|
+
}
|
|
62668
|
+
function reportDetailSurfaceOf(chart) {
|
|
62669
|
+
if (!chart || typeof chart !== "object") return "none";
|
|
62670
|
+
const value = chart;
|
|
62671
|
+
const chartType = String(value.chartType ?? "").trim().toLowerCase();
|
|
62672
|
+
if (chartType !== "table") {
|
|
62673
|
+
return "chart-display-chart";
|
|
62674
|
+
}
|
|
62675
|
+
const isPivotTable = Boolean(value.pivot) && Array.isArray(value.columns) && value.columns.length > 0;
|
|
62676
|
+
return isPivotTable ? "chart-display-pivot-table" : "flat-table";
|
|
62677
|
+
}
|
|
62678
|
+
function columnFormats(columns) {
|
|
62679
|
+
if (!Array.isArray(columns)) return [];
|
|
62680
|
+
return columns.map((column) => {
|
|
62681
|
+
const value = column ?? {};
|
|
62682
|
+
return {
|
|
62683
|
+
field: String(value.field ?? ""),
|
|
62684
|
+
label: String(value.label ?? ""),
|
|
62685
|
+
format: String(value.format ?? "")
|
|
62686
|
+
};
|
|
62687
|
+
});
|
|
62688
|
+
}
|
|
62689
|
+
function sampleRows(rows, count = 2) {
|
|
62690
|
+
return Array.isArray(rows) ? rows.slice(0, count) : [];
|
|
62691
|
+
}
|
|
62692
|
+
function hitsFor(surface, value) {
|
|
62693
|
+
return findNanValues(value).map((path) => ({ surface, path }));
|
|
62694
|
+
}
|
|
62695
|
+
function looksNumeric(value) {
|
|
62696
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
62697
|
+
if (typeof value !== "string") return false;
|
|
62698
|
+
const trimmed = value.trim();
|
|
62699
|
+
if (!trimmed) return false;
|
|
62700
|
+
return Number.isFinite(Number(trimmed.replace(/,/g, "")));
|
|
62701
|
+
}
|
|
62702
|
+
function alreadyGroupedNumberString(value) {
|
|
62703
|
+
return typeof value === "string" && /^-?\d{1,3}(?:,\d{3})+(?:\.\d+)?$/.test(value.trim());
|
|
62704
|
+
}
|
|
62705
|
+
function formatRowsAsChartDisplay(chart, rows, columns) {
|
|
62706
|
+
if (!Array.isArray(rows) || rows.length === 0) return [];
|
|
62707
|
+
const value = chart ?? {};
|
|
62708
|
+
try {
|
|
62709
|
+
return formatRowsFromReport(
|
|
62710
|
+
{
|
|
62711
|
+
...value,
|
|
62712
|
+
rows,
|
|
62713
|
+
columns: Array.isArray(columns) ? columns : [],
|
|
62714
|
+
pivot: chart?.pivot
|
|
62715
|
+
},
|
|
62716
|
+
value.xAxisField,
|
|
62717
|
+
value.xAxisFormat
|
|
62718
|
+
);
|
|
62719
|
+
} catch {
|
|
62720
|
+
return [];
|
|
62721
|
+
}
|
|
62722
|
+
}
|
|
62723
|
+
function formatMismatchesFor(columns, rows) {
|
|
62724
|
+
if (!Array.isArray(rows) || rows.length === 0) return [];
|
|
62725
|
+
const mismatches = [];
|
|
62726
|
+
for (const column of columns) {
|
|
62727
|
+
if (!NUMBER_FORMAT_TYPES.includes(column.format)) continue;
|
|
62728
|
+
for (let index = 0; index < Math.min(rows.length, 8); index += 1) {
|
|
62729
|
+
const row = rows[index];
|
|
62730
|
+
if (!row || typeof row !== "object") continue;
|
|
62731
|
+
const cell = row[column.field];
|
|
62732
|
+
if (cell == null || cell === "") continue;
|
|
62733
|
+
if (looksNumeric(cell)) continue;
|
|
62734
|
+
mismatches.push(
|
|
62735
|
+
`${column.field} format=${column.format} row[${index}]=${JSON.stringify(cell)}`
|
|
62736
|
+
);
|
|
62737
|
+
break;
|
|
62738
|
+
}
|
|
62739
|
+
}
|
|
62740
|
+
return mismatches;
|
|
62741
|
+
}
|
|
62742
|
+
function chartDisplayRows(chart) {
|
|
62743
|
+
if (!chart || typeof chart !== "object") return [];
|
|
62744
|
+
const value = chart;
|
|
62745
|
+
if (String(value.chartType ?? "").toLowerCase() !== "table") {
|
|
62746
|
+
return Array.isArray(value.rows) ? value.rows : [];
|
|
62747
|
+
}
|
|
62748
|
+
const tableColumns = value.includeCustomFields && value.columnsWithCustomFields && !value.pivot ? value.columnsWithCustomFields : value.columns ?? value.yAxisFields ?? [];
|
|
62749
|
+
try {
|
|
62750
|
+
return formatRowsFromReport(
|
|
62751
|
+
{ ...value, rows: value.rows ?? [], columns: tableColumns },
|
|
62752
|
+
value.xAxisField,
|
|
62753
|
+
value.xAxisFormat
|
|
62754
|
+
);
|
|
62755
|
+
} catch {
|
|
62756
|
+
return [];
|
|
62757
|
+
}
|
|
62758
|
+
}
|
|
62759
|
+
function pivotFieldHits(pivot) {
|
|
62760
|
+
if (!pivot || typeof pivot !== "object") return [];
|
|
62761
|
+
return hitsFor("pivotFields", {
|
|
62762
|
+
rowField: pivot.rowField,
|
|
62763
|
+
columnField: pivot.columnField,
|
|
62764
|
+
rowFieldTable: pivot.rowFieldTable,
|
|
62765
|
+
columnFieldTable: pivot.columnFieldTable
|
|
62766
|
+
});
|
|
62767
|
+
}
|
|
62768
|
+
function jsonSafe(value) {
|
|
62769
|
+
try {
|
|
62770
|
+
return JSON.parse(
|
|
62771
|
+
JSON.stringify(value, (_key, current) => {
|
|
62772
|
+
if (typeof current === "number" && Number.isNaN(current)) {
|
|
62773
|
+
return "__NaN__";
|
|
62774
|
+
}
|
|
62775
|
+
if (current === void 0) return "__undefined__";
|
|
62776
|
+
return current;
|
|
62777
|
+
})
|
|
62778
|
+
);
|
|
62779
|
+
} catch {
|
|
62780
|
+
return value;
|
|
62781
|
+
}
|
|
62782
|
+
}
|
|
62783
|
+
function snapshotUseReportNanState(input) {
|
|
62784
|
+
const chart = input.chart ?? null;
|
|
62785
|
+
const table = input.table ?? null;
|
|
62786
|
+
const sourceReport = input.sourceReport ?? null;
|
|
62787
|
+
const chartType = String(chart?.chartType ?? input.chartType ?? "").trim();
|
|
62788
|
+
const tableColumns = columnFormats(table?.columns);
|
|
62789
|
+
const chartColumns = columnFormats(chart?.columns);
|
|
62790
|
+
const tableRows = Array.isArray(table?.rows) ? table.rows : [];
|
|
62791
|
+
const chartRows = Array.isArray(chart?.rows) ? chart.rows : [];
|
|
62792
|
+
const pivotRows = Array.isArray(chart?.pivotRows) ? chart.pivotRows : [];
|
|
62793
|
+
const sourceRows = Array.isArray(sourceReport?.rows) ? sourceReport.rows : [];
|
|
62794
|
+
const sourcePivotRows = Array.isArray(sourceReport?.pivotRows) ? sourceReport.pivotRows : [];
|
|
62795
|
+
const displayRows = chartDisplayRows(chart);
|
|
62796
|
+
const doubleFormatRows = formatRowsAsChartDisplay(
|
|
62797
|
+
chart,
|
|
62798
|
+
tableRows,
|
|
62799
|
+
table?.columns ?? chart?.columns
|
|
62800
|
+
);
|
|
62801
|
+
const formPivot = input.formPivot ?? null;
|
|
62802
|
+
const nextPivot = input.nextPivot ?? null;
|
|
62803
|
+
const sourcePivot = sourceReport?.pivot ?? null;
|
|
62804
|
+
const chartPivot = chart?.pivot ?? null;
|
|
62805
|
+
const kind = pivotKindOf(chartPivot ?? nextPivot ?? formPivot ?? sourcePivot);
|
|
62806
|
+
const groupRowsBy = String(input.groupRowsBy ?? "").trim() || null;
|
|
62807
|
+
const groupColumnsBy = String(input.groupColumnsBy ?? "").trim() || null;
|
|
62808
|
+
const hasFormPivotSelection = Boolean(
|
|
62809
|
+
groupRowsBy || groupColumnsBy || Array.isArray(input.aggregations) && input.aggregations.some((value) => String(value ?? "").trim())
|
|
62810
|
+
);
|
|
62811
|
+
const unexpectedPivot = !hasFormPivotSelection && (kind === "1D" || kind === "2D" || kind === "aggregation-only" || kind === "empty-object");
|
|
62812
|
+
const nanHits = [
|
|
62813
|
+
...hitsFor("useReport.table", tableRows),
|
|
62814
|
+
...hitsFor("useReport.chart.rows", chartRows),
|
|
62815
|
+
...hitsFor("useReport.chart.pivotRows", pivotRows),
|
|
62816
|
+
...hitsFor("sourceReport.rows", sourceRows),
|
|
62817
|
+
...hitsFor("sourceReport.pivotRows", sourcePivotRows),
|
|
62818
|
+
...hitsFor("chartDisplay.formattedRows", displayRows),
|
|
62819
|
+
...hitsFor("chartDisplay.doubleFormatTableRows", doubleFormatRows),
|
|
62820
|
+
...hitsFor("columnLabels", [
|
|
62821
|
+
...tableColumns.map((column) => column.label),
|
|
62822
|
+
...chartColumns.map((column) => column.label)
|
|
62823
|
+
]),
|
|
62824
|
+
...hitsFor("columnFields", [
|
|
62825
|
+
...tableColumns.map((column) => column.field),
|
|
62826
|
+
...chartColumns.map((column) => column.field)
|
|
62827
|
+
]),
|
|
62828
|
+
...pivotFieldHits(chartPivot),
|
|
62829
|
+
...pivotFieldHits(formPivot),
|
|
62830
|
+
...pivotFieldHits(sourcePivot)
|
|
62831
|
+
];
|
|
62832
|
+
return {
|
|
62833
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
62834
|
+
atMs: Date.now() - startedAt,
|
|
62835
|
+
source: input.source ?? "useReport",
|
|
62836
|
+
flow: input.flow,
|
|
62837
|
+
step: input.step,
|
|
62838
|
+
reportId: String(input.reportId ?? ""),
|
|
62839
|
+
datasources: Array.isArray(input.datasources) ? input.datasources.map((value) => String(value)) : [],
|
|
62840
|
+
chartType,
|
|
62841
|
+
chartLoading: Boolean(input.chartLoading),
|
|
62842
|
+
tableLoading: Boolean(input.tableLoading),
|
|
62843
|
+
loading: Boolean(input.loading),
|
|
62844
|
+
groupRowsBy,
|
|
62845
|
+
groupColumnsBy,
|
|
62846
|
+
aggregations: input.aggregations ?? [],
|
|
62847
|
+
formPivot,
|
|
62848
|
+
nextPivot,
|
|
62849
|
+
sourcePivot,
|
|
62850
|
+
chartPivot,
|
|
62851
|
+
pivotKind: kind,
|
|
62852
|
+
unexpectedPivot,
|
|
62853
|
+
isPivotTableChart: Boolean(input.isPivotTableChart),
|
|
62854
|
+
reportDetailSurface: reportDetailSurfaceOf(chart),
|
|
62855
|
+
tableColumnFormats: tableColumns,
|
|
62856
|
+
chartColumnFormats: chartColumns,
|
|
62857
|
+
tableRowCount: tableRows.length,
|
|
62858
|
+
chartRowCount: chartRows.length,
|
|
62859
|
+
pivotRowCount: pivotRows.length,
|
|
62860
|
+
tableSample: sampleRows(tableRows),
|
|
62861
|
+
chartRowSample: sampleRows(chartRows),
|
|
62862
|
+
pivotRowSample: sampleRows(pivotRows),
|
|
62863
|
+
chartDisplaySample: sampleRows(displayRows),
|
|
62864
|
+
doubleFormatSample: sampleRows(doubleFormatRows),
|
|
62865
|
+
formatMismatches: [
|
|
62866
|
+
...formatMismatchesFor(tableColumns, sourceRows.length ? sourceRows : tableRows),
|
|
62867
|
+
...formatMismatchesFor(chartColumns, chartRows.length ? chartRows : pivotRows),
|
|
62868
|
+
...tableRows.flatMap((row, index) => {
|
|
62869
|
+
if (!row || typeof row !== "object") return [];
|
|
62870
|
+
return tableColumns.filter(
|
|
62871
|
+
(column) => NUMBER_FORMAT_TYPES.includes(column.format) && alreadyGroupedNumberString(
|
|
62872
|
+
row[column.field]
|
|
62873
|
+
)
|
|
62874
|
+
).map(
|
|
62875
|
+
(column) => `already-formatted ${column.field} row[${index}]=${JSON.stringify(
|
|
62876
|
+
row[column.field]
|
|
62877
|
+
)}`
|
|
62878
|
+
);
|
|
62879
|
+
})
|
|
62880
|
+
],
|
|
62881
|
+
nanHits
|
|
62882
|
+
};
|
|
62883
|
+
}
|
|
62884
|
+
var lastSerializedBySource = /* @__PURE__ */ new Map();
|
|
62885
|
+
function recordUseReportNanPivotState(input) {
|
|
62886
|
+
if (!isNanPivotDebugEnabled()) return null;
|
|
62887
|
+
const snapshot = snapshotUseReportNanState(input);
|
|
62888
|
+
const key = `${snapshot.source}:${snapshot.flow ?? ""}:${snapshot.reportId}`;
|
|
62889
|
+
const serialized = JSON.stringify(jsonSafe(snapshot));
|
|
62890
|
+
if (lastSerializedBySource.get(key) === serialized) {
|
|
62891
|
+
return snapshot;
|
|
62892
|
+
}
|
|
62893
|
+
lastSerializedBySource.set(key, serialized);
|
|
62894
|
+
const log = getNanPivotLog();
|
|
62895
|
+
log.push(snapshot);
|
|
62896
|
+
globalRecord()[NAN_PIVOT_LOG_FLAG] = log;
|
|
62897
|
+
const liveHits = snapshot.nanHits.filter(
|
|
62898
|
+
(hit) => hit.surface !== "chartDisplay.doubleFormatTableRows"
|
|
62899
|
+
);
|
|
62900
|
+
const compact = {
|
|
62901
|
+
atMs: snapshot.atMs,
|
|
62902
|
+
source: snapshot.source,
|
|
62903
|
+
flow: snapshot.flow,
|
|
62904
|
+
step: snapshot.step,
|
|
62905
|
+
reportId: snapshot.reportId,
|
|
62906
|
+
datasources: snapshot.datasources,
|
|
62907
|
+
chartType: snapshot.chartType,
|
|
62908
|
+
loading: snapshot.loading,
|
|
62909
|
+
chartLoading: snapshot.chartLoading,
|
|
62910
|
+
tableLoading: snapshot.tableLoading,
|
|
62911
|
+
groupRowsBy: snapshot.groupRowsBy,
|
|
62912
|
+
groupColumnsBy: snapshot.groupColumnsBy,
|
|
62913
|
+
pivotKind: snapshot.pivotKind,
|
|
62914
|
+
unexpectedPivot: snapshot.unexpectedPivot,
|
|
62915
|
+
isPivotTableChart: snapshot.isPivotTableChart,
|
|
62916
|
+
reportDetailSurface: snapshot.reportDetailSurface,
|
|
62917
|
+
tableRowCount: snapshot.tableRowCount,
|
|
62918
|
+
chartRowCount: snapshot.chartRowCount,
|
|
62919
|
+
pivotRowCount: snapshot.pivotRowCount,
|
|
62920
|
+
formatMismatches: snapshot.formatMismatches.slice(0, 8),
|
|
62921
|
+
nanHits: snapshot.nanHits.slice(0, 12)
|
|
62922
|
+
};
|
|
62923
|
+
if (liveHits.length > 0 || snapshot.unexpectedPivot) {
|
|
62924
|
+
console.log(
|
|
62925
|
+
"[useReport][nan-pivot][hit]",
|
|
62926
|
+
JSON.stringify(
|
|
62927
|
+
jsonSafe({
|
|
62928
|
+
...compact,
|
|
62929
|
+
tableSample: snapshot.tableSample,
|
|
62930
|
+
chartRowSample: snapshot.chartRowSample,
|
|
62931
|
+
pivotRowSample: snapshot.pivotRowSample,
|
|
62932
|
+
chartDisplaySample: snapshot.chartDisplaySample,
|
|
62933
|
+
doubleFormatSample: snapshot.doubleFormatSample,
|
|
62934
|
+
formPivot: snapshot.formPivot,
|
|
62935
|
+
chartPivot: snapshot.chartPivot,
|
|
62936
|
+
sourcePivot: snapshot.sourcePivot
|
|
62937
|
+
}),
|
|
62938
|
+
null,
|
|
62939
|
+
2
|
|
62940
|
+
)
|
|
62941
|
+
);
|
|
62942
|
+
} else if (snapshot.nanHits.length > 0) {
|
|
62943
|
+
console.log(
|
|
62944
|
+
"[useReport][nan-pivot][double-format]",
|
|
62945
|
+
JSON.stringify(compact)
|
|
62946
|
+
);
|
|
62947
|
+
} else {
|
|
62948
|
+
console.log("[useReport][nan-pivot][state]", JSON.stringify(compact));
|
|
62949
|
+
}
|
|
62950
|
+
return snapshot;
|
|
62951
|
+
}
|
|
62952
|
+
|
|
62953
|
+
// src/hooks/useForm.tsx
|
|
62602
62954
|
init_reportRequestPool();
|
|
62603
62955
|
|
|
62604
62956
|
// src/hooks/useForm.queries.ts
|
|
@@ -63778,22 +64130,21 @@ function isPlaceholderAxisLabel(label, field) {
|
|
|
63778
64130
|
function resolvedAxisLabel(savedLabel, field, generatedLabel) {
|
|
63779
64131
|
return isPlaceholderAxisLabel(savedLabel, field) ? generatedLabel : savedLabel;
|
|
63780
64132
|
}
|
|
64133
|
+
function uniqueAxisFormat(formats) {
|
|
64134
|
+
const values = formats.map((format9) => String(format9 ?? "").trim()).filter(Boolean);
|
|
64135
|
+
if (values.length === 0) return void 0;
|
|
64136
|
+
return values.every((format9) => format9 === values[0]) ? values[0] : void 0;
|
|
64137
|
+
}
|
|
63781
64138
|
function resolveYAxisFormatForField(field, aggregation, saved, fallback) {
|
|
63782
64139
|
const formatByField = new Map(
|
|
63783
64140
|
saved.map((axis) => [String(axis.field ?? "").trim(), axis.format])
|
|
63784
64141
|
);
|
|
64142
|
+
const savedFormats = uniqueAxisFormat(saved.map((axis) => axis.format));
|
|
63785
64143
|
if (aggregation?.aggregationType === "count") {
|
|
63786
|
-
return formatByField.get(field) ?? formatByField.get("count") ??
|
|
63787
|
-
}
|
|
63788
|
-
if (aggregation?.aggregationType === "percentage") {
|
|
63789
|
-
const savedFormat = formatByField.get(field);
|
|
63790
|
-
if (savedFormat === "percent" || savedFormat === "percentage") {
|
|
63791
|
-
return savedFormat;
|
|
63792
|
-
}
|
|
63793
|
-
return "percentage";
|
|
64144
|
+
return formatByField.get(field) ?? formatByField.get("count") ?? savedFormats ?? "whole_number";
|
|
63794
64145
|
}
|
|
63795
64146
|
const aggType = aggregation?.aggregationType ? String(aggregation.aggregationType) : void 0;
|
|
63796
|
-
return formatByField.get(field) ?? formatByField.get(trimAggregationSuffix(field, aggType)) ?? (aggregation?.valueField ? formatByField.get(aggregation.valueField) : void 0) ?? fallback;
|
|
64147
|
+
return formatByField.get(field) ?? formatByField.get(trimAggregationSuffix(field, aggType)) ?? (aggregation?.valueField ? formatByField.get(aggregation.valueField) : void 0) ?? savedFormats ?? fallback;
|
|
63797
64148
|
}
|
|
63798
64149
|
function aggregationIdentityForField(field, aggregations) {
|
|
63799
64150
|
return getAggregationIdentityKey(
|
|
@@ -63864,6 +64215,7 @@ function applyYAxisEdits(measures, edits, aggregations) {
|
|
|
63864
64215
|
const base = (identity ? byIdentity.get(identity) : void 0) ?? byField.get(field);
|
|
63865
64216
|
const label = String(edit.label ?? "").trim();
|
|
63866
64217
|
if (!base) {
|
|
64218
|
+
if (aggregations.length > 0) continue;
|
|
63867
64219
|
next.push({
|
|
63868
64220
|
field,
|
|
63869
64221
|
label: label || toTitleCaseLabel(field),
|
|
@@ -63877,7 +64229,16 @@ function applyYAxisEdits(measures, edits, aggregations) {
|
|
|
63877
64229
|
format: toAxisFormat(edit.format, base.format)
|
|
63878
64230
|
});
|
|
63879
64231
|
}
|
|
63880
|
-
|
|
64232
|
+
if (next.length > 0) return next;
|
|
64233
|
+
if (aggregations.length > 0 && measures.length === 1 && edits.length === 1 && edits[0]?.format) {
|
|
64234
|
+
return [
|
|
64235
|
+
{
|
|
64236
|
+
...measures[0],
|
|
64237
|
+
format: toAxisFormat(edits[0].format, measures[0].format)
|
|
64238
|
+
}
|
|
64239
|
+
];
|
|
64240
|
+
}
|
|
64241
|
+
return measures;
|
|
63881
64242
|
}
|
|
63882
64243
|
function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
63883
64244
|
const saved = chart.yAxisFields ?? [];
|
|
@@ -63888,7 +64249,6 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63888
64249
|
const aggregations = getPivotAggregations(chart);
|
|
63889
64250
|
const hasMultipleAggregations = aggregations.length > 1;
|
|
63890
64251
|
const columnField = String(chart.pivot?.columnField ?? "").trim();
|
|
63891
|
-
const isAggregationOnlyPivot = !String(chart.pivot?.rowField ?? "").trim() && !columnField;
|
|
63892
64252
|
const fallback = saved[0]?.format ?? chart.xAxisFormat ?? "whole_number";
|
|
63893
64253
|
const valueKeys = pivotValueFieldKeys(chart);
|
|
63894
64254
|
const fallbackKeys = pivotFallbackValueKeys(chart);
|
|
@@ -63910,9 +64270,9 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63910
64270
|
measure.field
|
|
63911
64271
|
);
|
|
63912
64272
|
if (matchedKey) return [{ ...measure, field: matchedKey }];
|
|
63913
|
-
return
|
|
64273
|
+
return [measure];
|
|
63914
64274
|
});
|
|
63915
|
-
if (!columnField && measures.length === 0 && saved.length > 0) {
|
|
64275
|
+
if (!columnField && measures.length === 0 && saved.length > 0 && aggregations.length === 0) {
|
|
63916
64276
|
measures = saved;
|
|
63917
64277
|
}
|
|
63918
64278
|
measures = applyYAxisEdits(measures, edits, aggregations);
|
|
@@ -63939,7 +64299,12 @@ function resolveReportYAxis(chart, edits, resolveTableLabel) {
|
|
|
63939
64299
|
measureLabel,
|
|
63940
64300
|
hasMultipleAggregations
|
|
63941
64301
|
),
|
|
63942
|
-
format: measure?.format ?? resolveYAxisFormatForField(
|
|
64302
|
+
format: measure?.format ?? resolveYAxisFormatForField(
|
|
64303
|
+
field,
|
|
64304
|
+
aggregation,
|
|
64305
|
+
saved,
|
|
64306
|
+
fallback
|
|
64307
|
+
)
|
|
63943
64308
|
}
|
|
63944
64309
|
];
|
|
63945
64310
|
});
|
|
@@ -63979,7 +64344,11 @@ function normalizePivotChartForDisplay(chart) {
|
|
|
63979
64344
|
pivotRowFieldEarly,
|
|
63980
64345
|
String(rowColumn?.format ?? "")
|
|
63981
64346
|
) ? pivotRowFieldEarly : config.xAxisField;
|
|
63982
|
-
const withResolvedXAxis = resolvedXAxisField && resolvedXAxisField !== config.xAxisField ? {
|
|
64347
|
+
const withResolvedXAxis = resolvedXAxisField && resolvedXAxisField !== config.xAxisField ? {
|
|
64348
|
+
...config,
|
|
64349
|
+
xAxisField: resolvedXAxisField,
|
|
64350
|
+
xAxisFormat: toAxisFormat(rowColumn?.format, "string")
|
|
64351
|
+
} : config;
|
|
63983
64352
|
const isMetricOrGauge = ["metric", "gauge"].includes(
|
|
63984
64353
|
String(withResolvedXAxis.chartType ?? "").toLowerCase()
|
|
63985
64354
|
);
|
|
@@ -66806,7 +67175,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
66806
67175
|
pivot,
|
|
66807
67176
|
operation
|
|
66808
67177
|
}) => {
|
|
66809
|
-
const
|
|
67178
|
+
const startedAt2 = performance.now();
|
|
66810
67179
|
const snapshot = await cacheCab.getReportSnapshot(
|
|
66811
67180
|
effectiveReportId,
|
|
66812
67181
|
tenants
|
|
@@ -66825,7 +67194,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
66825
67194
|
)
|
|
66826
67195
|
});
|
|
66827
67196
|
const diagnostics = globalThis.__QUILL_CACHECAB_DIAGNOSTICS__;
|
|
66828
|
-
const durationMs = performance.now() -
|
|
67197
|
+
const durationMs = performance.now() - startedAt2;
|
|
66829
67198
|
const outcome = resolution.resolved ? "hit" : "fallback";
|
|
66830
67199
|
if (Array.isArray(diagnostics)) {
|
|
66831
67200
|
diagnostics.push({
|
|
@@ -69813,11 +70182,12 @@ function useReport(reportIdArg, options = {}) {
|
|
|
69813
70182
|
registerOption(column.field, column.label, column.format);
|
|
69814
70183
|
}
|
|
69815
70184
|
for (const yAxis2 of yAxisResolved.measures) {
|
|
69816
|
-
|
|
70185
|
+
const field = String(yAxis2.field ?? "").trim();
|
|
70186
|
+
registerOption(field, field, yAxis2.format);
|
|
69817
70187
|
if (yAxis2.format) {
|
|
69818
|
-
const existing = optionsByField.get(
|
|
70188
|
+
const existing = optionsByField.get(field);
|
|
69819
70189
|
if (existing) {
|
|
69820
|
-
optionsByField.set(
|
|
70190
|
+
optionsByField.set(field, {
|
|
69821
70191
|
...existing,
|
|
69822
70192
|
format: toAxisFormat(yAxis2.format, existing.format)
|
|
69823
70193
|
});
|
|
@@ -69894,12 +70264,17 @@ function useReport(reportIdArg, options = {}) {
|
|
|
69894
70264
|
];
|
|
69895
70265
|
}, [chartAxisOptions, yAxisResolved.measures]);
|
|
69896
70266
|
const yAxisOptions = useMemo33(
|
|
69897
|
-
() => yAxisMeasures.map((measure) =>
|
|
69898
|
-
|
|
69899
|
-
|
|
69900
|
-
|
|
69901
|
-
|
|
69902
|
-
|
|
70267
|
+
() => yAxisMeasures.map((measure) => {
|
|
70268
|
+
const field = String(measure.field ?? "").trim();
|
|
70269
|
+
const catalog = chartAxisOptionByField.get(field);
|
|
70270
|
+
if (catalog) return catalog;
|
|
70271
|
+
return {
|
|
70272
|
+
value: field,
|
|
70273
|
+
label: toTitleCaseLabel(field),
|
|
70274
|
+
format: toAxisFormat(measure.format, "string")
|
|
70275
|
+
};
|
|
70276
|
+
}),
|
|
70277
|
+
[chartAxisOptionByField, yAxisMeasures]
|
|
69903
70278
|
);
|
|
69904
70279
|
const normalizedChartYAxisOptions = useMemo33(() => {
|
|
69905
70280
|
return yAxisOptions.map((option) => ({
|
|
@@ -70239,11 +70614,7 @@ function useReport(reportIdArg, options = {}) {
|
|
|
70239
70614
|
);
|
|
70240
70615
|
const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(pivotState);
|
|
70241
70616
|
const pivotTableColumns = useMemo33(
|
|
70242
|
-
() => isPivotTableChart ? buildPivotTableColumns(
|
|
70243
|
-
pivotState,
|
|
70244
|
-
chart,
|
|
70245
|
-
resolveTableDisplayLabel
|
|
70246
|
-
) : null,
|
|
70617
|
+
() => isPivotTableChart ? buildPivotTableColumns(pivotState, chart, resolveTableDisplayLabel) : null,
|
|
70247
70618
|
[chart, isPivotTableChart, pivotState, resolveTableDisplayLabel]
|
|
70248
70619
|
);
|
|
70249
70620
|
const chartAxes = useMemo33(() => {
|
|
@@ -70894,6 +71265,43 @@ function useReport(reportIdArg, options = {}) {
|
|
|
70894
71265
|
tableRefreshQuery.isFetching,
|
|
70895
71266
|
tableRefreshQueryEnabled
|
|
70896
71267
|
]);
|
|
71268
|
+
useEffect33(() => {
|
|
71269
|
+
if (!isNanPivotDebugEnabled()) return;
|
|
71270
|
+
recordUseReportNanPivotState({
|
|
71271
|
+
source: "useReport",
|
|
71272
|
+
reportId: effectiveReportId,
|
|
71273
|
+
datasources,
|
|
71274
|
+
chartType: resolvedChartType,
|
|
71275
|
+
chartLoading,
|
|
71276
|
+
tableLoading,
|
|
71277
|
+
loading,
|
|
71278
|
+
groupRowsBy,
|
|
71279
|
+
groupColumnsBy,
|
|
71280
|
+
aggregations: aggregationValues,
|
|
71281
|
+
formPivot: pivotState,
|
|
71282
|
+
nextPivot,
|
|
71283
|
+
sourceReport,
|
|
71284
|
+
chart: chartWithSort,
|
|
71285
|
+
table,
|
|
71286
|
+
isPivotTableChart
|
|
71287
|
+
});
|
|
71288
|
+
}, [
|
|
71289
|
+
aggregationValues,
|
|
71290
|
+
chartLoading,
|
|
71291
|
+
chartWithSort,
|
|
71292
|
+
datasources,
|
|
71293
|
+
effectiveReportId,
|
|
71294
|
+
groupColumnsBy,
|
|
71295
|
+
groupRowsBy,
|
|
71296
|
+
isPivotTableChart,
|
|
71297
|
+
loading,
|
|
71298
|
+
nextPivot,
|
|
71299
|
+
pivotState,
|
|
71300
|
+
resolvedChartType,
|
|
71301
|
+
sourceReport,
|
|
71302
|
+
table,
|
|
71303
|
+
tableLoading
|
|
71304
|
+
]);
|
|
70897
71305
|
const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
|
|
70898
71306
|
const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
|
|
70899
71307
|
return normalizedNextIds.map((columnId) => {
|