@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.js CHANGED
@@ -15180,7 +15180,7 @@ var init_dates = __esm({
15180
15180
  init_inMemoryPivotEngine();
15181
15181
  init_valueFormatter();
15182
15182
  DATE_BUCKET_AXIS_FORMATS = {
15183
- day: "MMM_dd_yyyy",
15183
+ day: "MMM_dd",
15184
15184
  week: "MMM_dd-MMM_dd",
15185
15185
  month: "MMM_yyyy",
15186
15186
  year: "yyyy"
@@ -17184,6 +17184,79 @@ var init_paginationProcessing = __esm({
17184
17184
  }
17185
17185
  });
17186
17186
 
17187
+ // src/utils/dashboardProfiler.ts
17188
+ function profilingEnabled() {
17189
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE === "true") {
17190
+ return true;
17191
+ }
17192
+ if (typeof window === "undefined") return false;
17193
+ return Boolean(window.__QUILL_DASHBOARD_PROFILE__);
17194
+ }
17195
+ function profileStore() {
17196
+ if (typeof window !== "undefined") {
17197
+ const profileWindow = window;
17198
+ profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
17199
+ return profileWindow.__QUILL_DASHBOARD_TRACE__;
17200
+ }
17201
+ const globalStore = globalThis;
17202
+ globalStore.__QUILL_DASHBOARD_TRACE__ ??= [];
17203
+ return globalStore.__QUILL_DASHBOARD_TRACE__;
17204
+ }
17205
+ function queryKeyFamily(queryKey) {
17206
+ const head = String(queryKey[0] ?? "");
17207
+ const next = String(queryKey[1] ?? "");
17208
+ if (head === "quill" && next === "dashboard-report") {
17209
+ return "quill/dashboard-report";
17210
+ }
17211
+ if (head === "useReport") {
17212
+ return `useReport/${next || "unknown"}`;
17213
+ }
17214
+ return head || "other";
17215
+ }
17216
+ function summarizeEngineRequest(input) {
17217
+ const metadata = input.metadata ?? {};
17218
+ return {
17219
+ task: input.task ?? null,
17220
+ shareRequest: Boolean(input.shareRequest),
17221
+ reuseExisting: input.reuseExisting ?? null,
17222
+ settled: input.settled ?? null,
17223
+ reportId: metadata.reportId ?? null,
17224
+ metadataKeys: Object.keys(metadata).sort(),
17225
+ dashboardName: metadata.dashboardName ?? null,
17226
+ dashboardItemId: metadata.dashboardItemId ?? null,
17227
+ useNewNodeSql: metadata.useNewNodeSql ?? null,
17228
+ dateBucket: metadata.dateBucket ?? null,
17229
+ hasPivot: Boolean(metadata.pivot),
17230
+ hasReportBuilderState: Boolean(metadata.reportBuilderState),
17231
+ additionalProcessing: metadata.additionalProcessing ?? null,
17232
+ filterCount: Array.isArray(metadata.filters) ? metadata.filters.length : null
17233
+ };
17234
+ }
17235
+ function profileDashboard(event, data) {
17236
+ if (!profilingEnabled()) return;
17237
+ const entry = {
17238
+ at: Math.round(performance.now() * 10) / 10,
17239
+ event,
17240
+ data
17241
+ };
17242
+ profileStore().push(entry);
17243
+ if (typeof window !== "undefined") {
17244
+ const profileWindow = window;
17245
+ profileWindow.__QUILL_DASHBOARD_PROFILE__ = true;
17246
+ profileWindow.__QUILL_DUMP_DASHBOARD_PROFILE__ = () => profileWindow.__QUILL_DASHBOARD_TRACE__ ?? [];
17247
+ }
17248
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE_CONSOLE === "true" && CONSOLE_EVENT_PATTERN.test(event)) {
17249
+ console.log(`[quill-profile] ${event}`, data ?? {});
17250
+ }
17251
+ }
17252
+ var CONSOLE_EVENT_PATTERN;
17253
+ var init_dashboardProfiler = __esm({
17254
+ "src/utils/dashboardProfiler.ts"() {
17255
+ "use strict";
17256
+ CONSOLE_EVENT_PATTERN = /cache|initial-load|use-report-loading|network|unique-values|table-refresh|pivot|shared-request|engine-fetch|generate-pivot/;
17257
+ }
17258
+ });
17259
+
17187
17260
  // src/utils/pivotConstructor.ts
17188
17261
  function normalizeLegacyPivotSortFieldValue(sortField) {
17189
17262
  if (sortField === void 0) {
@@ -17296,6 +17369,22 @@ async function generatePivotWithSQL({
17296
17369
  rowLimit: pivot.rowLimit,
17297
17370
  dateBucket: resolvedDateBucket
17298
17371
  };
17372
+ profileDashboard(
17373
+ "generate-pivot-sql",
17374
+ summarizeEngineRequest({
17375
+ task: "pivot-template",
17376
+ shareRequest: false,
17377
+ metadata: {
17378
+ reportId: report?.id,
17379
+ dashboardName,
17380
+ dateBucket: resolvedDateBucket,
17381
+ additionalProcessing,
17382
+ pivot: pivotConfig,
17383
+ reportBuilderState,
17384
+ filters: dashboardFilters
17385
+ }
17386
+ })
17387
+ );
17299
17388
  const resp = await quillFetch({
17300
17389
  client,
17301
17390
  task: "pivot-template",
@@ -17668,6 +17757,7 @@ var init_pivotConstructor = __esm({
17668
17757
  init_columnType();
17669
17758
  init_dataFetcher();
17670
17759
  init_dataProcessing();
17760
+ init_dashboardProfiler();
17671
17761
  init_dates();
17672
17762
  init_textProcessing();
17673
17763
  init_valueFormatter();
@@ -20090,6 +20180,20 @@ async function getOrFetchSharedRequest({
20090
20180
  }) {
20091
20181
  if (signal?.aborted) throw createAbortError(signal);
20092
20182
  let entry = entries.get(key);
20183
+ const reuseExisting = Boolean(entry);
20184
+ profileDashboard("shared-request", {
20185
+ ...summarizeEngineRequest({
20186
+ task: void 0,
20187
+ shareRequest: true,
20188
+ reuseExisting,
20189
+ settled: entry?.settled,
20190
+ metadata: { reportId }
20191
+ }),
20192
+ reportId: reportId ?? null,
20193
+ reuseExisting,
20194
+ settled: entry?.settled ?? false,
20195
+ keyLength: key.length
20196
+ });
20093
20197
  if (!entry) {
20094
20198
  const controller = new AbortController();
20095
20199
  entry = {
@@ -20165,6 +20269,7 @@ var ORPHAN_GRACE_MS, COMPLETED_TTL_MS, entries;
20165
20269
  var init_reportRequestPool = __esm({
20166
20270
  "src/utils/reportRequestPool.ts"() {
20167
20271
  "use strict";
20272
+ init_dashboardProfiler();
20168
20273
  ORPHAN_GRACE_MS = 100;
20169
20274
  COMPLETED_TTL_MS = 15e3;
20170
20275
  entries = /* @__PURE__ */ new Map();
@@ -20727,6 +20832,7 @@ var init_dataFetcher = __esm({
20727
20832
  init_dates();
20728
20833
  init_changelogNotify();
20729
20834
  init_reportRequestPool();
20835
+ init_dashboardProfiler();
20730
20836
  quillFetch = async ({
20731
20837
  client,
20732
20838
  task,
@@ -20787,6 +20893,14 @@ var init_dataFetcher = __esm({
20787
20893
  return { error: "Failed to fetch data" };
20788
20894
  }
20789
20895
  };
20896
+ profileDashboard(
20897
+ "engine-fetch",
20898
+ summarizeEngineRequest({
20899
+ task,
20900
+ shareRequest,
20901
+ metadata
20902
+ })
20903
+ );
20790
20904
  if (!shareRequest) {
20791
20905
  return execute(abortSignal);
20792
20906
  }
@@ -21358,22 +21472,7 @@ init_dates();
21358
21472
  init_pivotConstructor();
21359
21473
  init_columnProcessing();
21360
21474
  init_paginationProcessing();
21361
-
21362
- // src/utils/dashboardProfiler.ts
21363
- function profileDashboard(event, data) {
21364
- if (typeof window === "undefined") return;
21365
- const profileWindow = window;
21366
- if (!profileWindow.__QUILL_DASHBOARD_PROFILE__) return;
21367
- const entry = {
21368
- at: Math.round(performance.now() * 10) / 10,
21369
- event,
21370
- data
21371
- };
21372
- profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
21373
- profileWindow.__QUILL_DASHBOARD_TRACE__.push(entry);
21374
- }
21375
-
21376
- // src/utils/dashboard.ts
21475
+ init_dashboardProfiler();
21377
21476
  var defaultDashboardItem = {
21378
21477
  id: "",
21379
21478
  name: "",
@@ -22787,6 +22886,7 @@ init_tableProcessing();
22787
22886
  init_textProcessing();
22788
22887
  init_valueFormatter();
22789
22888
  init_astFilterProcessing();
22889
+ init_dashboardProfiler();
22790
22890
  init_reportBuilder();
22791
22891
  init_astProcessing();
22792
22892
 
@@ -26583,6 +26683,7 @@ function normalizePSTRanges(start, end) {
26583
26683
 
26584
26684
  // src/Context.tsx
26585
26685
  init_changelogNotify();
26686
+ init_dashboardProfiler();
26586
26687
 
26587
26688
  // src/reportStore.ts
26588
26689
  import { createContext, useContext, useSyncExternalStore } from "react";
@@ -32364,7 +32465,7 @@ function QuillTable({
32364
32465
  setSortColumn(sort?.field || "");
32365
32466
  setSortDirection(sort?.direction || "desc");
32366
32467
  }, [sort]);
32367
- const holdFullPageLoader = rows?.length === 0 && isLoading;
32468
+ const holdFullPageLoader = Boolean(isLoading);
32368
32469
  const pageCountUnknown = manualPagination && pageCount === -1;
32369
32470
  const { activeRows, maxPage } = useMemo4(() => {
32370
32471
  const start = currentPage * rowsPerPage;
@@ -37291,6 +37392,7 @@ function getDashboardReportProcessing(report, serverPagination) {
37291
37392
  }
37292
37393
 
37293
37394
  // src/hooks/useDashboard.ts
37395
+ init_dashboardProfiler();
37294
37396
  var DEFAULT_DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
37295
37397
  var useDashboardConfigInternal = (dashboardName) => {
37296
37398
  const { dashboardConfig, isLoading: dashboardsLoading } = useContext13(
@@ -38401,6 +38503,14 @@ var useDashboard = (dashboardName, config) => {
38401
38503
  additionalProcessing
38402
38504
  );
38403
38505
  const usePivotTask = !cacheEnabled && !!reportInfo.pivot;
38506
+ profileDashboard("dashboard-report-cache-path", {
38507
+ reportId,
38508
+ cacheEnabled,
38509
+ cacheCabCacheable: cacheCab.isCacheable(reportId),
38510
+ usePivotTask,
38511
+ forceCacheToRefresh,
38512
+ hasPivot: Boolean(reportInfo.pivot)
38513
+ });
38404
38514
  const allFilters = dashboardFilters2.concat(customFilters).concat(customReportFiltersArray);
38405
38515
  const applyInMemoryPivotIfNeeded = (report2) => {
38406
38516
  const pivotToApply = reportInfo.pivot ?? report2.pivot;
@@ -38634,7 +38744,9 @@ var useDashboard = (dashboardName, config) => {
38634
38744
  pivotColumns: pivotData.columns,
38635
38745
  pivotRowCount: pivotData.rowCount,
38636
38746
  pivotQuery: pivotData.pivotQuery,
38637
- comparisonPivotQuery: pivotData.comparisonPivotQuery
38747
+ comparisonPivotQuery: pivotData.comparisonPivotQuery,
38748
+ pivotResultRowField: pivotData.rowField,
38749
+ pivotResultSourceRowField: reportInfo.pivot?.rowField
38638
38750
  },
38639
38751
  error: void 0
38640
38752
  };
@@ -38664,6 +38776,26 @@ var useDashboard = (dashboardName, config) => {
38664
38776
  shareRequest: !forceCacheToRefresh
38665
38777
  });
38666
38778
  };
38779
+ const existingState = queryClient.getQueryState(queryKey);
38780
+ const existingData = queryClient.getQueryData(queryKey);
38781
+ const dataUpdatedAt = existingState?.dataUpdatedAt ?? 0;
38782
+ const ageMs = dataUpdatedAt ? Date.now() - dataUpdatedAt : null;
38783
+ const isStale = dataUpdatedAt === 0 || Date.now() - dataUpdatedAt >= reportStaleTimeMs;
38784
+ profileDashboard("dashboard-report-tanstack-cache", {
38785
+ reportId,
38786
+ keyFamily: "quill/dashboard-report",
38787
+ cacheEnabled,
38788
+ usePivotTask,
38789
+ forceCacheToRefresh,
38790
+ staleTimeMs: reportStaleTimeMs,
38791
+ status: existingState?.status ?? "missing",
38792
+ fetchStatus: existingState?.fetchStatus ?? "idle",
38793
+ hasData: existingData !== void 0,
38794
+ dataUpdatedAt,
38795
+ ageMs,
38796
+ isStale,
38797
+ willReuseTanstack: !forceCacheToRefresh && existingData !== void 0 && !isStale
38798
+ });
38667
38799
  const result = forceCacheToRefresh ? await fetchDashboardReport() : await queryClient.fetchQuery({
38668
38800
  queryKey,
38669
38801
  queryFn: fetchDashboardReport,
@@ -39066,6 +39198,7 @@ var useDashboardReport = (reportId, config) => {
39066
39198
  };
39067
39199
 
39068
39200
  // src/components/Dashboard/DataLoader.tsx
39201
+ init_dashboardProfiler();
39069
39202
  import { Fragment as Fragment5, jsx as jsx46 } from "react/jsx-runtime";
39070
39203
  var constructReportFromItem = (item) => {
39071
39204
  return {
@@ -41481,6 +41614,7 @@ function QuillTableDashboardComponent({
41481
41614
 
41482
41615
  // src/Chart.tsx
41483
41616
  init_valueFormatter();
41617
+ init_dashboardProfiler();
41484
41618
  import { Fragment as Fragment6, jsx as jsx50, jsxs as jsxs38 } from "react/jsx-runtime";
41485
41619
  function Chart({
41486
41620
  colors,
@@ -45472,6 +45606,7 @@ init_Filter();
45472
45606
 
45473
45607
  // src/StaticChart.tsx
45474
45608
  import { useEffect as useEffect20, useMemo as useMemo21 } from "react";
45609
+ init_dashboardProfiler();
45475
45610
  import { jsx as jsx60 } from "react/jsx-runtime";
45476
45611
  var CHART_TYPE_STYLES = {
45477
45612
  metric: { height: "100px", width: "200px" },
@@ -62120,6 +62255,24 @@ import {
62120
62255
  eachWeekOfInterval as eachWeekOfInterval2,
62121
62256
  eachYearOfInterval as eachYearOfInterval2
62122
62257
  } from "date-fns";
62258
+ var PIVOT_DATE_BUCKETS = /* @__PURE__ */ new Set([
62259
+ "day",
62260
+ "week",
62261
+ "month",
62262
+ "year"
62263
+ ]);
62264
+ function inBucketDateBucketForField(rules, field) {
62265
+ for (const entry of rules) {
62266
+ if (!entry || typeof entry !== "object") continue;
62267
+ const rule = entry;
62268
+ if (rule.operator !== "inBucket" || rule.field !== field) continue;
62269
+ const bucket = rule.value && typeof rule.value === "object" && !Array.isArray(rule.value) ? rule.value.bucket : void 0;
62270
+ if (typeof bucket === "string" && PIVOT_DATE_BUCKETS.has(bucket)) {
62271
+ return bucket;
62272
+ }
62273
+ }
62274
+ return void 0;
62275
+ }
62123
62276
  function buildPivotDateBucketStarts(range, bucket) {
62124
62277
  const min2 = new Date(range.min);
62125
62278
  const max2 = new Date(range.max);
@@ -62439,6 +62592,7 @@ function resolveReportFromCacheCab({
62439
62592
  }
62440
62593
 
62441
62594
  // src/hooks/useForm.tsx
62595
+ init_dashboardProfiler();
62442
62596
  init_reportRequestPool();
62443
62597
 
62444
62598
  // src/hooks/useForm.queries.ts
@@ -62484,6 +62638,15 @@ function createUseFormInitialLoadQueryKey(input) {
62484
62638
  input.additionalSchemaHash
62485
62639
  ];
62486
62640
  }
62641
+ var DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
62642
+ function findCachedDashboardReportQuery(queryClient, reportId) {
62643
+ const id = String(reportId ?? "").trim();
62644
+ if (!id) return void 0;
62645
+ return queryClient.getQueryCache().findAll({ queryKey: ["quill", "dashboard-report", id] }).find((query) => {
62646
+ const data = query.state.data;
62647
+ return Boolean(data?.report) && !data?.error;
62648
+ });
62649
+ }
62487
62650
  function shouldBootstrapUseFormInitialLoad(input) {
62488
62651
  return !input.hasInitialReportBuilderState && input.previouslyBootstrappedIdentity !== input.currentIdentity;
62489
62652
  }
@@ -63466,6 +63629,11 @@ function getPivotTableSlotReportColumn(reportColumns, aggregations, rowField, pi
63466
63629
  }
63467
63630
  return cols[aggIndex + 1];
63468
63631
  }
63632
+ function pivotRowKey(chart) {
63633
+ return String(
63634
+ chart?.pivotResultRowField ?? chart?.pivot?.rowField ?? ""
63635
+ ).trim();
63636
+ }
63469
63637
  function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63470
63638
  if (!chart?.pivot) return false;
63471
63639
  if (String(chart.chartType ?? "").toLowerCase() !== "table") return false;
@@ -63474,7 +63642,8 @@ function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63474
63642
  }
63475
63643
  const rowField = String(chart.pivot.rowField ?? "").trim();
63476
63644
  const xf = String(xAxisField ?? "").trim();
63477
- if (!rowField || xf !== rowField) return false;
63645
+ const rowKey = pivotRowKey(chart);
63646
+ if (!rowField || xf !== rowField && xf !== rowKey) return false;
63478
63647
  return isDateType(String(chart.pivot.rowFieldType ?? ""));
63479
63648
  }
63480
63649
  var RESOLVABLE_X_AXIS_DATE_BUCKETS = /* @__PURE__ */ new Set([
@@ -63488,22 +63657,24 @@ function resolvePivotDateBucketXAxisFormat(chart, xAxisField) {
63488
63657
  const dateBucket = String(chart?.pivot?.dateBucket ?? "").trim().toLowerCase();
63489
63658
  if (!RESOLVABLE_X_AXIS_DATE_BUCKETS.has(dateBucket)) return null;
63490
63659
  const rowField = String(chart?.pivot?.rowField ?? "").trim();
63491
- if (!rowField || String(xAxisField ?? "").trim() !== rowField) return null;
63660
+ const xf = String(xAxisField ?? "").trim();
63661
+ const rowKey = pivotRowKey(chart);
63662
+ if (!rowField || xf !== rowField && xf !== rowKey) return null;
63492
63663
  if (!isDateType(String(chart?.pivot?.rowFieldType ?? ""))) return null;
63493
63664
  return getDateFormatFromBucket(dateBucket);
63494
63665
  }
63495
63666
  function chartDetailRowsMissingPivotRowBucket(chart) {
63496
63667
  if (!chart?.pivot) return false;
63497
- const rowField = String(chart.pivot.rowField ?? "").trim();
63498
- if (!rowField) return false;
63668
+ const rowKey = pivotRowKey(chart);
63669
+ if (!rowKey) return false;
63499
63670
  const rows = chart.rows;
63500
63671
  if (!Array.isArray(rows) || rows.length === 0) return false;
63501
63672
  const first = rows.find(
63502
63673
  (r) => r && typeof r === "object" && Object.keys(r).length > 0
63503
63674
  );
63504
63675
  if (!first) return false;
63505
- if (!Object.prototype.hasOwnProperty.call(first, rowField)) return true;
63506
- const v = first[rowField];
63676
+ if (!Object.prototype.hasOwnProperty.call(first, rowKey)) return true;
63677
+ const v = first[rowKey];
63507
63678
  return v === void 0 || v === null;
63508
63679
  }
63509
63680
  function shouldUsePivotRowFieldAsXAxis(chartType, pivotRowField, rowColumnFormat) {
@@ -63539,7 +63710,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63539
63710
  } : chart;
63540
63711
  if (!config) return config;
63541
63712
  if (!config.pivot) return config;
63542
- const pivotRowFieldEarly = String(config.pivot?.rowField ?? "").trim();
63713
+ const pivotRowFieldEarly = pivotRowKey(config);
63543
63714
  const rowColumn = (config.pivotColumns ?? config.columns ?? []).find(
63544
63715
  (col) => String(col.field ?? "").trim() === pivotRowFieldEarly
63545
63716
  );
@@ -63574,7 +63745,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63574
63745
  return keys;
63575
63746
  })() : [];
63576
63747
  const pivotValueFields = pivotRowFields.filter(
63577
- (field) => field !== withResolvedXAxis.pivot?.rowField
63748
+ (field) => field !== pivotRowKey(withResolvedXAxis) && field !== withResolvedXAxis.pivot?.rowField
63578
63749
  );
63579
63750
  const isAggregationOnlyPivot = !String(withResolvedXAxis.pivot?.rowField ?? "").trim() && !String(withResolvedXAxis.pivot?.columnField ?? "").trim();
63580
63751
  const yAxisFormatByField = new Map(
@@ -63695,7 +63866,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63695
63866
  const normalizedPivotColumns = pivotColumnFields.length > 0 ? pivotColumnFields.map((field) => {
63696
63867
  const knownColumn = knownColumnsByField.get(field);
63697
63868
  const yAxis = yAxisFields.find((axis) => axis.field === field);
63698
- const format9 = yAxis?.format ?? knownColumn?.format ?? (field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63869
+ const format9 = yAxis?.format ?? knownColumn?.format ?? (field === pivotRowKey(withResolvedXAxis) || field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63699
63870
  return {
63700
63871
  field,
63701
63872
  label: yAxis?.label ?? knownColumn?.label ?? field,
@@ -63708,7 +63879,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63708
63879
  const slotCol = getPivotTableSlotReportColumn(
63709
63880
  pivotTableSlotColumns,
63710
63881
  aggregations,
63711
- withResolvedXAxis.pivot?.rowField,
63882
+ pivotRowKey(withResolvedXAxis) || withResolvedXAxis.pivot?.rowField,
63712
63883
  col.field
63713
63884
  );
63714
63885
  if (!slotCol) return col;
@@ -63730,9 +63901,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63730
63901
  const normalizedXAxisFormat = normalizedXAxisField === withResolvedXAxis.xAxisField ? withResolvedXAxis.xAxisFormat : yAxisFields.find((axis) => axis.field === normalizedXAxisField)?.format ?? pivotTableDisplayColumns.find(
63731
63902
  (column) => column.field === normalizedXAxisField
63732
63903
  )?.format ?? withResolvedXAxis.xAxisFormat;
63733
- const pivotDisplayRowField = String(
63734
- withResolvedXAxis.pivot?.rowField ?? ""
63735
- ).trim();
63904
+ const pivotDisplayRowField = pivotRowKey(withResolvedXAxis);
63736
63905
  const pivotDisplayRowFieldType = String(
63737
63906
  withResolvedXAxis.pivot?.rowFieldType ?? ""
63738
63907
  ).trim();
@@ -66696,19 +66865,30 @@ function useReport(reportIdArg, options = {}) {
66696
66865
  )
66697
66866
  });
66698
66867
  const diagnostics = globalThis.__QUILL_CACHECAB_DIAGNOSTICS__;
66868
+ const durationMs = performance.now() - startedAt;
66869
+ const outcome = resolution.resolved ? "hit" : "fallback";
66699
66870
  if (Array.isArray(diagnostics)) {
66700
66871
  diagnostics.push({
66701
66872
  reportId: effectiveReportId,
66702
66873
  operation,
66703
- outcome: resolution.resolved ? "hit" : "fallback",
66874
+ outcome,
66704
66875
  reason: resolution.resolved ? "complete" : resolution.reason,
66705
66876
  details: resolution.resolved ? void 0 : resolution.details,
66706
66877
  snapshotReason: snapshot?.reason ?? "cache_miss",
66707
66878
  forcedIncompleteSnapshot: Boolean(snapshot) && !snapshot?.complete && forceIncompleteCacheCabForParity,
66708
66879
  rowCount: snapshot?.rowCount ?? 0,
66709
- durationMs: performance.now() - startedAt
66880
+ durationMs
66710
66881
  });
66711
66882
  }
66883
+ profileDashboard("use-report-cachecab", {
66884
+ reportId: effectiveReportId,
66885
+ operation,
66886
+ outcome,
66887
+ reason: resolution.resolved ? "complete" : resolution.reason,
66888
+ snapshotReason: snapshot?.reason ?? "cache_miss",
66889
+ rowCount: snapshot?.rowCount ?? 0,
66890
+ durationMs: Math.round(durationMs * 10) / 10
66891
+ });
66712
66892
  return resolution.resolved ? resolution.report : null;
66713
66893
  },
66714
66894
  [
@@ -67282,9 +67462,15 @@ function useReport(reportIdArg, options = {}) {
67282
67462
  if (alias) localValues[alias] = values;
67283
67463
  }
67284
67464
  if (hasEveryColumn) {
67465
+ profileDashboard("use-report-unique-values-cachecab-hit", {
67466
+ reportId: effectiveReportId
67467
+ });
67285
67468
  return { uniqueValuesByColumn: localValues };
67286
67469
  }
67287
67470
  }
67471
+ profileDashboard("use-report-unique-values-network", {
67472
+ reportId: effectiveReportId
67473
+ });
67288
67474
  const tablesForUniqueValues = filterUniqueValuesRequest.reportBuilderState?.tables?.map(
67289
67475
  (table2) => String(table2?.name ?? "").trim()
67290
67476
  ) ?? filterUniqueValuesRequest.stringColumnsByTable.map((column) => String(column.table ?? "").trim()).filter(Boolean);
@@ -67803,6 +67989,29 @@ function useReport(reportIdArg, options = {}) {
67803
67989
  const initialLoadQuery = useQuery({
67804
67990
  queryKey: initialLoadQueryKey,
67805
67991
  queryFn: createUseFormQueryFn(async (signal) => {
67992
+ const tanstackState = queryClient.getQueryState(initialLoadQueryKey);
67993
+ const dashboardReportQueries = queryClient.getQueryCache().getAll().filter(
67994
+ (query) => queryKeyFamily(query.queryKey) === "quill/dashboard-report"
67995
+ );
67996
+ const matchingDashboardReport = dashboardReportQueries.find(
67997
+ (query) => String(query.queryKey[2] ?? "") === String(effectiveReportId)
67998
+ );
67999
+ profileDashboard("use-report-initial-load-queryfn", {
68000
+ reportId: effectiveReportId,
68001
+ reason: "TanStack ran this queryFn, so useReport/initial-load had no fresh cached data",
68002
+ keyFamily: "useReport/initial-load",
68003
+ status: tanstackState?.status ?? "missing",
68004
+ hasData: tanstackState?.data !== void 0,
68005
+ dataUpdatedAt: tanstackState?.dataUpdatedAt ?? 0,
68006
+ staleTime: 0,
68007
+ dashboardReportQueryCount: dashboardReportQueries.length,
68008
+ matchingDashboardReport: matchingDashboardReport ? {
68009
+ hasData: matchingDashboardReport.state.data !== void 0,
68010
+ status: matchingDashboardReport.state.status,
68011
+ staleTime: matchingDashboardReport.options?.staleTime ?? 0,
68012
+ unusedByUseReport: true
68013
+ } : null
68014
+ });
67806
68015
  let cachedReportBuilderState = initialReportBuilderStateForLoad ?? void 0;
67807
68016
  if (!cachedReportBuilderState) {
67808
68017
  const snapshot = await cacheCab.getReportSnapshot(
@@ -67827,6 +68036,9 @@ function useReport(reportIdArg, options = {}) {
67827
68036
  operation: "initial"
67828
68037
  });
67829
68038
  if (cachedReport) {
68039
+ profileDashboard("use-report-initial-load-served-from-cachecab", {
68040
+ reportId: effectiveReportId
68041
+ });
67830
68042
  return { report: cachedReport };
67831
68043
  }
67832
68044
  const allowReportTaskBootstrap = shouldBootstrapUseFormInitialLoad({
@@ -67841,6 +68053,12 @@ function useReport(reportIdArg, options = {}) {
67841
68053
  const formFiltersBelongToLoadTarget = Boolean(loadTargetId) && sourceReportIdentity === loadTargetId;
67842
68054
  const rulesForLoad = useInMemoryEngines || !formFiltersBelongToLoadTarget ? EMPTY_QUERY_FILTERS : queryFilters;
67843
68055
  const shareInitialRequest = sharedInitialRequestUsedForReportIdRef.current !== effectiveReportId;
68056
+ profileDashboard("use-report-initial-load-network", {
68057
+ reportId: effectiveReportId,
68058
+ path: "loadReportForUseForm",
68059
+ hasCachedReportBuilderState: Boolean(cachedReportBuilderState)
68060
+ });
68061
+ const networkStartedAt = performance.now();
67844
68062
  const loadResult = await loadReportForUseForm({
67845
68063
  reportId: effectiveReportId,
67846
68064
  initialReportBuilderState: initialReportBuilderStateForLoad,
@@ -67860,6 +68078,12 @@ function useReport(reportIdArg, options = {}) {
67860
68078
  rowsOnly: isCreatedReportBootstrapLoad,
67861
68079
  abortSignal: signal
67862
68080
  });
68081
+ profileDashboard("use-report-initial-load-network-done", {
68082
+ reportId: effectiveReportId,
68083
+ durationMs: Math.round(performance.now() - networkStartedAt),
68084
+ hasReport: Boolean(loadResult.report),
68085
+ error: loadResult.error ?? null
68086
+ });
67863
68087
  if (loadResult.report && !loadResult.error) {
67864
68088
  if (allowReportTaskBootstrap) {
67865
68089
  bootstrapReportTaskUsedForInitialLoadRef.current = initialLoadIdentityHash;
@@ -67871,7 +68095,17 @@ function useReport(reportIdArg, options = {}) {
67871
68095
  return loadResult;
67872
68096
  }),
67873
68097
  enabled: Boolean(effectiveReportId) && Boolean(client) && !reportOverride,
67874
- retry: false
68098
+ retry: false,
68099
+ initialData: () => {
68100
+ const cached = findCachedDashboardReportQuery(
68101
+ queryClient,
68102
+ effectiveReportId
68103
+ );
68104
+ const data = cached?.state.data;
68105
+ return data?.report ? { report: data.report, error: data.error } : void 0;
68106
+ },
68107
+ initialDataUpdatedAt: () => findCachedDashboardReportQuery(queryClient, effectiveReportId)?.state.dataUpdatedAt,
68108
+ staleTime: DASHBOARD_REPORT_STALE_TIME_MS
67875
68109
  });
67876
68110
  const reportNameQueryReportId = String(effectiveReportId ?? "").trim();
67877
68111
  const reportNameQuery = useQuery({
@@ -67922,15 +68156,6 @@ function useReport(reportIdArg, options = {}) {
67922
68156
  const shouldPromoteColumnToRowFromPendingFlag = pendingPromoteColumnToRow && !String(prev.groupRowsBy ?? "").trim();
67923
68157
  const sourceReportBuilderTables = (sourceReport.reportBuilderState?.tables ?? []).filter((table2) => Boolean(String(table2?.name ?? "").trim()));
67924
68158
  const sourceReportBuilderTableNames = sourceReportBuilderTables.map((table2) => table2.name).filter((name2) => Boolean(name2));
67925
- const sourceQueryColumns = normalizeReportBuilderColumns(
67926
- sourceReport.reportBuilderState?.columns ?? (sourceReport.columns ?? []).map((column) => ({
67927
- field: column.field,
67928
- table: column.table ?? resolveColumnTableFromReportMetadata(
67929
- sourceReport,
67930
- column.field
67931
- )
67932
- }))
67933
- );
67934
68159
  const nextQueryFilters = prev.queryFilters.rules.length ? prev.queryFilters : rulesFromReport(sourceReport);
67935
68160
  const pivotAggregationsFromSource = Array.isArray(sourceReport.pivot?.aggregations) ? sourceReport.pivot.aggregations : sourceReport.pivot?.aggregationType ? [
67936
68161
  {
@@ -67997,6 +68222,9 @@ function useReport(reportIdArg, options = {}) {
67997
68222
  tables: tableScopeForDisplayColumns,
67998
68223
  schemaTables: schemaForReportBuilderState
67999
68224
  });
68225
+ const sourceQueryColumns = normalizeReportBuilderColumns(
68226
+ sourceReport.reportBuilderState?.columns?.length ? sourceReport.reportBuilderState.columns : sourceDisplayColumnsFromSchema
68227
+ );
68000
68228
  const savedDisplayColumns = normalizeReportBuilderColumns(
68001
68229
  (sourceReport.columns ?? []).map((column) => ({
68002
68230
  ...column,
@@ -68510,13 +68738,12 @@ function useReport(reportIdArg, options = {}) {
68510
68738
  tables: effectiveReportBuilderState.tables,
68511
68739
  schemaTables: schemaForReportBuilderState
68512
68740
  });
68513
- const columnsToFetch = allColumnsBySelectedTable.length > 0 ? allColumnsBySelectedTable : effectiveReportBuilderState.columns;
68514
- if (columnsToFetch.length === 0) {
68741
+ if (allColumnsBySelectedTable.length === 0) {
68515
68742
  return void 0;
68516
68743
  }
68517
68744
  return {
68518
68745
  ...effectiveReportBuilderState,
68519
- columns: columnsToFetch,
68746
+ columns: allColumnsBySelectedTable,
68520
68747
  pivot: null,
68521
68748
  sort: [],
68522
68749
  limit: null
@@ -68559,6 +68786,29 @@ function useReport(reportIdArg, options = {}) {
68559
68786
  refreshDecision.shouldRefresh,
68560
68787
  queryFilters
68561
68788
  ]);
68789
+ const shouldSkipRedundantPivotTableDataQuery = useMemo33(() => {
68790
+ if (!sourceReport || !pivotState) {
68791
+ return false;
68792
+ }
68793
+ if (tableRefreshVersion !== 0 || pivotRefreshVersion !== 0) {
68794
+ return false;
68795
+ }
68796
+ if (!Array.isArray(sourceReport.rows) || sourceReport.rows.length === 0) {
68797
+ return false;
68798
+ }
68799
+ if (refreshDecision.shouldRefresh) {
68800
+ return false;
68801
+ }
68802
+ const sourceRules = sourceReport.reportBuilderState?.rules ?? EMPTY_QUERY_FILTERS;
68803
+ return stableSerializeForQueryKey(queryFilters) === stableSerializeForQueryKey(sourceRules);
68804
+ }, [
68805
+ sourceReport,
68806
+ pivotState,
68807
+ tableRefreshVersion,
68808
+ pivotRefreshVersion,
68809
+ refreshDecision.shouldRefresh,
68810
+ queryFilters
68811
+ ]);
68562
68812
  const shouldForceTableRefreshFromFilters = !useInMemoryEngines && !pivotState;
68563
68813
  const immediateTableRefreshInput = useMemo33(
68564
68814
  () => ({
@@ -68607,8 +68857,14 @@ function useReport(reportIdArg, options = {}) {
68607
68857
  operation: "table"
68608
68858
  });
68609
68859
  if (cachedReport) {
68860
+ profileDashboard("use-report-table-refresh-cachecab-hit", {
68861
+ reportId: effectiveReportId
68862
+ });
68610
68863
  return { report: cachedReport };
68611
68864
  }
68865
+ profileDashboard("use-report-table-refresh-network", {
68866
+ reportId: effectiveReportId
68867
+ });
68612
68868
  return loadViaReportBuilderState({
68613
68869
  reportId: effectiveReportId,
68614
68870
  reportBuilderState: tableRefreshInput.reportBuilderState,
@@ -69222,7 +69478,8 @@ function useReport(reportIdArg, options = {}) {
69222
69478
  sourceReport
69223
69479
  ]);
69224
69480
  const pivotRefreshQueryEnabled = !reportOverride && pendingPivotRefresh && !shouldSkipPivotRefreshForUnchangedPivot && Boolean(sourceReport) && Boolean(client) && Boolean(effectiveReportBuilderState) && Boolean(nextPivot) && sourceReportMatchesEffectiveReportId;
69225
- const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId;
69481
+ const initialLoadSettled = Boolean(reportOverride) || !effectiveReportId || Boolean(client) && !initialLoadQuery.isPending && !initialLoadQuery.isFetching;
69482
+ const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId && initialLoadSettled && !shouldSkipRedundantPivotTableDataQuery;
69226
69483
  const pivotRefreshQuery = useQuery({
69227
69484
  queryKey: createUseFormPivotRefreshQueryKey({
69228
69485
  reportId: effectiveReportId,
@@ -69336,7 +69593,7 @@ function useReport(reportIdArg, options = {}) {
69336
69593
  const paginationRangeStart = pagination.pageIndex * pagination.pageSize;
69337
69594
  const paginationRangeEnd = paginationRangeStart + pagination.pageSize;
69338
69595
  const pageWithinBaseWindow = paginationRangeEnd <= baseWindowRowsLength || trustedSourceRowCount !== void 0 && trustedSourceRowCount <= baseWindowRowsLength;
69339
- const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh;
69596
+ const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh && initialLoadSettled;
69340
69597
  const tablePageQuery = useQuery({
69341
69598
  queryKey: createUseFormTablePageQueryKey({
69342
69599
  reportId: effectiveReportId,
@@ -69508,21 +69765,17 @@ function useReport(reportIdArg, options = {}) {
69508
69765
  if (!sourceReport) return void 0;
69509
69766
  const rowsForChart = Array.isArray(sourceReport.rows) ? sourceReport.rows : [];
69510
69767
  const chartPivot = pendingPivotChangesDimensions ? sourceReport.pivot ?? null : nextPivot ?? (!chartPivotHydratedFromSourceRef.current ? sourceReport.pivot ?? null : null);
69511
- const chartPivotForDisplay = chartPivot && sourceReport.pivotResultRowField && sourceReport.pivotResultSourceRowField === chartPivot.rowField ? {
69512
- ...chartPivot,
69513
- rowField: sourceReport.pivotResultRowField
69514
- } : chartPivot;
69515
- const rowCountForChart = chartPivotForDisplay ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69768
+ const rowCountForChart = chartPivot ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69516
69769
  const referencedTablesForChart = effectiveReportBuilderState?.tables.map((table2) => table2.name).filter((name2) => Boolean(name2));
69517
69770
  const pivotRowsForChart = Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows : void 0;
69518
- const rowCountForChartResolved = chartPivotForDisplay ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69771
+ const rowCountForChartResolved = chartPivot ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69519
69772
  const chartDataPayload = {
69520
69773
  ...sourceReport,
69521
69774
  rows: rowsForChart,
69522
69775
  rowCount: rowCountForChartResolved,
69523
69776
  chartType: chartType ?? sourceReport.chartType,
69524
69777
  reportBuilderState: effectiveReportBuilderState,
69525
- pivot: chartPivotForDisplay,
69778
+ pivot: chartPivot,
69526
69779
  referencedTables: referencedTablesForChart && referencedTablesForChart.length > 0 ? referencedTablesForChart : sourceReport.referencedTables,
69527
69780
  pivotRows: pivotRowsForChart,
69528
69781
  pivotColumns: sourceReport.pivotColumns,
@@ -69623,7 +69876,7 @@ function useReport(reportIdArg, options = {}) {
69623
69876
  const xAxisOptions = useMemo33(() => {
69624
69877
  if (!chartAxesBaseChart) return chartAxisOptions;
69625
69878
  const pivot = chartAxesBaseChart.pivot;
69626
- const pivotRowField = String(pivot?.rowField ?? "").trim();
69879
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69627
69880
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69628
69881
  if (pivot && pivotRowField) {
69629
69882
  if (["metric", "gauge"].includes(chartType2)) {
@@ -69744,9 +69997,7 @@ function useReport(reportIdArg, options = {}) {
69744
69997
  const resolvedXAxisField = useMemo33(() => {
69745
69998
  if (!chartAxesBaseChart) return "";
69746
69999
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69747
- const pivotRowField = String(
69748
- chartAxesBaseChart.pivot?.rowField ?? ""
69749
- ).trim();
70000
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69750
70001
  if (pivotRowField) {
69751
70002
  const rowColumn = (chartAxesBaseChart.pivotColumns ?? chartAxesBaseChart.columns ?? []).find((col) => String(col.field ?? "").trim() === pivotRowField);
69752
70003
  if (shouldUsePivotRowFieldAsXAxis(
@@ -69882,11 +70133,11 @@ function useReport(reportIdArg, options = {}) {
69882
70133
  columns2 = mergePivotTableDisplayColumnLabelsFromYAxis({
69883
70134
  columns: columns2 ?? baseChart.columns,
69884
70135
  yAxisFields: resolvedYAxisFieldsForDisplay,
69885
- pivotRowField: String(baseChart.pivot.rowField ?? ""),
70136
+ pivotRowField: pivotRowKey(baseChart),
69886
70137
  xAxisLabel: resolvedXAxisLabel
69887
70138
  });
69888
70139
  } else {
69889
- const pivotRowField = String(baseChart.pivot.rowField ?? "").trim();
70140
+ const pivotRowField = pivotRowKey(baseChart);
69890
70141
  const pivotLabelByField = new Map(
69891
70142
  (baseChart.pivotColumns ?? []).map((column) => [
69892
70143
  String(column.field ?? "").trim(),
@@ -69934,8 +70185,11 @@ function useReport(reportIdArg, options = {}) {
69934
70185
  const rowField = String(pivot?.rowField ?? "").trim();
69935
70186
  if (rowField && isDateType(String(pivot?.rowFieldType ?? ""))) {
69936
70187
  const field = pivot?.rowFieldTable ? `${pivot.rowFieldTable}.${rowField}` : rowField;
69937
- const bucket = dateBucket || pivot?.dateBucket || "month";
69938
- const labelsByRaw = /* @__PURE__ */ new Map();
70188
+ const chartBucket = dateBucket || pivot?.dateBucket || "month";
70189
+ const bucket = inBucketDateBucketForField(
70190
+ filtersForQueryBuilder.rules ?? [],
70191
+ field
70192
+ ) ?? chartBucket;
69939
70193
  const cacheKey = `${String(effectiveReportId ?? "")}\0${field}\0${bucket}`;
69940
70194
  if (pivotDateFilterRangeCacheRef.current.key !== cacheKey) {
69941
70195
  pivotDateFilterRangeCacheRef.current = {
@@ -69951,7 +70205,6 @@ function useReport(reportIdArg, options = {}) {
69951
70205
  const key = String(raw);
69952
70206
  const timestamp = new Date(key).getTime();
69953
70207
  if (Number.isNaN(timestamp)) continue;
69954
- labelsByRaw.set(key, String(record[rowField] ?? key));
69955
70208
  const cachedMin = pivotDateFilterRangeCacheRef.current.min;
69956
70209
  const cachedMax = pivotDateFilterRangeCacheRef.current.max;
69957
70210
  if (cachedMin == null || timestamp < new Date(cachedMin).getTime()) {
@@ -69964,7 +70217,7 @@ function useReport(reportIdArg, options = {}) {
69964
70217
  const { min: min2, max: max2 } = pivotDateFilterRangeCacheRef.current;
69965
70218
  const options2 = min2 && max2 ? buildPivotDateBucketStarts({ min: min2, max: max2 }, bucket).map((value) => ({
69966
70219
  value,
69967
- label: labelsByRaw.get(value) ?? getDateString(value, void 0, bucket)
70220
+ label: getDateString(value, void 0, bucket)
69968
70221
  })) : [];
69969
70222
  out.push({
69970
70223
  field,
@@ -69980,7 +70233,8 @@ function useReport(reportIdArg, options = {}) {
69980
70233
  chart?.rows,
69981
70234
  dateBucket,
69982
70235
  effectiveReportId,
69983
- filterValueOptionsByFieldName
70236
+ filterValueOptionsByFieldName,
70237
+ filtersForQueryBuilder.rules
69984
70238
  ]);
69985
70239
  const chartForUi = useMemo33(() => {
69986
70240
  if (!chart?.pivot) return chart;
@@ -69993,10 +70247,10 @@ function useReport(reportIdArg, options = {}) {
69993
70247
  };
69994
70248
  const selectedValue = (field, operator, options2) => {
69995
70249
  const rule = filtersForQueryBuilder.rules.find(
69996
- (entry) => typeof entry === "object" && entry !== null && "field" in entry && entry.field === field && entry.operator === operator
70250
+ (entry) => typeof entry === "object" && entry !== null && "field" in entry && entry.field === field && (entry.operator === operator || operator === "inBucket" && entry.operator === "between")
69997
70251
  );
69998
70252
  if (!rule) return null;
69999
- const raw = operator === "inBucket" ? rule.value?.start : Array.isArray(rule.value) ? rule.value[0] : void 0;
70253
+ 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;
70000
70254
  if (raw == null) return null;
70001
70255
  const value = String(raw);
70002
70256
  return options2.some((option) => option.value === value) ? value : null;
@@ -70252,9 +70506,7 @@ function useReport(reportIdArg, options = {}) {
70252
70506
  sourceReport,
70253
70507
  includeSelectedSchemaFallback: tableColumnsEditedSignature !== null
70254
70508
  });
70255
- const pivotRowFieldForTable = String(
70256
- sourceReport?.pivot?.rowField ?? ""
70257
- ).trim();
70509
+ const pivotRowFieldForTable = pivotRowKey(sourceReport);
70258
70510
  const pivotRowTableUsesAxisFormat = chartAxisEdits.xAxisFormat !== void 0;
70259
70511
  const columns2 = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot && pivotRowFieldForTable && String(resolvedXAxisField ?? "").trim() === pivotRowFieldForTable ? mergedFromReport.map(
70260
70512
  (column) => column.field === pivotRowFieldForTable ? {
@@ -70266,7 +70518,7 @@ function useReport(reportIdArg, options = {}) {
70266
70518
  const pivotLabeledColumns = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot ? mergePivotTableDisplayColumnLabelsFromYAxis({
70267
70519
  columns: columns2,
70268
70520
  yAxisFields: resolvedYAxisFieldsForDisplay,
70269
- pivotRowField: String(sourceReport.pivot.rowField ?? ""),
70521
+ pivotRowField: pivotRowKey(sourceReport),
70270
70522
  xAxisLabel: resolvedXAxisLabel
70271
70523
  }) ?? columns2 : columns2;
70272
70524
  const tableColumnsWithPivotDisplayLabels = pivotLabeledColumns.map(
@@ -70515,7 +70767,7 @@ function useReport(reportIdArg, options = {}) {
70515
70767
  if (slotFormatting) {
70516
70768
  const aggregations = slotFormatting.aggregations;
70517
70769
  const hasMultiple = aggregations.length > 1;
70518
- const rowField = String(pivotState?.rowField ?? "").trim();
70770
+ const rowField = pivotRowKey(chart);
70519
70771
  const firstValueColumnFormat = String(
70520
70772
  (chart.columns ?? []).find(
70521
70773
  (c) => String(c.field ?? "").trim() !== rowField
@@ -70551,9 +70803,7 @@ function useReport(reportIdArg, options = {}) {
70551
70803
  }
70552
70804
  }
70553
70805
  }
70554
- const pivotRowFieldForSettings = String(
70555
- chart?.pivot?.rowField ?? ""
70556
- ).trim();
70806
+ const pivotRowFieldForSettings = pivotRowKey(chart);
70557
70807
  const rowAxisLabel = String(resolvedXAxisLabel ?? "").trim();
70558
70808
  for (const columnId of activeTableColumnIds) {
70559
70809
  const option = columnOptionById.get(columnId);
@@ -70613,7 +70863,7 @@ function useReport(reportIdArg, options = {}) {
70613
70863
  tableColumnSettingsCoalesceRef.current = new Map(tableColumnSettingsById);
70614
70864
  }, [tableColumnSettingsById]);
70615
70865
  const tableColumnItems = useMemo33(() => {
70616
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70866
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70617
70867
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70618
70868
  const items = activeTableColumnIds.map((columnId) => {
70619
70869
  const option = columnOptionById.get(columnId);
@@ -70652,7 +70902,7 @@ function useReport(reportIdArg, options = {}) {
70652
70902
  return new Map(tableColumnItems.map((item) => [item.id, item]));
70653
70903
  }, [tableColumnItems]);
70654
70904
  const tableColumnValues = useMemo33(() => {
70655
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70905
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70656
70906
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70657
70907
  return tableColumnItems.map((item) => {
70658
70908
  const coerced = coerceTableColumnFormatToAxisValue(item.format);
@@ -70673,8 +70923,89 @@ function useReport(reportIdArg, options = {}) {
70673
70923
  const initialLoadInProgress = !reportOverride && Boolean(effectiveReportId) && (!client || initialLoadQuery.isPending || initialLoadQuery.isFetching);
70674
70924
  const filterUniqueValuesLoading = filterUniqueValuesEnabled && (filterUniqueValuesQuery.isPending || filterUniqueValuesQuery.isFetching);
70675
70925
  const chartLoading = initialLoadInProgress || pendingPivotRefresh || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70676
- const tableLoading = initialLoadInProgress || pendingPivotRefresh || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70926
+ const awaitingPivotDetailRows = Boolean(nextPivot || sourceReport?.pivot) && !reportOverride && Boolean(sourceReport) && sourceReportMatchesEffectiveReportId && (!Array.isArray(sourceReport?.rows) || sourceReport.rows.length === 0) && pivotTableDataRefreshQuery.status !== "error";
70927
+ const tableLoading = initialLoadInProgress || pendingPivotRefresh || awaitingPivotDetailRows || tablePageFetching && pagination.pageIndex > 0 || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70677
70928
  const loading = chartLoading || tableLoading;
70929
+ const lastUseReportLoadingLogRef = useRef24("");
70930
+ useEffect33(() => {
70931
+ const snapshot = {
70932
+ reportId: effectiveReportId,
70933
+ chartLoading,
70934
+ tableLoading,
70935
+ loading,
70936
+ initialLoadInProgress,
70937
+ initialLoad: {
70938
+ status: initialLoadQuery.status,
70939
+ fetchStatus: initialLoadQuery.fetchStatus,
70940
+ isPending: initialLoadQuery.isPending,
70941
+ isFetching: initialLoadQuery.isFetching,
70942
+ hasData: initialLoadQuery.data !== void 0,
70943
+ dataUpdatedAt: initialLoadQuery.dataUpdatedAt,
70944
+ staleTime: 0
70945
+ },
70946
+ pendingPivotRefresh,
70947
+ pivotRefresh: {
70948
+ enabled: pivotRefreshQueryEnabled,
70949
+ isFetching: pivotRefreshQuery.isFetching
70950
+ },
70951
+ tableRefresh: {
70952
+ enabled: tableRefreshQueryEnabled,
70953
+ isFetching: tableRefreshQuery.isFetching
70954
+ },
70955
+ pivotTableData: {
70956
+ enabled: pivotTableDataRefreshQueryEnabled,
70957
+ isFetching: pivotTableDataRefreshQuery.isFetching
70958
+ },
70959
+ tablePage: {
70960
+ enabled: tablePageQueryEnabled,
70961
+ isFetching: tablePageQuery.isFetching
70962
+ },
70963
+ uniqueValues: {
70964
+ enabled: filterUniqueValuesEnabled,
70965
+ isFetching: filterUniqueValuesQuery.isFetching,
70966
+ isPending: filterUniqueValuesQuery.isPending
70967
+ },
70968
+ whyChartLoading: {
70969
+ noClient: !client,
70970
+ initialPending: initialLoadQuery.isPending,
70971
+ initialFetching: initialLoadQuery.isFetching,
70972
+ pendingPivotRefresh,
70973
+ pivotRefreshFetching: Boolean(nextPivot) && pivotRefreshQuery.isFetching,
70974
+ tableRefreshFetching: !nextPivot && tableRefreshQuery.isFetching
70975
+ }
70976
+ };
70977
+ const serialized = JSON.stringify(snapshot);
70978
+ if (serialized === lastUseReportLoadingLogRef.current) return;
70979
+ lastUseReportLoadingLogRef.current = serialized;
70980
+ profileDashboard("use-report-loading", snapshot);
70981
+ }, [
70982
+ client,
70983
+ chartLoading,
70984
+ effectiveReportId,
70985
+ filterUniqueValuesEnabled,
70986
+ filterUniqueValuesQuery.fetchStatus,
70987
+ filterUniqueValuesQuery.isFetching,
70988
+ filterUniqueValuesQuery.isPending,
70989
+ initialLoadInProgress,
70990
+ initialLoadQuery.data,
70991
+ initialLoadQuery.dataUpdatedAt,
70992
+ initialLoadQuery.fetchStatus,
70993
+ initialLoadQuery.isFetching,
70994
+ initialLoadQuery.isPending,
70995
+ initialLoadQuery.status,
70996
+ loading,
70997
+ nextPivot,
70998
+ pendingPivotRefresh,
70999
+ pivotRefreshQuery.isFetching,
71000
+ pivotRefreshQueryEnabled,
71001
+ pivotTableDataRefreshQuery.isFetching,
71002
+ pivotTableDataRefreshQueryEnabled,
71003
+ tableLoading,
71004
+ tablePageQuery.isFetching,
71005
+ tablePageQueryEnabled,
71006
+ tableRefreshQuery.isFetching,
71007
+ tableRefreshQueryEnabled
71008
+ ]);
70678
71009
  const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
70679
71010
  const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
70680
71011
  return normalizedNextIds.map((columnId) => {
@@ -70714,7 +71045,7 @@ function useReport(reportIdArg, options = {}) {
70714
71045
  const option = columnOptionById.get(normalizedId);
70715
71046
  const pivotField = String(option?.field ?? normalizedId).trim();
70716
71047
  const pivotModel = chartAxesBaseChart.pivot;
70717
- const rowField = String(pivotModel?.rowField ?? "").trim();
71048
+ const rowField = pivotRowKey(chartAxesBaseChart);
70718
71049
  if (!pivotModel) return null;
70719
71050
  const isPivotRowColumn = Boolean(
70720
71051
  pivotField && rowField && pivotField === rowField