@quillsql/react 2.16.10 → 2.16.11

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 +244 -27
  2. package/dist/index.js +244 -27
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -16224,6 +16224,128 @@ async function generatePivotTable({
16224
16224
  }
16225
16225
  throw Error("Failed to generate pivot table: invalid report");
16226
16226
  }
16227
+ function processPivotData({
16228
+ rows: responseRows,
16229
+ fields: responseFields,
16230
+ pivot,
16231
+ dateBucket,
16232
+ dateFilter,
16233
+ client,
16234
+ rowCount
16235
+ }) {
16236
+ const databaseType = client.databaseType || "postgresql";
16237
+ const rows = pivot.rowField ? responseRows.map(
16238
+ (row) => !row[pivot.rowField] ? { ...row, [pivot.rowField]: "-" } : row
16239
+ ) : responseRows;
16240
+ if (pivot.columnField && client.databaseType?.toLowerCase() === "bigquery") {
16241
+ rows.forEach((row) => {
16242
+ Object.keys(row).forEach((key) => {
16243
+ const processedKey = processColumnName(key);
16244
+ if (processedKey !== key) {
16245
+ row[processedKey] = row[key];
16246
+ delete row[key];
16247
+ }
16248
+ });
16249
+ });
16250
+ }
16251
+ const columns = responseFields?.map((field) => ({
16252
+ field: processColumnName(field.field || field.name),
16253
+ label: snakeCaseToTitleCase(
16254
+ processColumnName(
16255
+ (field.field || field.name).replace("comparison_", "comparison ")
16256
+ )
16257
+ ),
16258
+ format: (field.field || field.name) === pivot.rowField ? "string" : pivot.aggregations?.find(
16259
+ (agg) => agg.valueField === (field.field || field.name) || `${agg.valueField}_percentage` === (field.field || field.name) || !agg.valueField && agg.aggregationType === "percentage" && (field.field || field.name)?.endsWith("percentage")
16260
+ )?.aggregationType === "percentage" ? "percent" : "whole_number",
16261
+ fieldType: field.fieldType,
16262
+ jsType: field.jsType,
16263
+ dataTypeID: field.dataTypeID
16264
+ })).filter(
16265
+ (field, index) => field.field !== "comparison_" + pivot.rowField || index === 0
16266
+ ).sort((a, b) => {
16267
+ if (a.field === pivot.rowField) {
16268
+ return -1;
16269
+ }
16270
+ if (b.field === pivot.rowField) {
16271
+ return 1;
16272
+ }
16273
+ return 0;
16274
+ });
16275
+ if (pivot.rowField && !isStringType(pivot.rowFieldType || "")) {
16276
+ rows.forEach((row) => {
16277
+ row.__quillRawDate = typeof row[pivot.rowField || ""] === "object" ? row[pivot.rowField || ""].value : row[pivot.rowField || ""];
16278
+ let value = typeof row[pivot.rowField || ""] === "object" ? row[pivot.rowField || ""].value : row[pivot.rowField || ""];
16279
+ if (dateBucket === "week" && dateFilter?.startDate && dateFilter?.endDate) {
16280
+ const rowDate = new Date(value);
16281
+ if (rowDate < dateFilter.startDate) {
16282
+ value = dateFilter.startDate.toISOString();
16283
+ } else if (rowDate > dateFilter.endDate) {
16284
+ value = dateFilter.endDate.toISOString();
16285
+ }
16286
+ }
16287
+ const dateString = getDateString(
16288
+ value,
16289
+ dateFilter?.startDate && dateFilter?.endDate ? { start: dateFilter.startDate, end: dateFilter.endDate } : void 0,
16290
+ dateBucket,
16291
+ databaseType
16292
+ );
16293
+ row[pivot.rowField || ""] = dateString;
16294
+ });
16295
+ if (pivot.rowField && pivot.rowFieldType && !isStringType(pivot.rowFieldType) && dateFilter?.startDate && dateFilter?.endDate) {
16296
+ const dateSet = new Set(
16297
+ rows.map((row) => row[pivot.rowField || ""])
16298
+ );
16299
+ for (let date = dateFilter.startDate; date <= dateFilter.endDate; date = new Date(date.getTime() + 24 * 60 * 60 * 1e3)) {
16300
+ const formattedDate = getDateString(
16301
+ date.toISOString(),
16302
+ { start: dateFilter.startDate, end: dateFilter.endDate },
16303
+ dateBucket,
16304
+ databaseType
16305
+ );
16306
+ if (!dateSet.has(formattedDate)) {
16307
+ const newRow = {};
16308
+ newRow[pivot.rowField] = formattedDate;
16309
+ newRow.__quillRawDate = date.toISOString();
16310
+ rows.push(newRow);
16311
+ dateSet.add(formattedDate);
16312
+ }
16313
+ }
16314
+ }
16315
+ if (!pivot.sort || pivot.sortField === pivot.rowField) {
16316
+ rows.sort((a, b) => {
16317
+ const direction = pivot.sort && pivot.sortDirection === "DESC" ? -1 : 1;
16318
+ if (a.__quillRawDate < b.__quillRawDate) {
16319
+ return -1 * direction;
16320
+ }
16321
+ if (a.__quillRawDate > b.__quillRawDate) {
16322
+ return 1 * direction;
16323
+ }
16324
+ return 0;
16325
+ });
16326
+ }
16327
+ }
16328
+ columns?.forEach((column, index) => {
16329
+ if (column.label && ["null", "undefined"].includes(column.label.toLowerCase()) && !pivot.columnField && !pivot.aggregations?.[index]?.valueField && pivot.aggregations?.[index]?.aggregationType === "count") {
16330
+ column.label = "Count";
16331
+ }
16332
+ });
16333
+ const numericColumns = columns?.filter(
16334
+ (column) => column.format === "whole_number" || column.format === "percentage"
16335
+ );
16336
+ rows.forEach((row) => {
16337
+ numericColumns?.forEach((column) => {
16338
+ row[column.field] = row[column.field] ?? 0;
16339
+ });
16340
+ });
16341
+ return {
16342
+ rows,
16343
+ columns: columns ?? [],
16344
+ rowCount: rowCount || rows.length,
16345
+ pivotQuery: "",
16346
+ comparisonPivotQuery: ""
16347
+ };
16348
+ }
16227
16349
  var init_pivotConstructor = __esm({
16228
16350
  "src/utils/pivotConstructor.ts"() {
16229
16351
  "use strict";
@@ -19745,10 +19867,14 @@ async function cleanDashboardItem({
19745
19867
  const pivotChartProcessing = {
19746
19868
  page: DEFAULT_PAGINATION
19747
19869
  };
19748
- pivotTable = await getPivotTable(
19749
- {
19750
- ...item,
19751
- pivot: item.pivot && !skipPivotFetch ? {
19870
+ if (item.pivot && skipPivotFetch && item.rows && item.fields) {
19871
+ const dateFilter = dashboardFilters?.find(
19872
+ (filter) => filter.filterType === "date_range"
19873
+ );
19874
+ pivotTable = processPivotData({
19875
+ rows: item.rows,
19876
+ fields: item.fields,
19877
+ pivot: {
19752
19878
  ...item.pivot,
19753
19879
  aggregations: item.pivot.aggregations ?? [
19754
19880
  {
@@ -19759,18 +19885,40 @@ async function cleanDashboardItem({
19759
19885
  aggregationType: item.pivot.aggregationType
19760
19886
  }
19761
19887
  ]
19762
- } : void 0
19763
- },
19764
- dashboardFilters,
19765
- item.dashboardName,
19766
- getToken,
19767
- client,
19768
- eventTracking,
19769
- dateBucket,
19770
- shouldPaginatePivotAsTable ? additionalProcessing : pivotChartProcessing,
19771
- tenants,
19772
- customFields
19773
- );
19888
+ },
19889
+ dateBucket,
19890
+ dateFilter,
19891
+ client,
19892
+ rowCount: item.rowCount ? parseInt(item.rowCount) : item.rows.length
19893
+ });
19894
+ } else {
19895
+ pivotTable = await getPivotTable(
19896
+ {
19897
+ ...item,
19898
+ pivot: item.pivot && !skipPivotFetch ? {
19899
+ ...item.pivot,
19900
+ aggregations: item.pivot.aggregations ?? [
19901
+ {
19902
+ valueField: item.pivot.valueField,
19903
+ valueFieldType: item.pivot.valueFieldType,
19904
+ valueField2: item.pivot.valueField2,
19905
+ valueField2Type: item.pivot.valueField2Type,
19906
+ aggregationType: item.pivot.aggregationType
19907
+ }
19908
+ ]
19909
+ } : void 0
19910
+ },
19911
+ dashboardFilters,
19912
+ item.dashboardName,
19913
+ getToken,
19914
+ client,
19915
+ eventTracking,
19916
+ dateBucket,
19917
+ shouldPaginatePivotAsTable ? additionalProcessing : pivotChartProcessing,
19918
+ tenants,
19919
+ customFields
19920
+ );
19921
+ }
19774
19922
  } catch (e) {
19775
19923
  pivotTable = void 0;
19776
19924
  eventTracking?.logError?.({
@@ -20178,6 +20326,33 @@ function extractAllReportValuesFromQuillInternalReport(reportInternal) {
20178
20326
  pivotRowCount: reportInternal.pivotRowCount
20179
20327
  };
20180
20328
  }
20329
+ async function fetchReportRows({
20330
+ reportId,
20331
+ client,
20332
+ tenants,
20333
+ filters = [],
20334
+ getToken,
20335
+ abortSignal,
20336
+ additionalProcessing
20337
+ }) {
20338
+ const fetchResp = await quillFetch({
20339
+ client,
20340
+ task: "report",
20341
+ metadata: {
20342
+ reportId,
20343
+ clientId: client.publicKey,
20344
+ databaseType: client.databaseType,
20345
+ filters: filters.map((filter) => ({ ...filter, options: void 0 })),
20346
+ useNewNodeSql: true,
20347
+ tenants,
20348
+ additionalProcessing
20349
+ },
20350
+ abortSignal,
20351
+ getToken
20352
+ });
20353
+ const resp = await parseFetchResponse(client, "report", fetchResp, getToken);
20354
+ return { rows: resp.rows || [], rowCount: resp.rowCount || 0 };
20355
+ }
20181
20356
  async function fetchReport({
20182
20357
  reportId,
20183
20358
  client,
@@ -20192,14 +20367,15 @@ async function fetchReport({
20192
20367
  rowCountOnly,
20193
20368
  abortSignal,
20194
20369
  getToken,
20195
- eventTracking
20370
+ eventTracking,
20371
+ usePivotTask = false
20196
20372
  }) {
20197
20373
  let reportInfo = void 0;
20198
20374
  let errorMessage = void 0;
20199
20375
  try {
20200
20376
  const fetchResp = await quillFetch({
20201
20377
  client,
20202
- task: useReportTask ? "report" : "item",
20378
+ task: usePivotTask ? "pivot-template" : useReportTask ? "report" : "item",
20203
20379
  metadata: {
20204
20380
  reportId,
20205
20381
  dashboardItemId: reportId,
@@ -20219,7 +20395,7 @@ async function fetchReport({
20219
20395
  });
20220
20396
  const resp = await parseFetchResponse(
20221
20397
  client,
20222
- useReportTask ? "report" : "item",
20398
+ usePivotTask ? "pivot-template" : useReportTask ? "report" : "item",
20223
20399
  fetchResp,
20224
20400
  getToken
20225
20401
  );
@@ -20227,12 +20403,13 @@ async function fetchReport({
20227
20403
  resp,
20228
20404
  client,
20229
20405
  filters,
20230
- dateBucket,
20406
+ dateBucket: resp.dateBucket ?? dateBucket,
20231
20407
  additionalProcessing,
20232
20408
  customFields,
20233
20409
  getToken,
20234
20410
  eventTracking,
20235
- tenants
20411
+ tenants,
20412
+ skipPivotFetch: usePivotTask
20236
20413
  });
20237
20414
  } catch (error) {
20238
20415
  if (error instanceof Error && error.name === "AbortError") {
@@ -20281,7 +20458,8 @@ async function processReportResponse({
20281
20458
  customFields,
20282
20459
  getToken,
20283
20460
  eventTracking,
20284
- tenants
20461
+ tenants,
20462
+ skipPivotFetch = false
20285
20463
  }) {
20286
20464
  const dashboardItem = {
20287
20465
  ...resp,
@@ -20312,7 +20490,8 @@ async function processReportResponse({
20312
20490
  customFields,
20313
20491
  getToken,
20314
20492
  tenants,
20315
- eventTracking
20493
+ eventTracking,
20494
+ skipPivotFetch
20316
20495
  });
20317
20496
  if (additionalProcessing) {
20318
20497
  reportInfo.pagination = additionalProcessing.page;
@@ -32253,6 +32432,7 @@ function DataLoader({
32253
32432
  previousUserFilters.current = userFilters;
32254
32433
  rowsAbortController.current?.abort();
32255
32434
  rowsAbortController.current = new AbortController();
32435
+ const usePivotTask = !!item.pivot;
32256
32436
  try {
32257
32437
  if (dashboardName) {
32258
32438
  const { report: fetchedReport, error: error2 } = await fetchReport({
@@ -32268,7 +32448,8 @@ function DataLoader({
32268
32448
  rowCountOnly: false,
32269
32449
  abortSignal: rowsAbortController.current.signal,
32270
32450
  getToken,
32271
- eventTracking
32451
+ eventTracking,
32452
+ usePivotTask
32272
32453
  });
32273
32454
  addReport({
32274
32455
  ...fetchedReport,
@@ -32400,7 +32581,11 @@ var ChartDataLoader = ({
32400
32581
  dashboardName,
32401
32582
  propagateChanges
32402
32583
  }) => {
32403
- const { dashboardReports: dashboard, addReport } = useDashboardReports(dashboardName);
32584
+ const {
32585
+ dashboardReports: dashboard,
32586
+ addReport,
32587
+ updateReport
32588
+ } = useDashboardReports(dashboardName);
32404
32589
  const { dashboardFilters } = (0, import_react25.useContext)(DashboardFiltersContext);
32405
32590
  const { reports, fetchIndividualReport } = (0, import_react25.useContext)(ReportsContext);
32406
32591
  const { getToken } = (0, import_react25.useContext)(FetchContext);
@@ -32450,6 +32635,8 @@ var ChartDataLoader = ({
32450
32635
  setLoading(true);
32451
32636
  fetchReportAbortController.current?.abort();
32452
32637
  fetchReportAbortController.current = new AbortController();
32638
+ const usePivotTask = !!item.pivot;
32639
+ let backgroundFetch = null;
32453
32640
  try {
32454
32641
  if (dashboardName) {
32455
32642
  const { report, error: error2 } = await fetchReport({
@@ -32467,7 +32654,8 @@ var ChartDataLoader = ({
32467
32654
  customFields: schemaData.customFields,
32468
32655
  abortSignal: fetchReportAbortController.current.signal,
32469
32656
  getToken,
32470
- eventTracking
32657
+ eventTracking,
32658
+ usePivotTask
32471
32659
  });
32472
32660
  addReport({
32473
32661
  ...report,
@@ -32477,6 +32665,32 @@ var ChartDataLoader = ({
32477
32665
  loadingRows: false
32478
32666
  });
32479
32667
  setError(error2);
32668
+ if (usePivotTask) {
32669
+ const backgroundAbortController = new AbortController();
32670
+ backgroundFetch = () => {
32671
+ fetchReportRows({
32672
+ reportId: item.id,
32673
+ client,
32674
+ tenants,
32675
+ filters: filters.concat(userFilters ?? []),
32676
+ getToken,
32677
+ abortSignal: backgroundAbortController.signal,
32678
+ additionalProcessing: {
32679
+ ...additionalProcessing,
32680
+ ...{ page: DEFAULT_PAGINATION }
32681
+ }
32682
+ }).then(({ rows, rowCount }) => {
32683
+ updateReport({
32684
+ id: item.id,
32685
+ rows,
32686
+ rowCount
32687
+ });
32688
+ }).catch((e) => {
32689
+ if (e instanceof Error && e.name === "AbortError") return;
32690
+ console.error("Failed to fetch background rows", e);
32691
+ });
32692
+ };
32693
+ }
32480
32694
  } else {
32481
32695
  try {
32482
32696
  await fetchIndividualReport({
@@ -32532,6 +32746,9 @@ var ChartDataLoader = ({
32532
32746
  if (fetchRowsRequestId === rowsRequestId.current) {
32533
32747
  fetchReportAbortController.current = null;
32534
32748
  setLoading(false);
32749
+ if (backgroundFetch) {
32750
+ backgroundFetch();
32751
+ }
32535
32752
  }
32536
32753
  }
32537
32754
  };
@@ -38697,7 +38914,7 @@ function Dashboard({
38697
38914
  filters: populatedDashboardFilters ?? [],
38698
38915
  userFilters: dataLoaderUserFilters,
38699
38916
  additionalProcessing: {
38700
- page: DEFAULT_PAGINATION,
38917
+ page: pagination,
38701
38918
  last: additionalProcessing?.last
38702
38919
  },
38703
38920
  dashboardName: name2,
package/dist/index.js CHANGED
@@ -16261,6 +16261,128 @@ async function generatePivotTable({
16261
16261
  }
16262
16262
  throw Error("Failed to generate pivot table: invalid report");
16263
16263
  }
16264
+ function processPivotData({
16265
+ rows: responseRows,
16266
+ fields: responseFields,
16267
+ pivot,
16268
+ dateBucket,
16269
+ dateFilter,
16270
+ client,
16271
+ rowCount
16272
+ }) {
16273
+ const databaseType = client.databaseType || "postgresql";
16274
+ const rows = pivot.rowField ? responseRows.map(
16275
+ (row) => !row[pivot.rowField] ? { ...row, [pivot.rowField]: "-" } : row
16276
+ ) : responseRows;
16277
+ if (pivot.columnField && client.databaseType?.toLowerCase() === "bigquery") {
16278
+ rows.forEach((row) => {
16279
+ Object.keys(row).forEach((key) => {
16280
+ const processedKey = processColumnName(key);
16281
+ if (processedKey !== key) {
16282
+ row[processedKey] = row[key];
16283
+ delete row[key];
16284
+ }
16285
+ });
16286
+ });
16287
+ }
16288
+ const columns = responseFields?.map((field) => ({
16289
+ field: processColumnName(field.field || field.name),
16290
+ label: snakeCaseToTitleCase(
16291
+ processColumnName(
16292
+ (field.field || field.name).replace("comparison_", "comparison ")
16293
+ )
16294
+ ),
16295
+ format: (field.field || field.name) === pivot.rowField ? "string" : pivot.aggregations?.find(
16296
+ (agg) => agg.valueField === (field.field || field.name) || `${agg.valueField}_percentage` === (field.field || field.name) || !agg.valueField && agg.aggregationType === "percentage" && (field.field || field.name)?.endsWith("percentage")
16297
+ )?.aggregationType === "percentage" ? "percent" : "whole_number",
16298
+ fieldType: field.fieldType,
16299
+ jsType: field.jsType,
16300
+ dataTypeID: field.dataTypeID
16301
+ })).filter(
16302
+ (field, index) => field.field !== "comparison_" + pivot.rowField || index === 0
16303
+ ).sort((a, b) => {
16304
+ if (a.field === pivot.rowField) {
16305
+ return -1;
16306
+ }
16307
+ if (b.field === pivot.rowField) {
16308
+ return 1;
16309
+ }
16310
+ return 0;
16311
+ });
16312
+ if (pivot.rowField && !isStringType(pivot.rowFieldType || "")) {
16313
+ rows.forEach((row) => {
16314
+ row.__quillRawDate = typeof row[pivot.rowField || ""] === "object" ? row[pivot.rowField || ""].value : row[pivot.rowField || ""];
16315
+ let value = typeof row[pivot.rowField || ""] === "object" ? row[pivot.rowField || ""].value : row[pivot.rowField || ""];
16316
+ if (dateBucket === "week" && dateFilter?.startDate && dateFilter?.endDate) {
16317
+ const rowDate = new Date(value);
16318
+ if (rowDate < dateFilter.startDate) {
16319
+ value = dateFilter.startDate.toISOString();
16320
+ } else if (rowDate > dateFilter.endDate) {
16321
+ value = dateFilter.endDate.toISOString();
16322
+ }
16323
+ }
16324
+ const dateString = getDateString(
16325
+ value,
16326
+ dateFilter?.startDate && dateFilter?.endDate ? { start: dateFilter.startDate, end: dateFilter.endDate } : void 0,
16327
+ dateBucket,
16328
+ databaseType
16329
+ );
16330
+ row[pivot.rowField || ""] = dateString;
16331
+ });
16332
+ if (pivot.rowField && pivot.rowFieldType && !isStringType(pivot.rowFieldType) && dateFilter?.startDate && dateFilter?.endDate) {
16333
+ const dateSet = new Set(
16334
+ rows.map((row) => row[pivot.rowField || ""])
16335
+ );
16336
+ for (let date = dateFilter.startDate; date <= dateFilter.endDate; date = new Date(date.getTime() + 24 * 60 * 60 * 1e3)) {
16337
+ const formattedDate = getDateString(
16338
+ date.toISOString(),
16339
+ { start: dateFilter.startDate, end: dateFilter.endDate },
16340
+ dateBucket,
16341
+ databaseType
16342
+ );
16343
+ if (!dateSet.has(formattedDate)) {
16344
+ const newRow = {};
16345
+ newRow[pivot.rowField] = formattedDate;
16346
+ newRow.__quillRawDate = date.toISOString();
16347
+ rows.push(newRow);
16348
+ dateSet.add(formattedDate);
16349
+ }
16350
+ }
16351
+ }
16352
+ if (!pivot.sort || pivot.sortField === pivot.rowField) {
16353
+ rows.sort((a, b) => {
16354
+ const direction = pivot.sort && pivot.sortDirection === "DESC" ? -1 : 1;
16355
+ if (a.__quillRawDate < b.__quillRawDate) {
16356
+ return -1 * direction;
16357
+ }
16358
+ if (a.__quillRawDate > b.__quillRawDate) {
16359
+ return 1 * direction;
16360
+ }
16361
+ return 0;
16362
+ });
16363
+ }
16364
+ }
16365
+ columns?.forEach((column, index) => {
16366
+ if (column.label && ["null", "undefined"].includes(column.label.toLowerCase()) && !pivot.columnField && !pivot.aggregations?.[index]?.valueField && pivot.aggregations?.[index]?.aggregationType === "count") {
16367
+ column.label = "Count";
16368
+ }
16369
+ });
16370
+ const numericColumns = columns?.filter(
16371
+ (column) => column.format === "whole_number" || column.format === "percentage"
16372
+ );
16373
+ rows.forEach((row) => {
16374
+ numericColumns?.forEach((column) => {
16375
+ row[column.field] = row[column.field] ?? 0;
16376
+ });
16377
+ });
16378
+ return {
16379
+ rows,
16380
+ columns: columns ?? [],
16381
+ rowCount: rowCount || rows.length,
16382
+ pivotQuery: "",
16383
+ comparisonPivotQuery: ""
16384
+ };
16385
+ }
16264
16386
  var init_pivotConstructor = __esm({
16265
16387
  "src/utils/pivotConstructor.ts"() {
16266
16388
  "use strict";
@@ -19753,10 +19875,14 @@ async function cleanDashboardItem({
19753
19875
  const pivotChartProcessing = {
19754
19876
  page: DEFAULT_PAGINATION
19755
19877
  };
19756
- pivotTable = await getPivotTable(
19757
- {
19758
- ...item,
19759
- pivot: item.pivot && !skipPivotFetch ? {
19878
+ if (item.pivot && skipPivotFetch && item.rows && item.fields) {
19879
+ const dateFilter = dashboardFilters?.find(
19880
+ (filter) => filter.filterType === "date_range"
19881
+ );
19882
+ pivotTable = processPivotData({
19883
+ rows: item.rows,
19884
+ fields: item.fields,
19885
+ pivot: {
19760
19886
  ...item.pivot,
19761
19887
  aggregations: item.pivot.aggregations ?? [
19762
19888
  {
@@ -19767,18 +19893,40 @@ async function cleanDashboardItem({
19767
19893
  aggregationType: item.pivot.aggregationType
19768
19894
  }
19769
19895
  ]
19770
- } : void 0
19771
- },
19772
- dashboardFilters,
19773
- item.dashboardName,
19774
- getToken,
19775
- client,
19776
- eventTracking,
19777
- dateBucket,
19778
- shouldPaginatePivotAsTable ? additionalProcessing : pivotChartProcessing,
19779
- tenants,
19780
- customFields
19781
- );
19896
+ },
19897
+ dateBucket,
19898
+ dateFilter,
19899
+ client,
19900
+ rowCount: item.rowCount ? parseInt(item.rowCount) : item.rows.length
19901
+ });
19902
+ } else {
19903
+ pivotTable = await getPivotTable(
19904
+ {
19905
+ ...item,
19906
+ pivot: item.pivot && !skipPivotFetch ? {
19907
+ ...item.pivot,
19908
+ aggregations: item.pivot.aggregations ?? [
19909
+ {
19910
+ valueField: item.pivot.valueField,
19911
+ valueFieldType: item.pivot.valueFieldType,
19912
+ valueField2: item.pivot.valueField2,
19913
+ valueField2Type: item.pivot.valueField2Type,
19914
+ aggregationType: item.pivot.aggregationType
19915
+ }
19916
+ ]
19917
+ } : void 0
19918
+ },
19919
+ dashboardFilters,
19920
+ item.dashboardName,
19921
+ getToken,
19922
+ client,
19923
+ eventTracking,
19924
+ dateBucket,
19925
+ shouldPaginatePivotAsTable ? additionalProcessing : pivotChartProcessing,
19926
+ tenants,
19927
+ customFields
19928
+ );
19929
+ }
19782
19930
  } catch (e) {
19783
19931
  pivotTable = void 0;
19784
19932
  eventTracking?.logError?.({
@@ -20186,6 +20334,33 @@ function extractAllReportValuesFromQuillInternalReport(reportInternal) {
20186
20334
  pivotRowCount: reportInternal.pivotRowCount
20187
20335
  };
20188
20336
  }
20337
+ async function fetchReportRows({
20338
+ reportId,
20339
+ client,
20340
+ tenants,
20341
+ filters = [],
20342
+ getToken,
20343
+ abortSignal,
20344
+ additionalProcessing
20345
+ }) {
20346
+ const fetchResp = await quillFetch({
20347
+ client,
20348
+ task: "report",
20349
+ metadata: {
20350
+ reportId,
20351
+ clientId: client.publicKey,
20352
+ databaseType: client.databaseType,
20353
+ filters: filters.map((filter) => ({ ...filter, options: void 0 })),
20354
+ useNewNodeSql: true,
20355
+ tenants,
20356
+ additionalProcessing
20357
+ },
20358
+ abortSignal,
20359
+ getToken
20360
+ });
20361
+ const resp = await parseFetchResponse(client, "report", fetchResp, getToken);
20362
+ return { rows: resp.rows || [], rowCount: resp.rowCount || 0 };
20363
+ }
20189
20364
  async function fetchReport({
20190
20365
  reportId,
20191
20366
  client,
@@ -20200,14 +20375,15 @@ async function fetchReport({
20200
20375
  rowCountOnly,
20201
20376
  abortSignal,
20202
20377
  getToken,
20203
- eventTracking
20378
+ eventTracking,
20379
+ usePivotTask = false
20204
20380
  }) {
20205
20381
  let reportInfo = void 0;
20206
20382
  let errorMessage = void 0;
20207
20383
  try {
20208
20384
  const fetchResp = await quillFetch({
20209
20385
  client,
20210
- task: useReportTask ? "report" : "item",
20386
+ task: usePivotTask ? "pivot-template" : useReportTask ? "report" : "item",
20211
20387
  metadata: {
20212
20388
  reportId,
20213
20389
  dashboardItemId: reportId,
@@ -20227,7 +20403,7 @@ async function fetchReport({
20227
20403
  });
20228
20404
  const resp = await parseFetchResponse(
20229
20405
  client,
20230
- useReportTask ? "report" : "item",
20406
+ usePivotTask ? "pivot-template" : useReportTask ? "report" : "item",
20231
20407
  fetchResp,
20232
20408
  getToken
20233
20409
  );
@@ -20235,12 +20411,13 @@ async function fetchReport({
20235
20411
  resp,
20236
20412
  client,
20237
20413
  filters,
20238
- dateBucket,
20414
+ dateBucket: resp.dateBucket ?? dateBucket,
20239
20415
  additionalProcessing,
20240
20416
  customFields,
20241
20417
  getToken,
20242
20418
  eventTracking,
20243
- tenants
20419
+ tenants,
20420
+ skipPivotFetch: usePivotTask
20244
20421
  });
20245
20422
  } catch (error) {
20246
20423
  if (error instanceof Error && error.name === "AbortError") {
@@ -20289,7 +20466,8 @@ async function processReportResponse({
20289
20466
  customFields,
20290
20467
  getToken,
20291
20468
  eventTracking,
20292
- tenants
20469
+ tenants,
20470
+ skipPivotFetch = false
20293
20471
  }) {
20294
20472
  const dashboardItem = {
20295
20473
  ...resp,
@@ -20320,7 +20498,8 @@ async function processReportResponse({
20320
20498
  customFields,
20321
20499
  getToken,
20322
20500
  tenants,
20323
- eventTracking
20501
+ eventTracking,
20502
+ skipPivotFetch
20324
20503
  });
20325
20504
  if (additionalProcessing) {
20326
20505
  reportInfo.pagination = additionalProcessing.page;
@@ -32333,6 +32512,7 @@ function DataLoader({
32333
32512
  previousUserFilters.current = userFilters;
32334
32513
  rowsAbortController.current?.abort();
32335
32514
  rowsAbortController.current = new AbortController();
32515
+ const usePivotTask = !!item.pivot;
32336
32516
  try {
32337
32517
  if (dashboardName) {
32338
32518
  const { report: fetchedReport, error: error2 } = await fetchReport({
@@ -32348,7 +32528,8 @@ function DataLoader({
32348
32528
  rowCountOnly: false,
32349
32529
  abortSignal: rowsAbortController.current.signal,
32350
32530
  getToken,
32351
- eventTracking
32531
+ eventTracking,
32532
+ usePivotTask
32352
32533
  });
32353
32534
  addReport({
32354
32535
  ...fetchedReport,
@@ -32480,7 +32661,11 @@ var ChartDataLoader = ({
32480
32661
  dashboardName,
32481
32662
  propagateChanges
32482
32663
  }) => {
32483
- const { dashboardReports: dashboard, addReport } = useDashboardReports(dashboardName);
32664
+ const {
32665
+ dashboardReports: dashboard,
32666
+ addReport,
32667
+ updateReport
32668
+ } = useDashboardReports(dashboardName);
32484
32669
  const { dashboardFilters } = useContext13(DashboardFiltersContext);
32485
32670
  const { reports, fetchIndividualReport } = useContext13(ReportsContext);
32486
32671
  const { getToken } = useContext13(FetchContext);
@@ -32530,6 +32715,8 @@ var ChartDataLoader = ({
32530
32715
  setLoading(true);
32531
32716
  fetchReportAbortController.current?.abort();
32532
32717
  fetchReportAbortController.current = new AbortController();
32718
+ const usePivotTask = !!item.pivot;
32719
+ let backgroundFetch = null;
32533
32720
  try {
32534
32721
  if (dashboardName) {
32535
32722
  const { report, error: error2 } = await fetchReport({
@@ -32547,7 +32734,8 @@ var ChartDataLoader = ({
32547
32734
  customFields: schemaData.customFields,
32548
32735
  abortSignal: fetchReportAbortController.current.signal,
32549
32736
  getToken,
32550
- eventTracking
32737
+ eventTracking,
32738
+ usePivotTask
32551
32739
  });
32552
32740
  addReport({
32553
32741
  ...report,
@@ -32557,6 +32745,32 @@ var ChartDataLoader = ({
32557
32745
  loadingRows: false
32558
32746
  });
32559
32747
  setError(error2);
32748
+ if (usePivotTask) {
32749
+ const backgroundAbortController = new AbortController();
32750
+ backgroundFetch = () => {
32751
+ fetchReportRows({
32752
+ reportId: item.id,
32753
+ client,
32754
+ tenants,
32755
+ filters: filters.concat(userFilters ?? []),
32756
+ getToken,
32757
+ abortSignal: backgroundAbortController.signal,
32758
+ additionalProcessing: {
32759
+ ...additionalProcessing,
32760
+ ...{ page: DEFAULT_PAGINATION }
32761
+ }
32762
+ }).then(({ rows, rowCount }) => {
32763
+ updateReport({
32764
+ id: item.id,
32765
+ rows,
32766
+ rowCount
32767
+ });
32768
+ }).catch((e) => {
32769
+ if (e instanceof Error && e.name === "AbortError") return;
32770
+ console.error("Failed to fetch background rows", e);
32771
+ });
32772
+ };
32773
+ }
32560
32774
  } else {
32561
32775
  try {
32562
32776
  await fetchIndividualReport({
@@ -32612,6 +32826,9 @@ var ChartDataLoader = ({
32612
32826
  if (fetchRowsRequestId === rowsRequestId.current) {
32613
32827
  fetchReportAbortController.current = null;
32614
32828
  setLoading(false);
32829
+ if (backgroundFetch) {
32830
+ backgroundFetch();
32831
+ }
32615
32832
  }
32616
32833
  }
32617
32834
  };
@@ -38789,7 +39006,7 @@ function Dashboard({
38789
39006
  filters: populatedDashboardFilters ?? [],
38790
39007
  userFilters: dataLoaderUserFilters,
38791
39008
  additionalProcessing: {
38792
- page: DEFAULT_PAGINATION,
39009
+ page: pagination,
38793
39010
  last: additionalProcessing?.last
38794
39011
  },
38795
39012
  dashboardName: name2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillsql/react",
3
- "version": "2.16.10",
3
+ "version": "2.16.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {