@odoo/o-spreadsheet 17.0.54 → 17.0.55

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 17.0.54
6
- * @date 2025-03-19T08:14:16.001Z
7
- * @hash 945b375
5
+ * @version 17.0.55
6
+ * @date 2025-03-26T12:44:29.690Z
7
+ * @hash c3a4769
8
8
  */
9
9
 
10
10
  'use strict';
@@ -949,7 +949,10 @@ function rgbaStringToHex(color) {
949
949
  }
950
950
  else if (stringVals.length === 4) {
951
951
  const alpha = parseFloat(stringVals.pop() || "1");
952
- alphaHex = Math.round((alpha || 1) * 255);
952
+ if (isNaN(alpha)) {
953
+ throw new Error("invalid alpha value");
954
+ }
955
+ alphaHex = Math.round(alpha * 255);
953
956
  }
954
957
  const vals = stringVals.map((val) => parseInt(val, 10));
955
958
  if (alphaHex !== 255) {
@@ -8570,7 +8573,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
8570
8573
  }
8571
8574
  }
8572
8575
  else if (dataSets.length === 1) {
8573
- for (let i = 0; i < getData(getters, dataSets[0]).length; i++) {
8576
+ const dataLength = getData(getters, dataSets[0]).length;
8577
+ for (let i = 0; i < dataLength; i++) {
8574
8578
  labels.formattedValues.push("");
8575
8579
  labels.values.push("");
8576
8580
  }
@@ -30371,9 +30375,9 @@ const XLSX_CHART_TYPES = [
30371
30375
  /** In XLSX color format (no #) */
30372
30376
  const AUTO_COLOR = "000000";
30373
30377
  const XLSX_ICONSET_MAP = {
30374
- arrow: "3Arrows",
30378
+ arrows: "3Arrows",
30375
30379
  smiley: "3Symbols",
30376
- dot: "3TrafficLights1",
30380
+ dots: "3TrafficLights1",
30377
30381
  };
30378
30382
  const NAMESPACE = {
30379
30383
  styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
@@ -30789,6 +30793,7 @@ const ICON_SET_CONVERSION_MAP = {
30789
30793
  };
30790
30794
  /** Map between legend position in XLSX file and human readable position */
30791
30795
  const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
30796
+ none: "none",
30792
30797
  b: "bottom",
30793
30798
  t: "top",
30794
30799
  l: "left",
@@ -33021,7 +33026,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
33021
33026
  ? "right"
33022
33027
  : "left",
33023
33028
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
33024
- default: "b",
33029
+ default: "none",
33025
33030
  }).asString()],
33026
33031
  stacked: barChartGrouping === "stacked",
33027
33032
  fontColor: "000000",
@@ -53482,7 +53487,9 @@ css /* scss */ `
53482
53487
  margin-top: -1px;
53483
53488
  border: 1px solid;
53484
53489
 
53485
- .o-composer:empty:not(:focus):not(.active)::before {
53490
+ /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
53491
+ .o-composer:empty:not(:focus):not(.active)::before,
53492
+ &.o-topbar-composer-readonly .o-composer:empty::before {
53486
53493
  content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
53487
53494
  position: relative;
53488
53495
  top: 20%;
@@ -56483,10 +56490,14 @@ function addIconSetRule(cf, rule) {
56483
56490
  continue;
56484
56491
  }
56485
56492
  const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
56493
+ const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
56494
+ if (isIconSetReversed(rule.icons)) {
56495
+ iconSetAttrs.push(["reverse", "1"]);
56496
+ }
56486
56497
  conditionalFormats.push(escapeXml /*xml*/ `
56487
56498
  <conditionalFormatting sqref="${range}">
56488
56499
  <cfRule ${formatAttributes(ruleAttributes)}>
56489
- <iconSet iconSet="${getIconSet(rule.icons)}">
56500
+ <iconSet ${formatAttributes(iconSetAttrs)}>
56490
56501
  ${joinXmlNodes(cfValueObjectNodes)}
56491
56502
  </iconSet>
56492
56503
  </cfRule>
@@ -56504,9 +56515,21 @@ function commonCfAttributes(cf) {
56504
56515
  ["stopIfTrue", cf.stopIfTrue ? 1 : 0],
56505
56516
  ];
56506
56517
  }
56518
+ function isIconSetReversed(iconSet) {
56519
+ const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
56520
+ return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
56521
+ }
56507
56522
  function getIconSet(iconSet) {
56508
- return XLSX_ICONSET_MAP[Object.keys(XLSX_ICONSET_MAP).find((key) => iconSet.upper.toLowerCase().startsWith(key)) ||
56509
- "dots"];
56523
+ return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
56524
+ }
56525
+ /**
56526
+ * Partial detection based on "upper" point only.
56527
+ * We support any arbitrary icon in the set, while excel doesn't allow
56528
+ * mixing icons from different types.
56529
+ */
56530
+ function detectIconsType(iconSet) {
56531
+ const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
56532
+ return type;
56510
56533
  }
56511
56534
  function thresholdAttributes(threshold, position) {
56512
56535
  const type = getExcelThresholdType(threshold.type, position);
@@ -58082,6 +58105,6 @@ exports.setTranslationMethod = setTranslationMethod;
58082
58105
  exports.tokenize = tokenize;
58083
58106
 
58084
58107
 
58085
- __info__.version = "17.0.54";
58086
- __info__.date = "2025-03-19T08:14:16.001Z";
58087
- __info__.hash = "945b375";
58108
+ __info__.version = "17.0.55";
58109
+ __info__.date = "2025-03-26T12:44:29.690Z";
58110
+ __info__.hash = "c3a4769";
@@ -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 17.0.54
6
- * @date 2025-03-19T08:14:16.001Z
7
- * @hash 945b375
5
+ * @version 17.0.55
6
+ * @date 2025-03-26T12:44:29.690Z
7
+ * @hash c3a4769
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -947,7 +947,10 @@ function rgbaStringToHex(color) {
947
947
  }
948
948
  else if (stringVals.length === 4) {
949
949
  const alpha = parseFloat(stringVals.pop() || "1");
950
- alphaHex = Math.round((alpha || 1) * 255);
950
+ if (isNaN(alpha)) {
951
+ throw new Error("invalid alpha value");
952
+ }
953
+ alphaHex = Math.round(alpha * 255);
951
954
  }
952
955
  const vals = stringVals.map((val) => parseInt(val, 10));
953
956
  if (alphaHex !== 255) {
@@ -8568,7 +8571,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
8568
8571
  }
8569
8572
  }
8570
8573
  else if (dataSets.length === 1) {
8571
- for (let i = 0; i < getData(getters, dataSets[0]).length; i++) {
8574
+ const dataLength = getData(getters, dataSets[0]).length;
8575
+ for (let i = 0; i < dataLength; i++) {
8572
8576
  labels.formattedValues.push("");
8573
8577
  labels.values.push("");
8574
8578
  }
@@ -30369,9 +30373,9 @@ const XLSX_CHART_TYPES = [
30369
30373
  /** In XLSX color format (no #) */
30370
30374
  const AUTO_COLOR = "000000";
30371
30375
  const XLSX_ICONSET_MAP = {
30372
- arrow: "3Arrows",
30376
+ arrows: "3Arrows",
30373
30377
  smiley: "3Symbols",
30374
- dot: "3TrafficLights1",
30378
+ dots: "3TrafficLights1",
30375
30379
  };
30376
30380
  const NAMESPACE = {
30377
30381
  styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
@@ -30787,6 +30791,7 @@ const ICON_SET_CONVERSION_MAP = {
30787
30791
  };
30788
30792
  /** Map between legend position in XLSX file and human readable position */
30789
30793
  const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
30794
+ none: "none",
30790
30795
  b: "bottom",
30791
30796
  t: "top",
30792
30797
  l: "left",
@@ -33019,7 +33024,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
33019
33024
  ? "right"
33020
33025
  : "left",
33021
33026
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
33022
- default: "b",
33027
+ default: "none",
33023
33028
  }).asString()],
33024
33029
  stacked: barChartGrouping === "stacked",
33025
33030
  fontColor: "000000",
@@ -53480,7 +53485,9 @@ css /* scss */ `
53480
53485
  margin-top: -1px;
53481
53486
  border: 1px solid;
53482
53487
 
53483
- .o-composer:empty:not(:focus):not(.active)::before {
53488
+ /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
53489
+ .o-composer:empty:not(:focus):not(.active)::before,
53490
+ &.o-topbar-composer-readonly .o-composer:empty::before {
53484
53491
  content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
53485
53492
  position: relative;
53486
53493
  top: 20%;
@@ -56481,10 +56488,14 @@ function addIconSetRule(cf, rule) {
56481
56488
  continue;
56482
56489
  }
56483
56490
  const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
56491
+ const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
56492
+ if (isIconSetReversed(rule.icons)) {
56493
+ iconSetAttrs.push(["reverse", "1"]);
56494
+ }
56484
56495
  conditionalFormats.push(escapeXml /*xml*/ `
56485
56496
  <conditionalFormatting sqref="${range}">
56486
56497
  <cfRule ${formatAttributes(ruleAttributes)}>
56487
- <iconSet iconSet="${getIconSet(rule.icons)}">
56498
+ <iconSet ${formatAttributes(iconSetAttrs)}>
56488
56499
  ${joinXmlNodes(cfValueObjectNodes)}
56489
56500
  </iconSet>
56490
56501
  </cfRule>
@@ -56502,9 +56513,21 @@ function commonCfAttributes(cf) {
56502
56513
  ["stopIfTrue", cf.stopIfTrue ? 1 : 0],
56503
56514
  ];
56504
56515
  }
56516
+ function isIconSetReversed(iconSet) {
56517
+ const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
56518
+ return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
56519
+ }
56505
56520
  function getIconSet(iconSet) {
56506
- return XLSX_ICONSET_MAP[Object.keys(XLSX_ICONSET_MAP).find((key) => iconSet.upper.toLowerCase().startsWith(key)) ||
56507
- "dots"];
56521
+ return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
56522
+ }
56523
+ /**
56524
+ * Partial detection based on "upper" point only.
56525
+ * We support any arbitrary icon in the set, while excel doesn't allow
56526
+ * mixing icons from different types.
56527
+ */
56528
+ function detectIconsType(iconSet) {
56529
+ const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
56530
+ return type;
56508
56531
  }
56509
56532
  function thresholdAttributes(threshold, position) {
56510
56533
  const type = getExcelThresholdType(threshold.type, position);
@@ -58045,6 +58068,6 @@ const constants = {
58045
58068
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
58046
58069
 
58047
58070
 
58048
- __info__.version = "17.0.54";
58049
- __info__.date = "2025-03-19T08:14:16.001Z";
58050
- __info__.hash = "945b375";
58071
+ __info__.version = "17.0.55";
58072
+ __info__.date = "2025-03-26T12:44:29.690Z";
58073
+ __info__.hash = "c3a4769";
@@ -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 17.0.54
6
- * @date 2025-03-19T08:14:16.001Z
7
- * @hash 945b375
5
+ * @version 17.0.55
6
+ * @date 2025-03-26T12:44:29.690Z
7
+ * @hash c3a4769
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -948,7 +948,10 @@
948
948
  }
949
949
  else if (stringVals.length === 4) {
950
950
  const alpha = parseFloat(stringVals.pop() || "1");
951
- alphaHex = Math.round((alpha || 1) * 255);
951
+ if (isNaN(alpha)) {
952
+ throw new Error("invalid alpha value");
953
+ }
954
+ alphaHex = Math.round(alpha * 255);
952
955
  }
953
956
  const vals = stringVals.map((val) => parseInt(val, 10));
954
957
  if (alphaHex !== 255) {
@@ -8569,7 +8572,8 @@
8569
8572
  }
8570
8573
  }
8571
8574
  else if (dataSets.length === 1) {
8572
- for (let i = 0; i < getData(getters, dataSets[0]).length; i++) {
8575
+ const dataLength = getData(getters, dataSets[0]).length;
8576
+ for (let i = 0; i < dataLength; i++) {
8573
8577
  labels.formattedValues.push("");
8574
8578
  labels.values.push("");
8575
8579
  }
@@ -30370,9 +30374,9 @@
30370
30374
  /** In XLSX color format (no #) */
30371
30375
  const AUTO_COLOR = "000000";
30372
30376
  const XLSX_ICONSET_MAP = {
30373
- arrow: "3Arrows",
30377
+ arrows: "3Arrows",
30374
30378
  smiley: "3Symbols",
30375
- dot: "3TrafficLights1",
30379
+ dots: "3TrafficLights1",
30376
30380
  };
30377
30381
  const NAMESPACE = {
30378
30382
  styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
@@ -30788,6 +30792,7 @@
30788
30792
  };
30789
30793
  /** Map between legend position in XLSX file and human readable position */
30790
30794
  const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
30795
+ none: "none",
30791
30796
  b: "bottom",
30792
30797
  t: "top",
30793
30798
  l: "left",
@@ -33020,7 +33025,7 @@
33020
33025
  ? "right"
33021
33026
  : "left",
33022
33027
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
33023
- default: "b",
33028
+ default: "none",
33024
33029
  }).asString()],
33025
33030
  stacked: barChartGrouping === "stacked",
33026
33031
  fontColor: "000000",
@@ -53481,7 +53486,9 @@
53481
53486
  margin-top: -1px;
53482
53487
  border: 1px solid;
53483
53488
 
53484
- .o-composer:empty:not(:focus):not(.active)::before {
53489
+ /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
53490
+ .o-composer:empty:not(:focus):not(.active)::before,
53491
+ &.o-topbar-composer-readonly .o-composer:empty::before {
53485
53492
  content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
53486
53493
  position: relative;
53487
53494
  top: 20%;
@@ -56482,10 +56489,14 @@
56482
56489
  continue;
56483
56490
  }
56484
56491
  const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
56492
+ const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
56493
+ if (isIconSetReversed(rule.icons)) {
56494
+ iconSetAttrs.push(["reverse", "1"]);
56495
+ }
56485
56496
  conditionalFormats.push(escapeXml /*xml*/ `
56486
56497
  <conditionalFormatting sqref="${range}">
56487
56498
  <cfRule ${formatAttributes(ruleAttributes)}>
56488
- <iconSet iconSet="${getIconSet(rule.icons)}">
56499
+ <iconSet ${formatAttributes(iconSetAttrs)}>
56489
56500
  ${joinXmlNodes(cfValueObjectNodes)}
56490
56501
  </iconSet>
56491
56502
  </cfRule>
@@ -56503,9 +56514,21 @@
56503
56514
  ["stopIfTrue", cf.stopIfTrue ? 1 : 0],
56504
56515
  ];
56505
56516
  }
56517
+ function isIconSetReversed(iconSet) {
56518
+ const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
56519
+ return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
56520
+ }
56506
56521
  function getIconSet(iconSet) {
56507
- return XLSX_ICONSET_MAP[Object.keys(XLSX_ICONSET_MAP).find((key) => iconSet.upper.toLowerCase().startsWith(key)) ||
56508
- "dots"];
56522
+ return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
56523
+ }
56524
+ /**
56525
+ * Partial detection based on "upper" point only.
56526
+ * We support any arbitrary icon in the set, while excel doesn't allow
56527
+ * mixing icons from different types.
56528
+ */
56529
+ function detectIconsType(iconSet) {
56530
+ const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
56531
+ return type;
56509
56532
  }
56510
56533
  function thresholdAttributes(threshold, position) {
56511
56534
  const type = getExcelThresholdType(threshold.type, position);
@@ -58081,9 +58104,9 @@
58081
58104
  exports.tokenize = tokenize;
58082
58105
 
58083
58106
 
58084
- __info__.version = "17.0.54";
58085
- __info__.date = "2025-03-19T08:14:16.001Z";
58086
- __info__.hash = "945b375";
58107
+ __info__.version = "17.0.55";
58108
+ __info__.date = "2025-03-26T12:44:29.690Z";
58109
+ __info__.hash = "c3a4769";
58087
58110
 
58088
58111
 
58089
58112
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);