@quillsql/react 2.16.5 → 2.16.7

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 +306 -79
  2. package/dist/index.js +311 -83
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -14416,9 +14416,15 @@ function convertCaseWhenToPivotData(column) {
14416
14416
  return pivot;
14417
14417
  }
14418
14418
  function convertASTToPivotData(ast, columnInfo) {
14419
+ if (!ast) {
14420
+ return null;
14421
+ }
14419
14422
  const newPivot = {};
14420
14423
  const aliasMap = {};
14421
- if (ast.columns === "*") {
14424
+ if (!ast.columns || ast.columns === "*") {
14425
+ return null;
14426
+ }
14427
+ if (!Array.isArray(ast.columns)) {
14422
14428
  return null;
14423
14429
  }
14424
14430
  ast.columns.forEach((column) => {
@@ -14619,7 +14625,7 @@ var init_reportBuilder = __esm({
14619
14625
  const schemaTable = schema.find((s) => s.name === table.name);
14620
14626
  return schemaTable ? schemaTable.columns : [];
14621
14627
  });
14622
- const pivot = astGroupByToPivot(ast.groupby, relevantColumns);
14628
+ const pivot = astGroupByToPivot(ast, relevantColumns);
14623
14629
  const sort = astOrderByToSort(ast.orderby);
14624
14630
  const limit = astLimitToLimit(ast.limit);
14625
14631
  const filterStack = generateFilterStack(
@@ -14646,11 +14652,11 @@ var init_reportBuilder = __esm({
14646
14652
  };
14647
14653
  });
14648
14654
  };
14649
- astGroupByToPivot = (node, columnInfo) => {
14650
- if (!node) {
14655
+ astGroupByToPivot = (ast, columnInfo) => {
14656
+ if (!ast || !ast.groupby) {
14651
14657
  return null;
14652
14658
  }
14653
- return convertASTToPivotData(node, columnInfo);
14659
+ return convertASTToPivotData(ast, columnInfo);
14654
14660
  };
14655
14661
  astFromToTables = (node) => {
14656
14662
  if (!node) {
@@ -18945,7 +18951,9 @@ var init_dataFetcher = __esm({
18945
18951
  if (e instanceof Error && e.name === "AbortError") {
18946
18952
  throw e;
18947
18953
  }
18948
- console.error("Failed to fetch:", e);
18954
+ if (task !== "set-section-order") {
18955
+ console.error("Failed to fetch:", e);
18956
+ }
18949
18957
  return { error: "Failed to fetch data" };
18950
18958
  }
18951
18959
  };
@@ -22282,28 +22290,16 @@ var ContextProvider = ({
22282
22290
  dashboardName,
22283
22291
  sectionOrder: newSectionOrder
22284
22292
  };
22285
- try {
22286
- await quillFetch({
22287
- client,
22288
- task: "set-section-order",
22289
- metadata: body,
22290
- getToken: getAuthorizationToken
22291
- });
22292
- } catch (e) {
22293
- console.error(e);
22294
- eventTracking?.logError?.({
22295
- type: "bug",
22296
- // TODO: determine type
22297
- severity: "high",
22298
- message: "Error setting section order",
22299
- errorMessage: e.message,
22300
- errorStack: e.stack,
22301
- errorData: {
22302
- caller: "Context",
22303
- function: "loadDashboard"
22304
- }
22305
- });
22306
- }
22293
+ void quillFetch({
22294
+ client,
22295
+ task: "set-section-order",
22296
+ metadata: body,
22297
+ getToken: getAuthorizationToken
22298
+ }).catch((error) => {
22299
+ if (error instanceof Error && error.name === "AbortError") {
22300
+ return;
22301
+ }
22302
+ });
22307
22303
  }
22308
22304
  }
22309
22305
  }
@@ -23159,12 +23155,11 @@ var useDashboardInternal = (dashboardName, customFilters) => {
23159
23155
  dashboardName,
23160
23156
  sectionOrder
23161
23157
  };
23162
- try {
23163
- const response = await quillFetchWithToken({
23164
- client,
23165
- task: "set-section-order",
23166
- metadata: body
23167
- });
23158
+ void quillFetchWithToken({
23159
+ client,
23160
+ task: "set-section-order",
23161
+ metadata: body
23162
+ }).then((response) => {
23168
23163
  Object.entries(response?.data?.newIds ?? {}).forEach(
23169
23164
  ([section, newId2]) => {
23170
23165
  dashboardConfigDispatch({
@@ -23186,21 +23181,11 @@ var useDashboardInternal = (dashboardName, customFilters) => {
23186
23181
  });
23187
23182
  }
23188
23183
  );
23189
- } catch (e) {
23190
- console.error(e);
23191
- eventTracking?.logError?.({
23192
- type: "bug",
23193
- // TODO: determine type
23194
- severity: "high",
23195
- message: "Error setting section order",
23196
- errorMessage: e.message,
23197
- errorStack: e.stack,
23198
- errorData: {
23199
- caller: "useDashboard",
23200
- function: "setSectionOrder"
23201
- }
23202
- });
23203
- }
23184
+ }).catch((error) => {
23185
+ if (error instanceof Error && error.name === "AbortError") {
23186
+ return;
23187
+ }
23188
+ });
23204
23189
  }
23205
23190
  };
23206
23191
  function isDashboardFilterLoading(filterName) {
@@ -24761,25 +24746,58 @@ var import_react5 = __toESM(require("react"), 1);
24761
24746
  var import_recharts = require("recharts");
24762
24747
 
24763
24748
  // src/utils/color.ts
24749
+ var DEFAULT_GRADIENT_COLORS = [
24750
+ "#4E80EE",
24751
+ // vivid indigo
24752
+ "#586FF4",
24753
+ "#6464FA",
24754
+ "#715AFE",
24755
+ "#8450FF",
24756
+ "#9B48FF",
24757
+ "#B33FFF",
24758
+ "#CA37F3",
24759
+ "#DE2FE1",
24760
+ "#F028CB",
24761
+ "#FF20B5"
24762
+ ];
24764
24763
  function generateArrayFromColor(colors, length) {
24764
+ if (length <= 0) {
24765
+ return [];
24766
+ }
24765
24767
  if (typeof colors === "string") {
24766
- return monochromaticInterpolation(colors, length);
24768
+ const trimmedColor = colors.trim();
24769
+ return monochromaticInterpolation(
24770
+ trimmedColor.length > 0 ? trimmedColor : DEFAULT_GRADIENT_COLORS[0],
24771
+ length
24772
+ );
24767
24773
  }
24768
- if (colors.length === 1) {
24769
- return monochromaticInterpolation(colors[0], length);
24774
+ const normalizedColors = colors.filter((color2) => typeof color2 === "string").map((color2) => color2.trim()).filter((color2) => color2.length > 0);
24775
+ const baseColors = normalizedColors.length > 0 ? normalizedColors : DEFAULT_GRADIENT_COLORS;
24776
+ if (baseColors.length === 1) {
24777
+ return monochromaticInterpolation(baseColors[0], length);
24770
24778
  }
24771
- const pairs = colors.length - 1;
24772
- const needed = length - colors.length;
24779
+ if (length <= baseColors.length) {
24780
+ return baseColors.slice(0, length);
24781
+ }
24782
+ const pairs = baseColors.length - 1;
24783
+ if (pairs <= 0) {
24784
+ return [baseColors[0]];
24785
+ }
24786
+ const needed = length - baseColors.length;
24773
24787
  const baseAmount = Math.floor(needed / pairs);
24774
24788
  const extras = needed % pairs;
24775
24789
  let result = [];
24776
24790
  let i = 0;
24777
24791
  let j = 1;
24778
- while (j < colors.length) {
24792
+ while (j < baseColors.length) {
24779
24793
  const additional = i < extras ? 1 : 0;
24780
24794
  const interpLength = 2 + baseAmount + additional;
24781
- const interp = interpolateBetween(colors[i], colors[j], interpLength);
24782
- const lastIndex = j === colors.length - 1 ? void 0 : -1;
24795
+ const interp = interpolateBetween(
24796
+ baseColors[i],
24797
+ baseColors[j],
24798
+ interpLength
24799
+ );
24800
+ const lastIndex = j === baseColors.length - 1 ? void 0 : -1;
24783
24801
  result = result.concat(interp.slice(0, lastIndex));
24784
24802
  i++;
24785
24803
  j++;
@@ -25103,8 +25121,9 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25103
25121
  dataPoint[valueKey] = totalValue ? rawValue * 100 / totalValue : data.length > maxItems ? 100 / (maxItems + 1) : 100 / slicedData.length;
25104
25122
  dataPoint[`raw_${valueKey}`] = parseFloat(rawValue.toFixed(2));
25105
25123
  });
25124
+ const palette = colors.length >= maxItems ? colors.slice(0, maxItems) : generateArrayFromColor(colors, maxItems);
25106
25125
  const parsedData = slicedData.map((dataPoint, idx) => {
25107
- const baseColor = idx < colors.length ? colors[idx] : colors[colors.length - 1];
25126
+ const baseColor = palette[idx % palette.length];
25108
25127
  return {
25109
25128
  ...dataPoint,
25110
25129
  color: baseColor,
@@ -25122,7 +25141,7 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25122
25141
  ),
25123
25142
  0
25124
25143
  );
25125
- const otherColor = colors[colors.length - 1];
25144
+ const otherColor = palette[parsedData.length % palette.length] ?? palette[palette.length - 1];
25126
25145
  const normalizedOtherSum = totalValue ? otherSum * 100 / totalValue : 100 / (maxItems + 1);
25127
25146
  parsedData.push({
25128
25147
  [categoryKey]: "Other",
@@ -25495,7 +25514,7 @@ var PieChartWrapper = import_react5.default.forwardRef(
25495
25514
  (colorMap[category] && colorMap[category]["primary"] && generateArrayFromColor(
25496
25515
  colorMap[category]["primary"],
25497
25516
  data.length
25498
- )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors.slice(0, 2), data.length)),
25517
+ )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors, data.length)),
25499
25518
  index,
25500
25519
  category
25501
25520
  ),
@@ -31828,7 +31847,16 @@ var MetricDisplay = ({
31828
31847
  marginRight: "auto"
31829
31848
  },
31830
31849
  children: [
31831
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children }),
31850
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
31851
+ "div",
31852
+ {
31853
+ style: {
31854
+ display: "inline-block",
31855
+ lineHeight: 1.1
31856
+ },
31857
+ children
31858
+ }
31859
+ ),
31832
31860
  dateFilter?.comparison && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
31833
31861
  "span",
31834
31862
  {
@@ -31857,13 +31885,15 @@ var MetricDisplay = ({
31857
31885
  },
31858
31886
  children: [
31859
31887
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
31860
- "span",
31888
+ "div",
31861
31889
  {
31862
31890
  style: {
31863
31891
  fontSize: 28,
31864
31892
  fontWeight: "500",
31865
31893
  fontFamily: theme?.fontFamily,
31866
- color: theme?.secondaryTextColor
31894
+ color: theme?.secondaryTextColor,
31895
+ display: "inline-block",
31896
+ lineHeight: 1.1
31867
31897
  },
31868
31898
  children
31869
31899
  }
@@ -39261,6 +39291,7 @@ var PivotCard = ({
39261
39291
  }) => {
39262
39292
  const defaultValueField = pivotTable.pivot && pivotTable.pivot.aggregationType === "count" ? "whole_number" : "two_decimal_places";
39263
39293
  const maxRowsInPivotPeak = 5;
39294
+ const headerColumnCount = (pivotTable.pivot?.rowField ? 1 : 0) + (pivotTable.pivot?.columnField ? 1 : 0) + (!pivotTable.pivot?.columnField && pivotTable.pivot?.aggregations?.[0]?.valueField ? 1 : 0);
39264
39295
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
39265
39296
  CardComponent,
39266
39297
  {
@@ -39364,16 +39395,16 @@ var PivotCard = ({
39364
39395
  pivotTable.pivot.aggregations?.[0]?.valueField
39365
39396
  )
39366
39397
  ] }) }),
39367
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
39398
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("tbody", { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
39368
39399
  "tr",
39369
39400
  {
39370
39401
  style: {
39371
39402
  paddingLeft: "2px",
39372
39403
  width: "100%"
39373
39404
  },
39374
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TextComponent, { label: "No results" })
39405
+ children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("td", { colSpan: headerColumnCount || 1, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TextComponent, { label: "No results" }) })
39375
39406
  }
39376
- )
39407
+ ) })
39377
39408
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("table", { children: [
39378
39409
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("tr", { children: pivotTable.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
39379
39410
  "th",
@@ -40735,7 +40766,7 @@ var PivotModal = ({
40735
40766
  {
40736
40767
  id: "pivot-row-field",
40737
40768
  label: "Group rows by",
40738
- value: pivotRowField,
40769
+ value: pivotRowField ?? "",
40739
40770
  onChange: (e) => {
40740
40771
  pivotFieldChange(
40741
40772
  "rowField",
@@ -40762,7 +40793,7 @@ var PivotModal = ({
40762
40793
  {
40763
40794
  id: "pivot-column-field",
40764
40795
  label: "Group columns by",
40765
- value: pivotColumnField,
40796
+ value: pivotColumnField ?? "",
40766
40797
  onChange: (e) => {
40767
40798
  pivotFieldChange(
40768
40799
  "columnField",
@@ -40807,7 +40838,7 @@ var PivotModal = ({
40807
40838
  SelectComponent,
40808
40839
  {
40809
40840
  id: "pivot-aggregation-type",
40810
- value: agg.aggregationType,
40841
+ value: agg.aggregationType ?? "",
40811
40842
  onChange: (e) => {
40812
40843
  const newAgg = [
40813
40844
  ...pivotAggregations.slice(0, index),
@@ -40839,7 +40870,7 @@ var PivotModal = ({
40839
40870
  SelectComponent,
40840
40871
  {
40841
40872
  id: "pivot-value-field",
40842
- value: agg.valueField,
40873
+ value: agg.valueField ?? "",
40843
40874
  onChange: (e) => {
40844
40875
  const newAgg = [
40845
40876
  ...pivotAggregations.slice(0, index),
@@ -42454,7 +42485,7 @@ var CHART_TO_LABELS = {
42454
42485
  column: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42455
42486
  line: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42456
42487
  table: {},
42457
- metric: {},
42488
+ metric: { xAxisLabel: "Value" },
42458
42489
  bar: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42459
42490
  stacked: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42460
42491
  pie: { xAxisLabel: "Category", yAxisLabel: "Count" },
@@ -42884,7 +42915,7 @@ function ChartBuilder({
42884
42915
  }
42885
42916
  return columns2;
42886
42917
  };
42887
- const [processedColumns, setProcessedColumns] = (0, import_react44.useState)(
42918
+ const [columns, setColumns] = (0, import_react44.useState)(
42888
42919
  processColumns(report?.columnInternal ?? [])
42889
42920
  );
42890
42921
  const [currentPage, setCurrentPage] = (0, import_react44.useState)(0);
@@ -42998,7 +43029,6 @@ function ChartBuilder({
42998
43029
  pivotQuery: report.pivotQuery ?? "",
42999
43030
  comparisonPivotQuery: report.comparisonPivotQuery
43000
43031
  } : void 0;
43001
- const columns = report?.columnInternal ?? [];
43002
43032
  const destinationDashboardName = report?.dashboardName || destinationDashboard;
43003
43033
  const query = report?.queryString;
43004
43034
  const [loadingFormData, setLoadingFormData] = (0, import_react44.useState)(false);
@@ -43550,6 +43580,26 @@ function ChartBuilder({
43550
43580
  ) ?? {};
43551
43581
  }, [client?.allTenantTypes]);
43552
43582
  const [selectedPivotTable, setSelectedPivotTable] = (0, import_react44.useState)(pivotData);
43583
+ const getDefaultXAxisFormat = (0, import_react44.useCallback)(
43584
+ (form) => {
43585
+ if (form.pivot?.rowField) {
43586
+ if (isDateField(form.pivot.rowFieldType ?? "")) {
43587
+ return "string";
43588
+ }
43589
+ const pivotRowColumn = selectedPivotTable?.columns?.find(
43590
+ (col) => col.field === form.pivot?.rowField
43591
+ ) ?? columns.find((col) => col.field === form.pivot?.rowField);
43592
+ if (pivotRowColumn?.format) {
43593
+ return pivotRowColumn.format;
43594
+ }
43595
+ }
43596
+ const currentXAxisColumn = (selectedPivotTable?.columns ?? columns).find(
43597
+ (c) => c.field === form.xAxisField
43598
+ );
43599
+ return currentXAxisColumn?.format ?? "string";
43600
+ },
43601
+ [columns, selectedPivotTable]
43602
+ );
43553
43603
  const pivotCardTable = (0, import_react44.useMemo)(() => {
43554
43604
  return {
43555
43605
  pivot: formData.pivot,
@@ -43766,7 +43816,8 @@ function ChartBuilder({
43766
43816
  });
43767
43817
  setCurrentProcessing(processing);
43768
43818
  setRows(tableInfo.rows);
43769
- setProcessedColumns(processColumns(tableInfo.columns));
43819
+ const updatedColumns = processColumns(tableInfo.columns);
43820
+ setColumns(updatedColumns);
43770
43821
  if (tableInfo.itemQuery) {
43771
43822
  setItemQuery(tableInfo.itemQuery);
43772
43823
  }
@@ -43983,6 +44034,7 @@ function ChartBuilder({
43983
44034
  updatedForm = { ...updatedForm, [fieldName]: value };
43984
44035
  }
43985
44036
  if (fieldName === "chartType") {
44037
+ const previousChartType = formData.chartType;
43986
44038
  if (value === "metric") {
43987
44039
  updatedForm.xAxisFormat = "whole_number";
43988
44040
  const currentXAxisColumn = (selectedPivotTable?.columns ?? columns).find((c) => c.field === updatedForm.xAxisField);
@@ -43999,6 +44051,16 @@ function ChartBuilder({
43999
44051
  (c) => NUMBER_FORMAT_TYPES.includes(c.format)
44000
44052
  )?.field ?? updatedForm.xAxisField;
44001
44053
  }
44054
+ } else {
44055
+ if (previousChartType === "gauge" && updatedForm.xAxisFormat === "percent") {
44056
+ updatedForm.xAxisFormat = getDefaultXAxisFormat(updatedForm);
44057
+ }
44058
+ if (previousChartType === "metric" && updatedForm.xAxisFormat === "whole_number") {
44059
+ updatedForm.xAxisFormat = getDefaultXAxisFormat(updatedForm);
44060
+ }
44061
+ if (previousChartType === "gauge" && updatedForm.pivot?.rowField && updatedForm.xAxisField !== updatedForm.pivot.rowField) {
44062
+ updatedForm.xAxisField = updatedForm.pivot.rowField;
44063
+ }
44002
44064
  }
44003
44065
  }
44004
44066
  let dashboardName = updatedForm.dashboardName;
@@ -44701,7 +44763,7 @@ function ChartBuilder({
44701
44763
  setShowUpdatePivot: setIsEdittingPivot,
44702
44764
  parentRef,
44703
44765
  data: rows,
44704
- columns: processedColumns,
44766
+ columns,
44705
44767
  triggerButtonText: "Add pivot +",
44706
44768
  selectedPivotIndex,
44707
44769
  setSelectedPivotIndex,
@@ -44775,7 +44837,7 @@ function ChartBuilder({
44775
44837
  ]
44776
44838
  }
44777
44839
  ),
44778
- !hideChartView && (formData.pivot || formData.chartType !== "table" && formData.chartType !== "metric") && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { children: [
44840
+ !hideChartView && (formData.pivot || formData.chartType !== "table") && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { children: [
44779
44841
  CHART_TO_LABELS[formData.chartType]?.xAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
44780
44842
  "div",
44781
44843
  {
@@ -46342,6 +46404,166 @@ function setEditorTheme(_editor, monaco, schema, databaseType, clientName, event
46342
46404
  return null;
46343
46405
  }
46344
46406
  }
46407
+ function reconcileReportWithColumns(report, columns, previousReport) {
46408
+ const safeColumns = columns ?? [];
46409
+ const fallbackForm = createInitialFormData(safeColumns);
46410
+ const columnFieldSet = new Set(
46411
+ safeColumns.map((column) => column.field).filter(Boolean)
46412
+ );
46413
+ const previousColumnsByField = new Map(
46414
+ (previousReport?.columns ?? []).map((column) => [column.field, column])
46415
+ );
46416
+ const previousColumnInternalByField = new Map(
46417
+ (previousReport?.columnInternal ?? []).map((column) => [
46418
+ column.field,
46419
+ column
46420
+ ])
46421
+ );
46422
+ const existingColumnsByField = new Map(
46423
+ (report.columns ?? []).map((column) => [column.field, column])
46424
+ );
46425
+ const existingColumnInternalByField = new Map(
46426
+ (report.columnInternal ?? []).map((column) => [column.field, column])
46427
+ );
46428
+ const reconciledColumnInternal = safeColumns.map((column) => {
46429
+ const fallback = existingColumnInternalByField.get(column.field) ?? previousColumnInternalByField.get(column.field) ?? existingColumnsByField.get(column.field) ?? previousColumnsByField.get(column.field);
46430
+ return {
46431
+ ...column,
46432
+ format: fallback?.format ?? column.format,
46433
+ label: fallback?.label ?? column.label
46434
+ };
46435
+ });
46436
+ const reconciledColumns = reconciledColumnInternal.map((column) => ({
46437
+ field: column.field,
46438
+ label: column.label,
46439
+ format: column.format
46440
+ }));
46441
+ const resolveXAxisField = () => {
46442
+ if (report.xAxisField && columnFieldSet.has(report.xAxisField)) {
46443
+ return report.xAxisField;
46444
+ }
46445
+ if (previousReport?.xAxisField && columnFieldSet.has(previousReport.xAxisField)) {
46446
+ return previousReport.xAxisField;
46447
+ }
46448
+ return fallbackForm.xAxisField;
46449
+ };
46450
+ const xAxisField = resolveXAxisField();
46451
+ const xAxisColumn = reconciledColumnInternal.find(
46452
+ (column) => column.field === xAxisField
46453
+ );
46454
+ const xAxisFormat = (report.xAxisField === xAxisField ? report.xAxisFormat : void 0) ?? (previousReport?.xAxisField === xAxisField ? previousReport.xAxisFormat : void 0) ?? xAxisColumn?.format ?? fallbackForm.xAxisFormat ?? "string";
46455
+ const xAxisLabel = report.xAxisField === xAxisField ? report.xAxisLabel : previousReport?.xAxisField === xAxisField ? previousReport.xAxisLabel : fallbackForm.xAxisLabel ?? "";
46456
+ const existingYAxisFields = report.yAxisFields ?? previousReport?.yAxisFields ?? [];
46457
+ let yAxisFields = existingYAxisFields.filter((axis) => axis?.field && columnFieldSet.has(axis.field)).map((axis) => {
46458
+ const column = reconciledColumnInternal.find(
46459
+ (col) => col.field === axis.field
46460
+ );
46461
+ return {
46462
+ field: axis.field,
46463
+ label: axis.label,
46464
+ format: axis.format ?? column?.format ?? "string"
46465
+ };
46466
+ });
46467
+ if (yAxisFields.length === 0) {
46468
+ yAxisFields = fallbackForm.yAxisFields;
46469
+ }
46470
+ const existingReferenceLines = report.referenceLines ?? previousReport?.referenceLines ?? [];
46471
+ const referenceLines = existingReferenceLines.filter((line) => {
46472
+ if (line.label === REFERENCE_LINE) {
46473
+ return true;
46474
+ }
46475
+ return typeof line.label === "string" && columnFieldSet.has(line.label);
46476
+ });
46477
+ const existingReferenceLineYValues = report.referenceLineYValues ?? previousReport?.referenceLineYValues ?? [];
46478
+ const referenceLineYValues = existingReferenceLineYValues.filter((line) => {
46479
+ if (line.label === REFERENCE_LINE) {
46480
+ return true;
46481
+ }
46482
+ return typeof line.label === "string" && columnFieldSet.has(line.label);
46483
+ });
46484
+ const existingColumnsWithCustomFields = report.columnsWithCustomFields ?? previousReport?.columnsWithCustomFields ?? [];
46485
+ const columnsWithCustomFields = existingColumnsWithCustomFields.filter(
46486
+ (column) => columnFieldSet.has(column.field)
46487
+ );
46488
+ const existingFilterMap = report.filterMap ?? previousReport?.filterMap;
46489
+ const filterMap = existingFilterMap ? Object.fromEntries(
46490
+ Object.entries(existingFilterMap).filter(([, value]) => {
46491
+ return value.field && columnFieldSet.has(value.field);
46492
+ })
46493
+ ) : existingFilterMap;
46494
+ const existingFiltersApplied = report.filtersApplied ?? previousReport?.filtersApplied;
46495
+ const filtersApplied = existingFiltersApplied ? existingFiltersApplied.filter((filter) => {
46496
+ if (!filter.field) {
46497
+ return true;
46498
+ }
46499
+ return columnFieldSet.has(filter.field);
46500
+ }) : existingFiltersApplied;
46501
+ const existingSort = report.sort ?? previousReport?.sort;
46502
+ const sort = existingSort && columnFieldSet.has(existingSort.field) ? existingSort : void 0;
46503
+ let pivot = report.pivot ?? previousReport?.pivot ?? null;
46504
+ if (pivot) {
46505
+ const pivotFields = [];
46506
+ if (pivot.rowField) {
46507
+ pivotFields.push(pivot.rowField);
46508
+ }
46509
+ if (pivot.columnField) {
46510
+ pivotFields.push(pivot.columnField);
46511
+ }
46512
+ if ("aggregations" in pivot && Array.isArray(pivot.aggregations)) {
46513
+ pivot.aggregations.forEach((aggregation) => {
46514
+ if (aggregation.valueField) {
46515
+ pivotFields.push(aggregation.valueField);
46516
+ }
46517
+ if (aggregation.valueField2) {
46518
+ pivotFields.push(aggregation.valueField2);
46519
+ }
46520
+ });
46521
+ } else {
46522
+ const singleAggregation = pivot;
46523
+ if (singleAggregation.valueField) {
46524
+ pivotFields.push(singleAggregation.valueField);
46525
+ }
46526
+ if (singleAggregation.valueField2) {
46527
+ pivotFields.push(singleAggregation.valueField2);
46528
+ }
46529
+ }
46530
+ if (pivot.sortField) {
46531
+ pivotFields.push(pivot.sortField);
46532
+ }
46533
+ const missingPivotField = pivotFields.some(
46534
+ (field) => field && !columnFieldSet.has(field)
46535
+ );
46536
+ if (missingPivotField) {
46537
+ pivot = null;
46538
+ }
46539
+ }
46540
+ const pivotColumns = pivot ? (report.pivotColumns ?? previousReport?.pivotColumns)?.filter(
46541
+ (column) => columnFieldSet.has(column.field)
46542
+ ) : void 0;
46543
+ const pivotRows = pivot ? report.pivotRows ?? previousReport?.pivotRows : void 0;
46544
+ const pivotRowCount = pivot ? report.pivotRowCount ?? previousReport?.pivotRowCount : void 0;
46545
+ return {
46546
+ ...report,
46547
+ columns: reconciledColumns,
46548
+ columnInternal: reconciledColumnInternal,
46549
+ columnsWithCustomFields,
46550
+ xAxisField,
46551
+ xAxisFormat,
46552
+ xAxisLabel,
46553
+ yAxisFields,
46554
+ referenceLines,
46555
+ referenceLineYValues: referenceLineYValues.length ? referenceLineYValues : void 0,
46556
+ filterMap: filterMap && Object.keys(filterMap).length ? filterMap : void 0,
46557
+ filtersApplied: filtersApplied && filtersApplied.length ? filtersApplied : void 0,
46558
+ sort,
46559
+ pivot,
46560
+ pivotColumns,
46561
+ pivotRows,
46562
+ pivotRowCount,
46563
+ pivotQuery: pivot ? report.pivotQuery ?? previousReport?.pivotQuery : void 0,
46564
+ comparisonPivotQuery: pivot ? report.comparisonPivotQuery ?? previousReport?.comparisonPivotQuery : void 0
46565
+ };
46566
+ }
46345
46567
  function SQLEditor({
46346
46568
  ButtonComponent = MemoizedButton,
46347
46569
  SecondaryButtonComponent = MemoizedSecondaryButton,
@@ -46720,12 +46942,17 @@ function SQLEditor({
46720
46942
  referencedTables: tableInfo.referencedTables,
46721
46943
  queryString: query ?? tempReport.queryString ?? ""
46722
46944
  };
46945
+ const reconciledReport = reconcileReportWithColumns(
46946
+ newReport,
46947
+ tableInfo.columns ?? [],
46948
+ tempReport
46949
+ );
46723
46950
  if (reportId) {
46724
- setTempReport(newReport);
46951
+ setTempReport(reconciledReport);
46725
46952
  } else {
46726
46953
  const cleaned = await cleanDashboardItem({
46727
- item: newReport,
46728
- dashboardFilters: newReport.filtersApplied,
46954
+ item: reconciledReport,
46955
+ dashboardFilters: reconciledReport.filtersApplied,
46729
46956
  client,
46730
46957
  customFields: schemaData.customFields,
46731
46958
  getToken,
package/dist/index.js CHANGED
@@ -14453,9 +14453,15 @@ function convertCaseWhenToPivotData(column) {
14453
14453
  return pivot;
14454
14454
  }
14455
14455
  function convertASTToPivotData(ast, columnInfo) {
14456
+ if (!ast) {
14457
+ return null;
14458
+ }
14456
14459
  const newPivot = {};
14457
14460
  const aliasMap = {};
14458
- if (ast.columns === "*") {
14461
+ if (!ast.columns || ast.columns === "*") {
14462
+ return null;
14463
+ }
14464
+ if (!Array.isArray(ast.columns)) {
14459
14465
  return null;
14460
14466
  }
14461
14467
  ast.columns.forEach((column) => {
@@ -14656,7 +14662,7 @@ var init_reportBuilder = __esm({
14656
14662
  const schemaTable = schema.find((s) => s.name === table.name);
14657
14663
  return schemaTable ? schemaTable.columns : [];
14658
14664
  });
14659
- const pivot = astGroupByToPivot(ast.groupby, relevantColumns);
14665
+ const pivot = astGroupByToPivot(ast, relevantColumns);
14660
14666
  const sort = astOrderByToSort(ast.orderby);
14661
14667
  const limit = astLimitToLimit(ast.limit);
14662
14668
  const filterStack = generateFilterStack(
@@ -14683,11 +14689,11 @@ var init_reportBuilder = __esm({
14683
14689
  };
14684
14690
  });
14685
14691
  };
14686
- astGroupByToPivot = (node, columnInfo) => {
14687
- if (!node) {
14692
+ astGroupByToPivot = (ast, columnInfo) => {
14693
+ if (!ast || !ast.groupby) {
14688
14694
  return null;
14689
14695
  }
14690
- return convertASTToPivotData(node, columnInfo);
14696
+ return convertASTToPivotData(ast, columnInfo);
14691
14697
  };
14692
14698
  astFromToTables = (node) => {
14693
14699
  if (!node) {
@@ -18981,7 +18987,9 @@ var init_dataFetcher = __esm({
18981
18987
  if (e instanceof Error && e.name === "AbortError") {
18982
18988
  throw e;
18983
18989
  }
18984
- console.error("Failed to fetch:", e);
18990
+ if (task !== "set-section-order") {
18991
+ console.error("Failed to fetch:", e);
18992
+ }
18985
18993
  return { error: "Failed to fetch data" };
18986
18994
  }
18987
18995
  };
@@ -22290,28 +22298,16 @@ var ContextProvider = ({
22290
22298
  dashboardName,
22291
22299
  sectionOrder: newSectionOrder
22292
22300
  };
22293
- try {
22294
- await quillFetch({
22295
- client,
22296
- task: "set-section-order",
22297
- metadata: body,
22298
- getToken: getAuthorizationToken
22299
- });
22300
- } catch (e) {
22301
- console.error(e);
22302
- eventTracking?.logError?.({
22303
- type: "bug",
22304
- // TODO: determine type
22305
- severity: "high",
22306
- message: "Error setting section order",
22307
- errorMessage: e.message,
22308
- errorStack: e.stack,
22309
- errorData: {
22310
- caller: "Context",
22311
- function: "loadDashboard"
22312
- }
22313
- });
22314
- }
22301
+ void quillFetch({
22302
+ client,
22303
+ task: "set-section-order",
22304
+ metadata: body,
22305
+ getToken: getAuthorizationToken
22306
+ }).catch((error) => {
22307
+ if (error instanceof Error && error.name === "AbortError") {
22308
+ return;
22309
+ }
22310
+ });
22315
22311
  }
22316
22312
  }
22317
22313
  }
@@ -23173,12 +23169,11 @@ var useDashboardInternal = (dashboardName, customFilters) => {
23173
23169
  dashboardName,
23174
23170
  sectionOrder
23175
23171
  };
23176
- try {
23177
- const response = await quillFetchWithToken({
23178
- client,
23179
- task: "set-section-order",
23180
- metadata: body
23181
- });
23172
+ void quillFetchWithToken({
23173
+ client,
23174
+ task: "set-section-order",
23175
+ metadata: body
23176
+ }).then((response) => {
23182
23177
  Object.entries(response?.data?.newIds ?? {}).forEach(
23183
23178
  ([section, newId2]) => {
23184
23179
  dashboardConfigDispatch({
@@ -23200,21 +23195,11 @@ var useDashboardInternal = (dashboardName, customFilters) => {
23200
23195
  });
23201
23196
  }
23202
23197
  );
23203
- } catch (e) {
23204
- console.error(e);
23205
- eventTracking?.logError?.({
23206
- type: "bug",
23207
- // TODO: determine type
23208
- severity: "high",
23209
- message: "Error setting section order",
23210
- errorMessage: e.message,
23211
- errorStack: e.stack,
23212
- errorData: {
23213
- caller: "useDashboard",
23214
- function: "setSectionOrder"
23215
- }
23216
- });
23217
- }
23198
+ }).catch((error) => {
23199
+ if (error instanceof Error && error.name === "AbortError") {
23200
+ return;
23201
+ }
23202
+ });
23218
23203
  }
23219
23204
  };
23220
23205
  function isDashboardFilterLoading(filterName) {
@@ -24775,25 +24760,58 @@ import React3 from "react";
24775
24760
  import { Pie, PieChart, ResponsiveContainer, Tooltip } from "recharts";
24776
24761
 
24777
24762
  // src/utils/color.ts
24763
+ var DEFAULT_GRADIENT_COLORS = [
24764
+ "#4E80EE",
24765
+ // vivid indigo
24766
+ "#586FF4",
24767
+ "#6464FA",
24768
+ "#715AFE",
24769
+ "#8450FF",
24770
+ "#9B48FF",
24771
+ "#B33FFF",
24772
+ "#CA37F3",
24773
+ "#DE2FE1",
24774
+ "#F028CB",
24775
+ "#FF20B5"
24776
+ ];
24778
24777
  function generateArrayFromColor(colors, length) {
24778
+ if (length <= 0) {
24779
+ return [];
24780
+ }
24779
24781
  if (typeof colors === "string") {
24780
- return monochromaticInterpolation(colors, length);
24782
+ const trimmedColor = colors.trim();
24783
+ return monochromaticInterpolation(
24784
+ trimmedColor.length > 0 ? trimmedColor : DEFAULT_GRADIENT_COLORS[0],
24785
+ length
24786
+ );
24787
+ }
24788
+ const normalizedColors = colors.filter((color2) => typeof color2 === "string").map((color2) => color2.trim()).filter((color2) => color2.length > 0);
24789
+ const baseColors = normalizedColors.length > 0 ? normalizedColors : DEFAULT_GRADIENT_COLORS;
24790
+ if (baseColors.length === 1) {
24791
+ return monochromaticInterpolation(baseColors[0], length);
24781
24792
  }
24782
- if (colors.length === 1) {
24783
- return monochromaticInterpolation(colors[0], length);
24793
+ if (length <= baseColors.length) {
24794
+ return baseColors.slice(0, length);
24784
24795
  }
24785
- const pairs = colors.length - 1;
24786
- const needed = length - colors.length;
24796
+ const pairs = baseColors.length - 1;
24797
+ if (pairs <= 0) {
24798
+ return [baseColors[0]];
24799
+ }
24800
+ const needed = length - baseColors.length;
24787
24801
  const baseAmount = Math.floor(needed / pairs);
24788
24802
  const extras = needed % pairs;
24789
24803
  let result = [];
24790
24804
  let i = 0;
24791
24805
  let j = 1;
24792
- while (j < colors.length) {
24806
+ while (j < baseColors.length) {
24793
24807
  const additional = i < extras ? 1 : 0;
24794
24808
  const interpLength = 2 + baseAmount + additional;
24795
- const interp = interpolateBetween(colors[i], colors[j], interpLength);
24796
- const lastIndex = j === colors.length - 1 ? void 0 : -1;
24809
+ const interp = interpolateBetween(
24810
+ baseColors[i],
24811
+ baseColors[j],
24812
+ interpLength
24813
+ );
24814
+ const lastIndex = j === baseColors.length - 1 ? void 0 : -1;
24797
24815
  result = result.concat(interp.slice(0, lastIndex));
24798
24816
  i++;
24799
24817
  j++;
@@ -25117,8 +25135,9 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25117
25135
  dataPoint[valueKey] = totalValue ? rawValue * 100 / totalValue : data.length > maxItems ? 100 / (maxItems + 1) : 100 / slicedData.length;
25118
25136
  dataPoint[`raw_${valueKey}`] = parseFloat(rawValue.toFixed(2));
25119
25137
  });
25138
+ const palette = colors.length >= maxItems ? colors.slice(0, maxItems) : generateArrayFromColor(colors, maxItems);
25120
25139
  const parsedData = slicedData.map((dataPoint, idx) => {
25121
- const baseColor = idx < colors.length ? colors[idx] : colors[colors.length - 1];
25140
+ const baseColor = palette[idx % palette.length];
25122
25141
  return {
25123
25142
  ...dataPoint,
25124
25143
  color: baseColor,
@@ -25136,7 +25155,7 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25136
25155
  ),
25137
25156
  0
25138
25157
  );
25139
- const otherColor = colors[colors.length - 1];
25158
+ const otherColor = palette[parsedData.length % palette.length] ?? palette[palette.length - 1];
25140
25159
  const normalizedOtherSum = totalValue ? otherSum * 100 / totalValue : 100 / (maxItems + 1);
25141
25160
  parsedData.push({
25142
25161
  [categoryKey]: "Other",
@@ -25509,7 +25528,7 @@ var PieChartWrapper = React3.forwardRef(
25509
25528
  (colorMap[category] && colorMap[category]["primary"] && generateArrayFromColor(
25510
25529
  colorMap[category]["primary"],
25511
25530
  data.length
25512
- )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors.slice(0, 2), data.length)),
25531
+ )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors, data.length)),
25513
25532
  index,
25514
25533
  category
25515
25534
  ),
@@ -31908,7 +31927,16 @@ var MetricDisplay = ({
31908
31927
  marginRight: "auto"
31909
31928
  },
31910
31929
  children: [
31911
- /* @__PURE__ */ jsx43("span", { children }),
31930
+ /* @__PURE__ */ jsx43(
31931
+ "div",
31932
+ {
31933
+ style: {
31934
+ display: "inline-block",
31935
+ lineHeight: 1.1
31936
+ },
31937
+ children
31938
+ }
31939
+ ),
31912
31940
  dateFilter?.comparison && /* @__PURE__ */ jsx43(
31913
31941
  "span",
31914
31942
  {
@@ -31937,13 +31965,15 @@ var MetricDisplay = ({
31937
31965
  },
31938
31966
  children: [
31939
31967
  /* @__PURE__ */ jsx43(
31940
- "span",
31968
+ "div",
31941
31969
  {
31942
31970
  style: {
31943
31971
  fontSize: 28,
31944
31972
  fontWeight: "500",
31945
31973
  fontFamily: theme?.fontFamily,
31946
- color: theme?.secondaryTextColor
31974
+ color: theme?.secondaryTextColor,
31975
+ display: "inline-block",
31976
+ lineHeight: 1.1
31947
31977
  },
31948
31978
  children
31949
31979
  }
@@ -39245,7 +39275,7 @@ import {
39245
39275
  useEffect as useEffect25,
39246
39276
  useRef as useRef19,
39247
39277
  useMemo as useMemo22,
39248
- useCallback as useCallback3
39278
+ useCallback as useCallback4
39249
39279
  } from "react";
39250
39280
  import MonacoEditor from "@monaco-editor/react";
39251
39281
 
@@ -39255,7 +39285,8 @@ import {
39255
39285
  useRef as useRef18,
39256
39286
  useState as useState29,
39257
39287
  useContext as useContext26,
39258
- useMemo as useMemo21
39288
+ useMemo as useMemo21,
39289
+ useCallback as useCallback3
39259
39290
  } from "react";
39260
39291
  import {
39261
39292
  closestCenter,
@@ -39391,6 +39422,7 @@ var PivotCard = ({
39391
39422
  }) => {
39392
39423
  const defaultValueField = pivotTable.pivot && pivotTable.pivot.aggregationType === "count" ? "whole_number" : "two_decimal_places";
39393
39424
  const maxRowsInPivotPeak = 5;
39425
+ const headerColumnCount = (pivotTable.pivot?.rowField ? 1 : 0) + (pivotTable.pivot?.columnField ? 1 : 0) + (!pivotTable.pivot?.columnField && pivotTable.pivot?.aggregations?.[0]?.valueField ? 1 : 0);
39394
39426
  return /* @__PURE__ */ jsx61(
39395
39427
  CardComponent,
39396
39428
  {
@@ -39494,16 +39526,16 @@ var PivotCard = ({
39494
39526
  pivotTable.pivot.aggregations?.[0]?.valueField
39495
39527
  )
39496
39528
  ] }) }),
39497
- /* @__PURE__ */ jsx61(
39529
+ /* @__PURE__ */ jsx61("tbody", { children: /* @__PURE__ */ jsx61(
39498
39530
  "tr",
39499
39531
  {
39500
39532
  style: {
39501
39533
  paddingLeft: "2px",
39502
39534
  width: "100%"
39503
39535
  },
39504
- children: /* @__PURE__ */ jsx61(TextComponent, { label: "No results" })
39536
+ children: /* @__PURE__ */ jsx61("td", { colSpan: headerColumnCount || 1, children: /* @__PURE__ */ jsx61(TextComponent, { label: "No results" }) })
39505
39537
  }
39506
- )
39538
+ ) })
39507
39539
  ] }) : /* @__PURE__ */ jsxs43("table", { children: [
39508
39540
  /* @__PURE__ */ jsx61("thead", { children: /* @__PURE__ */ jsx61("tr", { children: pivotTable.columns.map((column) => /* @__PURE__ */ jsx61(
39509
39541
  "th",
@@ -40873,7 +40905,7 @@ var PivotModal = ({
40873
40905
  {
40874
40906
  id: "pivot-row-field",
40875
40907
  label: "Group rows by",
40876
- value: pivotRowField,
40908
+ value: pivotRowField ?? "",
40877
40909
  onChange: (e) => {
40878
40910
  pivotFieldChange(
40879
40911
  "rowField",
@@ -40900,7 +40932,7 @@ var PivotModal = ({
40900
40932
  {
40901
40933
  id: "pivot-column-field",
40902
40934
  label: "Group columns by",
40903
- value: pivotColumnField,
40935
+ value: pivotColumnField ?? "",
40904
40936
  onChange: (e) => {
40905
40937
  pivotFieldChange(
40906
40938
  "columnField",
@@ -40945,7 +40977,7 @@ var PivotModal = ({
40945
40977
  SelectComponent,
40946
40978
  {
40947
40979
  id: "pivot-aggregation-type",
40948
- value: agg.aggregationType,
40980
+ value: agg.aggregationType ?? "",
40949
40981
  onChange: (e) => {
40950
40982
  const newAgg = [
40951
40983
  ...pivotAggregations.slice(0, index),
@@ -40977,7 +41009,7 @@ var PivotModal = ({
40977
41009
  SelectComponent,
40978
41010
  {
40979
41011
  id: "pivot-value-field",
40980
- value: agg.valueField,
41012
+ value: agg.valueField ?? "",
40981
41013
  onChange: (e) => {
40982
41014
  const newAgg = [
40983
41015
  ...pivotAggregations.slice(0, index),
@@ -42604,7 +42636,7 @@ var CHART_TO_LABELS = {
42604
42636
  column: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42605
42637
  line: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42606
42638
  table: {},
42607
- metric: {},
42639
+ metric: { xAxisLabel: "Value" },
42608
42640
  bar: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42609
42641
  stacked: { xAxisLabel: "X-Axis", yAxisLabel: "Y-Axis" },
42610
42642
  pie: { xAxisLabel: "Category", yAxisLabel: "Count" },
@@ -43034,7 +43066,7 @@ function ChartBuilder({
43034
43066
  }
43035
43067
  return columns2;
43036
43068
  };
43037
- const [processedColumns, setProcessedColumns] = useState29(
43069
+ const [columns, setColumns] = useState29(
43038
43070
  processColumns(report?.columnInternal ?? [])
43039
43071
  );
43040
43072
  const [currentPage, setCurrentPage] = useState29(0);
@@ -43148,7 +43180,6 @@ function ChartBuilder({
43148
43180
  pivotQuery: report.pivotQuery ?? "",
43149
43181
  comparisonPivotQuery: report.comparisonPivotQuery
43150
43182
  } : void 0;
43151
- const columns = report?.columnInternal ?? [];
43152
43183
  const destinationDashboardName = report?.dashboardName || destinationDashboard;
43153
43184
  const query = report?.queryString;
43154
43185
  const [loadingFormData, setLoadingFormData] = useState29(false);
@@ -43700,6 +43731,26 @@ function ChartBuilder({
43700
43731
  ) ?? {};
43701
43732
  }, [client?.allTenantTypes]);
43702
43733
  const [selectedPivotTable, setSelectedPivotTable] = useState29(pivotData);
43734
+ const getDefaultXAxisFormat = useCallback3(
43735
+ (form) => {
43736
+ if (form.pivot?.rowField) {
43737
+ if (isDateField(form.pivot.rowFieldType ?? "")) {
43738
+ return "string";
43739
+ }
43740
+ const pivotRowColumn = selectedPivotTable?.columns?.find(
43741
+ (col) => col.field === form.pivot?.rowField
43742
+ ) ?? columns.find((col) => col.field === form.pivot?.rowField);
43743
+ if (pivotRowColumn?.format) {
43744
+ return pivotRowColumn.format;
43745
+ }
43746
+ }
43747
+ const currentXAxisColumn = (selectedPivotTable?.columns ?? columns).find(
43748
+ (c) => c.field === form.xAxisField
43749
+ );
43750
+ return currentXAxisColumn?.format ?? "string";
43751
+ },
43752
+ [columns, selectedPivotTable]
43753
+ );
43703
43754
  const pivotCardTable = useMemo21(() => {
43704
43755
  return {
43705
43756
  pivot: formData.pivot,
@@ -43916,7 +43967,8 @@ function ChartBuilder({
43916
43967
  });
43917
43968
  setCurrentProcessing(processing);
43918
43969
  setRows(tableInfo.rows);
43919
- setProcessedColumns(processColumns(tableInfo.columns));
43970
+ const updatedColumns = processColumns(tableInfo.columns);
43971
+ setColumns(updatedColumns);
43920
43972
  if (tableInfo.itemQuery) {
43921
43973
  setItemQuery(tableInfo.itemQuery);
43922
43974
  }
@@ -44133,6 +44185,7 @@ function ChartBuilder({
44133
44185
  updatedForm = { ...updatedForm, [fieldName]: value };
44134
44186
  }
44135
44187
  if (fieldName === "chartType") {
44188
+ const previousChartType = formData.chartType;
44136
44189
  if (value === "metric") {
44137
44190
  updatedForm.xAxisFormat = "whole_number";
44138
44191
  const currentXAxisColumn = (selectedPivotTable?.columns ?? columns).find((c) => c.field === updatedForm.xAxisField);
@@ -44149,6 +44202,16 @@ function ChartBuilder({
44149
44202
  (c) => NUMBER_FORMAT_TYPES.includes(c.format)
44150
44203
  )?.field ?? updatedForm.xAxisField;
44151
44204
  }
44205
+ } else {
44206
+ if (previousChartType === "gauge" && updatedForm.xAxisFormat === "percent") {
44207
+ updatedForm.xAxisFormat = getDefaultXAxisFormat(updatedForm);
44208
+ }
44209
+ if (previousChartType === "metric" && updatedForm.xAxisFormat === "whole_number") {
44210
+ updatedForm.xAxisFormat = getDefaultXAxisFormat(updatedForm);
44211
+ }
44212
+ if (previousChartType === "gauge" && updatedForm.pivot?.rowField && updatedForm.xAxisField !== updatedForm.pivot.rowField) {
44213
+ updatedForm.xAxisField = updatedForm.pivot.rowField;
44214
+ }
44152
44215
  }
44153
44216
  }
44154
44217
  let dashboardName = updatedForm.dashboardName;
@@ -44851,7 +44914,7 @@ function ChartBuilder({
44851
44914
  setShowUpdatePivot: setIsEdittingPivot,
44852
44915
  parentRef,
44853
44916
  data: rows,
44854
- columns: processedColumns,
44917
+ columns,
44855
44918
  triggerButtonText: "Add pivot +",
44856
44919
  selectedPivotIndex,
44857
44920
  setSelectedPivotIndex,
@@ -44925,7 +44988,7 @@ function ChartBuilder({
44925
44988
  ]
44926
44989
  }
44927
44990
  ),
44928
- !hideChartView && (formData.pivot || formData.chartType !== "table" && formData.chartType !== "metric") && /* @__PURE__ */ jsxs47("div", { children: [
44991
+ !hideChartView && (formData.pivot || formData.chartType !== "table") && /* @__PURE__ */ jsxs47("div", { children: [
44929
44992
  CHART_TO_LABELS[formData.chartType]?.xAxisLabel && /* @__PURE__ */ jsx65(
44930
44993
  "div",
44931
44994
  {
@@ -46492,6 +46555,166 @@ function setEditorTheme(_editor, monaco, schema, databaseType, clientName, event
46492
46555
  return null;
46493
46556
  }
46494
46557
  }
46558
+ function reconcileReportWithColumns(report, columns, previousReport) {
46559
+ const safeColumns = columns ?? [];
46560
+ const fallbackForm = createInitialFormData(safeColumns);
46561
+ const columnFieldSet = new Set(
46562
+ safeColumns.map((column) => column.field).filter(Boolean)
46563
+ );
46564
+ const previousColumnsByField = new Map(
46565
+ (previousReport?.columns ?? []).map((column) => [column.field, column])
46566
+ );
46567
+ const previousColumnInternalByField = new Map(
46568
+ (previousReport?.columnInternal ?? []).map((column) => [
46569
+ column.field,
46570
+ column
46571
+ ])
46572
+ );
46573
+ const existingColumnsByField = new Map(
46574
+ (report.columns ?? []).map((column) => [column.field, column])
46575
+ );
46576
+ const existingColumnInternalByField = new Map(
46577
+ (report.columnInternal ?? []).map((column) => [column.field, column])
46578
+ );
46579
+ const reconciledColumnInternal = safeColumns.map((column) => {
46580
+ const fallback = existingColumnInternalByField.get(column.field) ?? previousColumnInternalByField.get(column.field) ?? existingColumnsByField.get(column.field) ?? previousColumnsByField.get(column.field);
46581
+ return {
46582
+ ...column,
46583
+ format: fallback?.format ?? column.format,
46584
+ label: fallback?.label ?? column.label
46585
+ };
46586
+ });
46587
+ const reconciledColumns = reconciledColumnInternal.map((column) => ({
46588
+ field: column.field,
46589
+ label: column.label,
46590
+ format: column.format
46591
+ }));
46592
+ const resolveXAxisField = () => {
46593
+ if (report.xAxisField && columnFieldSet.has(report.xAxisField)) {
46594
+ return report.xAxisField;
46595
+ }
46596
+ if (previousReport?.xAxisField && columnFieldSet.has(previousReport.xAxisField)) {
46597
+ return previousReport.xAxisField;
46598
+ }
46599
+ return fallbackForm.xAxisField;
46600
+ };
46601
+ const xAxisField = resolveXAxisField();
46602
+ const xAxisColumn = reconciledColumnInternal.find(
46603
+ (column) => column.field === xAxisField
46604
+ );
46605
+ const xAxisFormat = (report.xAxisField === xAxisField ? report.xAxisFormat : void 0) ?? (previousReport?.xAxisField === xAxisField ? previousReport.xAxisFormat : void 0) ?? xAxisColumn?.format ?? fallbackForm.xAxisFormat ?? "string";
46606
+ const xAxisLabel = report.xAxisField === xAxisField ? report.xAxisLabel : previousReport?.xAxisField === xAxisField ? previousReport.xAxisLabel : fallbackForm.xAxisLabel ?? "";
46607
+ const existingYAxisFields = report.yAxisFields ?? previousReport?.yAxisFields ?? [];
46608
+ let yAxisFields = existingYAxisFields.filter((axis) => axis?.field && columnFieldSet.has(axis.field)).map((axis) => {
46609
+ const column = reconciledColumnInternal.find(
46610
+ (col) => col.field === axis.field
46611
+ );
46612
+ return {
46613
+ field: axis.field,
46614
+ label: axis.label,
46615
+ format: axis.format ?? column?.format ?? "string"
46616
+ };
46617
+ });
46618
+ if (yAxisFields.length === 0) {
46619
+ yAxisFields = fallbackForm.yAxisFields;
46620
+ }
46621
+ const existingReferenceLines = report.referenceLines ?? previousReport?.referenceLines ?? [];
46622
+ const referenceLines = existingReferenceLines.filter((line) => {
46623
+ if (line.label === REFERENCE_LINE) {
46624
+ return true;
46625
+ }
46626
+ return typeof line.label === "string" && columnFieldSet.has(line.label);
46627
+ });
46628
+ const existingReferenceLineYValues = report.referenceLineYValues ?? previousReport?.referenceLineYValues ?? [];
46629
+ const referenceLineYValues = existingReferenceLineYValues.filter((line) => {
46630
+ if (line.label === REFERENCE_LINE) {
46631
+ return true;
46632
+ }
46633
+ return typeof line.label === "string" && columnFieldSet.has(line.label);
46634
+ });
46635
+ const existingColumnsWithCustomFields = report.columnsWithCustomFields ?? previousReport?.columnsWithCustomFields ?? [];
46636
+ const columnsWithCustomFields = existingColumnsWithCustomFields.filter(
46637
+ (column) => columnFieldSet.has(column.field)
46638
+ );
46639
+ const existingFilterMap = report.filterMap ?? previousReport?.filterMap;
46640
+ const filterMap = existingFilterMap ? Object.fromEntries(
46641
+ Object.entries(existingFilterMap).filter(([, value]) => {
46642
+ return value.field && columnFieldSet.has(value.field);
46643
+ })
46644
+ ) : existingFilterMap;
46645
+ const existingFiltersApplied = report.filtersApplied ?? previousReport?.filtersApplied;
46646
+ const filtersApplied = existingFiltersApplied ? existingFiltersApplied.filter((filter) => {
46647
+ if (!filter.field) {
46648
+ return true;
46649
+ }
46650
+ return columnFieldSet.has(filter.field);
46651
+ }) : existingFiltersApplied;
46652
+ const existingSort = report.sort ?? previousReport?.sort;
46653
+ const sort = existingSort && columnFieldSet.has(existingSort.field) ? existingSort : void 0;
46654
+ let pivot = report.pivot ?? previousReport?.pivot ?? null;
46655
+ if (pivot) {
46656
+ const pivotFields = [];
46657
+ if (pivot.rowField) {
46658
+ pivotFields.push(pivot.rowField);
46659
+ }
46660
+ if (pivot.columnField) {
46661
+ pivotFields.push(pivot.columnField);
46662
+ }
46663
+ if ("aggregations" in pivot && Array.isArray(pivot.aggregations)) {
46664
+ pivot.aggregations.forEach((aggregation) => {
46665
+ if (aggregation.valueField) {
46666
+ pivotFields.push(aggregation.valueField);
46667
+ }
46668
+ if (aggregation.valueField2) {
46669
+ pivotFields.push(aggregation.valueField2);
46670
+ }
46671
+ });
46672
+ } else {
46673
+ const singleAggregation = pivot;
46674
+ if (singleAggregation.valueField) {
46675
+ pivotFields.push(singleAggregation.valueField);
46676
+ }
46677
+ if (singleAggregation.valueField2) {
46678
+ pivotFields.push(singleAggregation.valueField2);
46679
+ }
46680
+ }
46681
+ if (pivot.sortField) {
46682
+ pivotFields.push(pivot.sortField);
46683
+ }
46684
+ const missingPivotField = pivotFields.some(
46685
+ (field) => field && !columnFieldSet.has(field)
46686
+ );
46687
+ if (missingPivotField) {
46688
+ pivot = null;
46689
+ }
46690
+ }
46691
+ const pivotColumns = pivot ? (report.pivotColumns ?? previousReport?.pivotColumns)?.filter(
46692
+ (column) => columnFieldSet.has(column.field)
46693
+ ) : void 0;
46694
+ const pivotRows = pivot ? report.pivotRows ?? previousReport?.pivotRows : void 0;
46695
+ const pivotRowCount = pivot ? report.pivotRowCount ?? previousReport?.pivotRowCount : void 0;
46696
+ return {
46697
+ ...report,
46698
+ columns: reconciledColumns,
46699
+ columnInternal: reconciledColumnInternal,
46700
+ columnsWithCustomFields,
46701
+ xAxisField,
46702
+ xAxisFormat,
46703
+ xAxisLabel,
46704
+ yAxisFields,
46705
+ referenceLines,
46706
+ referenceLineYValues: referenceLineYValues.length ? referenceLineYValues : void 0,
46707
+ filterMap: filterMap && Object.keys(filterMap).length ? filterMap : void 0,
46708
+ filtersApplied: filtersApplied && filtersApplied.length ? filtersApplied : void 0,
46709
+ sort,
46710
+ pivot,
46711
+ pivotColumns,
46712
+ pivotRows,
46713
+ pivotRowCount,
46714
+ pivotQuery: pivot ? report.pivotQuery ?? previousReport?.pivotQuery : void 0,
46715
+ comparisonPivotQuery: pivot ? report.comparisonPivotQuery ?? previousReport?.comparisonPivotQuery : void 0
46716
+ };
46717
+ }
46495
46718
  function SQLEditor({
46496
46719
  ButtonComponent = MemoizedButton,
46497
46720
  SecondaryButtonComponent = MemoizedSecondaryButton,
@@ -46714,7 +46937,7 @@ function SQLEditor({
46714
46937
  onCloseChartBuilder && onCloseChartBuilder();
46715
46938
  }
46716
46939
  }, [isChartBuilderOpen]);
46717
- const handleRunSqlPrompt = useCallback3(async () => {
46940
+ const handleRunSqlPrompt = useCallback4(async () => {
46718
46941
  if (!client || sqlResponseLoading) {
46719
46942
  return;
46720
46943
  }
@@ -46733,7 +46956,7 @@ function SQLEditor({
46733
46956
  setQuery(resp.message);
46734
46957
  setSqlResponseLoading(false);
46735
46958
  }, [sqlPrompt, sqlResponseLoading]);
46736
- const debounceRunSqlPrompt = useCallback3(
46959
+ const debounceRunSqlPrompt = useCallback4(
46737
46960
  createDebounce(handleRunSqlPrompt, 500),
46738
46961
  [handleRunSqlPrompt]
46739
46962
  );
@@ -46870,12 +47093,17 @@ function SQLEditor({
46870
47093
  referencedTables: tableInfo.referencedTables,
46871
47094
  queryString: query ?? tempReport.queryString ?? ""
46872
47095
  };
47096
+ const reconciledReport = reconcileReportWithColumns(
47097
+ newReport,
47098
+ tableInfo.columns ?? [],
47099
+ tempReport
47100
+ );
46873
47101
  if (reportId) {
46874
- setTempReport(newReport);
47102
+ setTempReport(reconciledReport);
46875
47103
  } else {
46876
47104
  const cleaned = await cleanDashboardItem({
46877
- item: newReport,
46878
- dashboardFilters: newReport.filtersApplied,
47105
+ item: reconciledReport,
47106
+ dashboardFilters: reconciledReport.filtersApplied,
46879
47107
  client,
46880
47108
  customFields: schemaData.customFields,
46881
47109
  getToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillsql/react",
3
- "version": "2.16.5",
3
+ "version": "2.16.7",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {