@quillsql/react 2.16.91 → 2.16.93

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 +401 -110
  2. package/dist/index.js +401 -110
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -17136,6 +17136,79 @@ var init_paginationProcessing = __esm({
17136
17136
  }
17137
17137
  });
17138
17138
 
17139
+ // src/utils/dashboardProfiler.ts
17140
+ function profilingEnabled() {
17141
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE === "true") {
17142
+ return true;
17143
+ }
17144
+ if (typeof window === "undefined") return false;
17145
+ return Boolean(window.__QUILL_DASHBOARD_PROFILE__);
17146
+ }
17147
+ function profileStore() {
17148
+ if (typeof window !== "undefined") {
17149
+ const profileWindow = window;
17150
+ profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
17151
+ return profileWindow.__QUILL_DASHBOARD_TRACE__;
17152
+ }
17153
+ const globalStore = globalThis;
17154
+ globalStore.__QUILL_DASHBOARD_TRACE__ ??= [];
17155
+ return globalStore.__QUILL_DASHBOARD_TRACE__;
17156
+ }
17157
+ function queryKeyFamily(queryKey) {
17158
+ const head = String(queryKey[0] ?? "");
17159
+ const next = String(queryKey[1] ?? "");
17160
+ if (head === "quill" && next === "dashboard-report") {
17161
+ return "quill/dashboard-report";
17162
+ }
17163
+ if (head === "useReport") {
17164
+ return `useReport/${next || "unknown"}`;
17165
+ }
17166
+ return head || "other";
17167
+ }
17168
+ function summarizeEngineRequest(input) {
17169
+ const metadata = input.metadata ?? {};
17170
+ return {
17171
+ task: input.task ?? null,
17172
+ shareRequest: Boolean(input.shareRequest),
17173
+ reuseExisting: input.reuseExisting ?? null,
17174
+ settled: input.settled ?? null,
17175
+ reportId: metadata.reportId ?? null,
17176
+ metadataKeys: Object.keys(metadata).sort(),
17177
+ dashboardName: metadata.dashboardName ?? null,
17178
+ dashboardItemId: metadata.dashboardItemId ?? null,
17179
+ useNewNodeSql: metadata.useNewNodeSql ?? null,
17180
+ dateBucket: metadata.dateBucket ?? null,
17181
+ hasPivot: Boolean(metadata.pivot),
17182
+ hasReportBuilderState: Boolean(metadata.reportBuilderState),
17183
+ additionalProcessing: metadata.additionalProcessing ?? null,
17184
+ filterCount: Array.isArray(metadata.filters) ? metadata.filters.length : null
17185
+ };
17186
+ }
17187
+ function profileDashboard(event, data) {
17188
+ if (!profilingEnabled()) return;
17189
+ const entry = {
17190
+ at: Math.round(performance.now() * 10) / 10,
17191
+ event,
17192
+ data
17193
+ };
17194
+ profileStore().push(entry);
17195
+ if (typeof window !== "undefined") {
17196
+ const profileWindow = window;
17197
+ profileWindow.__QUILL_DASHBOARD_PROFILE__ = true;
17198
+ profileWindow.__QUILL_DUMP_DASHBOARD_PROFILE__ = () => profileWindow.__QUILL_DASHBOARD_TRACE__ ?? [];
17199
+ }
17200
+ if (typeof process !== "undefined" && process.env?.QUILL_DASHBOARD_PROFILE_CONSOLE === "true" && CONSOLE_EVENT_PATTERN.test(event)) {
17201
+ console.log(`[quill-profile] ${event}`, data ?? {});
17202
+ }
17203
+ }
17204
+ var CONSOLE_EVENT_PATTERN;
17205
+ var init_dashboardProfiler = __esm({
17206
+ "src/utils/dashboardProfiler.ts"() {
17207
+ "use strict";
17208
+ CONSOLE_EVENT_PATTERN = /cache|initial-load|use-report-loading|network|unique-values|table-refresh|pivot|shared-request|engine-fetch|generate-pivot/;
17209
+ }
17210
+ });
17211
+
17139
17212
  // src/utils/pivotConstructor.ts
17140
17213
  function normalizeLegacyPivotSortFieldValue(sortField) {
17141
17214
  if (sortField === void 0) {
@@ -17248,6 +17321,22 @@ async function generatePivotWithSQL({
17248
17321
  rowLimit: pivot.rowLimit,
17249
17322
  dateBucket: resolvedDateBucket
17250
17323
  };
17324
+ profileDashboard(
17325
+ "generate-pivot-sql",
17326
+ summarizeEngineRequest({
17327
+ task: "pivot-template",
17328
+ shareRequest: false,
17329
+ metadata: {
17330
+ reportId: report?.id,
17331
+ dashboardName,
17332
+ dateBucket: resolvedDateBucket,
17333
+ additionalProcessing,
17334
+ pivot: pivotConfig,
17335
+ reportBuilderState,
17336
+ filters: dashboardFilters
17337
+ }
17338
+ })
17339
+ );
17251
17340
  const resp = await quillFetch({
17252
17341
  client,
17253
17342
  task: "pivot-template",
@@ -17626,6 +17715,7 @@ var init_pivotConstructor = __esm({
17626
17715
  init_columnType();
17627
17716
  init_dataFetcher();
17628
17717
  init_dataProcessing();
17718
+ init_dashboardProfiler();
17629
17719
  init_dates();
17630
17720
  init_textProcessing();
17631
17721
  }
@@ -20048,6 +20138,20 @@ async function getOrFetchSharedRequest({
20048
20138
  }) {
20049
20139
  if (signal?.aborted) throw createAbortError(signal);
20050
20140
  let entry = entries.get(key);
20141
+ const reuseExisting = Boolean(entry);
20142
+ profileDashboard("shared-request", {
20143
+ ...summarizeEngineRequest({
20144
+ task: void 0,
20145
+ shareRequest: true,
20146
+ reuseExisting,
20147
+ settled: entry?.settled,
20148
+ metadata: { reportId }
20149
+ }),
20150
+ reportId: reportId ?? null,
20151
+ reuseExisting,
20152
+ settled: entry?.settled ?? false,
20153
+ keyLength: key.length
20154
+ });
20051
20155
  if (!entry) {
20052
20156
  const controller = new AbortController();
20053
20157
  entry = {
@@ -20123,6 +20227,7 @@ var ORPHAN_GRACE_MS, COMPLETED_TTL_MS, entries;
20123
20227
  var init_reportRequestPool = __esm({
20124
20228
  "src/utils/reportRequestPool.ts"() {
20125
20229
  "use strict";
20230
+ init_dashboardProfiler();
20126
20231
  ORPHAN_GRACE_MS = 100;
20127
20232
  COMPLETED_TTL_MS = 15e3;
20128
20233
  entries = /* @__PURE__ */ new Map();
@@ -20685,6 +20790,7 @@ var init_dataFetcher = __esm({
20685
20790
  init_dates();
20686
20791
  init_changelogNotify();
20687
20792
  init_reportRequestPool();
20793
+ init_dashboardProfiler();
20688
20794
  quillFetch = async ({
20689
20795
  client,
20690
20796
  task,
@@ -20745,6 +20851,14 @@ var init_dataFetcher = __esm({
20745
20851
  return { error: "Failed to fetch data" };
20746
20852
  }
20747
20853
  };
20854
+ profileDashboard(
20855
+ "engine-fetch",
20856
+ summarizeEngineRequest({
20857
+ task,
20858
+ shareRequest,
20859
+ metadata
20860
+ })
20861
+ );
20748
20862
  if (!shareRequest) {
20749
20863
  return execute(abortSignal);
20750
20864
  }
@@ -21380,22 +21494,7 @@ init_dates();
21380
21494
  init_pivotConstructor();
21381
21495
  init_columnProcessing();
21382
21496
  init_paginationProcessing();
21383
-
21384
- // src/utils/dashboardProfiler.ts
21385
- function profileDashboard(event, data) {
21386
- if (typeof window === "undefined") return;
21387
- const profileWindow = window;
21388
- if (!profileWindow.__QUILL_DASHBOARD_PROFILE__) return;
21389
- const entry = {
21390
- at: Math.round(performance.now() * 10) / 10,
21391
- event,
21392
- data
21393
- };
21394
- profileWindow.__QUILL_DASHBOARD_TRACE__ ??= [];
21395
- profileWindow.__QUILL_DASHBOARD_TRACE__.push(entry);
21396
- }
21397
-
21398
- // src/utils/dashboard.ts
21497
+ init_dashboardProfiler();
21399
21498
  var defaultDashboardItem = {
21400
21499
  id: "",
21401
21500
  name: "",
@@ -22808,6 +22907,7 @@ init_tableProcessing();
22808
22907
  init_textProcessing();
22809
22908
  init_valueFormatter();
22810
22909
  init_astFilterProcessing();
22910
+ init_dashboardProfiler();
22811
22911
  init_reportBuilder();
22812
22912
  init_astProcessing();
22813
22913
 
@@ -26567,6 +26667,7 @@ function normalizePSTRanges(start, end) {
26567
26667
 
26568
26668
  // src/Context.tsx
26569
26669
  init_changelogNotify();
26670
+ init_dashboardProfiler();
26570
26671
 
26571
26672
  // src/reportStore.ts
26572
26673
  var import_react = require("react");
@@ -32337,7 +32438,7 @@ function QuillTable({
32337
32438
  setSortColumn(sort?.field || "");
32338
32439
  setSortDirection(sort?.direction || "desc");
32339
32440
  }, [sort]);
32340
- const holdFullPageLoader = rows?.length === 0 && isLoading;
32441
+ const holdFullPageLoader = Boolean(isLoading);
32341
32442
  const pageCountUnknown = manualPagination && pageCount === -1;
32342
32443
  const { activeRows, maxPage } = (0, import_react14.useMemo)(() => {
32343
32444
  const start = currentPage * rowsPerPage;
@@ -37195,6 +37296,7 @@ function getDashboardReportProcessing(report, serverPagination) {
37195
37296
  }
37196
37297
 
37197
37298
  // src/hooks/useDashboard.ts
37299
+ init_dashboardProfiler();
37198
37300
  var DEFAULT_DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
37199
37301
  var useDashboardConfigInternal = (dashboardName) => {
37200
37302
  const { dashboardConfig, isLoading: dashboardsLoading } = (0, import_react26.useContext)(
@@ -38304,6 +38406,14 @@ var useDashboard = (dashboardName, config) => {
38304
38406
  additionalProcessing
38305
38407
  );
38306
38408
  const usePivotTask = !cacheEnabled && !!reportInfo.pivot;
38409
+ profileDashboard("dashboard-report-cache-path", {
38410
+ reportId,
38411
+ cacheEnabled,
38412
+ cacheCabCacheable: cacheCab.isCacheable(reportId),
38413
+ usePivotTask,
38414
+ forceCacheToRefresh,
38415
+ hasPivot: Boolean(reportInfo.pivot)
38416
+ });
38307
38417
  const allFilters = dashboardFilters2.concat(customFilters).concat(customReportFiltersArray);
38308
38418
  const applyInMemoryPivotIfNeeded = (report2) => {
38309
38419
  const pivotToApply = reportInfo.pivot ?? report2.pivot;
@@ -38537,7 +38647,9 @@ var useDashboard = (dashboardName, config) => {
38537
38647
  pivotColumns: pivotData.columns,
38538
38648
  pivotRowCount: pivotData.rowCount,
38539
38649
  pivotQuery: pivotData.pivotQuery,
38540
- comparisonPivotQuery: pivotData.comparisonPivotQuery
38650
+ comparisonPivotQuery: pivotData.comparisonPivotQuery,
38651
+ pivotResultRowField: pivotData.rowField,
38652
+ pivotResultSourceRowField: reportInfo.pivot?.rowField
38541
38653
  },
38542
38654
  error: void 0
38543
38655
  };
@@ -38567,6 +38679,26 @@ var useDashboard = (dashboardName, config) => {
38567
38679
  shareRequest: !forceCacheToRefresh
38568
38680
  });
38569
38681
  };
38682
+ const existingState = queryClient.getQueryState(queryKey);
38683
+ const existingData = queryClient.getQueryData(queryKey);
38684
+ const dataUpdatedAt = existingState?.dataUpdatedAt ?? 0;
38685
+ const ageMs = dataUpdatedAt ? Date.now() - dataUpdatedAt : null;
38686
+ const isStale = dataUpdatedAt === 0 || Date.now() - dataUpdatedAt >= reportStaleTimeMs;
38687
+ profileDashboard("dashboard-report-tanstack-cache", {
38688
+ reportId,
38689
+ keyFamily: "quill/dashboard-report",
38690
+ cacheEnabled,
38691
+ usePivotTask,
38692
+ forceCacheToRefresh,
38693
+ staleTimeMs: reportStaleTimeMs,
38694
+ status: existingState?.status ?? "missing",
38695
+ fetchStatus: existingState?.fetchStatus ?? "idle",
38696
+ hasData: existingData !== void 0,
38697
+ dataUpdatedAt,
38698
+ ageMs,
38699
+ isStale,
38700
+ willReuseTanstack: !forceCacheToRefresh && existingData !== void 0 && !isStale
38701
+ });
38570
38702
  const result = forceCacheToRefresh ? await fetchDashboardReport() : await queryClient.fetchQuery({
38571
38703
  queryKey,
38572
38704
  queryFn: fetchDashboardReport,
@@ -38969,6 +39101,7 @@ var useDashboardReport = (reportId, config) => {
38969
39101
  };
38970
39102
 
38971
39103
  // src/components/Dashboard/DataLoader.tsx
39104
+ init_dashboardProfiler();
38972
39105
  var import_jsx_runtime46 = require("react/jsx-runtime");
38973
39106
  var constructReportFromItem = (item) => {
38974
39107
  return {
@@ -41384,6 +41517,7 @@ function QuillTableDashboardComponent({
41384
41517
 
41385
41518
  // src/Chart.tsx
41386
41519
  init_valueFormatter();
41520
+ init_dashboardProfiler();
41387
41521
  var import_jsx_runtime50 = require("react/jsx-runtime");
41388
41522
  function Chart({
41389
41523
  colors,
@@ -45368,6 +45502,7 @@ init_Filter();
45368
45502
 
45369
45503
  // src/StaticChart.tsx
45370
45504
  var import_react42 = require("react");
45505
+ init_dashboardProfiler();
45371
45506
  var import_jsx_runtime60 = require("react/jsx-runtime");
45372
45507
  var CHART_TYPE_STYLES = {
45373
45508
  metric: { height: "100px", width: "200px" },
@@ -62220,6 +62355,7 @@ function resolveReportFromCacheCab({
62220
62355
  }
62221
62356
 
62222
62357
  // src/hooks/useForm.tsx
62358
+ init_dashboardProfiler();
62223
62359
  init_reportRequestPool();
62224
62360
 
62225
62361
  // src/hooks/useForm.queries.ts
@@ -62265,6 +62401,15 @@ function createUseFormInitialLoadQueryKey(input) {
62265
62401
  input.additionalSchemaHash
62266
62402
  ];
62267
62403
  }
62404
+ var DASHBOARD_REPORT_STALE_TIME_MS = 5 * 60 * 1e3;
62405
+ function findCachedDashboardReportQuery(queryClient, reportId) {
62406
+ const id = String(reportId ?? "").trim();
62407
+ if (!id) return void 0;
62408
+ return queryClient.getQueryCache().findAll({ queryKey: ["quill", "dashboard-report", id] }).find((query) => {
62409
+ const data = query.state.data;
62410
+ return Boolean(data?.report) && !data?.error;
62411
+ });
62412
+ }
62268
62413
  function shouldBootstrapUseFormInitialLoad(input) {
62269
62414
  return !input.hasInitialReportBuilderState && input.previouslyBootstrappedIdentity !== input.currentIdentity;
62270
62415
  }
@@ -63247,6 +63392,11 @@ function getPivotTableSlotReportColumn(reportColumns, aggregations, rowField, pi
63247
63392
  }
63248
63393
  return cols[aggIndex + 1];
63249
63394
  }
63395
+ function pivotRowKey(chart) {
63396
+ return String(
63397
+ chart?.pivotResultRowField ?? chart?.pivot?.rowField ?? ""
63398
+ ).trim();
63399
+ }
63250
63400
  function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63251
63401
  if (!chart?.pivot) return false;
63252
63402
  if (String(chart.chartType ?? "").toLowerCase() !== "table") return false;
@@ -63255,7 +63405,8 @@ function isPivotTableDateBucketRowAxis(chart, xAxisField) {
63255
63405
  }
63256
63406
  const rowField = String(chart.pivot.rowField ?? "").trim();
63257
63407
  const xf = String(xAxisField ?? "").trim();
63258
- if (!rowField || xf !== rowField) return false;
63408
+ const rowKey = pivotRowKey(chart);
63409
+ if (!rowField || xf !== rowField && xf !== rowKey) return false;
63259
63410
  return isDateType(String(chart.pivot.rowFieldType ?? ""));
63260
63411
  }
63261
63412
  var RESOLVABLE_X_AXIS_DATE_BUCKETS = /* @__PURE__ */ new Set([
@@ -63269,22 +63420,24 @@ function resolvePivotDateBucketXAxisFormat(chart, xAxisField) {
63269
63420
  const dateBucket = String(chart?.pivot?.dateBucket ?? "").trim().toLowerCase();
63270
63421
  if (!RESOLVABLE_X_AXIS_DATE_BUCKETS.has(dateBucket)) return null;
63271
63422
  const rowField = String(chart?.pivot?.rowField ?? "").trim();
63272
- if (!rowField || String(xAxisField ?? "").trim() !== rowField) return null;
63423
+ const xf = String(xAxisField ?? "").trim();
63424
+ const rowKey = pivotRowKey(chart);
63425
+ if (!rowField || xf !== rowField && xf !== rowKey) return null;
63273
63426
  if (!isDateType(String(chart?.pivot?.rowFieldType ?? ""))) return null;
63274
63427
  return getDateFormatFromBucket(dateBucket);
63275
63428
  }
63276
63429
  function chartDetailRowsMissingPivotRowBucket(chart) {
63277
63430
  if (!chart?.pivot) return false;
63278
- const rowField = String(chart.pivot.rowField ?? "").trim();
63279
- if (!rowField) return false;
63431
+ const rowKey = pivotRowKey(chart);
63432
+ if (!rowKey) return false;
63280
63433
  const rows = chart.rows;
63281
63434
  if (!Array.isArray(rows) || rows.length === 0) return false;
63282
63435
  const first = rows.find(
63283
63436
  (r) => r && typeof r === "object" && Object.keys(r).length > 0
63284
63437
  );
63285
63438
  if (!first) return false;
63286
- if (!Object.prototype.hasOwnProperty.call(first, rowField)) return true;
63287
- const v = first[rowField];
63439
+ if (!Object.prototype.hasOwnProperty.call(first, rowKey)) return true;
63440
+ const v = first[rowKey];
63288
63441
  return v === void 0 || v === null;
63289
63442
  }
63290
63443
  function shouldUsePivotRowFieldAsXAxis(chartType, pivotRowField, rowColumnFormat) {
@@ -63320,7 +63473,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63320
63473
  } : chart;
63321
63474
  if (!config) return config;
63322
63475
  if (!config.pivot) return config;
63323
- const pivotRowFieldEarly = String(config.pivot?.rowField ?? "").trim();
63476
+ const pivotRowFieldEarly = pivotRowKey(config);
63324
63477
  const rowColumn = (config.pivotColumns ?? config.columns ?? []).find(
63325
63478
  (col) => String(col.field ?? "").trim() === pivotRowFieldEarly
63326
63479
  );
@@ -63343,7 +63496,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63343
63496
  (field) => !INTERNAL_PIVOT_ROW_FIELDS.has(field)
63344
63497
  ) : [];
63345
63498
  const pivotValueFields = pivotRowFields.filter(
63346
- (field) => field !== withResolvedXAxis.pivot?.rowField
63499
+ (field) => field !== pivotRowKey(withResolvedXAxis) && field !== withResolvedXAxis.pivot?.rowField
63347
63500
  );
63348
63501
  const isAggregationOnlyPivot = !String(withResolvedXAxis.pivot?.rowField ?? "").trim() && !String(withResolvedXAxis.pivot?.columnField ?? "").trim();
63349
63502
  const yAxisFormatByField = new Map(
@@ -63460,7 +63613,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63460
63613
  const normalizedPivotColumns = pivotColumnFields.length > 0 ? pivotColumnFields.map((field) => {
63461
63614
  const knownColumn = knownColumnsByField.get(field);
63462
63615
  const yAxis = yAxisFields.find((axis) => axis.field === field);
63463
- const format9 = yAxis?.format ?? knownColumn?.format ?? (field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63616
+ const format9 = yAxis?.format ?? knownColumn?.format ?? (field === pivotRowKey(withResolvedXAxis) || field === withResolvedXAxis.pivot?.rowField ? isMetricOrGauge ? "string" : withResolvedXAxis.xAxisFormat ?? "string" : yAxisFallbackFormat);
63464
63617
  return {
63465
63618
  field,
63466
63619
  label: yAxis?.label ?? knownColumn?.label ?? field,
@@ -63473,7 +63626,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63473
63626
  const slotCol = getPivotTableSlotReportColumn(
63474
63627
  pivotTableSlotColumns,
63475
63628
  aggregations,
63476
- withResolvedXAxis.pivot?.rowField,
63629
+ pivotRowKey(withResolvedXAxis) || withResolvedXAxis.pivot?.rowField,
63477
63630
  col.field
63478
63631
  );
63479
63632
  if (!slotCol) return col;
@@ -63495,9 +63648,7 @@ function normalizePivotChartForDisplay(chart, resolveTableLabel) {
63495
63648
  const normalizedXAxisFormat = normalizedXAxisField === withResolvedXAxis.xAxisField ? withResolvedXAxis.xAxisFormat : yAxisFields.find((axis) => axis.field === normalizedXAxisField)?.format ?? pivotTableDisplayColumns.find(
63496
63649
  (column) => column.field === normalizedXAxisField
63497
63650
  )?.format ?? withResolvedXAxis.xAxisFormat;
63498
- const pivotDisplayRowField = String(
63499
- withResolvedXAxis.pivot?.rowField ?? ""
63500
- ).trim();
63651
+ const pivotDisplayRowField = pivotRowKey(withResolvedXAxis);
63501
63652
  const pivotDisplayRowFieldType = String(
63502
63653
  withResolvedXAxis.pivot?.rowFieldType ?? ""
63503
63654
  ).trim();
@@ -65898,6 +66049,19 @@ async function loadViaReportBuilderState({
65898
66049
  dashboardName: report?.dashboardName ?? dashboardName,
65899
66050
  name: report?.name ?? reportId
65900
66051
  };
66052
+ const processing = pagination ? {
66053
+ page: {
66054
+ page: pagination.pageIndex,
66055
+ rowsPerPage: pagination.pageSize,
66056
+ rowsPerRequest: pagination.pageSize
66057
+ },
66058
+ ...paginationSort?.field ? { sort: paginationSort } : {}
66059
+ } : {
66060
+ page: {
66061
+ ...DEFAULT_PAGINATION,
66062
+ rowsPerRequest: DEFAULT_USE_REPORT_ROWS_PER_REQUEST
66063
+ }
66064
+ };
65901
66065
  const reportBuilderInfo = await fetchReportBuilderDataFromState({
65902
66066
  reportBuilderState,
65903
66067
  schema,
@@ -65912,19 +66076,7 @@ async function loadViaReportBuilderState({
65912
66076
  skipRowCount: rowsOnly,
65913
66077
  rowCountOnly,
65914
66078
  previousRelevant: previousRelevantWhenSkippingInlineUniqueFetch(report),
65915
- processing: pagination ? {
65916
- page: {
65917
- page: pagination.pageIndex,
65918
- rowsPerPage: pagination.pageSize,
65919
- rowsPerRequest: pagination.pageSize
65920
- },
65921
- ...paginationSort?.field ? { sort: paginationSort } : {}
65922
- } : {
65923
- page: {
65924
- ...DEFAULT_PAGINATION,
65925
- rowsPerRequest: DEFAULT_USE_REPORT_ROWS_PER_REQUEST
65926
- }
65927
- },
66079
+ processing,
65928
66080
  dashboardName,
65929
66081
  getToken,
65930
66082
  eventTracking: null,
@@ -66460,19 +66612,30 @@ function useReport(reportIdArg, options = {}) {
66460
66612
  )
66461
66613
  });
66462
66614
  const diagnostics = globalThis.__QUILL_CACHECAB_DIAGNOSTICS__;
66615
+ const durationMs = performance.now() - startedAt;
66616
+ const outcome = resolution.resolved ? "hit" : "fallback";
66463
66617
  if (Array.isArray(diagnostics)) {
66464
66618
  diagnostics.push({
66465
66619
  reportId: effectiveReportId,
66466
66620
  operation,
66467
- outcome: resolution.resolved ? "hit" : "fallback",
66621
+ outcome,
66468
66622
  reason: resolution.resolved ? "complete" : resolution.reason,
66469
66623
  details: resolution.resolved ? void 0 : resolution.details,
66470
66624
  snapshotReason: snapshot?.reason ?? "cache_miss",
66471
66625
  forcedIncompleteSnapshot: Boolean(snapshot) && !snapshot?.complete && forceIncompleteCacheCabForParity,
66472
66626
  rowCount: snapshot?.rowCount ?? 0,
66473
- durationMs: performance.now() - startedAt
66627
+ durationMs
66474
66628
  });
66475
66629
  }
66630
+ profileDashboard("use-report-cachecab", {
66631
+ reportId: effectiveReportId,
66632
+ operation,
66633
+ outcome,
66634
+ reason: resolution.resolved ? "complete" : resolution.reason,
66635
+ snapshotReason: snapshot?.reason ?? "cache_miss",
66636
+ rowCount: snapshot?.rowCount ?? 0,
66637
+ durationMs: Math.round(durationMs * 10) / 10
66638
+ });
66476
66639
  return resolution.resolved ? resolution.report : null;
66477
66640
  },
66478
66641
  [
@@ -67046,9 +67209,15 @@ function useReport(reportIdArg, options = {}) {
67046
67209
  if (alias) localValues[alias] = values;
67047
67210
  }
67048
67211
  if (hasEveryColumn) {
67212
+ profileDashboard("use-report-unique-values-cachecab-hit", {
67213
+ reportId: effectiveReportId
67214
+ });
67049
67215
  return { uniqueValuesByColumn: localValues };
67050
67216
  }
67051
67217
  }
67218
+ profileDashboard("use-report-unique-values-network", {
67219
+ reportId: effectiveReportId
67220
+ });
67052
67221
  const tablesForUniqueValues = filterUniqueValuesRequest.reportBuilderState?.tables?.map(
67053
67222
  (table2) => String(table2?.name ?? "").trim()
67054
67223
  ) ?? filterUniqueValuesRequest.stringColumnsByTable.map((column) => String(column.table ?? "").trim()).filter(Boolean);
@@ -67567,6 +67736,29 @@ function useReport(reportIdArg, options = {}) {
67567
67736
  const initialLoadQuery = (0, import_react_query3.useQuery)({
67568
67737
  queryKey: initialLoadQueryKey,
67569
67738
  queryFn: createUseFormQueryFn(async (signal) => {
67739
+ const tanstackState = queryClient.getQueryState(initialLoadQueryKey);
67740
+ const dashboardReportQueries = queryClient.getQueryCache().getAll().filter(
67741
+ (query) => queryKeyFamily(query.queryKey) === "quill/dashboard-report"
67742
+ );
67743
+ const matchingDashboardReport = dashboardReportQueries.find(
67744
+ (query) => String(query.queryKey[2] ?? "") === String(effectiveReportId)
67745
+ );
67746
+ profileDashboard("use-report-initial-load-queryfn", {
67747
+ reportId: effectiveReportId,
67748
+ reason: "TanStack ran this queryFn, so useReport/initial-load had no fresh cached data",
67749
+ keyFamily: "useReport/initial-load",
67750
+ status: tanstackState?.status ?? "missing",
67751
+ hasData: tanstackState?.data !== void 0,
67752
+ dataUpdatedAt: tanstackState?.dataUpdatedAt ?? 0,
67753
+ staleTime: 0,
67754
+ dashboardReportQueryCount: dashboardReportQueries.length,
67755
+ matchingDashboardReport: matchingDashboardReport ? {
67756
+ hasData: matchingDashboardReport.state.data !== void 0,
67757
+ status: matchingDashboardReport.state.status,
67758
+ staleTime: matchingDashboardReport.options?.staleTime ?? 0,
67759
+ unusedByUseReport: true
67760
+ } : null
67761
+ });
67570
67762
  let cachedReportBuilderState = initialReportBuilderStateForLoad ?? void 0;
67571
67763
  if (!cachedReportBuilderState) {
67572
67764
  const snapshot = await cacheCab.getReportSnapshot(
@@ -67591,6 +67783,9 @@ function useReport(reportIdArg, options = {}) {
67591
67783
  operation: "initial"
67592
67784
  });
67593
67785
  if (cachedReport) {
67786
+ profileDashboard("use-report-initial-load-served-from-cachecab", {
67787
+ reportId: effectiveReportId
67788
+ });
67594
67789
  return { report: cachedReport };
67595
67790
  }
67596
67791
  const allowReportTaskBootstrap = shouldBootstrapUseFormInitialLoad({
@@ -67605,6 +67800,12 @@ function useReport(reportIdArg, options = {}) {
67605
67800
  const formFiltersBelongToLoadTarget = Boolean(loadTargetId) && sourceReportIdentity === loadTargetId;
67606
67801
  const rulesForLoad = useInMemoryEngines || !formFiltersBelongToLoadTarget ? EMPTY_QUERY_FILTERS : queryFilters;
67607
67802
  const shareInitialRequest = sharedInitialRequestUsedForReportIdRef.current !== effectiveReportId;
67803
+ profileDashboard("use-report-initial-load-network", {
67804
+ reportId: effectiveReportId,
67805
+ path: "loadReportForUseForm",
67806
+ hasCachedReportBuilderState: Boolean(cachedReportBuilderState)
67807
+ });
67808
+ const networkStartedAt = performance.now();
67608
67809
  const loadResult = await loadReportForUseForm({
67609
67810
  reportId: effectiveReportId,
67610
67811
  initialReportBuilderState: initialReportBuilderStateForLoad,
@@ -67624,6 +67825,12 @@ function useReport(reportIdArg, options = {}) {
67624
67825
  rowsOnly: isCreatedReportBootstrapLoad,
67625
67826
  abortSignal: signal
67626
67827
  });
67828
+ profileDashboard("use-report-initial-load-network-done", {
67829
+ reportId: effectiveReportId,
67830
+ durationMs: Math.round(performance.now() - networkStartedAt),
67831
+ hasReport: Boolean(loadResult.report),
67832
+ error: loadResult.error ?? null
67833
+ });
67627
67834
  if (loadResult.report && !loadResult.error) {
67628
67835
  if (allowReportTaskBootstrap) {
67629
67836
  bootstrapReportTaskUsedForInitialLoadRef.current = initialLoadIdentityHash;
@@ -67635,7 +67842,17 @@ function useReport(reportIdArg, options = {}) {
67635
67842
  return loadResult;
67636
67843
  }),
67637
67844
  enabled: Boolean(effectiveReportId) && Boolean(client) && !reportOverride,
67638
- retry: false
67845
+ retry: false,
67846
+ initialData: () => {
67847
+ const cached = findCachedDashboardReportQuery(
67848
+ queryClient,
67849
+ effectiveReportId
67850
+ );
67851
+ const data = cached?.state.data;
67852
+ return data?.report ? { report: data.report, error: data.error } : void 0;
67853
+ },
67854
+ initialDataUpdatedAt: () => findCachedDashboardReportQuery(queryClient, effectiveReportId)?.state.dataUpdatedAt,
67855
+ staleTime: DASHBOARD_REPORT_STALE_TIME_MS
67639
67856
  });
67640
67857
  const reportNameQueryReportId = String(effectiveReportId ?? "").trim();
67641
67858
  const reportNameQuery = (0, import_react_query3.useQuery)({
@@ -67686,15 +67903,6 @@ function useReport(reportIdArg, options = {}) {
67686
67903
  const shouldPromoteColumnToRowFromPendingFlag = pendingPromoteColumnToRow && !String(prev.groupRowsBy ?? "").trim();
67687
67904
  const sourceReportBuilderTables = (sourceReport.reportBuilderState?.tables ?? []).filter((table2) => Boolean(String(table2?.name ?? "").trim()));
67688
67905
  const sourceReportBuilderTableNames = sourceReportBuilderTables.map((table2) => table2.name).filter((name2) => Boolean(name2));
67689
- const sourceQueryColumns = normalizeReportBuilderColumns(
67690
- sourceReport.reportBuilderState?.columns ?? (sourceReport.columns ?? []).map((column) => ({
67691
- field: column.field,
67692
- table: column.table ?? resolveColumnTableFromReportMetadata(
67693
- sourceReport,
67694
- column.field
67695
- )
67696
- }))
67697
- );
67698
67906
  const nextQueryFilters = prev.queryFilters.rules.length ? prev.queryFilters : rulesFromReport(sourceReport);
67699
67907
  const pivotAggregationsFromSource = Array.isArray(sourceReport.pivot?.aggregations) ? sourceReport.pivot.aggregations : sourceReport.pivot?.aggregationType ? [
67700
67908
  {
@@ -67761,6 +67969,9 @@ function useReport(reportIdArg, options = {}) {
67761
67969
  tables: tableScopeForDisplayColumns,
67762
67970
  schemaTables: schemaForReportBuilderState
67763
67971
  });
67972
+ const sourceQueryColumns = normalizeReportBuilderColumns(
67973
+ sourceReport.reportBuilderState?.columns?.length ? sourceReport.reportBuilderState.columns : sourceDisplayColumnsFromSchema
67974
+ );
67764
67975
  const savedDisplayColumns = normalizeReportBuilderColumns(
67765
67976
  (sourceReport.columns ?? []).map((column) => ({
67766
67977
  ...column,
@@ -68274,13 +68485,12 @@ function useReport(reportIdArg, options = {}) {
68274
68485
  tables: effectiveReportBuilderState.tables,
68275
68486
  schemaTables: schemaForReportBuilderState
68276
68487
  });
68277
- const columnsToFetch = allColumnsBySelectedTable.length > 0 ? allColumnsBySelectedTable : effectiveReportBuilderState.columns;
68278
- if (columnsToFetch.length === 0) {
68488
+ if (allColumnsBySelectedTable.length === 0) {
68279
68489
  return void 0;
68280
68490
  }
68281
68491
  return {
68282
68492
  ...effectiveReportBuilderState,
68283
- columns: columnsToFetch,
68493
+ columns: allColumnsBySelectedTable,
68284
68494
  pivot: null,
68285
68495
  sort: [],
68286
68496
  limit: null
@@ -68323,6 +68533,29 @@ function useReport(reportIdArg, options = {}) {
68323
68533
  refreshDecision.shouldRefresh,
68324
68534
  queryFilters
68325
68535
  ]);
68536
+ const shouldSkipRedundantPivotTableDataQuery = (0, import_react63.useMemo)(() => {
68537
+ if (!sourceReport || !pivotState) {
68538
+ return false;
68539
+ }
68540
+ if (tableRefreshVersion !== 0 || pivotRefreshVersion !== 0) {
68541
+ return false;
68542
+ }
68543
+ if (!Array.isArray(sourceReport.rows) || sourceReport.rows.length === 0) {
68544
+ return false;
68545
+ }
68546
+ if (refreshDecision.shouldRefresh) {
68547
+ return false;
68548
+ }
68549
+ const sourceRules = sourceReport.reportBuilderState?.rules ?? EMPTY_QUERY_FILTERS;
68550
+ return stableSerializeForQueryKey(queryFilters) === stableSerializeForQueryKey(sourceRules);
68551
+ }, [
68552
+ sourceReport,
68553
+ pivotState,
68554
+ tableRefreshVersion,
68555
+ pivotRefreshVersion,
68556
+ refreshDecision.shouldRefresh,
68557
+ queryFilters
68558
+ ]);
68326
68559
  const shouldForceTableRefreshFromFilters = !useInMemoryEngines && !pivotState;
68327
68560
  const immediateTableRefreshInput = (0, import_react63.useMemo)(
68328
68561
  () => ({
@@ -68371,8 +68604,14 @@ function useReport(reportIdArg, options = {}) {
68371
68604
  operation: "table"
68372
68605
  });
68373
68606
  if (cachedReport) {
68607
+ profileDashboard("use-report-table-refresh-cachecab-hit", {
68608
+ reportId: effectiveReportId
68609
+ });
68374
68610
  return { report: cachedReport };
68375
68611
  }
68612
+ profileDashboard("use-report-table-refresh-network", {
68613
+ reportId: effectiveReportId
68614
+ });
68376
68615
  return loadViaReportBuilderState({
68377
68616
  reportId: effectiveReportId,
68378
68617
  reportBuilderState: tableRefreshInput.reportBuilderState,
@@ -68985,31 +69224,9 @@ function useReport(reportIdArg, options = {}) {
68985
69224
  shouldSkipPivotRefreshForUnchangedPivot,
68986
69225
  sourceReport
68987
69226
  ]);
68988
- const shouldSkipRedundantPivotTableDataReportBuilderQuery = (0, import_react63.useMemo)(() => {
68989
- if (!sourceReport || !nextPivot) {
68990
- return false;
68991
- }
68992
- if (tableRefreshVersion !== 0 || pivotRefreshVersion !== 0) {
68993
- return false;
68994
- }
68995
- if (!Array.isArray(sourceReport.rows) || sourceReport.rows.length === 0) {
68996
- return false;
68997
- }
68998
- if (refreshDecision.shouldRefresh) {
68999
- return false;
69000
- }
69001
- const sourceRules = sourceReport.reportBuilderState?.rules ?? EMPTY_QUERY_FILTERS;
69002
- return stableSerializeForQueryKey(queryFilters) === stableSerializeForQueryKey(sourceRules);
69003
- }, [
69004
- sourceReport,
69005
- nextPivot,
69006
- tableRefreshVersion,
69007
- pivotRefreshVersion,
69008
- refreshDecision.shouldRefresh,
69009
- queryFilters
69010
- ]);
69011
69227
  const pivotRefreshQueryEnabled = !reportOverride && pendingPivotRefresh && !shouldSkipPivotRefreshForUnchangedPivot && Boolean(sourceReport) && Boolean(client) && Boolean(effectiveReportBuilderState) && Boolean(nextPivot) && sourceReportMatchesEffectiveReportId;
69012
- const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId && !shouldSkipRedundantPivotTableDataReportBuilderQuery;
69228
+ const initialLoadSettled = Boolean(reportOverride) || !effectiveReportId || Boolean(client) && !initialLoadQuery.isPending && !initialLoadQuery.isFetching;
69229
+ const pivotTableDataRefreshQueryEnabled = !reportOverride && Boolean(sourceReport) && Boolean(client) && Boolean(nextPivot) && Boolean(pivotTableDataReportBuilderState) && !pendingPivotRefresh && sourceReportMatchesEffectiveReportId && initialLoadSettled && !shouldSkipRedundantPivotTableDataQuery;
69013
69230
  const pivotRefreshQuery = (0, import_react_query3.useQuery)({
69014
69231
  queryKey: createUseFormPivotRefreshQueryKey({
69015
69232
  reportId: effectiveReportId,
@@ -69123,7 +69340,7 @@ function useReport(reportIdArg, options = {}) {
69123
69340
  const paginationRangeStart = pagination.pageIndex * pagination.pageSize;
69124
69341
  const paginationRangeEnd = paginationRangeStart + pagination.pageSize;
69125
69342
  const pageWithinBaseWindow = paginationRangeEnd <= baseWindowRowsLength || trustedSourceRowCount !== void 0 && trustedSourceRowCount <= baseWindowRowsLength;
69126
- const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh;
69343
+ const tablePageQueryEnabled = !pageWithinBaseWindow && !reportOverride && !useInMemoryEngines && Boolean(client) && Boolean(sourceReport) && Boolean(tablePageReportBuilderState) && sourceReportMatchesEffectiveReportId && !pendingPivotRefresh && initialLoadSettled;
69127
69344
  const tablePageQuery = (0, import_react_query3.useQuery)({
69128
69345
  queryKey: createUseFormTablePageQueryKey({
69129
69346
  reportId: effectiveReportId,
@@ -69295,21 +69512,17 @@ function useReport(reportIdArg, options = {}) {
69295
69512
  if (!sourceReport) return void 0;
69296
69513
  const rowsForChart = Array.isArray(sourceReport.rows) ? sourceReport.rows : [];
69297
69514
  const chartPivot = pendingPivotChangesDimensions ? sourceReport.pivot ?? null : nextPivot ?? (!chartPivotHydratedFromSourceRef.current ? sourceReport.pivot ?? null : null);
69298
- const chartPivotForDisplay = chartPivot && sourceReport.pivotResultRowField && sourceReport.pivotResultSourceRowField === chartPivot.rowField ? {
69299
- ...chartPivot,
69300
- rowField: sourceReport.pivotResultRowField
69301
- } : chartPivot;
69302
- const rowCountForChart = chartPivotForDisplay ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69515
+ const rowCountForChart = chartPivot ? sourceReport.pivotRowCount ?? (Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows.length : sourceReport.rowCount) : useInMemoryEngines ? rowsForChart.length : sourceReport.rowCount;
69303
69516
  const referencedTablesForChart = effectiveReportBuilderState?.tables.map((table2) => table2.name).filter((name2) => Boolean(name2));
69304
69517
  const pivotRowsForChart = Array.isArray(sourceReport.pivotRows) ? sourceReport.pivotRows : void 0;
69305
- const rowCountForChartResolved = chartPivotForDisplay ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69518
+ const rowCountForChartResolved = chartPivot ? Array.isArray(pivotRowsForChart) ? pivotRowsForChart.length : rowCountForChart : rowCountForChart;
69306
69519
  const chartDataPayload = {
69307
69520
  ...sourceReport,
69308
69521
  rows: rowsForChart,
69309
69522
  rowCount: rowCountForChartResolved,
69310
69523
  chartType: chartType ?? sourceReport.chartType,
69311
69524
  reportBuilderState: effectiveReportBuilderState,
69312
- pivot: chartPivotForDisplay,
69525
+ pivot: chartPivot,
69313
69526
  referencedTables: referencedTablesForChart && referencedTablesForChart.length > 0 ? referencedTablesForChart : sourceReport.referencedTables,
69314
69527
  pivotRows: pivotRowsForChart,
69315
69528
  pivotColumns: sourceReport.pivotColumns,
@@ -69390,7 +69603,7 @@ function useReport(reportIdArg, options = {}) {
69390
69603
  const xAxisOptions = (0, import_react63.useMemo)(() => {
69391
69604
  if (!chartAxesBaseChart) return chartAxisOptions;
69392
69605
  const pivot = chartAxesBaseChart.pivot;
69393
- const pivotRowField = String(pivot?.rowField ?? "").trim();
69606
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69394
69607
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69395
69608
  if (pivot && pivotRowField) {
69396
69609
  if (["metric", "gauge"].includes(chartType2)) {
@@ -69511,9 +69724,7 @@ function useReport(reportIdArg, options = {}) {
69511
69724
  const resolvedXAxisField = (0, import_react63.useMemo)(() => {
69512
69725
  if (!chartAxesBaseChart) return "";
69513
69726
  const chartType2 = String(chartAxesBaseChart.chartType ?? "").toLowerCase();
69514
- const pivotRowField = String(
69515
- chartAxesBaseChart.pivot?.rowField ?? ""
69516
- ).trim();
69727
+ const pivotRowField = pivotRowKey(chartAxesBaseChart);
69517
69728
  if (pivotRowField) {
69518
69729
  const rowColumn = (chartAxesBaseChart.pivotColumns ?? chartAxesBaseChart.columns ?? []).find((col) => String(col.field ?? "").trim() === pivotRowField);
69519
69730
  if (shouldUsePivotRowFieldAsXAxis(
@@ -69649,11 +69860,11 @@ function useReport(reportIdArg, options = {}) {
69649
69860
  columns2 = mergePivotTableDisplayColumnLabelsFromYAxis({
69650
69861
  columns: columns2 ?? baseChart.columns,
69651
69862
  yAxisFields: resolvedYAxisFieldsForDisplay,
69652
- pivotRowField: String(baseChart.pivot.rowField ?? ""),
69863
+ pivotRowField: pivotRowKey(baseChart),
69653
69864
  xAxisLabel: resolvedXAxisLabel
69654
69865
  });
69655
69866
  } else {
69656
- const pivotRowField = String(baseChart.pivot.rowField ?? "").trim();
69867
+ const pivotRowField = pivotRowKey(baseChart);
69657
69868
  const pivotLabelByField = new Map(
69658
69869
  (baseChart.pivotColumns ?? []).map((column) => [
69659
69870
  String(column.field ?? "").trim(),
@@ -69718,7 +69929,10 @@ function useReport(reportIdArg, options = {}) {
69718
69929
  const key = String(raw);
69719
69930
  const timestamp = new Date(key).getTime();
69720
69931
  if (Number.isNaN(timestamp)) continue;
69721
- labelsByRaw.set(key, String(record[rowField] ?? key));
69932
+ labelsByRaw.set(
69933
+ key,
69934
+ String(record[pivotRowKey(chart)] ?? record[rowField] ?? key)
69935
+ );
69722
69936
  const cachedMin = pivotDateFilterRangeCacheRef.current.min;
69723
69937
  const cachedMax = pivotDateFilterRangeCacheRef.current.max;
69724
69938
  if (cachedMin == null || timestamp < new Date(cachedMin).getTime()) {
@@ -70019,9 +70233,7 @@ function useReport(reportIdArg, options = {}) {
70019
70233
  sourceReport,
70020
70234
  includeSelectedSchemaFallback: tableColumnsEditedSignature !== null
70021
70235
  });
70022
- const pivotRowFieldForTable = String(
70023
- sourceReport?.pivot?.rowField ?? ""
70024
- ).trim();
70236
+ const pivotRowFieldForTable = pivotRowKey(sourceReport);
70025
70237
  const pivotRowTableUsesAxisFormat = chartAxisEdits.xAxisFormat !== void 0;
70026
70238
  const columns2 = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot && pivotRowFieldForTable && String(resolvedXAxisField ?? "").trim() === pivotRowFieldForTable ? mergedFromReport.map(
70027
70239
  (column) => column.field === pivotRowFieldForTable ? {
@@ -70033,7 +70245,7 @@ function useReport(reportIdArg, options = {}) {
70033
70245
  const pivotLabeledColumns = String(chartType ?? "").toLowerCase() === "table" && sourceReport?.pivot ? mergePivotTableDisplayColumnLabelsFromYAxis({
70034
70246
  columns: columns2,
70035
70247
  yAxisFields: resolvedYAxisFieldsForDisplay,
70036
- pivotRowField: String(sourceReport.pivot.rowField ?? ""),
70248
+ pivotRowField: pivotRowKey(sourceReport),
70037
70249
  xAxisLabel: resolvedXAxisLabel
70038
70250
  }) ?? columns2 : columns2;
70039
70251
  const tableColumnsWithPivotDisplayLabels = pivotLabeledColumns.map(
@@ -70282,7 +70494,7 @@ function useReport(reportIdArg, options = {}) {
70282
70494
  if (slotFormatting) {
70283
70495
  const aggregations = slotFormatting.aggregations;
70284
70496
  const hasMultiple = aggregations.length > 1;
70285
- const rowField = String(pivotState?.rowField ?? "").trim();
70497
+ const rowField = pivotRowKey(chart);
70286
70498
  const firstValueColumnFormat = String(
70287
70499
  (chart.columns ?? []).find(
70288
70500
  (c) => String(c.field ?? "").trim() !== rowField
@@ -70318,9 +70530,7 @@ function useReport(reportIdArg, options = {}) {
70318
70530
  }
70319
70531
  }
70320
70532
  }
70321
- const pivotRowFieldForSettings = String(
70322
- chart?.pivot?.rowField ?? ""
70323
- ).trim();
70533
+ const pivotRowFieldForSettings = pivotRowKey(chart);
70324
70534
  const rowAxisLabel = String(resolvedXAxisLabel ?? "").trim();
70325
70535
  for (const columnId of activeTableColumnIds) {
70326
70536
  const option = columnOptionById.get(columnId);
@@ -70380,7 +70590,7 @@ function useReport(reportIdArg, options = {}) {
70380
70590
  tableColumnSettingsCoalesceRef.current = new Map(tableColumnSettingsById);
70381
70591
  }, [tableColumnSettingsById]);
70382
70592
  const tableColumnItems = (0, import_react63.useMemo)(() => {
70383
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70593
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70384
70594
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70385
70595
  const items = activeTableColumnIds.map((columnId) => {
70386
70596
  const option = columnOptionById.get(columnId);
@@ -70419,7 +70629,7 @@ function useReport(reportIdArg, options = {}) {
70419
70629
  return new Map(tableColumnItems.map((item) => [item.id, item]));
70420
70630
  }, [tableColumnItems]);
70421
70631
  const tableColumnValues = (0, import_react63.useMemo)(() => {
70422
- const pivotRowFieldForFormat = String(chart?.pivot?.rowField ?? "").trim();
70632
+ const pivotRowFieldForFormat = pivotRowKey(chart);
70423
70633
  const pivotRowFieldType = String(chart?.pivot?.rowFieldType ?? "").trim();
70424
70634
  return tableColumnItems.map((item) => {
70425
70635
  const coerced = coerceTableColumnFormatToAxisValue(item.format);
@@ -70440,8 +70650,89 @@ function useReport(reportIdArg, options = {}) {
70440
70650
  const initialLoadInProgress = !reportOverride && Boolean(effectiveReportId) && (!client || initialLoadQuery.isPending || initialLoadQuery.isFetching);
70441
70651
  const filterUniqueValuesLoading = filterUniqueValuesEnabled && (filterUniqueValuesQuery.isPending || filterUniqueValuesQuery.isFetching);
70442
70652
  const chartLoading = initialLoadInProgress || pendingPivotRefresh || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70443
- const tableLoading = initialLoadInProgress || pendingPivotRefresh || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70653
+ const awaitingPivotDetailRows = Boolean(nextPivot || sourceReport?.pivot) && !reportOverride && Boolean(sourceReport) && sourceReportMatchesEffectiveReportId && (!Array.isArray(sourceReport?.rows) || sourceReport.rows.length === 0) && pivotTableDataRefreshQuery.status !== "error";
70654
+ const tableLoading = initialLoadInProgress || pendingPivotRefresh || awaitingPivotDetailRows || tablePageFetching && pagination.pageIndex > 0 || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
70444
70655
  const loading = chartLoading || tableLoading;
70656
+ const lastUseReportLoadingLogRef = (0, import_react63.useRef)("");
70657
+ (0, import_react63.useEffect)(() => {
70658
+ const snapshot = {
70659
+ reportId: effectiveReportId,
70660
+ chartLoading,
70661
+ tableLoading,
70662
+ loading,
70663
+ initialLoadInProgress,
70664
+ initialLoad: {
70665
+ status: initialLoadQuery.status,
70666
+ fetchStatus: initialLoadQuery.fetchStatus,
70667
+ isPending: initialLoadQuery.isPending,
70668
+ isFetching: initialLoadQuery.isFetching,
70669
+ hasData: initialLoadQuery.data !== void 0,
70670
+ dataUpdatedAt: initialLoadQuery.dataUpdatedAt,
70671
+ staleTime: 0
70672
+ },
70673
+ pendingPivotRefresh,
70674
+ pivotRefresh: {
70675
+ enabled: pivotRefreshQueryEnabled,
70676
+ isFetching: pivotRefreshQuery.isFetching
70677
+ },
70678
+ tableRefresh: {
70679
+ enabled: tableRefreshQueryEnabled,
70680
+ isFetching: tableRefreshQuery.isFetching
70681
+ },
70682
+ pivotTableData: {
70683
+ enabled: pivotTableDataRefreshQueryEnabled,
70684
+ isFetching: pivotTableDataRefreshQuery.isFetching
70685
+ },
70686
+ tablePage: {
70687
+ enabled: tablePageQueryEnabled,
70688
+ isFetching: tablePageQuery.isFetching
70689
+ },
70690
+ uniqueValues: {
70691
+ enabled: filterUniqueValuesEnabled,
70692
+ isFetching: filterUniqueValuesQuery.isFetching,
70693
+ isPending: filterUniqueValuesQuery.isPending
70694
+ },
70695
+ whyChartLoading: {
70696
+ noClient: !client,
70697
+ initialPending: initialLoadQuery.isPending,
70698
+ initialFetching: initialLoadQuery.isFetching,
70699
+ pendingPivotRefresh,
70700
+ pivotRefreshFetching: Boolean(nextPivot) && pivotRefreshQuery.isFetching,
70701
+ tableRefreshFetching: !nextPivot && tableRefreshQuery.isFetching
70702
+ }
70703
+ };
70704
+ const serialized = JSON.stringify(snapshot);
70705
+ if (serialized === lastUseReportLoadingLogRef.current) return;
70706
+ lastUseReportLoadingLogRef.current = serialized;
70707
+ profileDashboard("use-report-loading", snapshot);
70708
+ }, [
70709
+ client,
70710
+ chartLoading,
70711
+ effectiveReportId,
70712
+ filterUniqueValuesEnabled,
70713
+ filterUniqueValuesQuery.fetchStatus,
70714
+ filterUniqueValuesQuery.isFetching,
70715
+ filterUniqueValuesQuery.isPending,
70716
+ initialLoadInProgress,
70717
+ initialLoadQuery.data,
70718
+ initialLoadQuery.dataUpdatedAt,
70719
+ initialLoadQuery.fetchStatus,
70720
+ initialLoadQuery.isFetching,
70721
+ initialLoadQuery.isPending,
70722
+ initialLoadQuery.status,
70723
+ loading,
70724
+ nextPivot,
70725
+ pendingPivotRefresh,
70726
+ pivotRefreshQuery.isFetching,
70727
+ pivotRefreshQueryEnabled,
70728
+ pivotTableDataRefreshQuery.isFetching,
70729
+ pivotTableDataRefreshQueryEnabled,
70730
+ tableLoading,
70731
+ tablePageQuery.isFetching,
70732
+ tablePageQueryEnabled,
70733
+ tableRefreshQuery.isFetching,
70734
+ tableRefreshQueryEnabled
70735
+ ]);
70445
70736
  const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
70446
70737
  const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
70447
70738
  return normalizedNextIds.map((columnId) => {
@@ -70481,7 +70772,7 @@ function useReport(reportIdArg, options = {}) {
70481
70772
  const option = columnOptionById.get(normalizedId);
70482
70773
  const pivotField = String(option?.field ?? normalizedId).trim();
70483
70774
  const pivotModel = chartAxesBaseChart.pivot;
70484
- const rowField = String(pivotModel?.rowField ?? "").trim();
70775
+ const rowField = pivotRowKey(chartAxesBaseChart);
70485
70776
  if (!pivotModel) return null;
70486
70777
  const isPivotRowColumn = Boolean(
70487
70778
  pivotField && rowField && pivotField === rowField