@quillsql/react 2.16.94 → 2.16.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.cjs +412 -81
  2. package/dist/index.js +412 -81
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -15133,7 +15133,7 @@ var init_dates = __esm({
15133
15133
  init_inMemoryPivotEngine();
15134
15134
  init_valueFormatter();
15135
15135
  DATE_BUCKET_AXIS_FORMATS = {
15136
- day: "MMM_dd_yyyy",
15136
+ day: "MMM_dd",
15137
15137
  week: "MMM_dd-MMM_dd",
15138
15138
  month: "MMM_yyyy",
15139
15139
  year: "yyyy"
@@ -17137,6 +17137,79 @@ var init_paginationProcessing = __esm({
17137
17137
  }
17138
17138
  });
17139
17139
 
17140
+ // src/utils/dashboardProfiler.ts
17141
+ function profilingEnabled() {
17142
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE === "true") {
17143
+ return true;
17144
+ }
17145
+ if (typeof window === "undefined") return false;
17146
+ return Boolean(window.__QUILL_DASHBOARD_PROFILE__);
17147
+ }
17148
+ function profileStore() {
17149
+ if (typeof window !== "undefined") {
17150
+ const profileWindow = window;
17151
+ profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
17152
+ return profileWindow.__QUILL_DASHBOARD_TRACE__;
17153
+ }
17154
+ const globalStore = globalThis;
17155
+ globalStore.__QUILL_DASHBOARD_TRACE__ ??= [];
17156
+ return globalStore.__QUILL_DASHBOARD_TRACE__;
17157
+ }
17158
+ function queryKeyFamily(queryKey) {
17159
+ const head = String(queryKey[0] ?? "");
17160
+ const next = String(queryKey[1] ?? "");
17161
+ if (head === "quill" && next === "dashboard-report") {
17162
+ return "quill/dashboard-report";
17163
+ }
17164
+ if (head === "useReport") {
17165
+ return `useReport/${next || "unknown"}`;
17166
+ }
17167
+ return head || "other";
17168
+ }
17169
+ function summarizeEngineRequest(input) {
17170
+ const metadata = input.metadata ?? {};
17171
+ return {
17172
+ task: input.task ?? null,
17173
+ shareRequest: Boolean(input.shareRequest),
17174
+ reuseExisting: input.reuseExisting ?? null,
17175
+ settled: input.settled ?? null,
17176
+ reportId: metadata.reportId ?? null,
17177
+ metadataKeys: Object.keys(metadata).sort(),
17178
+ dashboardName: metadata.dashboardName ?? null,
17179
+ dashboardItemId: metadata.dashboardItemId ?? null,
17180
+ useNewNodeSql: metadata.useNewNodeSql ?? null,
17181
+ dateBucket: metadata.dateBucket ?? null,
17182
+ hasPivot: Boolean(metadata.pivot),
17183
+ hasReportBuilderState: Boolean(metadata.reportBuilderState),
17184
+ additionalProcessing: metadata.additionalProcessing ?? null,
17185
+ filterCount: Array.isArray(metadata.filters) ? metadata.filters.length : null
17186
+ };
17187
+ }
17188
+ function profileDashboard(event, data) {
17189
+ if (!profilingEnabled()) return;
17190
+ const entry = {
17191
+ at: Math.round(performance.now() * 10) / 10,
17192
+ event,
17193
+ data
17194
+ };
17195
+ profileStore().push(entry);
17196
+ if (typeof window !== "undefined") {
17197
+ const profileWindow = window;
17198
+ profileWindow.__QUILL_DASHBOARD_PROFILE__ = true;
17199
+ profileWindow.__QUILL_DUMP_DASHBOARD_PROFILE__ = () => profileWindow.__QUILL_DASHBOARD_TRACE__ ?? [];
17200
+ }
17201
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE_CONSOLE === "true" && CONSOLE_EVENT_PATTERN.test(event)) {
17202
+ console.log(`[quill-profile] ${event}`, data ?? {});
17203
+ }
17204
+ }
17205
+ var CONSOLE_EVENT_PATTERN;
17206
+ var init_dashboardProfiler = __esm({
17207
+ "src/utils/dashboardProfiler.ts"() {
17208
+ "use strict";
17209
+ CONSOLE_EVENT_PATTERN = /cache|initial-load|use-report-loading|network|unique-values|table-refresh|pivot|shared-request|engine-fetch|generate-pivot/;
17210
+ }
17211
+ });
17212
+
17140
17213
  // src/utils/pivotConstructor.ts
17141
17214
  function normalizeLegacyPivotSortFieldValue(sortField) {
17142
17215
  if (sortField === void 0) {
@@ -17249,6 +17322,22 @@ async function generatePivotWithSQL({
17249
17322
  rowLimit: pivot.rowLimit,
17250
17323
  dateBucket: resolvedDateBucket
17251
17324
  };
17325
+ profileDashboard(
17326
+ "generate-pivot-sql",
17327
+ summarizeEngineRequest({
17328
+ task: "pivot-template",
17329
+ shareRequest: false,
17330
+ metadata: {
17331
+ reportId: report?.id,
17332
+ dashboardName,
17333
+ dateBucket: resolvedDateBucket,
17334
+ additionalProcessing,
17335
+ pivot: pivotConfig,
17336
+ reportBuilderState,
17337
+ filters: dashboardFilters
17338
+ }
17339
+ })
17340
+ );
17252
17341
  const resp = await quillFetch({
17253
17342
  client,
17254
17343
  task: "pivot-template",
@@ -17621,6 +17710,7 @@ var init_pivotConstructor = __esm({
17621
17710
  init_columnType();
17622
17711
  init_dataFetcher();
17623
17712
  init_dataProcessing();
17713
+ init_dashboardProfiler();
17624
17714
  init_dates();
17625
17715
  init_textProcessing();
17626
17716
  init_valueFormatter();
@@ -20044,6 +20134,20 @@ async function getOrFetchSharedRequest({
20044
20134
  }) {
20045
20135
  if (signal?.aborted) throw createAbortError(signal);
20046
20136
  let entry = entries.get(key);
20137
+ const reuseExisting = Boolean(entry);
20138
+ profileDashboard("shared-request", {
20139
+ ...summarizeEngineRequest({
20140
+ task: void 0,
20141
+ shareRequest: true,
20142
+ reuseExisting,
20143
+ settled: entry?.settled,
20144
+ metadata: { reportId }
20145
+ }),
20146
+ reportId: reportId ?? null,
20147
+ reuseExisting,
20148
+ settled: entry?.settled ?? false,
20149
+ keyLength: key.length
20150
+ });
20047
20151
  if (!entry) {
20048
20152
  const controller = new AbortController();
20049
20153
  entry = {
@@ -20119,6 +20223,7 @@ var ORPHAN_GRACE_MS, COMPLETED_TTL_MS, entries;
20119
20223
  var init_reportRequestPool = __esm({
20120
20224
  "src/utils/reportRequestPool.ts"() {
20121
20225
  "use strict";
20226
+ init_dashboardProfiler();
20122
20227
  ORPHAN_GRACE_MS = 100;
20123
20228
  COMPLETED_TTL_MS = 15e3;
20124
20229
  entries = /* @__PURE__ */ new Map();
@@ -20681,6 +20786,7 @@ var init_dataFetcher = __esm({
20681
20786
  init_dates();
20682
20787
  init_changelogNotify();
20683
20788
  init_reportRequestPool();
20789
+ init_dashboardProfiler();
20684
20790
  quillFetch = async ({
20685
20791
  client,
20686
20792
  task,
@@ -20741,6 +20847,14 @@ var init_dataFetcher = __esm({
20741
20847
  return { error: "Failed to fetch data" };
20742
20848
  }
20743
20849
  };
20850
+ profileDashboard(
20851
+ "engine-fetch",
20852
+ summarizeEngineRequest({
20853
+ task,
20854
+ shareRequest,
20855
+ metadata
20856
+ })
20857
+ );
20744
20858
  if (!shareRequest) {
20745
20859
  return execute(abortSignal);
20746
20860
  }
@@ -21376,22 +21490,7 @@ init_dates();
21376
21490
  init_pivotConstructor();
21377
21491
  init_columnProcessing();
21378
21492
  init_paginationProcessing();
21379
-
21380
- // src/utils/dashboardProfiler.ts
21381
- function profileDashboard(event, data) {
21382
- if (typeof window === "undefined") return;
21383
- const profileWindow = window;
21384
- if (!profileWindow.__QUILL_DASHBOARD_PROFILE__) return;
21385
- const entry = {
21386
- at: Math.round(performance.now() * 10) / 10,
21387
- event,
21388
- data
21389
- };
21390
- profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
21391
- profileWindow.__QUILL_DASHBOARD_TRACE__.push(entry);
21392
- }
21393
-
21394
- // src/utils/dashboard.ts
21493
+ init_dashboardProfiler();
21395
21494
  var defaultDashboardItem = {
21396
21495
  id: "",
21397
21496
  name: "",
@@ -22805,6 +22904,7 @@ init_tableProcessing();
22805
22904
  init_textProcessing();
22806
22905
  init_valueFormatter();
22807
22906
  init_astFilterProcessing();
22907
+ init_dashboardProfiler();
22808
22908
  init_reportBuilder();
22809
22909
  init_astProcessing();
22810
22910
 
@@ -26577,6 +26677,7 @@ function normalizePSTRanges(start, end) {
26577
26677
 
26578
26678
  // src/Context.tsx
26579
26679
  init_changelogNotify();
26680
+ init_dashboardProfiler();
26580
26681
 
26581
26682
  // src/reportStore.ts
26582
26683
  var import_react = require("react");
@@ -32347,7 +32448,7 @@ function QuillTable({
32347
32448
  setSortColumn(sort?.field || "");
32348
32449
  setSortDirection(sort?.direction || "desc");
32349
32450
  }, [sort]);
32350
- const holdFullPageLoader = rows?.length === 0 && isLoading;
32451
+ const holdFullPageLoader = Boolean(isLoading);
32351
32452
  const pageCountUnknown = manualPagination && pageCount === -1;
32352
32453
  const { activeRows, maxPage } = (0, import_react14.useMemo)(() => {
32353
32454
  const start = currentPage * rowsPerPage;
@@ -37204,6 +37305,7 @@ function getDashboardReportProcessing(report, serverPagination) {
37204
37305
  }
37205
37306
 
37206
37307
  // src/hooks/useDashboard.ts
37308
+ init_dashboardProfiler();
37207
37309
  var DEFAULT_DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
37208
37310
  var useDashboardConfigInternal = (dashboardName) => {
37209
37311
  const { dashboardConfig, isLoading: dashboardsLoading } = (0, import_react26.useContext)(
@@ -38314,6 +38416,14 @@ var useDashboard = (dashboardName, config) => {
38314
38416
  additionalProcessing
38315
38417
  );
38316
38418
  const usePivotTask = !cacheEnabled && !!reportInfo.pivot;
38419
+ profileDashboard("dashboard-report-cache-path", {
38420
+ reportId,
38421
+ cacheEnabled,
38422
+ cacheCabCacheable: cacheCab.isCacheable(reportId),
38423
+ usePivotTask,
38424
+ forceCacheToRefresh,
38425
+ hasPivot: Boolean(reportInfo.pivot)
38426
+ });
38317
38427
  const allFilters = dashboardFilters2.concat(customFilters).concat(customReportFiltersArray);
38318
38428
  const applyInMemoryPivotIfNeeded = (report2) => {
38319
38429
  const pivotToApply = reportInfo.pivot ?? report2.pivot;
@@ -38547,7 +38657,9 @@ var useDashboard = (dashboardName, config) => {
38547
38657
  pivotColumns: pivotData.columns,
38548
38658
  pivotRowCount: pivotData.rowCount,
38549
38659
  pivotQuery: pivotData.pivotQuery,
38550
- comparisonPivotQuery: pivotData.comparisonPivotQuery
38660
+ comparisonPivotQuery: pivotData.comparisonPivotQuery,
38661
+ pivotResultRowField: pivotData.rowField,
38662
+ pivotResultSourceRowField: reportInfo.pivot?.rowField
38551
38663
  },
38552
38664
  error: void 0
38553
38665
  };
@@ -38577,6 +38689,26 @@ var useDashboard = (dashboardName, config) => {
38577
38689
  shareRequest: !forceCacheToRefresh
38578
38690
  });
38579
38691
  };
38692
+ const existingState = queryClient.getQueryState(queryKey);
38693
+ const existingData = queryClient.getQueryData(queryKey);
38694
+ const dataUpdatedAt = existingState?.dataUpdatedAt ?? 0;
38695
+ const ageMs = dataUpdatedAt ? Date.now() - dataUpdatedAt : null;
38696
+ const isStale = dataUpdatedAt === 0 || Date.now() - dataUpdatedAt >= reportStaleTimeMs;
38697
+ profileDashboard("dashboard-report-tanstack-cache", {
38698
+ reportId,
38699
+ keyFamily: "quill/dashboard-report",
38700
+ cacheEnabled,
38701
+ usePivotTask,
38702
+ forceCacheToRefresh,
38703
+ staleTimeMs: reportStaleTimeMs,
38704
+ status: existingState?.status ?? "missing",
38705
+ fetchStatus: existingState?.fetchStatus ?? "idle",
38706
+ hasData: existingData !== void 0,
38707
+ dataUpdatedAt,
38708
+ ageMs,
38709
+ isStale,
38710
+ willReuseTanstack: !forceCacheToRefresh && existingData !== void 0 && !isStale
38711
+ });
38580
38712
  const result = forceCacheToRefresh ? await fetchDashboardReport() : await queryClient.fetchQuery({
38581
38713
  queryKey,
38582
38714
  queryFn: fetchDashboardReport,
@@ -38979,6 +39111,7 @@ var useDashboardReport = (reportId, config) => {
38979
39111
  };
38980
39112
 
38981
39113
  // src/components/Dashboard/DataLoader.tsx
39114
+ init_dashboardProfiler();
38982
39115
  var import_jsx_runtime46 = require("react/jsx-runtime");
38983
39116
  var constructReportFromItem = (item) => {
38984
39117
  return {
@@ -41394,6 +41527,7 @@ function QuillTableDashboardComponent({
41394
41527
 
41395
41528
  // src/Chart.tsx
41396
41529
  init_valueFormatter();
41530
+ init_dashboardProfiler();
41397
41531
  var import_jsx_runtime50 = require("react/jsx-runtime");
41398
41532
  function Chart({
41399
41533
  colors,
@@ -45378,6 +45512,7 @@ init_Filter();
45378
45512
 
45379
45513
  // src/StaticChart.tsx
45380
45514
  var import_react42 = require("react");
45515
+ init_dashboardProfiler();
45381
45516
  var import_jsx_runtime60 = require("react/jsx-runtime");
45382
45517
  var CHART_TYPE_STYLES = {
45383
45518
  metric: { height: "100px", width: "200px" },
@@ -61912,6 +62047,24 @@ function useDebouncedRefreshInput(value, delayMs = REPORT_REFRESH_DEBOUNCE_MS) {
61912
62047
 
61913
62048
  // src/utils/pivotDateBuckets.ts
61914
62049
  var import_date_fns18 = require("date-fns");
62050
+ var PIVOT_DATE_BUCKETS = /* @__PURE__ */ new Set([
62051
+ "day",
62052
+ "week",
62053
+ "month",
62054
+ "year"
62055
+ ]);
62056
+ function inBucketDateBucketForField(rules, field) {
62057
+ for (const entry of rules) {
62058
+ if (!entry || typeof entry !== "object") continue;
62059
+ const rule = entry;
62060
+ if (rule.operator !== "inBucket" || rule.field !== field) continue;
62061
+ const bucket = rule.value && typeof rule.value === "object" && !Array.isArray(rule.value) ? rule.value.bucket : void 0;
62062
+ if (typeof bucket === "string" && PIVOT_DATE_BUCKETS.has(bucket)) {
62063
+ return bucket;
62064
+ }
62065
+ }
62066
+ return void 0;
62067
+ }
61915
62068
  function buildPivotDateBucketStarts(range, bucket) {
61916
62069
  const min2 = new Date(range.min);
61917
62070
  const max2 = new Date(range.max);
@@ -62231,6 +62384,7 @@ function resolveReportFromCacheCab({
62231
62384
  }
62232
62385
 
62233
62386
  // src/hooks/useForm.tsx
62387
+ init_dashboardProfiler();
62234
62388
  init_reportRequestPool();
62235
62389
 
62236
62390
  // src/hooks/useForm.queries.ts
@@ -62276,6 +62430,15 @@ function createUseFormInitialLoadQueryKey(input) {
62276
62430
  input.additionalSchemaHash
62277
62431
  ];
62278
62432
  }
62433
+ var DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
62434
+ function findCachedDashboardReportQuery(queryClient, reportId) {
62435
+ const id = String(reportId ?? "").trim();
62436
+ if (!id) return void 0;
62437
+ return queryClient.getQueryCache().findAll({ queryKey: ["quill", "dashboard-report", id] }).find((query) => {
62438
+ const data = query.state.data;
62439
+ return Boolean(data?.report) && !data?.error;
62440
+ });
62441
+ }
62279
62442
  function shouldBootstrapUseFormInitialLoad(input) {
62280
62443
  return !input.hasInitialReportBuilderState && input.previouslyBootstrappedIdentity !== input.currentIdentity;
62281
62444
  }
@@ -63258,6 +63421,11 @@ function getPivotTableSlotReportColumn(reportColumns, aggregations, rowField, pi
63258
63421
  }
63259
63422
  return cols[aggIndex + 1];
63260
63423
  }
63424
+ function pivotRowKey(chart) {
63425
+ return String(
63426
+ chart?.pivotResultRowField ?? chart?.pivot?.rowField ?? ""
63427
+ ).trim();
63428
+ }
63261
63429
  function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63262
63430
  if (!chart?.pivot) return false;
63263
63431
  if (String(chart.chartType ?? "").toLowerCase() !== "table") return false;
@@ -63266,7 +63434,8 @@ function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63266
63434
  }
63267
63435
  const rowField = String(chart.pivot.rowField ?? "").trim();
63268
63436
  const xf = String(xAxisField ?? "").trim();
63269
- if (!rowField || xf !== rowField) return false;
63437
+ const rowKey = pivotRowKey(chart);
63438
+ if (!rowField || xf !== rowField && xf !== rowKey) return false;
63270
63439
  return isDateType(String(chart.pivot.rowFieldType ?? ""));
63271
63440
  }
63272
63441
  var RESOLVABLE_X_AXIS_DATE_BUCKETS = /* @__PURE__ */ new Set([
@@ -63280,22 +63449,24 @@ function resolvePivotDateBucketXAxisFormat(chart, xAxisField) {
63280
63449
  const dateBucket = String(chart?.pivot?.dateBucket ?? "").trim().toLowerCase();
63281
63450
  if (!RESOLVABLE_X_AXIS_DATE_BUCKETS.has(dateBucket)) return null;
63282
63451
  const rowField = String(chart?.pivot?.rowField ?? "").trim();
63283
- if (!rowField || String(xAxisField ?? "").trim() !== rowField) return null;
63452
+ const xf = String(xAxisField ?? "").trim();
63453
+ const rowKey = pivotRowKey(chart);
63454
+ if (!rowField || xf !== rowField && xf !== rowKey) return null;
63284
63455
  if (!isDateType(String(chart?.pivot?.rowFieldType ?? ""))) return null;
63285
63456
  return getDateFormatFromBucket(dateBucket);
63286
63457
  }
63287
63458
  function chartDetailRowsMissingPivotRowBucket(chart) {
63288
63459
  if (!chart?.pivot) return false;
63289
- const rowField = String(chart.pivot.rowField ?? "").trim();
63290
- if (!rowField) return false;
63460
+ const rowKey = pivotRowKey(chart);
63461
+ if (!rowKey) return false;
63291
63462
  const rows = chart.rows;
63292
63463
  if (!Array.isArray(rows) || rows.length === 0) return false;
63293
63464
  const first = rows.find(
63294
63465
  (r) => r && typeof r === "object" && Object.keys(r).length > 0
63295
63466
  );
63296
63467
  if (!first) return false;
63297
- if (!Object.prototype.hasOwnProperty.call(first, rowField)) return true;
63298
- const v = first[rowField];
63468
+ if (!Object.prototype.hasOwnProperty.call(first, rowKey)) return true;
63469
+ const v = first[rowKey];
63299
63470
  return v === void 0 || v === null;
63300
63471
  }
63301
63472
  function shouldUsePivotRowFieldAsXAxis(chartType, pivotRowField, rowColumnFormat) {
@@ -63331,7 +63502,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63331
63502
  } : chart;
63332
63503
  if (!config) return config;
63333
63504
  if (!config.pivot) return config;
63334
- const pivotRowFieldEarly = String(config.pivot?.rowField ?? "").trim();
63505
+ const pivotRowFieldEarly = pivotRowKey(config);
63335
63506
  const rowColumn = (config.pivotColumns ?? config.columns ?? []).find(
63336
63507
  (col) => String(col.field ?? "").trim() === pivotRowFieldEarly
63337
63508
  );
@@ -63366,7 +63537,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63366
63537
  return keys;
63367
63538
  })() : [];
63368
63539
  const pivotValueFields = pivotRowFields.filter(
63369
- (field) => field !== withResolvedXAxis.pivot?.rowField
63540
+ (field) => field !== pivotRowKey(withResolvedXAxis) && field !== withResolvedXAxis.pivot?.rowField
63370
63541
  );
63371
63542
  const isAggregationOnlyPivot = !String(withResolvedXAxis.pivot?.rowField ?? "").trim() && !String(withResolvedXAxis.pivot?.columnField ?? "").trim();
63372
63543
  const yAxisFormatByField = new Map(
@@ -63487,7 +63658,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63487
63658
  const normalizedPivotColumns = pivotColumnFields.length > 0 ? pivotColumnFields.map((field) => {
63488
63659
  const knownColumn = knownColumnsByField.get(field);
63489
63660
  const yAxis = yAxisFields.find((axis) => axis.field === field);
63490
- const format9 = yAxis?.format ?? knownColumn?.format ?? (field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63661
+ const format9 = yAxis?.format ?? knownColumn?.format ?? (field === pivotRowKey(withResolvedXAxis) || field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63491
63662
  return {
63492
63663
  field,
63493
63664
  label: yAxis?.label ?? knownColumn?.label ?? field,
@@ -63500,7 +63671,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63500
63671
  const slotCol = getPivotTableSlotReportColumn(
63501
63672
  pivotTableSlotColumns,
63502
63673
  aggregations,
63503
- withResolvedXAxis.pivot?.rowField,
63674
+ pivotRowKey(withResolvedXAxis) || withResolvedXAxis.pivot?.rowField,
63504
63675
  col.field
63505
63676
  );
63506
63677
  if (!slotCol) return col;
@@ -63522,9 +63693,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63522
63693
  const normalizedXAxisFormat = normalizedXAxisField === withResolvedXAxis.xAxisField ? withResolvedXAxis.xAxisFormat : yAxisFields.find((axis) => axis.field === normalizedXAxisField)?.format ?? pivotTableDisplayColumns.find(
63523
63694
  (column) => column.field === normalizedXAxisField
63524
63695
  )?.format ?? withResolvedXAxis.xAxisFormat;
63525
- const pivotDisplayRowField = String(
63526
- withResolvedXAxis.pivot?.rowField ?? ""
63527
- ).trim();
63696
+ const pivotDisplayRowField = pivotRowKey(withResolvedXAxis);
63528
63697
  const pivotDisplayRowFieldType = String(
63529
63698
  withResolvedXAxis.pivot?.rowFieldType ?? ""
63530
63699
  ).trim();
@@ -66488,19 +66657,30 @@ function useReport(reportIdArg, options = {}) {
66488
66657
  )
66489
66658
  });
66490
66659
  const diagnostics = globalThis.__QUILL_CACHECAB_DIAGNOSTICS__;
66660
+ const durationMs = performance.now() - startedAt;
66661
+ const outcome = resolution.resolved ? "hit" : "fallback";
66491
66662
  if (Array.isArray(diagnostics)) {
66492
66663
  diagnostics.push({
66493
66664
  reportId: effectiveReportId,
66494
66665
  operation,
66495
- outcome: resolution.resolved ? "hit" : "fallback",
66666
+ outcome,
66496
66667
  reason: resolution.resolved ? "complete" : resolution.reason,
66497
66668
  details: resolution.resolved ? void 0 : resolution.details,
66498
66669
  snapshotReason: snapshot?.reason ?? "cache_miss",
66499
66670
  forcedIncompleteSnapshot: Boolean(snapshot) && !snapshot?.complete && forceIncompleteCacheCabForParity,
66500
66671
  rowCount: snapshot?.rowCount ?? 0,
66501
- durationMs: performance.now() - startedAt
66672
+ durationMs
66502
66673
  });
66503
66674
  }
66675
+ profileDashboard("use-report-cachecab", {
66676
+ reportId: effectiveReportId,
66677
+ operation,
66678
+ outcome,
66679
+ reason: resolution.resolved ? "complete" : resolution.reason,
66680
+ snapshotReason: snapshot?.reason ?? "cache_miss",
66681
+ rowCount: snapshot?.rowCount ?? 0,
66682
+ durationMs: Math.round(durationMs * 10) / 10
66683
+ });
66504
66684
  return resolution.resolved ? resolution.report : null;
66505
66685
  },
66506
66686
  [
@@ -67074,9 +67254,15 @@ function useReport(reportIdArg, options = {}) {
67074
67254
  if (alias) localValues[alias] = values;
67075
67255
  }
67076
67256
  if (hasEveryColumn) {
67257
+ profileDashboard("use-report-unique-values-cachecab-hit", {
67258
+ reportId: effectiveReportId
67259
+ });
67077
67260
  return { uniqueValuesByColumn: localValues };
67078
67261
  }
67079
67262
  }
67263
+ profileDashboard("use-report-unique-values-network", {
67264
+ reportId: effectiveReportId
67265
+ });
67080
67266
  const tablesForUniqueValues = filterUniqueValuesRequest.reportBuilderState?.tables?.map(
67081
67267
  (table2) => String(table2?.name ?? "").trim()
67082
67268
  ) ?? filterUniqueValuesRequest.stringColumnsByTable.map((column) => String(column.table ?? "").trim()).filter(Boolean);
@@ -67595,6 +67781,29 @@ function useReport(reportIdArg, options = {}) {
67595
67781
  const initialLoadQuery = (0, import_react_query3.useQuery)({
67596
67782
  queryKey: initialLoadQueryKey,
67597
67783
  queryFn: createUseFormQueryFn(async (signal) => {
67784
+ const tanstackState = queryClient.getQueryState(initialLoadQueryKey);
67785
+ const dashboardReportQueries = queryClient.getQueryCache().getAll().filter(
67786
+ (query) => queryKeyFamily(query.queryKey) === "quill/dashboard-report"
67787
+ );
67788
+ const matchingDashboardReport = dashboardReportQueries.find(
67789
+ (query) => String(query.queryKey[2] ?? "") === String(effectiveReportId)
67790
+ );
67791
+ profileDashboard("use-report-initial-load-queryfn", {
67792
+ reportId: effectiveReportId,
67793
+ reason: "TanStack ran this queryFn, so useReport/initial-load had no fresh cached data",
67794
+ keyFamily: "useReport/initial-load",
67795
+ status: tanstackState?.status ?? "missing",
67796
+ hasData: tanstackState?.data !== void 0,
67797
+ dataUpdatedAt: tanstackState?.dataUpdatedAt ?? 0,
67798
+ staleTime: 0,
67799
+ dashboardReportQueryCount: dashboardReportQueries.length,
67800
+ matchingDashboardReport: matchingDashboardReport ? {
67801
+ hasData: matchingDashboardReport.state.data !== void 0,
67802
+ status: matchingDashboardReport.state.status,
67803
+ staleTime: matchingDashboardReport.options?.staleTime ?? 0,
67804
+ unusedByUseReport: true
67805
+ } : null
67806
+ });
67598
67807
  let cachedReportBuilderState = initialReportBuilderStateForLoad ?? void 0;
67599
67808
  if (!cachedReportBuilderState) {
67600
67809
  const snapshot = await cacheCab.getReportSnapshot(
@@ -67619,6 +67828,9 @@ function useReport(reportIdArg, options = {}) {
67619
67828
  operation: "initial"
67620
67829
  });
67621
67830
  if (cachedReport) {
67831
+ profileDashboard("use-report-initial-load-served-from-cachecab", {
67832
+ reportId: effectiveReportId
67833
+ });
67622
67834
  return { report: cachedReport };
67623
67835
  }
67624
67836
  const allowReportTaskBootstrap = shouldBootstrapUseFormInitialLoad({
@@ -67633,6 +67845,12 @@ function useReport(reportIdArg, options = {}) {
67633
67845
  const formFiltersBelongToLoadTarget = Boolean(loadTargetId) && sourceReportIdentity === loadTargetId;
67634
67846
  const rulesForLoad = useInMemoryEngines || !formFiltersBelongToLoadTarget ? EMPTY_QUERY_FILTERS : queryFilters;
67635
67847
  const shareInitialRequest = sharedInitialRequestUsedForReportIdRef.current !== effectiveReportId;
67848
+ profileDashboard("use-report-initial-load-network", {
67849
+ reportId: effectiveReportId,
67850
+ path: "loadReportForUseForm",
67851
+ hasCachedReportBuilderState: Boolean(cachedReportBuilderState)
67852
+ });
67853
+ const networkStartedAt = performance.now();
67636
67854
  const loadResult = await loadReportForUseForm({
67637
67855
  reportId: effectiveReportId,
67638
67856
  initialReportBuilderState: initialReportBuilderStateForLoad,
@@ -67652,6 +67870,12 @@ function useReport(reportIdArg, options = {}) {
67652
67870
  rowsOnly: isCreatedReportBootstrapLoad,
67653
67871
  abortSignal: signal
67654
67872
  });
67873
+ profileDashboard("use-report-initial-load-network-done", {
67874
+ reportId: effectiveReportId,
67875
+ durationMs: Math.round(performance.now() - networkStartedAt),
67876
+ hasReport: Boolean(loadResult.report),
67877
+ error: loadResult.error ?? null
67878
+ });
67655
67879
  if (loadResult.report && !loadResult.error) {
67656
67880
  if (allowReportTaskBootstrap) {
67657
67881
  bootstrapReportTaskUsedForInitialLoadRef.current = initialLoadIdentityHash;
@@ -67663,7 +67887,17 @@ function useReport(reportIdArg, options = {}) {
67663
67887
  return loadResult;
67664
67888
  }),
67665
67889
  enabled: Boolean(effectiveReportId) && Boolean(client) && !reportOverride,
67666
- retry: false
67890
+ retry: false,
67891
+ initialData: () => {
67892
+ const cached = findCachedDashboardReportQuery(
67893
+ queryClient,
67894
+ effectiveReportId
67895
+ );
67896
+ const data = cached?.state.data;
67897
+ return data?.report ? { report: data.report, error: data.error } : void 0;
67898
+ },
67899
+ initialDataUpdatedAt: () => findCachedDashboardReportQuery(queryClient, effectiveReportId)?.state.dataUpdatedAt,
67900
+ staleTime: DASHBOARD_REPORT_STALE_TIME_MS
67667
67901
  });
67668
67902
  const reportNameQueryReportId = String(effectiveReportId ?? "").trim();
67669
67903
  const reportNameQuery = (0, import_react_query3.useQuery)({
@@ -67714,15 +67948,6 @@ function useReport(reportIdArg, options = {}) {
67714
67948
  const shouldPromoteColumnToRowFromPendingFlag = pendingPromoteColumnToRow && !String(prev.groupRowsBy ?? "").trim();
67715
67949
  const sourceReportBuilderTables = (sourceReport.reportBuilderState?.tables ?? []).filter((table2) => Boolean(String(table2?.name ?? "").trim()));
67716
67950
  const sourceReportBuilderTableNames = sourceReportBuilderTables.map((table2) => table2.name).filter((name2) => Boolean(name2));
67717
- const sourceQueryColumns = normalizeReportBuilderColumns(
67718
- sourceReport.reportBuilderState?.columns ?? (sourceReport.columns ?? []).map((column) => ({
67719
- field: column.field,
67720
- table: column.table ?? resolveColumnTableFromReportMetadata(
67721
- sourceReport,
67722
- column.field
67723
- )
67724
- }))
67725
- );
67726
67951
  const nextQueryFilters = prev.queryFilters.rules.length ? prev.queryFilters : rulesFromReport(sourceReport);
67727
67952
  const pivotAggregationsFromSource = Array.isArray(sourceReport.pivot?.aggregations) ? sourceReport.pivot.aggregations : sourceReport.pivot?.aggregationType ? [
67728
67953
  {
@@ -67789,6 +68014,9 @@ function useReport(reportIdArg, options = {}) {
67789
68014
  tables: tableScopeForDisplayColumns,
67790
68015
  schemaTables: schemaForReportBuilderState
67791
68016
  });
68017
+ const sourceQueryColumns = normalizeReportBuilderColumns(
68018
+ sourceReport.reportBuilderState?.columns?.length ? sourceReport.reportBuilderState.columns : sourceDisplayColumnsFromSchema
68019
+ );
67792
68020
  const savedDisplayColumns = normalizeReportBuilderColumns(
67793
68021
  (sourceReport.columns ?? []).map((column) => ({
67794
68022
  ...column,
@@ -68302,13 +68530,12 @@ function useReport(reportIdArg, options = {}) {
68302
68530
  tables: effectiveReportBuilderState.tables,
68303
68531
  schemaTables: schemaForReportBuilderState
68304
68532
  });
68305
- const columnsToFetch = allColumnsBySelectedTable.length > 0 ? allColumnsBySelectedTable : effectiveReportBuilderState.columns;
68306
- if (columnsToFetch.length === 0) {
68533
+ if (allColumnsBySelectedTable.length === 0) {
68307
68534
  return void 0;
68308
68535
  }
68309
68536
  return {
68310
68537
  ...effectiveReportBuilderState,
68311
- columns: columnsToFetch,
68538
+ columns: allColumnsBySelectedTable,
68312
68539
  pivot: null,
68313
68540
  sort: [],
68314
68541
  limit: null
@@ -68351,6 +68578,29 @@ function useReport(reportIdArg, options = {}) {
68351
68578
  refreshDecision.shouldRefresh,
68352
68579
  queryFilters
68353
68580
  ]);
68581
+ const shouldSkipRedundantPivotTableDataQuery = (0, import_react63.useMemo)(() => {
68582
+ if (!sourceReport || !pivotState) {
68583
+ return false;
68584
+ }
68585
+ if (tableRefreshVersion !== 0 || pivotRefreshVersion !== 0) {
68586
+ return false;
68587
+ }
68588
+ if (!Array.isArray(sourceReport.rows) || sourceReport.rows.length === 0) {
68589
+ return false;
68590
+ }
68591
+ if (refreshDecision.shouldRefresh) {
68592
+ return false;
68593
+ }
68594
+ const sourceRules = sourceReport.reportBuilderState?.rules ?? EMPTY_QUERY_FILTERS;
68595
+ return stableSerializeForQueryKey(queryFilters) === stableSerializeForQueryKey(sourceRules);
68596
+ }, [
68597
+ sourceReport,
68598
+ pivotState,
68599
+ tableRefreshVersion,
68600
+ pivotRefreshVersion,
68601
+ refreshDecision.shouldRefresh,
68602
+ queryFilters
68603
+ ]);
68354
68604
  const shouldForceTableRefreshFromFilters = !useInMemoryEngines && !pivotState;
68355
68605
  const immediateTableRefreshInput = (0, import_react63.useMemo)(
68356
68606
  () => ({
@@ -68399,8 +68649,14 @@ function useReport(reportIdArg, options = {}) {
68399
68649
  operation: "table"
68400
68650
  });
68401
68651
  if (cachedReport) {
68652
+ profileDashboard("use-report-table-refresh-cachecab-hit", {
68653
+ reportId: effectiveReportId
68654
+ });
68402
68655
  return { report: cachedReport };
68403
68656
  }
68657
+ profileDashboard("use-report-table-refresh-network", {
68658
+ reportId: effectiveReportId
68659
+ });
68404
68660
  return loadViaReportBuilderState({
68405
68661
  reportId: effectiveReportId,
68406
68662
  reportBuilderState: tableRefreshInput.reportBuilderState,
@@ -69014,7 +69270,8 @@ function useReport(reportIdArg, options = {}) {
69014
69270
  sourceReport
69015
69271
  ]);
69016
69272
  const pivotRefreshQueryEnabled = !reportOverride && pendingPivotRefresh && !shouldSkipPivotRefreshForUnchangedPivot && Boolean(sourceReport) && Boolean(client) && Boolean(effectiveReportBuilderState) && Boolean(nextPivot) && sourceReportMatchesEffectiveReportId;
69017
- const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId;
69273
+ const initialLoadSettled = Boolean(reportOverride) || !effectiveReportId || Boolean(client) && !initialLoadQuery.isPending && !initialLoadQuery.isFetching;
69274
+ const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId && initialLoadSettled && !shouldSkipRedundantPivotTableDataQuery;
69018
69275
  const pivotRefreshQuery = (0, import_react_query3.useQuery)({
69019
69276
  queryKey: createUseFormPivotRefreshQueryKey({
69020
69277
  reportId: effectiveReportId,
@@ -69128,7 +69385,7 @@ function useReport(reportIdArg, options = {}) {
69128
69385
  const paginationRangeStart = pagination.pageIndex * pagination.pageSize;
69129
69386
  const paginationRangeEnd = paginationRangeStart + pagination.pageSize;
69130
69387
  const pageWithinBaseWindow = paginationRangeEnd <= baseWindowRowsLength || trustedSourceRowCount !== void 0 && trustedSourceRowCount <= baseWindowRowsLength;
69131
- const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh;
69388
+ const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh && initialLoadSettled;
69132
69389
  const tablePageQuery = (0, import_react_query3.useQuery)({
69133
69390
  queryKey: createUseFormTablePageQueryKey({
69134
69391
  reportId: effectiveReportId,
@@ -69300,21 +69557,17 @@ function useReport(reportIdArg, options = {}) {
69300
69557
  if (!sourceReport) return void 0;
69301
69558
  const rowsForChart = Array.isArray(sourceReport.rows) ? sourceReport.rows : [];
69302
69559
  const chartPivot = pendingPivotChangesDimensions ? sourceReport.pivot ?? null : nextPivot ?? (!chartPivotHydratedFromSourceRef.current ? sourceReport.pivot ?? null : null);
69303
- const chartPivotForDisplay = chartPivot && sourceReport.pivotResultRowField && sourceReport.pivotResultSourceRowField === chartPivot.rowField ? {
69304
- ...chartPivot,
69305
- rowField: sourceReport.pivotResultRowField
69306
- } : chartPivot;
69307
- const rowCountForChart = chartPivotForDisplay ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69560
+ const rowCountForChart = chartPivot ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69308
69561
  const referencedTablesForChart = effectiveReportBuilderState?.tables.map((table2) => table2.name).filter((name2) => Boolean(name2));
69309
69562
  const pivotRowsForChart = Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows : void 0;
69310
- const rowCountForChartResolved = chartPivotForDisplay ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69563
+ const rowCountForChartResolved = chartPivot ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69311
69564
  const chartDataPayload = {
69312
69565
  ...sourceReport,
69313
69566
  rows: rowsForChart,
69314
69567
  rowCount: rowCountForChartResolved,
69315
69568
  chartType: chartType ?? sourceReport.chartType,
69316
69569
  reportBuilderState: effectiveReportBuilderState,
69317
- pivot: chartPivotForDisplay,
69570
+ pivot: chartPivot,
69318
69571
  referencedTables: referencedTablesForChart && referencedTablesForChart.length > 0 ? referencedTablesForChart : sourceReport.referencedTables,
69319
69572
  pivotRows: pivotRowsForChart,
69320
69573
  pivotColumns: sourceReport.pivotColumns,
@@ -69415,7 +69668,7 @@ function useReport(reportIdArg, options = {}) {
69415
69668
  const xAxisOptions = (0, import_react63.useMemo)(() => {
69416
69669
  if (!chartAxesBaseChart) return chartAxisOptions;
69417
69670
  const pivot = chartAxesBaseChart.pivot;
69418
- const pivotRowField = String(pivot?.rowField ?? "").trim();
69671
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69419
69672
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69420
69673
  if (pivot && pivotRowField) {
69421
69674
  if (["metric", "gauge"].includes(chartType2)) {
@@ -69536,9 +69789,7 @@ function useReport(reportIdArg, options = {}) {
69536
69789
  const resolvedXAxisField = (0, import_react63.useMemo)(() => {
69537
69790
  if (!chartAxesBaseChart) return "";
69538
69791
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69539
- const pivotRowField = String(
69540
- chartAxesBaseChart.pivot?.rowField ?? ""
69541
- ).trim();
69792
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69542
69793
  if (pivotRowField) {
69543
69794
  const rowColumn = (chartAxesBaseChart.pivotColumns ?? chartAxesBaseChart.columns ?? []).find((col) => String(col.field ?? "").trim() === pivotRowField);
69544
69795
  if (shouldUsePivotRowFieldAsXAxis(
@@ -69674,11 +69925,11 @@ function useReport(reportIdArg, options = {}) {
69674
69925
  columns2 = mergePivotTableDisplayColumnLabelsFromYAxis({
69675
69926
  columns: columns2 ?? baseChart.columns,
69676
69927
  yAxisFields: resolvedYAxisFieldsForDisplay,
69677
- pivotRowField: String(baseChart.pivot.rowField ?? ""),
69928
+ pivotRowField: pivotRowKey(baseChart),
69678
69929
  xAxisLabel: resolvedXAxisLabel
69679
69930
  });
69680
69931
  } else {
69681
- const pivotRowField = String(baseChart.pivot.rowField ?? "").trim();
69932
+ const pivotRowField = pivotRowKey(baseChart);
69682
69933
  const pivotLabelByField = new Map(
69683
69934
  (baseChart.pivotColumns ?? []).map((column) => [
69684
69935
  String(column.field ?? "").trim(),
@@ -69726,8 +69977,11 @@ function useReport(reportIdArg, options = {}) {
69726
69977
  const rowField = String(pivot?.rowField ?? "").trim();
69727
69978
  if (rowField && isDateType(String(pivot?.rowFieldType ?? ""))) {
69728
69979
  const field = pivot?.rowFieldTable ? `${pivot.rowFieldTable}.${rowField}` : rowField;
69729
- const bucket = dateBucket || pivot?.dateBucket || "month";
69730
- const labelsByRaw = /* @__PURE__ */ new Map();
69980
+ const chartBucket = dateBucket || pivot?.dateBucket || "month";
69981
+ const bucket = inBucketDateBucketForField(
69982
+ filtersForQueryBuilder.rules ?? [],
69983
+ field
69984
+ ) ?? chartBucket;
69731
69985
  const cacheKey = `${String(effectiveReportId ?? "")}\0${field}\0${bucket}`;
69732
69986
  if (pivotDateFilterRangeCacheRef.current.key !== cacheKey) {
69733
69987
  pivotDateFilterRangeCacheRef.current = {
@@ -69743,7 +69997,6 @@ function useReport(reportIdArg, options = {}) {
69743
69997
  const key = String(raw);
69744
69998
  const timestamp = new Date(key).getTime();
69745
69999
  if (Number.isNaN(timestamp)) continue;
69746
- labelsByRaw.set(key, String(record[rowField] ?? key));
69747
70000
  const cachedMin = pivotDateFilterRangeCacheRef.current.min;
69748
70001
  const cachedMax = pivotDateFilterRangeCacheRef.current.max;
69749
70002
  if (cachedMin == null || timestamp < new Date(cachedMin).getTime()) {
@@ -69756,7 +70009,7 @@ function useReport(reportIdArg, options = {}) {
69756
70009
  const { min: min2, max: max2 } = pivotDateFilterRangeCacheRef.current;
69757
70010
  const options2 = min2 && max2 ? buildPivotDateBucketStarts({ min: min2, max: max2 }, bucket).map((value) => ({
69758
70011
  value,
69759
- label: labelsByRaw.get(value) ?? getDateString(value, void 0, bucket)
70012
+ label: getDateString(value, void 0, bucket)
69760
70013
  })) : [];
69761
70014
  out.push({
69762
70015
  field,
@@ -69772,7 +70025,8 @@ function useReport(reportIdArg, options = {}) {
69772
70025
  chart?.rows,
69773
70026
  dateBucket,
69774
70027
  effectiveReportId,
69775
- filterValueOptionsByFieldName
70028
+ filterValueOptionsByFieldName,
70029
+ filtersForQueryBuilder.rules
69776
70030
  ]);
69777
70031
  const chartForUi = (0, import_react63.useMemo)(() => {
69778
70032
  if (!chart?.pivot) return chart;
@@ -69785,10 +70039,10 @@ function useReport(reportIdArg, options = {}) {
69785
70039
  };
69786
70040
  const selectedValue = (field, operator, options2) => {
69787
70041
  const rule = filtersForQueryBuilder.rules.find(
69788
- (entry) => typeof entry === "object" && entry !== null && "field" in entry && entry.field === field && entry.operator === operator
70042
+ (entry) => typeof entry === "object" && entry !== null && "field" in entry && entry.field === field && (entry.operator === operator || operator === "inBucket" && entry.operator === "between")
69789
70043
  );
69790
70044
  if (!rule) return null;
69791
- const raw = operator === "inBucket" ? rule.value?.start : Array.isArray(rule.value) ? rule.value[0] : void 0;
70045
+ const raw = operator === "inBucket" ? rule.operator === "between" && Array.isArray(rule.value) ? rule.value[0] : rule.value?.start : Array.isArray(rule.value) ? rule.value[0] : void 0;
69792
70046
  if (raw == null) return null;
69793
70047
  const value = String(raw);
69794
70048
  return options2.some((option) => option.value === value) ? value : null;
@@ -70044,9 +70298,7 @@ function useReport(reportIdArg, options = {}) {
70044
70298
  sourceReport,
70045
70299
  includeSelectedSchemaFallback: tableColumnsEditedSignature !== null
70046
70300
  });
70047
- const pivotRowFieldForTable = String(
70048
- sourceReport?.pivot?.rowField ?? ""
70049
- ).trim();
70301
+ const pivotRowFieldForTable = pivotRowKey(sourceReport);
70050
70302
  const pivotRowTableUsesAxisFormat = chartAxisEdits.xAxisFormat !== void 0;
70051
70303
  const columns2 = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot && pivotRowFieldForTable && String(resolvedXAxisField ?? "").trim() === pivotRowFieldForTable ? mergedFromReport.map(
70052
70304
  (column) => column.field === pivotRowFieldForTable ? {
@@ -70058,7 +70310,7 @@ function useReport(reportIdArg, options = {}) {
70058
70310
  const pivotLabeledColumns = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot ? mergePivotTableDisplayColumnLabelsFromYAxis({
70059
70311
  columns: columns2,
70060
70312
  yAxisFields: resolvedYAxisFieldsForDisplay,
70061
- pivotRowField: String(sourceReport.pivot.rowField ?? ""),
70313
+ pivotRowField: pivotRowKey(sourceReport),
70062
70314
  xAxisLabel: resolvedXAxisLabel
70063
70315
  }) ?? columns2 : columns2;
70064
70316
  const tableColumnsWithPivotDisplayLabels = pivotLabeledColumns.map(
@@ -70307,7 +70559,7 @@ function useReport(reportIdArg, options = {}) {
70307
70559
  if (slotFormatting) {
70308
70560
  const aggregations = slotFormatting.aggregations;
70309
70561
  const hasMultiple = aggregations.length > 1;
70310
- const rowField = String(pivotState?.rowField ?? "").trim();
70562
+ const rowField = pivotRowKey(chart);
70311
70563
  const firstValueColumnFormat = String(
70312
70564
  (chart.columns ?? []).find(
70313
70565
  (c) => String(c.field ?? "").trim() !== rowField
@@ -70343,9 +70595,7 @@ function useReport(reportIdArg, options = {}) {
70343
70595
  }
70344
70596
  }
70345
70597
  }
70346
- const pivotRowFieldForSettings = String(
70347
- chart?.pivot?.rowField ?? ""
70348
- ).trim();
70598
+ const pivotRowFieldForSettings = pivotRowKey(chart);
70349
70599
  const rowAxisLabel = String(resolvedXAxisLabel ?? "").trim();
70350
70600
  for (const columnId of activeTableColumnIds) {
70351
70601
  const option = columnOptionById.get(columnId);
@@ -70405,7 +70655,7 @@ function useReport(reportIdArg, options = {}) {
70405
70655
  tableColumnSettingsCoalesceRef.current = new Map(tableColumnSettingsById);
70406
70656
  }, [tableColumnSettingsById]);
70407
70657
  const tableColumnItems = (0, import_react63.useMemo)(() => {
70408
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70658
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70409
70659
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70410
70660
  const items = activeTableColumnIds.map((columnId) => {
70411
70661
  const option = columnOptionById.get(columnId);
@@ -70444,7 +70694,7 @@ function useReport(reportIdArg, options = {}) {
70444
70694
  return new Map(tableColumnItems.map((item) => [item.id, item]));
70445
70695
  }, [tableColumnItems]);
70446
70696
  const tableColumnValues = (0, import_react63.useMemo)(() => {
70447
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70697
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70448
70698
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70449
70699
  return tableColumnItems.map((item) => {
70450
70700
  const coerced = coerceTableColumnFormatToAxisValue(item.format);
@@ -70465,8 +70715,89 @@ function useReport(reportIdArg, options = {}) {
70465
70715
  const initialLoadInProgress = !reportOverride && Boolean(effectiveReportId) && (!client || initialLoadQuery.isPending || initialLoadQuery.isFetching);
70466
70716
  const filterUniqueValuesLoading = filterUniqueValuesEnabled && (filterUniqueValuesQuery.isPending || filterUniqueValuesQuery.isFetching);
70467
70717
  const chartLoading = initialLoadInProgress || pendingPivotRefresh || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70468
- const tableLoading = initialLoadInProgress || pendingPivotRefresh || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70718
+ const awaitingPivotDetailRows = Boolean(nextPivot || sourceReport?.pivot) && !reportOverride && Boolean(sourceReport) && sourceReportMatchesEffectiveReportId && (!Array.isArray(sourceReport?.rows) || sourceReport.rows.length === 0) && pivotTableDataRefreshQuery.status !== "error";
70719
+ const tableLoading = initialLoadInProgress || pendingPivotRefresh || awaitingPivotDetailRows || tablePageFetching && pagination.pageIndex > 0 || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70469
70720
  const loading = chartLoading || tableLoading;
70721
+ const lastUseReportLoadingLogRef = (0, import_react63.useRef)("");
70722
+ (0, import_react63.useEffect)(() => {
70723
+ const snapshot = {
70724
+ reportId: effectiveReportId,
70725
+ chartLoading,
70726
+ tableLoading,
70727
+ loading,
70728
+ initialLoadInProgress,
70729
+ initialLoad: {
70730
+ status: initialLoadQuery.status,
70731
+ fetchStatus: initialLoadQuery.fetchStatus,
70732
+ isPending: initialLoadQuery.isPending,
70733
+ isFetching: initialLoadQuery.isFetching,
70734
+ hasData: initialLoadQuery.data !== void 0,
70735
+ dataUpdatedAt: initialLoadQuery.dataUpdatedAt,
70736
+ staleTime: 0
70737
+ },
70738
+ pendingPivotRefresh,
70739
+ pivotRefresh: {
70740
+ enabled: pivotRefreshQueryEnabled,
70741
+ isFetching: pivotRefreshQuery.isFetching
70742
+ },
70743
+ tableRefresh: {
70744
+ enabled: tableRefreshQueryEnabled,
70745
+ isFetching: tableRefreshQuery.isFetching
70746
+ },
70747
+ pivotTableData: {
70748
+ enabled: pivotTableDataRefreshQueryEnabled,
70749
+ isFetching: pivotTableDataRefreshQuery.isFetching
70750
+ },
70751
+ tablePage: {
70752
+ enabled: tablePageQueryEnabled,
70753
+ isFetching: tablePageQuery.isFetching
70754
+ },
70755
+ uniqueValues: {
70756
+ enabled: filterUniqueValuesEnabled,
70757
+ isFetching: filterUniqueValuesQuery.isFetching,
70758
+ isPending: filterUniqueValuesQuery.isPending
70759
+ },
70760
+ whyChartLoading: {
70761
+ noClient: !client,
70762
+ initialPending: initialLoadQuery.isPending,
70763
+ initialFetching: initialLoadQuery.isFetching,
70764
+ pendingPivotRefresh,
70765
+ pivotRefreshFetching: Boolean(nextPivot) && pivotRefreshQuery.isFetching,
70766
+ tableRefreshFetching: !nextPivot && tableRefreshQuery.isFetching
70767
+ }
70768
+ };
70769
+ const serialized = JSON.stringify(snapshot);
70770
+ if (serialized === lastUseReportLoadingLogRef.current) return;
70771
+ lastUseReportLoadingLogRef.current = serialized;
70772
+ profileDashboard("use-report-loading", snapshot);
70773
+ }, [
70774
+ client,
70775
+ chartLoading,
70776
+ effectiveReportId,
70777
+ filterUniqueValuesEnabled,
70778
+ filterUniqueValuesQuery.fetchStatus,
70779
+ filterUniqueValuesQuery.isFetching,
70780
+ filterUniqueValuesQuery.isPending,
70781
+ initialLoadInProgress,
70782
+ initialLoadQuery.data,
70783
+ initialLoadQuery.dataUpdatedAt,
70784
+ initialLoadQuery.fetchStatus,
70785
+ initialLoadQuery.isFetching,
70786
+ initialLoadQuery.isPending,
70787
+ initialLoadQuery.status,
70788
+ loading,
70789
+ nextPivot,
70790
+ pendingPivotRefresh,
70791
+ pivotRefreshQuery.isFetching,
70792
+ pivotRefreshQueryEnabled,
70793
+ pivotTableDataRefreshQuery.isFetching,
70794
+ pivotTableDataRefreshQueryEnabled,
70795
+ tableLoading,
70796
+ tablePageQuery.isFetching,
70797
+ tablePageQueryEnabled,
70798
+ tableRefreshQuery.isFetching,
70799
+ tableRefreshQueryEnabled
70800
+ ]);
70470
70801
  const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
70471
70802
  const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
70472
70803
  return normalizedNextIds.map((columnId) => {
@@ -70506,7 +70837,7 @@ function useReport(reportIdArg, options = {}) {
70506
70837
  const option = columnOptionById.get(normalizedId);
70507
70838
  const pivotField = String(option?.field ?? normalizedId).trim();
70508
70839
  const pivotModel = chartAxesBaseChart.pivot;
70509
- const rowField = String(pivotModel?.rowField ?? "").trim();
70840
+ const rowField = pivotRowKey(chartAxesBaseChart);
70510
70841
  if (!pivotModel) return null;
70511
70842
  const isPivotRowColumn = Boolean(
70512
70843
  pivotField && rowField && pivotField === rowField