@quillsql/react 2.16.15 → 2.16.17

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.
package/dist/index.cjs CHANGED
@@ -24292,15 +24292,33 @@ var useDashboard = (dashboardName, config) => {
24292
24292
  const { eventTracking } = (0, import_react2.useContext)(EventTrackingContext);
24293
24293
  const customFiltersRef = (0, import_react2.useRef)(customReportFilters);
24294
24294
  const reportRequestIds = (0, import_react2.useRef)({});
24295
+ const lastDashboardName = (0, import_react2.useRef)(null);
24296
+ const pendingNameChangeReload = (0, import_react2.useRef)(false);
24295
24297
  (0, import_react2.useEffect)(() => {
24296
24298
  customFiltersRef.current = customReportFilters;
24297
24299
  }, [customReportFilters]);
24298
24300
  (0, import_react2.useEffect)(() => {
24299
- if (!isLoading && !data && initialLoad.current) {
24301
+ const nameChanged = dashboardName !== lastDashboardName.current;
24302
+ if (nameChanged) {
24303
+ lastDashboardName.current = dashboardName ?? null;
24304
+ initialLoad.current = true;
24305
+ fetchedInitialReports.current = false;
24306
+ backfilledDashboards.current = false;
24307
+ reportRequestIds.current = {};
24308
+ pendingNameChangeReload.current = true;
24309
+ }
24310
+ if (!dashboardName) return;
24311
+ if (pendingNameChangeReload.current && data) {
24312
+ pendingNameChangeReload.current = false;
24313
+ initialLoad.current = false;
24314
+ return;
24315
+ }
24316
+ if (pendingNameChangeReload.current && !isLoading && !data && initialLoad.current) {
24300
24317
  initialLoad.current = false;
24318
+ pendingNameChangeReload.current = false;
24301
24319
  reload();
24302
24320
  }
24303
- }, [isLoading, data]);
24321
+ }, [isLoading, data, dashboardName]);
24304
24322
  (0, import_react2.useEffect)(() => {
24305
24323
  if (backfilledDashboards.current) return;
24306
24324
  if (isLoading || !data) return;
@@ -24310,7 +24328,7 @@ var useDashboard = (dashboardName, config) => {
24310
24328
  if (!needsBackfill) return;
24311
24329
  backfilledDashboards.current = true;
24312
24330
  reload(dashboardName, false);
24313
- }, [isLoading, data, dashboardFilters, dashboardName, reload]);
24331
+ }, [isLoading, data, dashboardFilters, dashboardName]);
24314
24332
  const { allReportsById } = useAllReports();
24315
24333
  const sections = (0, import_react2.useMemo)(() => {
24316
24334
  if (!data?.sections) return null;
@@ -25868,9 +25886,8 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25868
25886
  dataPoint[valueKey] = totalValue ? rawValue * 100 / totalValue : data.length > maxItems ? 100 / (maxItems + 1) : 100 / slicedData.length;
25869
25887
  dataPoint[`raw_${valueKey}`] = parseFloat(rawValue.toFixed(2));
25870
25888
  });
25871
- const palette = colors.length >= maxItems ? colors.slice(0, maxItems) : generateArrayFromColor(colors, maxItems);
25872
25889
  const parsedData = slicedData.map((dataPoint, idx) => {
25873
- const baseColor = palette[idx % palette.length];
25890
+ const baseColor = colors.length > 0 ? idx < colors.length ? colors[idx] : colors[colors.length - 1] : "#808080";
25874
25891
  return {
25875
25892
  ...dataPoint,
25876
25893
  color: baseColor,
@@ -25888,7 +25905,7 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25888
25905
  ),
25889
25906
  0
25890
25907
  );
25891
- const otherColor = palette[parsedData.length % palette.length] ?? palette[palette.length - 1];
25908
+ const otherColor = colors.length > 0 ? colors[colors.length - 1] : "#808080";
25892
25909
  const normalizedOtherSum = totalValue ? otherSum * 100 / totalValue : 100 / (maxItems + 1);
25893
25910
  parsedData.push({
25894
25911
  [categoryKey]: "Other",
@@ -26258,10 +26275,18 @@ var PieChartWrapper = import_react5.default.forwardRef(
26258
26275
  {
26259
26276
  data: parseData2(
26260
26277
  data,
26261
- (colorMap[category] && colorMap[category]["primary"] && generateArrayFromColor(
26262
- colorMap[category]["primary"],
26263
- data.length
26264
- )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors, data.length)),
26278
+ (() => {
26279
+ const colorArray = colorMap[category] && colorMap[category]["primary"] && colorMap[category]["primary"] || colors;
26280
+ const containsCssVars = colorArray.some(
26281
+ (color2) => typeof color2 === "string" && color2.includes("var(")
26282
+ );
26283
+ if (containsCssVars) {
26284
+ return Array.from({ length: data.length }).map(
26285
+ (_, idx) => colorArray[idx % colorArray.length] ?? colorArray[colorArray.length - 1] ?? "#808080"
26286
+ );
26287
+ }
26288
+ return colorArray.length >= data.length ? colorArray.slice(0, data.length) : generateArrayFromColor(colorArray, data.length);
26289
+ })(),
26265
26290
  index,
26266
26291
  category
26267
26292
  ),
@@ -30422,12 +30447,18 @@ function QuillSelectComponent({
30422
30447
  const rect = buttonRef?.current?.getBoundingClientRect();
30423
30448
  if (rect) {
30424
30449
  const viewportHeight = window.innerHeight;
30425
- const availableHeight = viewportHeight - rect.bottom - 64;
30450
+ const spacing = 12;
30451
+ const availableHeight = viewportHeight - rect.bottom - spacing;
30452
+ const maxHeight = Math.max(availableHeight, 120);
30453
+ const top = Math.max(
30454
+ spacing,
30455
+ Math.min(rect.bottom, viewportHeight - maxHeight - spacing)
30456
+ );
30426
30457
  setPopoverPosition({
30427
- top: rect.bottom + window.scrollY,
30428
- left: rect.left + window.scrollX,
30458
+ top,
30459
+ left: rect.left,
30429
30460
  width: rect.width,
30430
- maxHeight: availableHeight
30461
+ maxHeight
30431
30462
  });
30432
30463
  }
30433
30464
  });
@@ -30565,11 +30596,11 @@ function QuillSelectComponent({
30565
30596
  "div",
30566
30597
  {
30567
30598
  style: {
30568
- position: "absolute",
30599
+ position: "fixed",
30569
30600
  top: `${popoverPosition?.top ?? 0}px`,
30570
30601
  left: `${popoverPosition?.left ?? 0}px`,
30571
30602
  width: `${popoverPosition?.width ?? 0}px`,
30572
- maxHeight: `${Math.max(popoverPosition?.maxHeight ?? 0, 100)}px`,
30603
+ maxHeight: `${popoverPosition?.maxHeight ?? 120}px`,
30573
30604
  minHeight: options.length > 2 ? 120 : options.length * 40,
30574
30605
  visibility: popoverPosition ? "visible" : "hidden",
30575
30606
  display: "flex",
@@ -43829,6 +43860,20 @@ function ChartBuilder({
43829
43860
  const resolvedReport = reportId && !tempReport ? allReportsById[reportId] : tempReport;
43830
43861
  return resolvedReport;
43831
43862
  }, [reportId, tempReport, allReportsById]);
43863
+ const reportFieldsByName = (0, import_react44.useMemo)(() => {
43864
+ const fields = report?.fields;
43865
+ if (!fields || fields.length === 0) {
43866
+ return {};
43867
+ }
43868
+ const map = {};
43869
+ for (const f of fields) {
43870
+ const key = f?.name ?? f?.field;
43871
+ if (key) {
43872
+ map[key] = f;
43873
+ }
43874
+ }
43875
+ return map;
43876
+ }, [report]);
43832
43877
  const [windowWidth, setWindowWidth] = (0, import_react44.useState)(1200);
43833
43878
  const [rows, setRows] = (0, import_react44.useState)(() => report?.rows ?? []);
43834
43879
  const [itemQuery, setItemQuery] = (0, import_react44.useState)(report?.itemQuery);
@@ -43859,6 +43904,19 @@ function ChartBuilder({
43859
43904
  return col;
43860
43905
  }
43861
43906
  const newCol = { ...col };
43907
+ const reportField = reportFieldsByName[col.field];
43908
+ if (reportField && typeof reportField.dataTypeID === "number") {
43909
+ const converted = convertPostgresColumn({
43910
+ name: col.field,
43911
+ dataTypeID: reportField.dataTypeID
43912
+ });
43913
+ return {
43914
+ ...col,
43915
+ fieldType: col.fieldType ?? converted.fieldType,
43916
+ jsType: col.jsType ?? converted.jsType,
43917
+ dataTypeID: col.dataTypeID ?? converted.dataTypeID
43918
+ };
43919
+ }
43862
43920
  let foundColumn;
43863
43921
  schemaData.schemaWithCustomFields.forEach((table) => {
43864
43922
  if (table.columns) {
@@ -43871,6 +43929,18 @@ function ChartBuilder({
43871
43929
  }
43872
43930
  });
43873
43931
  if (!foundColumn) {
43932
+ if (typeof col.dataTypeID === "number") {
43933
+ const converted = convertPostgresColumn({
43934
+ field: col.field,
43935
+ dataTypeID: col.dataTypeID
43936
+ });
43937
+ return {
43938
+ ...col,
43939
+ fieldType: col.fieldType ?? converted.fieldType,
43940
+ jsType: col.jsType ?? converted.jsType,
43941
+ dataTypeID: col.dataTypeID ?? converted.dataTypeID
43942
+ };
43943
+ }
43874
43944
  return col;
43875
43945
  }
43876
43946
  newCol.fieldType = foundColumn.fieldType;
@@ -45349,6 +45419,9 @@ function ChartBuilder({
45349
45419
  ),
45350
45420
  pivotRows: selectedPivotTable?.rows || void 0,
45351
45421
  pivotColumns: selectedPivotTable?.columns || void 0,
45422
+ // Preserve underlying column metadata in the in-memory cache.
45423
+ // ChartEditor/ChartBuilder use this for Pivot form field options on edit-chart.
45424
+ columnInternal: report?.columnInternal ?? columns ?? [],
45352
45425
  triggerReload: true,
45353
45426
  error: void 0,
45354
45427
  section: formData.section
@@ -45967,9 +46040,9 @@ function ChartBuilder({
45967
46040
  /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
45968
46041
  SelectComponent,
45969
46042
  {
45970
- value: formData.pivot && isDateField(formData.pivot.rowFieldType ?? "") ? "string" : formData.xAxisFormat,
46043
+ value: formData.pivot && formData.xAxisField === formData.pivot.rowField && isDateField(formData.pivot.rowFieldType ?? "") ? "string" : formData.xAxisFormat,
45971
46044
  onChange: (e) => handleChange(e.target.value, "xAxisFormat"),
45972
- options: formData.pivot && isDateField(formData.pivot.rowFieldType ?? "") ? [{ value: "string", label: "date" }] : xAxisFormatOptions,
46045
+ options: formData.pivot && formData.xAxisField === formData.pivot.rowField && isDateField(formData.pivot.rowFieldType ?? "") ? [{ value: "string", label: "date" }] : xAxisFormatOptions,
45973
46046
  width: 200,
45974
46047
  hideEmptyOption: true
45975
46048
  }
package/dist/index.js CHANGED
@@ -24312,15 +24312,33 @@ var useDashboard = (dashboardName, config) => {
24312
24312
  const { eventTracking } = useContext(EventTrackingContext);
24313
24313
  const customFiltersRef = useRef2(customReportFilters);
24314
24314
  const reportRequestIds = useRef2({});
24315
+ const lastDashboardName = useRef2(null);
24316
+ const pendingNameChangeReload = useRef2(false);
24315
24317
  useEffect2(() => {
24316
24318
  customFiltersRef.current = customReportFilters;
24317
24319
  }, [customReportFilters]);
24318
24320
  useEffect2(() => {
24319
- if (!isLoading && !data && initialLoad.current) {
24321
+ const nameChanged = dashboardName !== lastDashboardName.current;
24322
+ if (nameChanged) {
24323
+ lastDashboardName.current = dashboardName ?? null;
24324
+ initialLoad.current = true;
24325
+ fetchedInitialReports.current = false;
24326
+ backfilledDashboards.current = false;
24327
+ reportRequestIds.current = {};
24328
+ pendingNameChangeReload.current = true;
24329
+ }
24330
+ if (!dashboardName) return;
24331
+ if (pendingNameChangeReload.current && data) {
24332
+ pendingNameChangeReload.current = false;
24333
+ initialLoad.current = false;
24334
+ return;
24335
+ }
24336
+ if (pendingNameChangeReload.current && !isLoading && !data && initialLoad.current) {
24320
24337
  initialLoad.current = false;
24338
+ pendingNameChangeReload.current = false;
24321
24339
  reload();
24322
24340
  }
24323
- }, [isLoading, data]);
24341
+ }, [isLoading, data, dashboardName]);
24324
24342
  useEffect2(() => {
24325
24343
  if (backfilledDashboards.current) return;
24326
24344
  if (isLoading || !data) return;
@@ -24330,7 +24348,7 @@ var useDashboard = (dashboardName, config) => {
24330
24348
  if (!needsBackfill) return;
24331
24349
  backfilledDashboards.current = true;
24332
24350
  reload(dashboardName, false);
24333
- }, [isLoading, data, dashboardFilters, dashboardName, reload]);
24351
+ }, [isLoading, data, dashboardFilters, dashboardName]);
24334
24352
  const { allReportsById } = useAllReports();
24335
24353
  const sections = useMemo2(() => {
24336
24354
  if (!data?.sections) return null;
@@ -25888,9 +25906,8 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25888
25906
  dataPoint[valueKey] = totalValue ? rawValue * 100 / totalValue : data.length > maxItems ? 100 / (maxItems + 1) : 100 / slicedData.length;
25889
25907
  dataPoint[`raw_${valueKey}`] = parseFloat(rawValue.toFixed(2));
25890
25908
  });
25891
- const palette = colors.length >= maxItems ? colors.slice(0, maxItems) : generateArrayFromColor(colors, maxItems);
25892
25909
  const parsedData = slicedData.map((dataPoint, idx) => {
25893
- const baseColor = palette[idx % palette.length];
25910
+ const baseColor = colors.length > 0 ? idx < colors.length ? colors[idx] : colors[colors.length - 1] : "#808080";
25894
25911
  return {
25895
25912
  ...dataPoint,
25896
25913
  color: baseColor,
@@ -25908,7 +25925,7 @@ var parseData2 = (data, colors, categoryKey, valueKey) => {
25908
25925
  ),
25909
25926
  0
25910
25927
  );
25911
- const otherColor = palette[parsedData.length % palette.length] ?? palette[palette.length - 1];
25928
+ const otherColor = colors.length > 0 ? colors[colors.length - 1] : "#808080";
25912
25929
  const normalizedOtherSum = totalValue ? otherSum * 100 / totalValue : 100 / (maxItems + 1);
25913
25930
  parsedData.push({
25914
25931
  [categoryKey]: "Other",
@@ -26278,10 +26295,18 @@ var PieChartWrapper = React3.forwardRef(
26278
26295
  {
26279
26296
  data: parseData2(
26280
26297
  data,
26281
- (colorMap[category] && colorMap[category]["primary"] && generateArrayFromColor(
26282
- colorMap[category]["primary"],
26283
- data.length
26284
- )) ?? (colors.length >= data.length ? colors : generateArrayFromColor(colors, data.length)),
26298
+ (() => {
26299
+ const colorArray = colorMap[category] && colorMap[category]["primary"] && colorMap[category]["primary"] || colors;
26300
+ const containsCssVars = colorArray.some(
26301
+ (color2) => typeof color2 === "string" && color2.includes("var(")
26302
+ );
26303
+ if (containsCssVars) {
26304
+ return Array.from({ length: data.length }).map(
26305
+ (_, idx) => colorArray[idx % colorArray.length] ?? colorArray[colorArray.length - 1] ?? "#808080"
26306
+ );
26307
+ }
26308
+ return colorArray.length >= data.length ? colorArray.slice(0, data.length) : generateArrayFromColor(colorArray, data.length);
26309
+ })(),
26285
26310
  index,
26286
26311
  category
26287
26312
  ),
@@ -30497,12 +30522,18 @@ function QuillSelectComponent({
30497
30522
  const rect = buttonRef?.current?.getBoundingClientRect();
30498
30523
  if (rect) {
30499
30524
  const viewportHeight = window.innerHeight;
30500
- const availableHeight = viewportHeight - rect.bottom - 64;
30525
+ const spacing = 12;
30526
+ const availableHeight = viewportHeight - rect.bottom - spacing;
30527
+ const maxHeight = Math.max(availableHeight, 120);
30528
+ const top = Math.max(
30529
+ spacing,
30530
+ Math.min(rect.bottom, viewportHeight - maxHeight - spacing)
30531
+ );
30501
30532
  setPopoverPosition({
30502
- top: rect.bottom + window.scrollY,
30503
- left: rect.left + window.scrollX,
30533
+ top,
30534
+ left: rect.left,
30504
30535
  width: rect.width,
30505
- maxHeight: availableHeight
30536
+ maxHeight
30506
30537
  });
30507
30538
  }
30508
30539
  });
@@ -30640,11 +30671,11 @@ function QuillSelectComponent({
30640
30671
  "div",
30641
30672
  {
30642
30673
  style: {
30643
- position: "absolute",
30674
+ position: "fixed",
30644
30675
  top: `${popoverPosition?.top ?? 0}px`,
30645
30676
  left: `${popoverPosition?.left ?? 0}px`,
30646
30677
  width: `${popoverPosition?.width ?? 0}px`,
30647
- maxHeight: `${Math.max(popoverPosition?.maxHeight ?? 0, 100)}px`,
30678
+ maxHeight: `${popoverPosition?.maxHeight ?? 120}px`,
30648
30679
  minHeight: options.length > 2 ? 120 : options.length * 40,
30649
30680
  visibility: popoverPosition ? "visible" : "hidden",
30650
30681
  display: "flex",
@@ -43986,6 +44017,20 @@ function ChartBuilder({
43986
44017
  const resolvedReport = reportId && !tempReport ? allReportsById[reportId] : tempReport;
43987
44018
  return resolvedReport;
43988
44019
  }, [reportId, tempReport, allReportsById]);
44020
+ const reportFieldsByName = useMemo21(() => {
44021
+ const fields = report?.fields;
44022
+ if (!fields || fields.length === 0) {
44023
+ return {};
44024
+ }
44025
+ const map = {};
44026
+ for (const f of fields) {
44027
+ const key = f?.name ?? f?.field;
44028
+ if (key) {
44029
+ map[key] = f;
44030
+ }
44031
+ }
44032
+ return map;
44033
+ }, [report]);
43989
44034
  const [windowWidth, setWindowWidth] = useState29(1200);
43990
44035
  const [rows, setRows] = useState29(() => report?.rows ?? []);
43991
44036
  const [itemQuery, setItemQuery] = useState29(report?.itemQuery);
@@ -44016,6 +44061,19 @@ function ChartBuilder({
44016
44061
  return col;
44017
44062
  }
44018
44063
  const newCol = { ...col };
44064
+ const reportField = reportFieldsByName[col.field];
44065
+ if (reportField && typeof reportField.dataTypeID === "number") {
44066
+ const converted = convertPostgresColumn({
44067
+ name: col.field,
44068
+ dataTypeID: reportField.dataTypeID
44069
+ });
44070
+ return {
44071
+ ...col,
44072
+ fieldType: col.fieldType ?? converted.fieldType,
44073
+ jsType: col.jsType ?? converted.jsType,
44074
+ dataTypeID: col.dataTypeID ?? converted.dataTypeID
44075
+ };
44076
+ }
44019
44077
  let foundColumn;
44020
44078
  schemaData.schemaWithCustomFields.forEach((table) => {
44021
44079
  if (table.columns) {
@@ -44028,6 +44086,18 @@ function ChartBuilder({
44028
44086
  }
44029
44087
  });
44030
44088
  if (!foundColumn) {
44089
+ if (typeof col.dataTypeID === "number") {
44090
+ const converted = convertPostgresColumn({
44091
+ field: col.field,
44092
+ dataTypeID: col.dataTypeID
44093
+ });
44094
+ return {
44095
+ ...col,
44096
+ fieldType: col.fieldType ?? converted.fieldType,
44097
+ jsType: col.jsType ?? converted.jsType,
44098
+ dataTypeID: col.dataTypeID ?? converted.dataTypeID
44099
+ };
44100
+ }
44031
44101
  return col;
44032
44102
  }
44033
44103
  newCol.fieldType = foundColumn.fieldType;
@@ -45506,6 +45576,9 @@ function ChartBuilder({
45506
45576
  ),
45507
45577
  pivotRows: selectedPivotTable?.rows || void 0,
45508
45578
  pivotColumns: selectedPivotTable?.columns || void 0,
45579
+ // Preserve underlying column metadata in the in-memory cache.
45580
+ // ChartEditor/ChartBuilder use this for Pivot form field options on edit-chart.
45581
+ columnInternal: report?.columnInternal ?? columns ?? [],
45509
45582
  triggerReload: true,
45510
45583
  error: void 0,
45511
45584
  section: formData.section
@@ -46124,9 +46197,9 @@ function ChartBuilder({
46124
46197
  /* @__PURE__ */ jsx66(
46125
46198
  SelectComponent,
46126
46199
  {
46127
- value: formData.pivot && isDateField(formData.pivot.rowFieldType ?? "") ? "string" : formData.xAxisFormat,
46200
+ value: formData.pivot && formData.xAxisField === formData.pivot.rowField && isDateField(formData.pivot.rowFieldType ?? "") ? "string" : formData.xAxisFormat,
46128
46201
  onChange: (e) => handleChange(e.target.value, "xAxisFormat"),
46129
- options: formData.pivot && isDateField(formData.pivot.rowFieldType ?? "") ? [{ value: "string", label: "date" }] : xAxisFormatOptions,
46202
+ options: formData.pivot && formData.xAxisField === formData.pivot.rowField && isDateField(formData.pivot.rowFieldType ?? "") ? [{ value: "string", label: "date" }] : xAxisFormatOptions,
46130
46203
  width: 200,
46131
46204
  hideEmptyOption: true
46132
46205
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillsql/react",
3
- "version": "2.16.15",
3
+ "version": "2.16.17",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {