@quillsql/react 2.16.63 → 2.16.65

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 +210 -115
  2. package/dist/index.js +211 -116
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -22972,6 +22972,7 @@ var fetchReportBuilderDataFromState = async ({
22972
22972
  customFields,
22973
22973
  skipUniqueValues,
22974
22974
  skipRowCount,
22975
+ rowCountOnly,
22975
22976
  processing,
22976
22977
  dashboardName,
22977
22978
  getToken,
@@ -23048,7 +23049,7 @@ var fetchReportBuilderDataFromState = async ({
23048
23049
  processing ?? { page: DEFAULT_PAGINATION },
23049
23050
  customFields,
23050
23051
  skipRowCount,
23051
- void 0,
23052
+ rowCountOnly,
23052
23053
  curReport?.id ? String(curReport.id).trim() : void 0,
23053
23054
  draftSessionId ? String(draftSessionId).trim() : void 0
23054
23055
  );
@@ -61220,22 +61221,18 @@ function normalizePivotChartForAxisControls(chart, reportId) {
61220
61221
  yAxisFields
61221
61222
  };
61222
61223
  }
61223
- function buildPivotColumnPivotTableFormattingColumns(chart) {
61224
- if (!Array.isArray(chart.columns) || chart.columns.length === 0) {
61225
- return null;
61226
- }
61227
- const columnField = String(chart.pivot?.columnField ?? "").trim();
61228
- const aggregations = getPivotAggregations(chart);
61229
- if (!columnField || aggregations.length === 0) {
61230
- return null;
61231
- }
61224
+ function buildPivotColumnPivotTableFormattingColumns(pivot, chart) {
61225
+ if (!pivot) return null;
61226
+ const reportForControls = chart ? { ...chart, pivot } : { pivot };
61227
+ const aggregations = getPivotAggregations(reportForControls);
61228
+ if (aggregations.length === 0) return null;
61232
61229
  const hasMultipleAggregations = aggregations.length > 1;
61233
- const rowField = String(chart.pivot?.rowField ?? "").trim();
61230
+ const rowField = String(pivot.rowField ?? "").trim();
61234
61231
  const tableColumns = [];
61235
61232
  const selectedColumnIds = [];
61236
61233
  if (rowField) {
61237
- const rowSource = chart.columns.find(
61238
- (c) => String(c.field ?? "").trim() === rowField
61234
+ const rowSource = chart?.columns?.find(
61235
+ (column) => String(column.field ?? "").trim() === rowField
61239
61236
  );
61240
61237
  const rowTable = String(
61241
61238
  rowSource?.table ?? ""
@@ -61243,8 +61240,8 @@ function buildPivotColumnPivotTableFormattingColumns(chart) {
61243
61240
  tableColumns.push({
61244
61241
  field: rowField,
61245
61242
  label: String(
61246
- rowSource?.label ?? chart.xAxisLabel ?? chart.xAxisField ?? rowField
61247
- ).trim() || rowField
61243
+ rowSource?.label ?? chart?.xAxisLabel ?? chart?.xAxisField ?? toTitleCaseLabel(rowField)
61244
+ ).trim() || toTitleCaseLabel(rowField)
61248
61245
  });
61249
61246
  const rowId = encodeColumnOptionValue(rowTable || void 0, rowField);
61250
61247
  if (rowId) {
@@ -61259,14 +61256,14 @@ function buildPivotColumnPivotTableFormattingColumns(chart) {
61259
61256
  if (!fieldKey) continue;
61260
61257
  tableColumns.push({
61261
61258
  field: fieldKey,
61262
- label: buildAggregationLabel(aggregation, chart)
61259
+ label: buildAggregationLabel(aggregation, reportForControls)
61263
61260
  });
61264
61261
  const id = encodeColumnOptionValue(void 0, fieldKey);
61265
61262
  if (id) {
61266
61263
  selectedColumnIds.push(id);
61267
61264
  }
61268
61265
  }
61269
- return { tableColumns, selectedColumnIds };
61266
+ return { tableColumns, selectedColumnIds, aggregations };
61270
61267
  }
61271
61268
  function mergePivotColumnSeriesLabelWithUserEdit(normalizedLabel, userRowLabel, pivotSeriesField) {
61272
61269
  const user = String(userRowLabel ?? "").trim();
@@ -63046,7 +63043,9 @@ async function loadViaReportBuilderState({
63046
63043
  report,
63047
63044
  draftSessionId,
63048
63045
  pagination,
63049
- paginationSort
63046
+ paginationSort,
63047
+ rowsOnly,
63048
+ rowCountOnly
63050
63049
  }) {
63051
63050
  const baseReport = {
63052
63051
  ...EMPTY_INTERNAL_REPORT,
@@ -63066,6 +63065,8 @@ async function loadViaReportBuilderState({
63066
63065
  // Unique values are fetched separately via `filterUniqueValuesQuery` so chart/table
63067
63066
  // refresh queries are not blocked on `report-builder-unique-values`.
63068
63067
  skipUniqueValues: true,
63068
+ skipRowCount: rowsOnly,
63069
+ rowCountOnly,
63069
63070
  previousRelevant: previousRelevantWhenSkippingInlineUniqueFetch(report),
63070
63071
  processing: pagination ? {
63071
63072
  page: {
@@ -63129,6 +63130,9 @@ async function loadViaReportBuilderState({
63129
63130
  report: {
63130
63131
  ...baseReport,
63131
63132
  ...reportBuilderInfo.report,
63133
+ // A rows-only response intentionally has no count; retain the previous
63134
+ // value until the independent count query completes.
63135
+ rowCount: rowsOnly ? baseReport.rowCount : reportBuilderInfo.report.rowCount,
63132
63136
  reportBuilderState: normalizedReportBuilderState,
63133
63137
  pivot: reportBuilderState.pivot,
63134
63138
  pivotRows: refreshedPivotData?.rows ?? compatibleReportPivotRows ?? (canReuseBasePivotRowsAndColumns ? baseReport.pivotRows : []) ?? [],
@@ -63158,7 +63162,8 @@ async function loadReportForUseForm({
63158
63162
  customFields,
63159
63163
  dashboardName,
63160
63164
  useInMemoryEngines,
63161
- draftSessionId
63165
+ draftSessionId,
63166
+ rowsOnly = false
63162
63167
  }) {
63163
63168
  const effectivePivot = pivot ?? initialReportBuilderState?.pivot ?? void 0;
63164
63169
  const hasPivot = Boolean(effectivePivot);
@@ -63255,7 +63260,9 @@ async function loadReportForUseForm({
63255
63260
  schema,
63256
63261
  customFields,
63257
63262
  dashboardName,
63258
- draftSessionId
63263
+ report: baseReport,
63264
+ draftSessionId,
63265
+ rowsOnly
63259
63266
  });
63260
63267
  }
63261
63268
  function generateDraftSessionId() {
@@ -63263,8 +63270,8 @@ function generateDraftSessionId() {
63263
63270
  }
63264
63271
  function useReport(reportIdArg, options = {}) {
63265
63272
  const propReportId = String(reportIdArg ?? "").trim();
63266
- const [createdReportId, setCreatedReportId] = (0, import_react61.useState)(null);
63267
- const effectiveReportId = propReportId || createdReportId || "";
63273
+ const [createdReportBootstrap, setCreatedReportBootstrap] = (0, import_react61.useState)(null);
63274
+ const effectiveReportId = propReportId || createdReportBootstrap?.reportId || "";
63268
63275
  const { eventTracking } = (0, import_react61.useContext)(EventTrackingContext);
63269
63276
  const [draftSessionId, setDraftSessionId] = (0, import_react61.useState)(generateDraftSessionId);
63270
63277
  const useInMemoryEngines = options.useInMemoryEngines ?? false;
@@ -63481,13 +63488,57 @@ function useReport(reportIdArg, options = {}) {
63481
63488
  const dashboardNameForNewReport = (0, import_react61.useMemo)(() => {
63482
63489
  return [clientDefaultDashboardName, destinationDashboardName].map((entry) => String(entry ?? "").trim()).find((entry) => entry.length > 0) ?? "";
63483
63490
  }, [clientDefaultDashboardName, destinationDashboardName]);
63491
+ const { mutate: createReport } = (0, import_react_query2.useMutation)({
63492
+ mutationKey: ["useReport", "create-report", draftSessionId],
63493
+ mutationFn: async ({
63494
+ reportBuilderState,
63495
+ tables
63496
+ }) => {
63497
+ if (!client) {
63498
+ throw new Error("Missing client for create-report");
63499
+ }
63500
+ const fallbackName = tables[0]?.name ? snakeAndCamelCaseToTitleCase(tables[0].name) : "New report";
63501
+ const resp = await saveReport({
63502
+ report: {
63503
+ ...EMPTY_INTERNAL_REPORT,
63504
+ name: fallbackName,
63505
+ chartType: "table",
63506
+ dashboardName: "quill-draft-reports",
63507
+ reportBuilderState
63508
+ },
63509
+ client,
63510
+ getToken,
63511
+ eventTracking,
63512
+ tenants,
63513
+ draftSessionId: draftSessionId || void 0
63514
+ });
63515
+ const reportId = String(resp?.id ?? resp?._id ?? "").trim();
63516
+ if (!reportId) {
63517
+ throw new Error("create-report returned no report id");
63518
+ }
63519
+ return {
63520
+ reportId,
63521
+ reportBuilderState,
63522
+ report: {
63523
+ ...EMPTY_INTERNAL_REPORT,
63524
+ ...resp,
63525
+ id: reportId,
63526
+ name: String(resp?.name ?? "").trim() || fallbackName,
63527
+ dashboardName: String(resp?.dashboardName ?? "").trim() || "quill-draft-reports",
63528
+ chartType: resp?.chartType ?? "table",
63529
+ pivot: null,
63530
+ reportBuilderState
63531
+ }
63532
+ };
63533
+ }
63534
+ });
63484
63535
  const filterStackRef = (0, import_react61.useRef)(filterStack);
63485
63536
  filterStackRef.current = filterStack;
63486
63537
  const resolvedGroupRowsBy = decodePivotGroupOptionValue(groupRowsBy);
63487
63538
  const resolvedGroupColumnsBy = decodePivotGroupOptionValue(groupColumnsBy);
63488
63539
  (0, import_react61.useEffect)(() => {
63489
63540
  if (propReportId) {
63490
- setCreatedReportId(null);
63541
+ setCreatedReportBootstrap(null);
63491
63542
  }
63492
63543
  }, [propReportId]);
63493
63544
  (0, import_react61.useEffect)(() => {
@@ -63567,7 +63618,7 @@ function useReport(reportIdArg, options = {}) {
63567
63618
  (0, import_react61.useEffect)(() => {
63568
63619
  if (reportOverride) return;
63569
63620
  if (propReportId) return;
63570
- if (createdReportId) return;
63621
+ if (createdReportBootstrap) return;
63571
63622
  if (!client) return;
63572
63623
  if (!String(dashboardNameForNewReport ?? "").trim()) {
63573
63624
  return;
@@ -63598,59 +63649,34 @@ function useReport(reportIdArg, options = {}) {
63598
63649
  );
63599
63650
  }
63600
63651
  if (bootstrapColumns.length === 0) return;
63601
- let cancelled = false;
63602
- (async () => {
63603
- try {
63604
- const fkMapForMerge = getSchemaForeignKeyMapping(
63605
- schemaForReportBuilderState
63606
- );
63607
- const tables = mergeReportBuilderTables(
63608
- ids.map((name2) => ({ name: name2 })),
63609
- bootstrapColumns.map((col) => String(col.table ?? "").trim()).filter(Boolean),
63610
- fkMapForMerge
63611
- );
63612
- const reportBuilderState = {
63613
- tables,
63614
- columns: bootstrapColumns,
63615
- filterStack: [],
63616
- sort: [],
63617
- limit: null,
63618
- pivot: null
63619
- };
63620
- const resp = await saveReport({
63621
- report: {
63622
- ...EMPTY_INTERNAL_REPORT,
63623
- name: tables[0]?.name ? snakeAndCamelCaseToTitleCase(tables[0].name) : "New report",
63624
- chartType: "table",
63625
- dashboardName: "quill-draft-reports",
63626
- reportBuilderState
63627
- },
63628
- client,
63629
- getToken,
63630
- eventTracking,
63631
- tenants,
63632
- draftSessionId: draftSessionId || void 0
63633
- });
63634
- if (cancelled) return;
63635
- const id = String(resp?.id ?? resp?._id ?? "").trim();
63636
- if (id) setCreatedReportId(id);
63637
- } catch {
63638
- }
63639
- })();
63640
- return () => {
63641
- cancelled = true;
63652
+ const fkMapForMerge = getSchemaForeignKeyMapping(
63653
+ schemaForReportBuilderState
63654
+ );
63655
+ const tables = mergeReportBuilderTables(
63656
+ ids.map((name2) => ({ name: name2 })),
63657
+ bootstrapColumns.map((col) => String(col.table ?? "").trim()).filter(Boolean),
63658
+ fkMapForMerge
63659
+ );
63660
+ const reportBuilderState = {
63661
+ tables,
63662
+ columns: bootstrapColumns,
63663
+ filterStack: [],
63664
+ sort: [],
63665
+ limit: null,
63666
+ pivot: null
63642
63667
  };
63668
+ createReport(
63669
+ { reportBuilderState, tables },
63670
+ { onSuccess: setCreatedReportBootstrap }
63671
+ );
63643
63672
  }, [
63644
63673
  reportOverride,
63645
63674
  propReportId,
63646
- createdReportId,
63675
+ createdReportBootstrap,
63647
63676
  client,
63677
+ createReport,
63648
63678
  schemaDatasourceIdsKey,
63649
63679
  dashboardNameForNewReport,
63650
- draftSessionId,
63651
- getToken,
63652
- eventTracking,
63653
- tenants,
63654
63680
  schemaForReportBuilderState,
63655
63681
  queryColumnsBootstrapKey
63656
63682
  ]);
@@ -64096,7 +64122,7 @@ function useReport(reportIdArg, options = {}) {
64096
64122
  }
64097
64123
  });
64098
64124
  return { uniqueValuesByColumn: normalizedUniqueValuesByColumn };
64099
- } catch (error) {
64125
+ } catch {
64100
64126
  return { uniqueValuesByColumn: {} };
64101
64127
  }
64102
64128
  }),
@@ -64525,19 +64551,27 @@ function useReport(reportIdArg, options = {}) {
64525
64551
  setExpandReportBuilderColumnsForFlatTable(false);
64526
64552
  prevPivotStateForColumnExpansionRef.current = null;
64527
64553
  }, [propReportId, reportOverride]);
64554
+ const createdBootstrapForInitialLoad = !propReportId && createdReportBootstrap?.reportId === effectiveReportId ? createdReportBootstrap : null;
64555
+ const initialReportBuilderStateForLoad = initialReportBuilderState ?? createdBootstrapForInitialLoad?.reportBuilderState ?? null;
64556
+ const initialBaseReportForLoad = createdBootstrapForInitialLoad?.report ?? null;
64557
+ const isCreatedReportBootstrapLoad = Boolean(
64558
+ createdBootstrapForInitialLoad && initialReportBuilderStateForLoad
64559
+ );
64528
64560
  const initialLoadQuery = (0, import_react_query2.useQuery)({
64529
64561
  queryKey: createUseFormInitialLoadQueryKey({
64530
64562
  reportId: effectiveReportId,
64531
64563
  draftSessionId,
64532
64564
  useInMemoryEngines,
64533
- hasInitialReportBuilderState: Boolean(initialReportBuilderState),
64565
+ hasInitialReportBuilderState: Boolean(
64566
+ initialReportBuilderStateForLoad
64567
+ ),
64534
64568
  reloadKeyHash,
64535
64569
  tenantHash,
64536
64570
  flagHash,
64537
64571
  clientHash
64538
64572
  }),
64539
64573
  queryFn: createUseFormQueryFn(async () => {
64540
- const allowReportTaskBootstrap = !initialReportBuilderState && bootstrapReportTaskUsedForReportIdRef.current !== effectiveReportId;
64574
+ const allowReportTaskBootstrap = !initialReportBuilderStateForLoad && bootstrapReportTaskUsedForReportIdRef.current !== effectiveReportId;
64541
64575
  const loadTargetId = String(effectiveReportId ?? "").trim();
64542
64576
  const sourceReportIdentity = String(
64543
64577
  sourceReport?.id ?? sourceReport?._id ?? ""
@@ -64549,7 +64583,8 @@ function useReport(reportIdArg, options = {}) {
64549
64583
  }
64550
64584
  const loadResult = await loadReportForUseForm({
64551
64585
  reportId: effectiveReportId,
64552
- initialReportBuilderState,
64586
+ initialReportBuilderState: initialReportBuilderStateForLoad,
64587
+ baseReport: initialBaseReportForLoad,
64553
64588
  allowReportTaskBootstrap,
64554
64589
  client,
64555
64590
  getToken,
@@ -64560,7 +64595,8 @@ function useReport(reportIdArg, options = {}) {
64560
64595
  customFields: customFieldsRef.current,
64561
64596
  dashboardName: resolvedSourceDashboardName,
64562
64597
  useInMemoryEngines,
64563
- draftSessionId: draftSessionId || void 0
64598
+ draftSessionId: draftSessionId || void 0,
64599
+ rowsOnly: isCreatedReportBootstrapLoad
64564
64600
  });
64565
64601
  return loadResult;
64566
64602
  }),
@@ -65181,6 +65217,7 @@ function useReport(reportIdArg, options = {}) {
65181
65217
  () => stableSerializeForQueryKey(effectiveReportBuilderState),
65182
65218
  [effectiveReportBuilderState]
65183
65219
  );
65220
+ const createdBootstrapStateMatchesEffectiveState = isCreatedReportBootstrapLoad && stableSerializeForQueryKey(initialReportBuilderStateForLoad) === effectiveReportBuilderStateHash;
65184
65221
  const prevPaginationResetStateHashRef = (0, import_react61.useRef)(null);
65185
65222
  (0, import_react61.useEffect)(() => {
65186
65223
  const prevHash = prevPaginationResetStateHashRef.current;
@@ -65287,12 +65324,61 @@ function useReport(reportIdArg, options = {}) {
65287
65324
  enabled: tableRefreshQueryEnabled,
65288
65325
  retry: false
65289
65326
  });
65327
+ const createdBootstrapRowCountQuery = (0, import_react_query2.useQuery)({
65328
+ queryKey: [
65329
+ "useReport",
65330
+ "created-bootstrap-row-count",
65331
+ effectiveReportId,
65332
+ stableSerializeForQueryKey(initialReportBuilderStateForLoad),
65333
+ tenantHash,
65334
+ clientHash
65335
+ ],
65336
+ queryFn: createUseFormQueryFn(async () => {
65337
+ if (!createdBootstrapForInitialLoad || !initialReportBuilderStateForLoad || !client) {
65338
+ return { report: null, error: "Missing bootstrap count prerequisites" };
65339
+ }
65340
+ return loadViaReportBuilderState({
65341
+ reportId: effectiveReportId,
65342
+ reportBuilderState: initialReportBuilderStateForLoad,
65343
+ client,
65344
+ getToken,
65345
+ tenants,
65346
+ schema: schemaForReportBuilderState,
65347
+ customFields: schemaData.customFields,
65348
+ dashboardName: resolvedSourceDashboardName,
65349
+ report: createdBootstrapForInitialLoad.report,
65350
+ draftSessionId: draftSessionId || void 0,
65351
+ rowCountOnly: true
65352
+ });
65353
+ }),
65354
+ enabled: createdBootstrapStateMatchesEffectiveState && Boolean(client) && !reportOverride,
65355
+ retry: false
65356
+ });
65290
65357
  (0, import_react61.useEffect)(() => {
65291
65358
  if (!tableRefreshQueryEnabled) return;
65292
65359
  const report = tableRefreshQuery.data?.report;
65293
65360
  if (tableRefreshQuery.data?.error || !report) return;
65294
65361
  setSourceReport(report);
65295
65362
  }, [effectiveReportId, tableRefreshQuery.data, tableRefreshQueryEnabled]);
65363
+ (0, import_react61.useEffect)(() => {
65364
+ if (!createdBootstrapStateMatchesEffectiveState) return;
65365
+ const countReport = createdBootstrapRowCountQuery.data?.report;
65366
+ if (createdBootstrapRowCountQuery.data?.error || !countReport) return;
65367
+ setSourceReport((currentReport) => {
65368
+ if (!currentReport || currentReport.id !== effectiveReportId) {
65369
+ return currentReport;
65370
+ }
65371
+ if (currentReport.rowCount === countReport.rowCount) {
65372
+ return currentReport;
65373
+ }
65374
+ return { ...currentReport, rowCount: countReport.rowCount };
65375
+ });
65376
+ }, [
65377
+ createdBootstrapRowCountQuery.data,
65378
+ createdBootstrapStateMatchesEffectiveState,
65379
+ effectiveReportId,
65380
+ sourceReport?.id
65381
+ ]);
65296
65382
  const chartTypes = (0, import_react61.useMemo)(() => {
65297
65383
  return getChartTypeOptions2({ pivot: pivotState });
65298
65384
  }, [pivotState]);
@@ -65961,7 +66047,8 @@ function useReport(reportIdArg, options = {}) {
65961
66047
  pageIndex: pagination.pageIndex,
65962
66048
  pageSize: pagination.pageSize
65963
66049
  },
65964
- paginationSort: tablePaginationSort
66050
+ paginationSort: tablePaginationSort,
66051
+ rowsOnly: true
65965
66052
  });
65966
66053
  }),
65967
66054
  enabled: tablePageQueryEnabled,
@@ -66602,8 +66689,10 @@ function useReport(reportIdArg, options = {}) {
66602
66689
  }
66603
66690
  };
66604
66691
  }, [chart, filterOptions, filtersForQueryBuilder]);
66605
- const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(
66606
- chart && chart.pivot && Array.isArray(chart.columns) && chart.columns.length > 0
66692
+ const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(pivotState);
66693
+ const pivotTableColumnControls = (0, import_react61.useMemo)(
66694
+ () => isPivotTableChart ? buildPivotColumnPivotTableFormattingColumns(pivotState, chart) : null,
66695
+ [chart, isPivotTableChart, pivotState]
66607
66696
  );
66608
66697
  const chartAxes = (0, import_react61.useMemo)(() => {
66609
66698
  const yAxisItems = resolvedYAxisFields.map(
@@ -66903,24 +66992,19 @@ function useReport(reportIdArg, options = {}) {
66903
66992
  columnsOptions: tableFormattingColumnOptions,
66904
66993
  hasTableDrivenColumnOrder
66905
66994
  } = (0, import_react61.useMemo)(() => {
66906
- if (isPivotTableChart && chart?.columns?.length) {
66907
- const aggregationSlotColumns = buildPivotColumnPivotTableFormattingColumns(chart);
66908
- const pivotTableColumns = aggregationSlotColumns ? aggregationSlotColumns.tableColumns : chart.columns.map((c) => ({
66909
- field: String(c.field ?? "").trim(),
66910
- label: String(c.label ?? c.field ?? "").trim() || String(c.field ?? "")
66911
- }));
66912
- const selectedPivotIds = aggregationSlotColumns ? aggregationSlotColumns.selectedColumnIds : chart.columns.map(
66913
- (c) => encodeColumnOptionValue(
66914
- String(c.table ?? "").trim() || void 0,
66915
- String(c.field ?? "").trim()
66916
- )
66917
- ).filter(Boolean);
66995
+ if (pivotTableColumnControls) {
66918
66996
  return getAllColumnOptions({
66919
66997
  schemaColumnOptions,
66920
- tableColumns: pivotTableColumns,
66921
- selectedColumnIds: selectedPivotIds
66998
+ tableColumns: pivotTableColumnControls.tableColumns,
66999
+ selectedColumnIds: pivotTableColumnControls.selectedColumnIds
66922
67000
  });
66923
67001
  }
67002
+ if (isPivotTableChart) {
67003
+ return {
67004
+ columnsOptions: [],
67005
+ hasTableDrivenColumnOrder: true
67006
+ };
67007
+ }
66924
67008
  return getAllColumnOptions({
66925
67009
  schemaColumnOptions,
66926
67010
  tableColumns: table.columns,
@@ -66933,6 +67017,7 @@ function useReport(reportIdArg, options = {}) {
66933
67017
  chart?.xAxisLabel,
66934
67018
  columns,
66935
67019
  isPivotTableChart,
67020
+ pivotTableColumnControls,
66936
67021
  schemaColumnOptions,
66937
67022
  table.columns
66938
67023
  ]);
@@ -66954,17 +67039,11 @@ function useReport(reportIdArg, options = {}) {
66954
67039
  [tableDerivedColumnOrder]
66955
67040
  );
66956
67041
  const activeTableColumnIds = (0, import_react61.useMemo)(() => {
66957
- if (isPivotTableChart && chart?.columns?.length) {
66958
- const aggregationSlotColumns = buildPivotColumnPivotTableFormattingColumns(chart);
66959
- if (aggregationSlotColumns) {
66960
- return aggregationSlotColumns.selectedColumnIds;
66961
- }
66962
- return chart.columns.map(
66963
- (c) => encodeColumnOptionValue(
66964
- String(c.table ?? "").trim() || void 0,
66965
- String(c.field ?? "").trim()
66966
- )
66967
- ).filter(Boolean);
67042
+ if (pivotTableColumnControls) {
67043
+ return pivotTableColumnControls.selectedColumnIds;
67044
+ }
67045
+ if (isPivotTableChart) {
67046
+ return [];
66968
67047
  }
66969
67048
  const currentColumns = (columns ?? []).filter(Boolean);
66970
67049
  if (!hasTableDrivenColumnOrder) {
@@ -66989,6 +67068,7 @@ function useReport(reportIdArg, options = {}) {
66989
67068
  columns,
66990
67069
  hasTableDrivenColumnOrder,
66991
67070
  isPivotTableChart,
67071
+ pivotTableColumnControls,
66992
67072
  tableDerivedColumnOrder,
66993
67073
  tableFormattingColumnOptions
66994
67074
  ]);
@@ -67043,12 +67123,12 @@ function useReport(reportIdArg, options = {}) {
67043
67123
  });
67044
67124
  }
67045
67125
  const columnPivotMeasureFormatByAggregationField = /* @__PURE__ */ new Map();
67046
- if (isPivotTableChart && chart?.pivot) {
67047
- const slotFormatting = buildPivotColumnPivotTableFormattingColumns(chart);
67126
+ if (pivotTableColumnControls && chart) {
67127
+ const slotFormatting = pivotTableColumnControls;
67048
67128
  if (slotFormatting) {
67049
- const aggregations = getPivotAggregations(chart);
67129
+ const aggregations = slotFormatting.aggregations;
67050
67130
  const hasMultiple = aggregations.length > 1;
67051
- const rowField = String(chart.pivot.rowField ?? "").trim();
67131
+ const rowField = String(pivotState?.rowField ?? "").trim();
67052
67132
  const firstValueColumnFormat = String(
67053
67133
  (chart.columns ?? []).find(
67054
67134
  (c) => String(c.field ?? "").trim() !== rowField
@@ -67128,6 +67208,8 @@ function useReport(reportIdArg, options = {}) {
67128
67208
  columnOptionById,
67129
67209
  displayColumnById,
67130
67210
  isPivotTableChart,
67211
+ pivotState,
67212
+ pivotTableColumnControls,
67131
67213
  resolvedXAxisFormat,
67132
67214
  resolvedXAxisLabel,
67133
67215
  sourceReport?.columns,
@@ -67199,8 +67281,8 @@ function useReport(reportIdArg, options = {}) {
67199
67281
  ]);
67200
67282
  const initialLoadInProgress = !reportOverride && Boolean(effectiveReportId) && (!client || initialLoadQuery.isPending || initialLoadQuery.isFetching);
67201
67283
  const filterUniqueValuesLoading = filterUniqueValuesEnabled && (filterUniqueValuesQuery.isPending || filterUniqueValuesQuery.isFetching);
67202
- const chartLoading = initialLoadInProgress || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67203
- const tableLoading = initialLoadInProgress || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67284
+ const chartLoading = initialLoadInProgress || pendingPivotRefresh || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67285
+ const tableLoading = initialLoadInProgress || pendingPivotRefresh || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67204
67286
  const loading = chartLoading || tableLoading;
67205
67287
  const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
67206
67288
  const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
@@ -67477,11 +67559,12 @@ function useReport(reportIdArg, options = {}) {
67477
67559
  const isClearingRowGrouping = effectiveNextState.groupRowsBy !== void 0 && String(effectiveNextState.groupRowsBy ?? "").trim().length === 0;
67478
67560
  const queuePromoteColumnToRow = isClearingRowGrouping && !sourceReport;
67479
67561
  const shouldRefreshExpandedTableData = useInMemoryEngines && (hasRowGroupSelection || hasColumnGroupSelection || hasAggregationSelection) || !useInMemoryEngines && !nextPivot && effectiveNextState.sort !== void 0;
67480
- const dispatchTouchesPivot = touchesPivotState || isDatasourceUpdate;
67562
+ const hasReportIdentity = Boolean(effectiveReportId);
67563
+ const dispatchTouchesPivot = touchesPivotState || hasReportIdentity && isDatasourceUpdate;
67481
67564
  dispatchFormRuntime({
67482
67565
  type: "APPLY_SET_REPORT",
67483
67566
  touchesPivotState: dispatchTouchesPivot,
67484
- shouldRefreshExpandedTableData: shouldRefreshExpandedTableData || isDatasourceUpdate || addedRequestedDisplayColumns.length > 0,
67567
+ shouldRefreshExpandedTableData: shouldRefreshExpandedTableData || hasReportIdentity && (isDatasourceUpdate || addedRequestedDisplayColumns.length > 0),
67485
67568
  queuePromoteColumnToRow,
67486
67569
  updater: (prev) => {
67487
67570
  const next = {
@@ -67553,13 +67636,25 @@ function useReport(reportIdArg, options = {}) {
67553
67636
  const normalizedDisplayColumns = normalizedRequestedDisplayColumns ?? [];
67554
67637
  const addedDisplayColumns = addedRequestedDisplayColumns;
67555
67638
  next.columns = normalizedDisplayColumns;
67556
- if (addedDisplayColumns.length > 0) {
67639
+ const hasPivotSelection = Boolean(
67640
+ decodePivotGroupOptionValue(next.groupRowsBy) || decodePivotGroupOptionValue(next.groupColumnsBy)
67641
+ ) || next.aggregationState.some(isAppliedAggregation);
67642
+ const requestedDisplayTableNames = new Set(
67643
+ normalizedDisplayColumns.map((column) => String(column.table ?? "").trim()).filter(Boolean)
67644
+ );
67645
+ const selectedDatasourceTableNames = new Set(
67646
+ (next.schemaDatasourceIds ?? []).map((tableName) => String(tableName ?? "").trim()).filter(Boolean)
67647
+ );
67648
+ const replacesDatasourceTableScope = !hasPivotSelection && requestedDisplayTableNames.size > 0 && selectedDatasourceTableNames.size > 0 && [...requestedDisplayTableNames].every(
67649
+ (tableName) => !selectedDatasourceTableNames.has(tableName)
67650
+ );
67651
+ if (replacesDatasourceTableScope) {
67652
+ next.queryColumns = normalizedDisplayColumns;
67653
+ next.schemaDatasourceIds = [...requestedDisplayTableNames];
67654
+ } else if (addedDisplayColumns.length > 0) {
67557
67655
  const queryTableNames = new Set(
67558
67656
  next.queryColumns.map((column) => String(column.table ?? "").trim()).filter(Boolean)
67559
67657
  );
67560
- const hasPivotSelection = Boolean(
67561
- decodePivotGroupOptionValue(next.groupRowsBy) || decodePivotGroupOptionValue(next.groupColumnsBy)
67562
- ) || next.aggregationState.some(isAppliedAggregation);
67563
67658
  const queryColumnsToInclude = addedDisplayColumns.filter(
67564
67659
  (column) => {
67565
67660
  const tableName = String(column.table ?? "").trim();
package/dist/index.js CHANGED
@@ -22969,6 +22969,7 @@ var fetchReportBuilderDataFromState = async ({
22969
22969
  customFields,
22970
22970
  skipUniqueValues,
22971
22971
  skipRowCount,
22972
+ rowCountOnly,
22972
22973
  processing,
22973
22974
  dashboardName,
22974
22975
  getToken,
@@ -23045,7 +23046,7 @@ var fetchReportBuilderDataFromState = async ({
23045
23046
  processing ?? { page: DEFAULT_PAGINATION },
23046
23047
  customFields,
23047
23048
  skipRowCount,
23048
- void 0,
23049
+ rowCountOnly,
23049
23050
  curReport?.id ? String(curReport.id).trim() : void 0,
23050
23051
  draftSessionId ? String(draftSessionId).trim() : void 0
23051
23052
  );
@@ -58821,7 +58822,7 @@ import {
58821
58822
  useRef as useRef24,
58822
58823
  useState as useState41
58823
58824
  } from "react";
58824
- import { keepPreviousData, useQuery } from "@tanstack/react-query";
58825
+ import { keepPreviousData, useMutation, useQuery } from "@tanstack/react-query";
58825
58826
  init_util();
58826
58827
  init_columnType();
58827
58828
  init_columnProcessing();
@@ -61432,22 +61433,18 @@ function normalizePivotChartForAxisControls(chart, reportId) {
61432
61433
  yAxisFields
61433
61434
  };
61434
61435
  }
61435
- function buildPivotColumnPivotTableFormattingColumns(chart) {
61436
- if (!Array.isArray(chart.columns) || chart.columns.length === 0) {
61437
- return null;
61438
- }
61439
- const columnField = String(chart.pivot?.columnField ?? "").trim();
61440
- const aggregations = getPivotAggregations(chart);
61441
- if (!columnField || aggregations.length === 0) {
61442
- return null;
61443
- }
61436
+ function buildPivotColumnPivotTableFormattingColumns(pivot, chart) {
61437
+ if (!pivot) return null;
61438
+ const reportForControls = chart ? { ...chart, pivot } : { pivot };
61439
+ const aggregations = getPivotAggregations(reportForControls);
61440
+ if (aggregations.length === 0) return null;
61444
61441
  const hasMultipleAggregations = aggregations.length > 1;
61445
- const rowField = String(chart.pivot?.rowField ?? "").trim();
61442
+ const rowField = String(pivot.rowField ?? "").trim();
61446
61443
  const tableColumns = [];
61447
61444
  const selectedColumnIds = [];
61448
61445
  if (rowField) {
61449
- const rowSource = chart.columns.find(
61450
- (c) => String(c.field ?? "").trim() === rowField
61446
+ const rowSource = chart?.columns?.find(
61447
+ (column) => String(column.field ?? "").trim() === rowField
61451
61448
  );
61452
61449
  const rowTable = String(
61453
61450
  rowSource?.table ?? ""
@@ -61455,8 +61452,8 @@ function buildPivotColumnPivotTableFormattingColumns(chart) {
61455
61452
  tableColumns.push({
61456
61453
  field: rowField,
61457
61454
  label: String(
61458
- rowSource?.label ?? chart.xAxisLabel ?? chart.xAxisField ?? rowField
61459
- ).trim() || rowField
61455
+ rowSource?.label ?? chart?.xAxisLabel ?? chart?.xAxisField ?? toTitleCaseLabel(rowField)
61456
+ ).trim() || toTitleCaseLabel(rowField)
61460
61457
  });
61461
61458
  const rowId = encodeColumnOptionValue(rowTable || void 0, rowField);
61462
61459
  if (rowId) {
@@ -61471,14 +61468,14 @@ function buildPivotColumnPivotTableFormattingColumns(chart) {
61471
61468
  if (!fieldKey) continue;
61472
61469
  tableColumns.push({
61473
61470
  field: fieldKey,
61474
- label: buildAggregationLabel(aggregation, chart)
61471
+ label: buildAggregationLabel(aggregation, reportForControls)
61475
61472
  });
61476
61473
  const id = encodeColumnOptionValue(void 0, fieldKey);
61477
61474
  if (id) {
61478
61475
  selectedColumnIds.push(id);
61479
61476
  }
61480
61477
  }
61481
- return { tableColumns, selectedColumnIds };
61478
+ return { tableColumns, selectedColumnIds, aggregations };
61482
61479
  }
61483
61480
  function mergePivotColumnSeriesLabelWithUserEdit(normalizedLabel, userRowLabel, pivotSeriesField) {
61484
61481
  const user = String(userRowLabel ?? "").trim();
@@ -63258,7 +63255,9 @@ async function loadViaReportBuilderState({
63258
63255
  report,
63259
63256
  draftSessionId,
63260
63257
  pagination,
63261
- paginationSort
63258
+ paginationSort,
63259
+ rowsOnly,
63260
+ rowCountOnly
63262
63261
  }) {
63263
63262
  const baseReport = {
63264
63263
  ...EMPTY_INTERNAL_REPORT,
@@ -63278,6 +63277,8 @@ async function loadViaReportBuilderState({
63278
63277
  // Unique values are fetched separately via `filterUniqueValuesQuery` so chart/table
63279
63278
  // refresh queries are not blocked on `report-builder-unique-values`.
63280
63279
  skipUniqueValues: true,
63280
+ skipRowCount: rowsOnly,
63281
+ rowCountOnly,
63281
63282
  previousRelevant: previousRelevantWhenSkippingInlineUniqueFetch(report),
63282
63283
  processing: pagination ? {
63283
63284
  page: {
@@ -63341,6 +63342,9 @@ async function loadViaReportBuilderState({
63341
63342
  report: {
63342
63343
  ...baseReport,
63343
63344
  ...reportBuilderInfo.report,
63345
+ // A rows-only response intentionally has no count; retain the previous
63346
+ // value until the independent count query completes.
63347
+ rowCount: rowsOnly ? baseReport.rowCount : reportBuilderInfo.report.rowCount,
63344
63348
  reportBuilderState: normalizedReportBuilderState,
63345
63349
  pivot: reportBuilderState.pivot,
63346
63350
  pivotRows: refreshedPivotData?.rows ?? compatibleReportPivotRows ?? (canReuseBasePivotRowsAndColumns ? baseReport.pivotRows : []) ?? [],
@@ -63370,7 +63374,8 @@ async function loadReportForUseForm({
63370
63374
  customFields,
63371
63375
  dashboardName,
63372
63376
  useInMemoryEngines,
63373
- draftSessionId
63377
+ draftSessionId,
63378
+ rowsOnly = false
63374
63379
  }) {
63375
63380
  const effectivePivot = pivot ?? initialReportBuilderState?.pivot ?? void 0;
63376
63381
  const hasPivot = Boolean(effectivePivot);
@@ -63467,7 +63472,9 @@ async function loadReportForUseForm({
63467
63472
  schema,
63468
63473
  customFields,
63469
63474
  dashboardName,
63470
- draftSessionId
63475
+ report: baseReport,
63476
+ draftSessionId,
63477
+ rowsOnly
63471
63478
  });
63472
63479
  }
63473
63480
  function generateDraftSessionId() {
@@ -63475,8 +63482,8 @@ function generateDraftSessionId() {
63475
63482
  }
63476
63483
  function useReport(reportIdArg, options = {}) {
63477
63484
  const propReportId = String(reportIdArg ?? "").trim();
63478
- const [createdReportId, setCreatedReportId] = useState41(null);
63479
- const effectiveReportId = propReportId || createdReportId || "";
63485
+ const [createdReportBootstrap, setCreatedReportBootstrap] = useState41(null);
63486
+ const effectiveReportId = propReportId || createdReportBootstrap?.reportId || "";
63480
63487
  const { eventTracking } = useContext36(EventTrackingContext);
63481
63488
  const [draftSessionId, setDraftSessionId] = useState41(generateDraftSessionId);
63482
63489
  const useInMemoryEngines = options.useInMemoryEngines ?? false;
@@ -63693,13 +63700,57 @@ function useReport(reportIdArg, options = {}) {
63693
63700
  const dashboardNameForNewReport = useMemo32(() => {
63694
63701
  return [clientDefaultDashboardName, destinationDashboardName].map((entry) => String(entry ?? "").trim()).find((entry) => entry.length > 0) ?? "";
63695
63702
  }, [clientDefaultDashboardName, destinationDashboardName]);
63703
+ const { mutate: createReport } = useMutation({
63704
+ mutationKey: ["useReport", "create-report", draftSessionId],
63705
+ mutationFn: async ({
63706
+ reportBuilderState,
63707
+ tables
63708
+ }) => {
63709
+ if (!client) {
63710
+ throw new Error("Missing client for create-report");
63711
+ }
63712
+ const fallbackName = tables[0]?.name ? snakeAndCamelCaseToTitleCase(tables[0].name) : "New report";
63713
+ const resp = await saveReport({
63714
+ report: {
63715
+ ...EMPTY_INTERNAL_REPORT,
63716
+ name: fallbackName,
63717
+ chartType: "table",
63718
+ dashboardName: "quill-draft-reports",
63719
+ reportBuilderState
63720
+ },
63721
+ client,
63722
+ getToken,
63723
+ eventTracking,
63724
+ tenants,
63725
+ draftSessionId: draftSessionId || void 0
63726
+ });
63727
+ const reportId = String(resp?.id ?? resp?._id ?? "").trim();
63728
+ if (!reportId) {
63729
+ throw new Error("create-report returned no report id");
63730
+ }
63731
+ return {
63732
+ reportId,
63733
+ reportBuilderState,
63734
+ report: {
63735
+ ...EMPTY_INTERNAL_REPORT,
63736
+ ...resp,
63737
+ id: reportId,
63738
+ name: String(resp?.name ?? "").trim() || fallbackName,
63739
+ dashboardName: String(resp?.dashboardName ?? "").trim() || "quill-draft-reports",
63740
+ chartType: resp?.chartType ?? "table",
63741
+ pivot: null,
63742
+ reportBuilderState
63743
+ }
63744
+ };
63745
+ }
63746
+ });
63696
63747
  const filterStackRef = useRef24(filterStack);
63697
63748
  filterStackRef.current = filterStack;
63698
63749
  const resolvedGroupRowsBy = decodePivotGroupOptionValue(groupRowsBy);
63699
63750
  const resolvedGroupColumnsBy = decodePivotGroupOptionValue(groupColumnsBy);
63700
63751
  useEffect31(() => {
63701
63752
  if (propReportId) {
63702
- setCreatedReportId(null);
63753
+ setCreatedReportBootstrap(null);
63703
63754
  }
63704
63755
  }, [propReportId]);
63705
63756
  useEffect31(() => {
@@ -63779,7 +63830,7 @@ function useReport(reportIdArg, options = {}) {
63779
63830
  useEffect31(() => {
63780
63831
  if (reportOverride) return;
63781
63832
  if (propReportId) return;
63782
- if (createdReportId) return;
63833
+ if (createdReportBootstrap) return;
63783
63834
  if (!client) return;
63784
63835
  if (!String(dashboardNameForNewReport ?? "").trim()) {
63785
63836
  return;
@@ -63810,59 +63861,34 @@ function useReport(reportIdArg, options = {}) {
63810
63861
  );
63811
63862
  }
63812
63863
  if (bootstrapColumns.length === 0) return;
63813
- let cancelled = false;
63814
- (async () => {
63815
- try {
63816
- const fkMapForMerge = getSchemaForeignKeyMapping(
63817
- schemaForReportBuilderState
63818
- );
63819
- const tables = mergeReportBuilderTables(
63820
- ids.map((name2) => ({ name: name2 })),
63821
- bootstrapColumns.map((col) => String(col.table ?? "").trim()).filter(Boolean),
63822
- fkMapForMerge
63823
- );
63824
- const reportBuilderState = {
63825
- tables,
63826
- columns: bootstrapColumns,
63827
- filterStack: [],
63828
- sort: [],
63829
- limit: null,
63830
- pivot: null
63831
- };
63832
- const resp = await saveReport({
63833
- report: {
63834
- ...EMPTY_INTERNAL_REPORT,
63835
- name: tables[0]?.name ? snakeAndCamelCaseToTitleCase(tables[0].name) : "New report",
63836
- chartType: "table",
63837
- dashboardName: "quill-draft-reports",
63838
- reportBuilderState
63839
- },
63840
- client,
63841
- getToken,
63842
- eventTracking,
63843
- tenants,
63844
- draftSessionId: draftSessionId || void 0
63845
- });
63846
- if (cancelled) return;
63847
- const id = String(resp?.id ?? resp?._id ?? "").trim();
63848
- if (id) setCreatedReportId(id);
63849
- } catch {
63850
- }
63851
- })();
63852
- return () => {
63853
- cancelled = true;
63864
+ const fkMapForMerge = getSchemaForeignKeyMapping(
63865
+ schemaForReportBuilderState
63866
+ );
63867
+ const tables = mergeReportBuilderTables(
63868
+ ids.map((name2) => ({ name: name2 })),
63869
+ bootstrapColumns.map((col) => String(col.table ?? "").trim()).filter(Boolean),
63870
+ fkMapForMerge
63871
+ );
63872
+ const reportBuilderState = {
63873
+ tables,
63874
+ columns: bootstrapColumns,
63875
+ filterStack: [],
63876
+ sort: [],
63877
+ limit: null,
63878
+ pivot: null
63854
63879
  };
63880
+ createReport(
63881
+ { reportBuilderState, tables },
63882
+ { onSuccess: setCreatedReportBootstrap }
63883
+ );
63855
63884
  }, [
63856
63885
  reportOverride,
63857
63886
  propReportId,
63858
- createdReportId,
63887
+ createdReportBootstrap,
63859
63888
  client,
63889
+ createReport,
63860
63890
  schemaDatasourceIdsKey,
63861
63891
  dashboardNameForNewReport,
63862
- draftSessionId,
63863
- getToken,
63864
- eventTracking,
63865
- tenants,
63866
63892
  schemaForReportBuilderState,
63867
63893
  queryColumnsBootstrapKey
63868
63894
  ]);
@@ -64308,7 +64334,7 @@ function useReport(reportIdArg, options = {}) {
64308
64334
  }
64309
64335
  });
64310
64336
  return { uniqueValuesByColumn: normalizedUniqueValuesByColumn };
64311
- } catch (error) {
64337
+ } catch {
64312
64338
  return { uniqueValuesByColumn: {} };
64313
64339
  }
64314
64340
  }),
@@ -64737,19 +64763,27 @@ function useReport(reportIdArg, options = {}) {
64737
64763
  setExpandReportBuilderColumnsForFlatTable(false);
64738
64764
  prevPivotStateForColumnExpansionRef.current = null;
64739
64765
  }, [propReportId, reportOverride]);
64766
+ const createdBootstrapForInitialLoad = !propReportId && createdReportBootstrap?.reportId === effectiveReportId ? createdReportBootstrap : null;
64767
+ const initialReportBuilderStateForLoad = initialReportBuilderState ?? createdBootstrapForInitialLoad?.reportBuilderState ?? null;
64768
+ const initialBaseReportForLoad = createdBootstrapForInitialLoad?.report ?? null;
64769
+ const isCreatedReportBootstrapLoad = Boolean(
64770
+ createdBootstrapForInitialLoad && initialReportBuilderStateForLoad
64771
+ );
64740
64772
  const initialLoadQuery = useQuery({
64741
64773
  queryKey: createUseFormInitialLoadQueryKey({
64742
64774
  reportId: effectiveReportId,
64743
64775
  draftSessionId,
64744
64776
  useInMemoryEngines,
64745
- hasInitialReportBuilderState: Boolean(initialReportBuilderState),
64777
+ hasInitialReportBuilderState: Boolean(
64778
+ initialReportBuilderStateForLoad
64779
+ ),
64746
64780
  reloadKeyHash,
64747
64781
  tenantHash,
64748
64782
  flagHash,
64749
64783
  clientHash
64750
64784
  }),
64751
64785
  queryFn: createUseFormQueryFn(async () => {
64752
- const allowReportTaskBootstrap = !initialReportBuilderState && bootstrapReportTaskUsedForReportIdRef.current !== effectiveReportId;
64786
+ const allowReportTaskBootstrap = !initialReportBuilderStateForLoad && bootstrapReportTaskUsedForReportIdRef.current !== effectiveReportId;
64753
64787
  const loadTargetId = String(effectiveReportId ?? "").trim();
64754
64788
  const sourceReportIdentity = String(
64755
64789
  sourceReport?.id ?? sourceReport?._id ?? ""
@@ -64761,7 +64795,8 @@ function useReport(reportIdArg, options = {}) {
64761
64795
  }
64762
64796
  const loadResult = await loadReportForUseForm({
64763
64797
  reportId: effectiveReportId,
64764
- initialReportBuilderState,
64798
+ initialReportBuilderState: initialReportBuilderStateForLoad,
64799
+ baseReport: initialBaseReportForLoad,
64765
64800
  allowReportTaskBootstrap,
64766
64801
  client,
64767
64802
  getToken,
@@ -64772,7 +64807,8 @@ function useReport(reportIdArg, options = {}) {
64772
64807
  customFields: customFieldsRef.current,
64773
64808
  dashboardName: resolvedSourceDashboardName,
64774
64809
  useInMemoryEngines,
64775
- draftSessionId: draftSessionId || void 0
64810
+ draftSessionId: draftSessionId || void 0,
64811
+ rowsOnly: isCreatedReportBootstrapLoad
64776
64812
  });
64777
64813
  return loadResult;
64778
64814
  }),
@@ -65393,6 +65429,7 @@ function useReport(reportIdArg, options = {}) {
65393
65429
  () => stableSerializeForQueryKey(effectiveReportBuilderState),
65394
65430
  [effectiveReportBuilderState]
65395
65431
  );
65432
+ const createdBootstrapStateMatchesEffectiveState = isCreatedReportBootstrapLoad && stableSerializeForQueryKey(initialReportBuilderStateForLoad) === effectiveReportBuilderStateHash;
65396
65433
  const prevPaginationResetStateHashRef = useRef24(null);
65397
65434
  useEffect31(() => {
65398
65435
  const prevHash = prevPaginationResetStateHashRef.current;
@@ -65499,12 +65536,61 @@ function useReport(reportIdArg, options = {}) {
65499
65536
  enabled: tableRefreshQueryEnabled,
65500
65537
  retry: false
65501
65538
  });
65539
+ const createdBootstrapRowCountQuery = useQuery({
65540
+ queryKey: [
65541
+ "useReport",
65542
+ "created-bootstrap-row-count",
65543
+ effectiveReportId,
65544
+ stableSerializeForQueryKey(initialReportBuilderStateForLoad),
65545
+ tenantHash,
65546
+ clientHash
65547
+ ],
65548
+ queryFn: createUseFormQueryFn(async () => {
65549
+ if (!createdBootstrapForInitialLoad || !initialReportBuilderStateForLoad || !client) {
65550
+ return { report: null, error: "Missing bootstrap count prerequisites" };
65551
+ }
65552
+ return loadViaReportBuilderState({
65553
+ reportId: effectiveReportId,
65554
+ reportBuilderState: initialReportBuilderStateForLoad,
65555
+ client,
65556
+ getToken,
65557
+ tenants,
65558
+ schema: schemaForReportBuilderState,
65559
+ customFields: schemaData.customFields,
65560
+ dashboardName: resolvedSourceDashboardName,
65561
+ report: createdBootstrapForInitialLoad.report,
65562
+ draftSessionId: draftSessionId || void 0,
65563
+ rowCountOnly: true
65564
+ });
65565
+ }),
65566
+ enabled: createdBootstrapStateMatchesEffectiveState && Boolean(client) && !reportOverride,
65567
+ retry: false
65568
+ });
65502
65569
  useEffect31(() => {
65503
65570
  if (!tableRefreshQueryEnabled) return;
65504
65571
  const report = tableRefreshQuery.data?.report;
65505
65572
  if (tableRefreshQuery.data?.error || !report) return;
65506
65573
  setSourceReport(report);
65507
65574
  }, [effectiveReportId, tableRefreshQuery.data, tableRefreshQueryEnabled]);
65575
+ useEffect31(() => {
65576
+ if (!createdBootstrapStateMatchesEffectiveState) return;
65577
+ const countReport = createdBootstrapRowCountQuery.data?.report;
65578
+ if (createdBootstrapRowCountQuery.data?.error || !countReport) return;
65579
+ setSourceReport((currentReport) => {
65580
+ if (!currentReport || currentReport.id !== effectiveReportId) {
65581
+ return currentReport;
65582
+ }
65583
+ if (currentReport.rowCount === countReport.rowCount) {
65584
+ return currentReport;
65585
+ }
65586
+ return { ...currentReport, rowCount: countReport.rowCount };
65587
+ });
65588
+ }, [
65589
+ createdBootstrapRowCountQuery.data,
65590
+ createdBootstrapStateMatchesEffectiveState,
65591
+ effectiveReportId,
65592
+ sourceReport?.id
65593
+ ]);
65508
65594
  const chartTypes = useMemo32(() => {
65509
65595
  return getChartTypeOptions2({ pivot: pivotState });
65510
65596
  }, [pivotState]);
@@ -66173,7 +66259,8 @@ function useReport(reportIdArg, options = {}) {
66173
66259
  pageIndex: pagination.pageIndex,
66174
66260
  pageSize: pagination.pageSize
66175
66261
  },
66176
- paginationSort: tablePaginationSort
66262
+ paginationSort: tablePaginationSort,
66263
+ rowsOnly: true
66177
66264
  });
66178
66265
  }),
66179
66266
  enabled: tablePageQueryEnabled,
@@ -66814,8 +66901,10 @@ function useReport(reportIdArg, options = {}) {
66814
66901
  }
66815
66902
  };
66816
66903
  }, [chart, filterOptions, filtersForQueryBuilder]);
66817
- const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(
66818
- chart && chart.pivot && Array.isArray(chart.columns) && chart.columns.length > 0
66904
+ const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(pivotState);
66905
+ const pivotTableColumnControls = useMemo32(
66906
+ () => isPivotTableChart ? buildPivotColumnPivotTableFormattingColumns(pivotState, chart) : null,
66907
+ [chart, isPivotTableChart, pivotState]
66819
66908
  );
66820
66909
  const chartAxes = useMemo32(() => {
66821
66910
  const yAxisItems = resolvedYAxisFields.map(
@@ -67115,24 +67204,19 @@ function useReport(reportIdArg, options = {}) {
67115
67204
  columnsOptions: tableFormattingColumnOptions,
67116
67205
  hasTableDrivenColumnOrder
67117
67206
  } = useMemo32(() => {
67118
- if (isPivotTableChart && chart?.columns?.length) {
67119
- const aggregationSlotColumns = buildPivotColumnPivotTableFormattingColumns(chart);
67120
- const pivotTableColumns = aggregationSlotColumns ? aggregationSlotColumns.tableColumns : chart.columns.map((c) => ({
67121
- field: String(c.field ?? "").trim(),
67122
- label: String(c.label ?? c.field ?? "").trim() || String(c.field ?? "")
67123
- }));
67124
- const selectedPivotIds = aggregationSlotColumns ? aggregationSlotColumns.selectedColumnIds : chart.columns.map(
67125
- (c) => encodeColumnOptionValue(
67126
- String(c.table ?? "").trim() || void 0,
67127
- String(c.field ?? "").trim()
67128
- )
67129
- ).filter(Boolean);
67207
+ if (pivotTableColumnControls) {
67130
67208
  return getAllColumnOptions({
67131
67209
  schemaColumnOptions,
67132
- tableColumns: pivotTableColumns,
67133
- selectedColumnIds: selectedPivotIds
67210
+ tableColumns: pivotTableColumnControls.tableColumns,
67211
+ selectedColumnIds: pivotTableColumnControls.selectedColumnIds
67134
67212
  });
67135
67213
  }
67214
+ if (isPivotTableChart) {
67215
+ return {
67216
+ columnsOptions: [],
67217
+ hasTableDrivenColumnOrder: true
67218
+ };
67219
+ }
67136
67220
  return getAllColumnOptions({
67137
67221
  schemaColumnOptions,
67138
67222
  tableColumns: table.columns,
@@ -67145,6 +67229,7 @@ function useReport(reportIdArg, options = {}) {
67145
67229
  chart?.xAxisLabel,
67146
67230
  columns,
67147
67231
  isPivotTableChart,
67232
+ pivotTableColumnControls,
67148
67233
  schemaColumnOptions,
67149
67234
  table.columns
67150
67235
  ]);
@@ -67166,17 +67251,11 @@ function useReport(reportIdArg, options = {}) {
67166
67251
  [tableDerivedColumnOrder]
67167
67252
  );
67168
67253
  const activeTableColumnIds = useMemo32(() => {
67169
- if (isPivotTableChart && chart?.columns?.length) {
67170
- const aggregationSlotColumns = buildPivotColumnPivotTableFormattingColumns(chart);
67171
- if (aggregationSlotColumns) {
67172
- return aggregationSlotColumns.selectedColumnIds;
67173
- }
67174
- return chart.columns.map(
67175
- (c) => encodeColumnOptionValue(
67176
- String(c.table ?? "").trim() || void 0,
67177
- String(c.field ?? "").trim()
67178
- )
67179
- ).filter(Boolean);
67254
+ if (pivotTableColumnControls) {
67255
+ return pivotTableColumnControls.selectedColumnIds;
67256
+ }
67257
+ if (isPivotTableChart) {
67258
+ return [];
67180
67259
  }
67181
67260
  const currentColumns = (columns ?? []).filter(Boolean);
67182
67261
  if (!hasTableDrivenColumnOrder) {
@@ -67201,6 +67280,7 @@ function useReport(reportIdArg, options = {}) {
67201
67280
  columns,
67202
67281
  hasTableDrivenColumnOrder,
67203
67282
  isPivotTableChart,
67283
+ pivotTableColumnControls,
67204
67284
  tableDerivedColumnOrder,
67205
67285
  tableFormattingColumnOptions
67206
67286
  ]);
@@ -67255,12 +67335,12 @@ function useReport(reportIdArg, options = {}) {
67255
67335
  });
67256
67336
  }
67257
67337
  const columnPivotMeasureFormatByAggregationField = /* @__PURE__ */ new Map();
67258
- if (isPivotTableChart && chart?.pivot) {
67259
- const slotFormatting = buildPivotColumnPivotTableFormattingColumns(chart);
67338
+ if (pivotTableColumnControls && chart) {
67339
+ const slotFormatting = pivotTableColumnControls;
67260
67340
  if (slotFormatting) {
67261
- const aggregations = getPivotAggregations(chart);
67341
+ const aggregations = slotFormatting.aggregations;
67262
67342
  const hasMultiple = aggregations.length > 1;
67263
- const rowField = String(chart.pivot.rowField ?? "").trim();
67343
+ const rowField = String(pivotState?.rowField ?? "").trim();
67264
67344
  const firstValueColumnFormat = String(
67265
67345
  (chart.columns ?? []).find(
67266
67346
  (c) => String(c.field ?? "").trim() !== rowField
@@ -67340,6 +67420,8 @@ function useReport(reportIdArg, options = {}) {
67340
67420
  columnOptionById,
67341
67421
  displayColumnById,
67342
67422
  isPivotTableChart,
67423
+ pivotState,
67424
+ pivotTableColumnControls,
67343
67425
  resolvedXAxisFormat,
67344
67426
  resolvedXAxisLabel,
67345
67427
  sourceReport?.columns,
@@ -67411,8 +67493,8 @@ function useReport(reportIdArg, options = {}) {
67411
67493
  ]);
67412
67494
  const initialLoadInProgress = !reportOverride && Boolean(effectiveReportId) && (!client || initialLoadQuery.isPending || initialLoadQuery.isFetching);
67413
67495
  const filterUniqueValuesLoading = filterUniqueValuesEnabled && (filterUniqueValuesQuery.isPending || filterUniqueValuesQuery.isFetching);
67414
- const chartLoading = initialLoadInProgress || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67415
- const tableLoading = initialLoadInProgress || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67496
+ const chartLoading = initialLoadInProgress || pendingPivotRefresh || (Boolean(nextPivot) ? pivotRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67497
+ const tableLoading = initialLoadInProgress || pendingPivotRefresh || tablePageFetching || (Boolean(nextPivot) ? pivotTableDataRefreshQuery.isFetching : tableRefreshQuery.isFetching);
67416
67498
  const loading = chartLoading || tableLoading;
67417
67499
  const buildSetReportColumnsFromIds = (nextColumnIds, settingsById) => {
67418
67500
  const normalizedNextIds = nextColumnIds.map((columnId) => String(columnId ?? "").trim()).filter(Boolean);
@@ -67689,11 +67771,12 @@ function useReport(reportIdArg, options = {}) {
67689
67771
  const isClearingRowGrouping = effectiveNextState.groupRowsBy !== void 0 && String(effectiveNextState.groupRowsBy ?? "").trim().length === 0;
67690
67772
  const queuePromoteColumnToRow = isClearingRowGrouping && !sourceReport;
67691
67773
  const shouldRefreshExpandedTableData = useInMemoryEngines && (hasRowGroupSelection || hasColumnGroupSelection || hasAggregationSelection) || !useInMemoryEngines && !nextPivot && effectiveNextState.sort !== void 0;
67692
- const dispatchTouchesPivot = touchesPivotState || isDatasourceUpdate;
67774
+ const hasReportIdentity = Boolean(effectiveReportId);
67775
+ const dispatchTouchesPivot = touchesPivotState || hasReportIdentity && isDatasourceUpdate;
67693
67776
  dispatchFormRuntime({
67694
67777
  type: "APPLY_SET_REPORT",
67695
67778
  touchesPivotState: dispatchTouchesPivot,
67696
- shouldRefreshExpandedTableData: shouldRefreshExpandedTableData || isDatasourceUpdate || addedRequestedDisplayColumns.length > 0,
67779
+ shouldRefreshExpandedTableData: shouldRefreshExpandedTableData || hasReportIdentity && (isDatasourceUpdate || addedRequestedDisplayColumns.length > 0),
67697
67780
  queuePromoteColumnToRow,
67698
67781
  updater: (prev) => {
67699
67782
  const next = {
@@ -67765,13 +67848,25 @@ function useReport(reportIdArg, options = {}) {
67765
67848
  const normalizedDisplayColumns = normalizedRequestedDisplayColumns ?? [];
67766
67849
  const addedDisplayColumns = addedRequestedDisplayColumns;
67767
67850
  next.columns = normalizedDisplayColumns;
67768
- if (addedDisplayColumns.length > 0) {
67851
+ const hasPivotSelection = Boolean(
67852
+ decodePivotGroupOptionValue(next.groupRowsBy) || decodePivotGroupOptionValue(next.groupColumnsBy)
67853
+ ) || next.aggregationState.some(isAppliedAggregation);
67854
+ const requestedDisplayTableNames = new Set(
67855
+ normalizedDisplayColumns.map((column) => String(column.table ?? "").trim()).filter(Boolean)
67856
+ );
67857
+ const selectedDatasourceTableNames = new Set(
67858
+ (next.schemaDatasourceIds ?? []).map((tableName) => String(tableName ?? "").trim()).filter(Boolean)
67859
+ );
67860
+ const replacesDatasourceTableScope = !hasPivotSelection && requestedDisplayTableNames.size > 0 && selectedDatasourceTableNames.size > 0 && [...requestedDisplayTableNames].every(
67861
+ (tableName) => !selectedDatasourceTableNames.has(tableName)
67862
+ );
67863
+ if (replacesDatasourceTableScope) {
67864
+ next.queryColumns = normalizedDisplayColumns;
67865
+ next.schemaDatasourceIds = [...requestedDisplayTableNames];
67866
+ } else if (addedDisplayColumns.length > 0) {
67769
67867
  const queryTableNames = new Set(
67770
67868
  next.queryColumns.map((column) => String(column.table ?? "").trim()).filter(Boolean)
67771
67869
  );
67772
- const hasPivotSelection = Boolean(
67773
- decodePivotGroupOptionValue(next.groupRowsBy) || decodePivotGroupOptionValue(next.groupColumnsBy)
67774
- ) || next.aggregationState.some(isAppliedAggregation);
67775
67870
  const queryColumnsToInclude = addedDisplayColumns.filter(
67776
67871
  (column) => {
67777
67872
  const tableName = String(column.table ?? "").trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillsql/react",
3
- "version": "2.16.63",
3
+ "version": "2.16.65",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {