@odoo/o-spreadsheet 18.4.3 → 18.4.5

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.3
6
- * @date 2025-07-28T13:39:06.036Z
7
- * @hash 4b596d7
5
+ * @version 18.4.5
6
+ * @date 2025-08-04T06:54:49.107Z
7
+ * @hash 358931f
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -1056,16 +1056,21 @@ const colors = [
1056
1056
  "#001f3f",
1057
1057
  ];
1058
1058
  /*
1059
- * transform a color number (R * 256^2 + G * 256 + B) into classic hex6 value
1059
+ * transform a color number (R * 256^2 + G * 256 + B) into classic hex (+alpha) value
1060
1060
  * */
1061
- function colorNumberString(color) {
1062
- return toHex(color.toString(16).padStart(6, "0"));
1061
+ function colorNumberToHex(color, alpha = 1) {
1062
+ const alphaHex = alpha !== 1
1063
+ ? Math.round(alpha * 255)
1064
+ .toString(16)
1065
+ .padStart(2, "0")
1066
+ : "";
1067
+ return toHex(color.toString(16).padStart(6, "0")) + alphaHex;
1063
1068
  }
1064
1069
  function colorToNumber(color) {
1065
1070
  if (typeof color === "number") {
1066
1071
  return color;
1067
1072
  }
1068
- return Number.parseInt(toHex(color).slice(1), 16);
1073
+ return Number.parseInt(toHex(color).slice(1, 7), 16);
1069
1074
  }
1070
1075
  /**
1071
1076
  * Converts any CSS color value to a standardized hex6 value.
@@ -1324,6 +1329,12 @@ function hslaToHex(hsla) {
1324
1329
  function hexToHSLA(hex) {
1325
1330
  return rgbaToHSLA(colorToRGBA(hex));
1326
1331
  }
1332
+ function colorOrNumberToRGBA(color) {
1333
+ if (typeof color === "number") {
1334
+ return colorToRGBA(colorNumberToHex(color));
1335
+ }
1336
+ return colorToRGBA(color);
1337
+ }
1327
1338
  /**
1328
1339
  * Will compare two color strings
1329
1340
  * A tolerance can be provided to account for small differences that could
@@ -1605,6 +1616,8 @@ function getColorScale(colorScalePoints) {
1605
1616
  const sortedColorScalePoints = [...colorScalePoints.sort((a, b) => a.value - b.value)];
1606
1617
  const thresholds = [];
1607
1618
  for (let i = 1; i < sortedColorScalePoints.length; i++) {
1619
+ const minColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i - 1].color).a;
1620
+ const maxColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i].color).a;
1608
1621
  const minColor = colorToNumber(sortedColorScalePoints[i - 1].color);
1609
1622
  const maxColor = colorToNumber(sortedColorScalePoints[i].color);
1610
1623
  thresholds.push({
@@ -1612,19 +1625,21 @@ function getColorScale(colorScalePoints) {
1612
1625
  max: sortedColorScalePoints[i].value,
1613
1626
  minColor,
1614
1627
  maxColor,
1628
+ minColorAlpha: minColorAlpha,
1629
+ maxColorAlpha: maxColorAlpha,
1615
1630
  colorDiff: computeColorDiffUnits(sortedColorScalePoints[i - 1].value, sortedColorScalePoints[i].value, minColor, maxColor),
1616
1631
  });
1617
1632
  }
1618
1633
  return (value) => {
1619
1634
  if (value < thresholds[0].min) {
1620
- return colorNumberString(thresholds[0].minColor);
1635
+ return colorNumberToHex(thresholds[0].minColor, thresholds[0].minColorAlpha);
1621
1636
  }
1622
1637
  for (const threshold of thresholds) {
1623
1638
  if (value >= threshold.min && value <= threshold.max) {
1624
- return colorNumberString(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff));
1639
+ return colorNumberToHex(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff), threshold.maxColorAlpha);
1625
1640
  }
1626
1641
  }
1627
- return colorNumberString(thresholds[thresholds.length - 1].maxColor);
1642
+ return colorNumberToHex(thresholds[thresholds.length - 1].maxColor, thresholds[thresholds.length - 1].maxColorAlpha);
1628
1643
  };
1629
1644
  }
1630
1645
  function computeColorDiffUnits(minValue, maxValue, minColor, maxColor) {
@@ -8624,12 +8639,12 @@ const AGGREGATOR_NAMES = {
8624
8639
  avg: _t("Average"),
8625
8640
  sum: _t("Sum"),
8626
8641
  };
8627
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8642
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8628
8643
  const AGGREGATORS_BY_FIELD_TYPE = {
8629
- integer: NUMBER_CHAR_AGGREGATORS,
8630
- char: NUMBER_CHAR_AGGREGATORS,
8644
+ integer: DEFAULT_AGGREGATORS,
8645
+ char: DEFAULT_AGGREGATORS,
8646
+ datetime: DEFAULT_AGGREGATORS,
8631
8647
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8632
- datetime: ["max", "min", "count_distinct", "count"],
8633
8648
  };
8634
8649
  const AGGREGATORS = {};
8635
8650
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -22760,6 +22775,7 @@ class ChartJsComponent extends Component {
22760
22775
  this.animationStore = useStore(ChartAnimationStore);
22761
22776
  }
22762
22777
  onMounted(() => {
22778
+ registerChartJSExtensions();
22763
22779
  const runtime = this.chartRuntime;
22764
22780
  this.currentRuntime = runtime;
22765
22781
  // Note: chartJS modify the runtime in place, so it's important to give it a copy
@@ -31707,7 +31723,7 @@ criterionEvaluatorRegistry.add("isValueInRange", {
31707
31723
  }
31708
31724
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31709
31725
  return criterionValues
31710
- .map((value) => value.toLowerCase())
31726
+ .map((value) => value.value.toLowerCase())
31711
31727
  .includes(value.toString().toLowerCase());
31712
31728
  },
31713
31729
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -51843,16 +51859,16 @@ class ConditionalFormatPreview extends Component {
51843
51859
  return cssPropertiesToCss(cellStyleToCss(rule.style));
51844
51860
  }
51845
51861
  else if (rule.type === "ColorScaleRule") {
51846
- const minColor = colorNumberString(rule.minimum.color);
51847
- const midColor = rule.midpoint ? colorNumberString(rule.midpoint.color) : null;
51848
- const maxColor = colorNumberString(rule.maximum.color);
51862
+ const minColor = colorNumberToHex(rule.minimum.color);
51863
+ const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
51864
+ const maxColor = colorNumberToHex(rule.maximum.color);
51849
51865
  const baseString = "background-image: linear-gradient(to right, ";
51850
51866
  return midColor
51851
51867
  ? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
51852
51868
  : baseString + minColor + ", " + maxColor + ")";
51853
51869
  }
51854
51870
  else if (rule.type === "DataBarRule") {
51855
- const color = colorNumberString(rule.color);
51871
+ const color = colorNumberToHex(rule.color);
51856
51872
  return `background-image: linear-gradient(to right, ${color} 50%, white 50%)`;
51857
51873
  }
51858
51874
  return "";
@@ -52042,7 +52058,8 @@ class ConditionalFormattingEditor extends Component {
52042
52058
  static props = {
52043
52059
  editedCf: Object,
52044
52060
  onCancel: Function,
52045
- onSave: Function,
52061
+ onExit: Function,
52062
+ isNewCf: Boolean,
52046
52063
  };
52047
52064
  static components = {
52048
52065
  SelectionInput,
@@ -52059,7 +52076,7 @@ class ConditionalFormattingEditor extends Component {
52059
52076
  icons = ICONS;
52060
52077
  iconSets = ICON_SETS;
52061
52078
  getTextDecoration = getTextDecoration;
52062
- colorNumberString = colorNumberString;
52079
+ colorNumberToHex = colorNumberToHex;
52063
52080
  state;
52064
52081
  setup() {
52065
52082
  this.state = useState({
@@ -52067,6 +52084,7 @@ class ConditionalFormattingEditor extends Component {
52067
52084
  currentCFType: this.props.editedCf.rule.type,
52068
52085
  ranges: this.props.editedCf.ranges,
52069
52086
  rules: this.getDefaultRules(),
52087
+ hasEditedCf: this.props.isNewCf,
52070
52088
  });
52071
52089
  switch (this.props.editedCf.rule.type) {
52072
52090
  case "CellIsRule":
@@ -52118,6 +52136,9 @@ class ConditionalFormattingEditor extends Component {
52118
52136
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52119
52137
  sheetId,
52120
52138
  });
52139
+ if (result.isSuccessful) {
52140
+ this.state.hasEditedCf = true;
52141
+ }
52121
52142
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52122
52143
  if (!newCf.suppressErrors) {
52123
52144
  this.state.errors = reasons;
@@ -52139,7 +52160,15 @@ class ConditionalFormattingEditor extends Component {
52139
52160
  onSave() {
52140
52161
  const result = this.updateConditionalFormat({});
52141
52162
  if (result.length === 0) {
52142
- this.props.onSave();
52163
+ this.props.onExit();
52164
+ }
52165
+ }
52166
+ onCancel() {
52167
+ if (this.state.hasEditedCf) {
52168
+ this.props.onCancel();
52169
+ }
52170
+ else {
52171
+ this.props.onExit();
52143
52172
  }
52144
52173
  }
52145
52174
  getDefaultRules() {
@@ -52298,9 +52327,9 @@ class ConditionalFormattingEditor extends Component {
52298
52327
  }
52299
52328
  getPreviewGradient() {
52300
52329
  const rule = this.state.rules.colorScale;
52301
- const minColor = colorNumberString(rule.minimum.color);
52302
- const midColor = colorNumberString(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52303
- const maxColor = colorNumberString(rule.maximum.color);
52330
+ const minColor = colorNumberToHex(rule.minimum.color);
52331
+ const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52332
+ const maxColor = colorNumberToHex(rule.maximum.color);
52304
52333
  const baseString = "background-image: linear-gradient(to right, ";
52305
52334
  return rule.midpoint === undefined
52306
52335
  ? baseString + minColor + ", " + maxColor + ")"
@@ -52308,8 +52337,8 @@ class ConditionalFormattingEditor extends Component {
52308
52337
  }
52309
52338
  getThresholdColor(threshold) {
52310
52339
  return threshold
52311
- ? colorNumberString(threshold.color)
52312
- : colorNumberString(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52340
+ ? colorNumberToHex(threshold.color)
52341
+ : colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52313
52342
  }
52314
52343
  onMidpointChange(ev) {
52315
52344
  const type = ev.target.value;
@@ -66532,9 +66561,9 @@ class CustomColorsPlugin extends CoreViewPlugin {
66532
66561
  formatColors.push(rule.style.fillColor);
66533
66562
  }
66534
66563
  else if (rule.type === "ColorScaleRule") {
66535
- formatColors.push(colorNumberString(rule.minimum.color));
66536
- formatColors.push(rule.midpoint ? colorNumberString(rule.midpoint.color) : undefined);
66537
- formatColors.push(colorNumberString(rule.maximum.color));
66564
+ formatColors.push(colorNumberToHex(rule.minimum.color));
66565
+ formatColors.push(rule.midpoint ? colorNumberToHex(rule.midpoint.color) : undefined);
66566
+ formatColors.push(colorNumberToHex(rule.maximum.color));
66538
66567
  }
66539
66568
  }
66540
66569
  return formatColors.filter(isDefined);
@@ -66905,7 +66934,7 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
66905
66934
  if (!computedDataBars[col])
66906
66935
  computedDataBars[col] = [];
66907
66936
  computedDataBars[col][row] = {
66908
- color: colorNumberString(color),
66937
+ color: colorNumberToHex(color),
66909
66938
  percentage: (cell.value * 100) / max,
66910
66939
  };
66911
66940
  }
@@ -67034,8 +67063,16 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
67034
67063
  }
67035
67064
  getDataValidationRangeValues(sheetId, criterion) {
67036
67065
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67037
- const criterionValues = this.getters.getRangeValues(range);
67038
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67066
+ const values = [];
67067
+ const labelsSet = new Set();
67068
+ for (const p of positions(range.zone)) {
67069
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67070
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67071
+ labelsSet.add(cell.formattedValue);
67072
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67073
+ }
67074
+ }
67075
+ return values;
67039
67076
  }
67040
67077
  isCellValidCheckbox(cellPosition) {
67041
67078
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -75650,25 +75687,30 @@ autoCompleteProviders.add("dataValidation", {
75650
75687
  }
75651
75688
  const sheetId = this.composer.currentEditedCell.sheetId;
75652
75689
  const values = rule.criterion.type === "isValueInRange"
75653
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75654
- : rule.criterion.values;
75690
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75691
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75655
75692
  const isChip = rule.criterion.displayStyle === "chip";
75656
75693
  if (!isChip) {
75657
- return values.map((value) => ({ text: value }));
75694
+ return values.map((value) => ({
75695
+ text: value.value,
75696
+ fuzzySearchKey: value.label,
75697
+ htmlContent: [{ value: value.label }],
75698
+ }));
75658
75699
  }
75659
75700
  const colors = rule.criterion.colors;
75660
75701
  return values.map((value) => {
75661
- const color = colors?.[value];
75702
+ const color = colors?.[value.value];
75662
75703
  return {
75663
- text: value,
75704
+ text: value.value,
75664
75705
  htmlContent: [
75665
75706
  {
75666
- value,
75707
+ value: value.label,
75667
75708
  color: color ? chipTextColor(color) : undefined,
75668
75709
  backgroundColor: color || GRAY_200,
75669
75710
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75670
75711
  },
75671
75712
  ],
75713
+ fuzzySearchKey: value.label,
75672
75714
  };
75673
75715
  });
75674
75716
  },
@@ -79909,7 +79951,6 @@ css /* scss */ `
79909
79951
  }
79910
79952
  }
79911
79953
 
79912
- .o-spreadsheet-topbar-wrapper,
79913
79954
  .o-spreadsheet-bottombar-wrapper {
79914
79955
  z-index: ${ComponentsImportance.ScrollBar + 1};
79915
79956
  }
@@ -80024,7 +80065,6 @@ class Spreadsheet extends Component {
80024
80065
  this.checkViewportSize();
80025
80066
  stores.on("store-updated", this, render);
80026
80067
  resizeObserver.observe(this.spreadsheetRef.el);
80027
- registerChartJSExtensions();
80028
80068
  });
80029
80069
  onWillUnmount(() => {
80030
80070
  this.unbindModelEvents();
@@ -82557,7 +82597,7 @@ function addDataBarRule(cf, rule) {
82557
82597
  <dataBar>
82558
82598
  <cfvo type="min" val="0"/>
82559
82599
  <cfvo type="max" val="100"/>
82560
- <color rgb="${toXlsxHexColor(colorNumberString(rule.color))}"/>
82600
+ <color rgb="${toXlsxHexColor(colorNumberToHex(rule.color))}"/>
82561
82601
  </dataBar>
82562
82602
  </cfRule>
82563
82603
  </conditionalFormatting>
@@ -82585,7 +82625,7 @@ function addColorScaleRule(cf, rule) {
82585
82625
  continue;
82586
82626
  }
82587
82627
  cfValueObject.push(thresholdAttributes(threshold, position));
82588
- colors.push([["rgb", toXlsxHexColor(colorNumberString(threshold.color))]]);
82628
+ colors.push([["rgb", toXlsxHexColor(colorNumberToHex(threshold.color))]]);
82589
82629
  }
82590
82630
  if (!canExport) {
82591
82631
  console.warn("Conditional formats with formula rules are not supported at the moment. The rule is therefore skipped.");
@@ -84596,6 +84636,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84596
84636
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84597
84637
 
84598
84638
 
84599
- __info__.version = "18.4.3";
84600
- __info__.date = "2025-07-28T13:39:06.036Z";
84601
- __info__.hash = "4b596d7";
84639
+ __info__.version = "18.4.5";
84640
+ __info__.date = "2025-08-04T06:54:49.107Z";
84641
+ __info__.hash = "358931f";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.3
6
- * @date 2025-07-28T13:39:06.036Z
7
- * @hash 4b596d7
5
+ * @version 18.4.5
6
+ * @date 2025-08-04T06:54:49.107Z
7
+ * @hash 358931f
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -1057,16 +1057,21 @@
1057
1057
  "#001f3f",
1058
1058
  ];
1059
1059
  /*
1060
- * transform a color number (R * 256^2 + G * 256 + B) into classic hex6 value
1060
+ * transform a color number (R * 256^2 + G * 256 + B) into classic hex (+alpha) value
1061
1061
  * */
1062
- function colorNumberString(color) {
1063
- return toHex(color.toString(16).padStart(6, "0"));
1062
+ function colorNumberToHex(color, alpha = 1) {
1063
+ const alphaHex = alpha !== 1
1064
+ ? Math.round(alpha * 255)
1065
+ .toString(16)
1066
+ .padStart(2, "0")
1067
+ : "";
1068
+ return toHex(color.toString(16).padStart(6, "0")) + alphaHex;
1064
1069
  }
1065
1070
  function colorToNumber(color) {
1066
1071
  if (typeof color === "number") {
1067
1072
  return color;
1068
1073
  }
1069
- return Number.parseInt(toHex(color).slice(1), 16);
1074
+ return Number.parseInt(toHex(color).slice(1, 7), 16);
1070
1075
  }
1071
1076
  /**
1072
1077
  * Converts any CSS color value to a standardized hex6 value.
@@ -1325,6 +1330,12 @@
1325
1330
  function hexToHSLA(hex) {
1326
1331
  return rgbaToHSLA(colorToRGBA(hex));
1327
1332
  }
1333
+ function colorOrNumberToRGBA(color) {
1334
+ if (typeof color === "number") {
1335
+ return colorToRGBA(colorNumberToHex(color));
1336
+ }
1337
+ return colorToRGBA(color);
1338
+ }
1328
1339
  /**
1329
1340
  * Will compare two color strings
1330
1341
  * A tolerance can be provided to account for small differences that could
@@ -1606,6 +1617,8 @@
1606
1617
  const sortedColorScalePoints = [...colorScalePoints.sort((a, b) => a.value - b.value)];
1607
1618
  const thresholds = [];
1608
1619
  for (let i = 1; i < sortedColorScalePoints.length; i++) {
1620
+ const minColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i - 1].color).a;
1621
+ const maxColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i].color).a;
1609
1622
  const minColor = colorToNumber(sortedColorScalePoints[i - 1].color);
1610
1623
  const maxColor = colorToNumber(sortedColorScalePoints[i].color);
1611
1624
  thresholds.push({
@@ -1613,19 +1626,21 @@
1613
1626
  max: sortedColorScalePoints[i].value,
1614
1627
  minColor,
1615
1628
  maxColor,
1629
+ minColorAlpha: minColorAlpha,
1630
+ maxColorAlpha: maxColorAlpha,
1616
1631
  colorDiff: computeColorDiffUnits(sortedColorScalePoints[i - 1].value, sortedColorScalePoints[i].value, minColor, maxColor),
1617
1632
  });
1618
1633
  }
1619
1634
  return (value) => {
1620
1635
  if (value < thresholds[0].min) {
1621
- return colorNumberString(thresholds[0].minColor);
1636
+ return colorNumberToHex(thresholds[0].minColor, thresholds[0].minColorAlpha);
1622
1637
  }
1623
1638
  for (const threshold of thresholds) {
1624
1639
  if (value >= threshold.min && value <= threshold.max) {
1625
- return colorNumberString(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff));
1640
+ return colorNumberToHex(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff), threshold.maxColorAlpha);
1626
1641
  }
1627
1642
  }
1628
- return colorNumberString(thresholds[thresholds.length - 1].maxColor);
1643
+ return colorNumberToHex(thresholds[thresholds.length - 1].maxColor, thresholds[thresholds.length - 1].maxColorAlpha);
1629
1644
  };
1630
1645
  }
1631
1646
  function computeColorDiffUnits(minValue, maxValue, minColor, maxColor) {
@@ -8625,12 +8640,12 @@
8625
8640
  avg: _t("Average"),
8626
8641
  sum: _t("Sum"),
8627
8642
  };
8628
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8643
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8629
8644
  const AGGREGATORS_BY_FIELD_TYPE = {
8630
- integer: NUMBER_CHAR_AGGREGATORS,
8631
- char: NUMBER_CHAR_AGGREGATORS,
8645
+ integer: DEFAULT_AGGREGATORS,
8646
+ char: DEFAULT_AGGREGATORS,
8647
+ datetime: DEFAULT_AGGREGATORS,
8632
8648
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8633
- datetime: ["max", "min", "count_distinct", "count"],
8634
8649
  };
8635
8650
  const AGGREGATORS = {};
8636
8651
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -22761,6 +22776,7 @@ stores.inject(MyMetaStore, storeInstance);
22761
22776
  this.animationStore = useStore(ChartAnimationStore);
22762
22777
  }
22763
22778
  owl.onMounted(() => {
22779
+ registerChartJSExtensions();
22764
22780
  const runtime = this.chartRuntime;
22765
22781
  this.currentRuntime = runtime;
22766
22782
  // Note: chartJS modify the runtime in place, so it's important to give it a copy
@@ -31708,7 +31724,7 @@ stores.inject(MyMetaStore, storeInstance);
31708
31724
  }
31709
31725
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31710
31726
  return criterionValues
31711
- .map((value) => value.toLowerCase())
31727
+ .map((value) => value.value.toLowerCase())
31712
31728
  .includes(value.toString().toLowerCase());
31713
31729
  },
31714
31730
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -51844,16 +51860,16 @@ stores.inject(MyMetaStore, storeInstance);
51844
51860
  return cssPropertiesToCss(cellStyleToCss(rule.style));
51845
51861
  }
51846
51862
  else if (rule.type === "ColorScaleRule") {
51847
- const minColor = colorNumberString(rule.minimum.color);
51848
- const midColor = rule.midpoint ? colorNumberString(rule.midpoint.color) : null;
51849
- const maxColor = colorNumberString(rule.maximum.color);
51863
+ const minColor = colorNumberToHex(rule.minimum.color);
51864
+ const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
51865
+ const maxColor = colorNumberToHex(rule.maximum.color);
51850
51866
  const baseString = "background-image: linear-gradient(to right, ";
51851
51867
  return midColor
51852
51868
  ? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
51853
51869
  : baseString + minColor + ", " + maxColor + ")";
51854
51870
  }
51855
51871
  else if (rule.type === "DataBarRule") {
51856
- const color = colorNumberString(rule.color);
51872
+ const color = colorNumberToHex(rule.color);
51857
51873
  return `background-image: linear-gradient(to right, ${color} 50%, white 50%)`;
51858
51874
  }
51859
51875
  return "";
@@ -52043,7 +52059,8 @@ stores.inject(MyMetaStore, storeInstance);
52043
52059
  static props = {
52044
52060
  editedCf: Object,
52045
52061
  onCancel: Function,
52046
- onSave: Function,
52062
+ onExit: Function,
52063
+ isNewCf: Boolean,
52047
52064
  };
52048
52065
  static components = {
52049
52066
  SelectionInput,
@@ -52060,7 +52077,7 @@ stores.inject(MyMetaStore, storeInstance);
52060
52077
  icons = ICONS;
52061
52078
  iconSets = ICON_SETS;
52062
52079
  getTextDecoration = getTextDecoration;
52063
- colorNumberString = colorNumberString;
52080
+ colorNumberToHex = colorNumberToHex;
52064
52081
  state;
52065
52082
  setup() {
52066
52083
  this.state = owl.useState({
@@ -52068,6 +52085,7 @@ stores.inject(MyMetaStore, storeInstance);
52068
52085
  currentCFType: this.props.editedCf.rule.type,
52069
52086
  ranges: this.props.editedCf.ranges,
52070
52087
  rules: this.getDefaultRules(),
52088
+ hasEditedCf: this.props.isNewCf,
52071
52089
  });
52072
52090
  switch (this.props.editedCf.rule.type) {
52073
52091
  case "CellIsRule":
@@ -52119,6 +52137,9 @@ stores.inject(MyMetaStore, storeInstance);
52119
52137
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52120
52138
  sheetId,
52121
52139
  });
52140
+ if (result.isSuccessful) {
52141
+ this.state.hasEditedCf = true;
52142
+ }
52122
52143
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52123
52144
  if (!newCf.suppressErrors) {
52124
52145
  this.state.errors = reasons;
@@ -52140,7 +52161,15 @@ stores.inject(MyMetaStore, storeInstance);
52140
52161
  onSave() {
52141
52162
  const result = this.updateConditionalFormat({});
52142
52163
  if (result.length === 0) {
52143
- this.props.onSave();
52164
+ this.props.onExit();
52165
+ }
52166
+ }
52167
+ onCancel() {
52168
+ if (this.state.hasEditedCf) {
52169
+ this.props.onCancel();
52170
+ }
52171
+ else {
52172
+ this.props.onExit();
52144
52173
  }
52145
52174
  }
52146
52175
  getDefaultRules() {
@@ -52299,9 +52328,9 @@ stores.inject(MyMetaStore, storeInstance);
52299
52328
  }
52300
52329
  getPreviewGradient() {
52301
52330
  const rule = this.state.rules.colorScale;
52302
- const minColor = colorNumberString(rule.minimum.color);
52303
- const midColor = colorNumberString(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52304
- const maxColor = colorNumberString(rule.maximum.color);
52331
+ const minColor = colorNumberToHex(rule.minimum.color);
52332
+ const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52333
+ const maxColor = colorNumberToHex(rule.maximum.color);
52305
52334
  const baseString = "background-image: linear-gradient(to right, ";
52306
52335
  return rule.midpoint === undefined
52307
52336
  ? baseString + minColor + ", " + maxColor + ")"
@@ -52309,8 +52338,8 @@ stores.inject(MyMetaStore, storeInstance);
52309
52338
  }
52310
52339
  getThresholdColor(threshold) {
52311
52340
  return threshold
52312
- ? colorNumberString(threshold.color)
52313
- : colorNumberString(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52341
+ ? colorNumberToHex(threshold.color)
52342
+ : colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52314
52343
  }
52315
52344
  onMidpointChange(ev) {
52316
52345
  const type = ev.target.value;
@@ -66533,9 +66562,9 @@ stores.inject(MyMetaStore, storeInstance);
66533
66562
  formatColors.push(rule.style.fillColor);
66534
66563
  }
66535
66564
  else if (rule.type === "ColorScaleRule") {
66536
- formatColors.push(colorNumberString(rule.minimum.color));
66537
- formatColors.push(rule.midpoint ? colorNumberString(rule.midpoint.color) : undefined);
66538
- formatColors.push(colorNumberString(rule.maximum.color));
66565
+ formatColors.push(colorNumberToHex(rule.minimum.color));
66566
+ formatColors.push(rule.midpoint ? colorNumberToHex(rule.midpoint.color) : undefined);
66567
+ formatColors.push(colorNumberToHex(rule.maximum.color));
66539
66568
  }
66540
66569
  }
66541
66570
  return formatColors.filter(isDefined);
@@ -66906,7 +66935,7 @@ stores.inject(MyMetaStore, storeInstance);
66906
66935
  if (!computedDataBars[col])
66907
66936
  computedDataBars[col] = [];
66908
66937
  computedDataBars[col][row] = {
66909
- color: colorNumberString(color),
66938
+ color: colorNumberToHex(color),
66910
66939
  percentage: (cell.value * 100) / max,
66911
66940
  };
66912
66941
  }
@@ -67035,8 +67064,16 @@ stores.inject(MyMetaStore, storeInstance);
67035
67064
  }
67036
67065
  getDataValidationRangeValues(sheetId, criterion) {
67037
67066
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67038
- const criterionValues = this.getters.getRangeValues(range);
67039
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67067
+ const values = [];
67068
+ const labelsSet = new Set();
67069
+ for (const p of positions(range.zone)) {
67070
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67071
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67072
+ labelsSet.add(cell.formattedValue);
67073
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67074
+ }
67075
+ }
67076
+ return values;
67040
67077
  }
67041
67078
  isCellValidCheckbox(cellPosition) {
67042
67079
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -75651,25 +75688,30 @@ stores.inject(MyMetaStore, storeInstance);
75651
75688
  }
75652
75689
  const sheetId = this.composer.currentEditedCell.sheetId;
75653
75690
  const values = rule.criterion.type === "isValueInRange"
75654
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75655
- : rule.criterion.values;
75691
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75692
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75656
75693
  const isChip = rule.criterion.displayStyle === "chip";
75657
75694
  if (!isChip) {
75658
- return values.map((value) => ({ text: value }));
75695
+ return values.map((value) => ({
75696
+ text: value.value,
75697
+ fuzzySearchKey: value.label,
75698
+ htmlContent: [{ value: value.label }],
75699
+ }));
75659
75700
  }
75660
75701
  const colors = rule.criterion.colors;
75661
75702
  return values.map((value) => {
75662
- const color = colors?.[value];
75703
+ const color = colors?.[value.value];
75663
75704
  return {
75664
- text: value,
75705
+ text: value.value,
75665
75706
  htmlContent: [
75666
75707
  {
75667
- value,
75708
+ value: value.label,
75668
75709
  color: color ? chipTextColor(color) : undefined,
75669
75710
  backgroundColor: color || GRAY_200,
75670
75711
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75671
75712
  },
75672
75713
  ],
75714
+ fuzzySearchKey: value.label,
75673
75715
  };
75674
75716
  });
75675
75717
  },
@@ -79910,7 +79952,6 @@ stores.inject(MyMetaStore, storeInstance);
79910
79952
  }
79911
79953
  }
79912
79954
 
79913
- .o-spreadsheet-topbar-wrapper,
79914
79955
  .o-spreadsheet-bottombar-wrapper {
79915
79956
  z-index: ${ComponentsImportance.ScrollBar + 1};
79916
79957
  }
@@ -80025,7 +80066,6 @@ stores.inject(MyMetaStore, storeInstance);
80025
80066
  this.checkViewportSize();
80026
80067
  stores.on("store-updated", this, render);
80027
80068
  resizeObserver.observe(this.spreadsheetRef.el);
80028
- registerChartJSExtensions();
80029
80069
  });
80030
80070
  owl.onWillUnmount(() => {
80031
80071
  this.unbindModelEvents();
@@ -82558,7 +82598,7 @@ stores.inject(MyMetaStore, storeInstance);
82558
82598
  <dataBar>
82559
82599
  <cfvo type="min" val="0"/>
82560
82600
  <cfvo type="max" val="100"/>
82561
- <color rgb="${toXlsxHexColor(colorNumberString(rule.color))}"/>
82601
+ <color rgb="${toXlsxHexColor(colorNumberToHex(rule.color))}"/>
82562
82602
  </dataBar>
82563
82603
  </cfRule>
82564
82604
  </conditionalFormatting>
@@ -82586,7 +82626,7 @@ stores.inject(MyMetaStore, storeInstance);
82586
82626
  continue;
82587
82627
  }
82588
82628
  cfValueObject.push(thresholdAttributes(threshold, position));
82589
- colors.push([["rgb", toXlsxHexColor(colorNumberString(threshold.color))]]);
82629
+ colors.push([["rgb", toXlsxHexColor(colorNumberToHex(threshold.color))]]);
82590
82630
  }
82591
82631
  if (!canExport) {
82592
82632
  console.warn("Conditional formats with formula rules are not supported at the moment. The rule is therefore skipped.");
@@ -84645,9 +84685,9 @@ stores.inject(MyMetaStore, storeInstance);
84645
84685
  exports.tokenize = tokenize;
84646
84686
 
84647
84687
 
84648
- __info__.version = "18.4.3";
84649
- __info__.date = "2025-07-28T13:39:06.036Z";
84650
- __info__.hash = "4b596d7";
84688
+ __info__.version = "18.4.5";
84689
+ __info__.date = "2025-08-04T06:54:49.107Z";
84690
+ __info__.hash = "358931f";
84651
84691
 
84652
84692
 
84653
84693
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);