@odoo/o-spreadsheet 17.3.2 → 17.3.3

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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.3.2
7
- * @date 2024-06-10T09:38:56.657Z
8
- * @hash c3b358f
6
+ * @version 17.3.3
7
+ * @date 2024-06-14T10:02:58.082Z
8
+ * @hash c690e9f
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -2780,7 +2780,7 @@
2780
2780
  return false;
2781
2781
  }
2782
2782
  if (typeof operand === "number" && operator === "=") {
2783
- return toString(value) === toString(operand);
2783
+ return value.toString() === operand.toString();
2784
2784
  }
2785
2785
  if (operator === "<>" || operator === "=") {
2786
2786
  let result;
@@ -2840,14 +2840,13 @@
2840
2840
  if (countArg % 2 === 1) {
2841
2841
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
2842
2842
  }
2843
- const dimRow = args[0].length;
2844
- const dimCol = args[0][0].length;
2843
+ const firstArg = toMatrix(args[0]);
2844
+ const dimRow = firstArg.length;
2845
+ const dimCol = firstArg[0].length;
2845
2846
  let predicates = [];
2846
2847
  for (let i = 0; i < countArg - 1; i += 2) {
2847
- const criteriaRange = args[i];
2848
- if (!isMatrix(criteriaRange) ||
2849
- criteriaRange.length !== dimRow ||
2850
- criteriaRange[0].length !== dimCol) {
2848
+ const criteriaRange = toMatrix(args[i]);
2849
+ if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
2851
2850
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
2852
2851
  }
2853
2852
  const description = toString(args[i + 1]);
@@ -2861,7 +2860,7 @@
2861
2860
  for (let j = 0; j < dimCol; j++) {
2862
2861
  let validatedPredicates = true;
2863
2862
  for (let k = 0; k < countArg - 1; k += 2) {
2864
- const criteriaValue = args[k][i][j].value;
2863
+ const criteriaValue = toMatrix(args[k])[i][j].value;
2865
2864
  const criterion = predicates[k / 2];
2866
2865
  validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2867
2866
  if (!validatedPredicates) {
@@ -10989,6 +10988,9 @@ stores.inject(MyMetaStore, storeInstance);
10989
10988
  if (types.some((t) => t.startsWith("RANGE"))) {
10990
10989
  result.acceptMatrix = true;
10991
10990
  }
10991
+ if (types.every((t) => t.startsWith("RANGE"))) {
10992
+ result.acceptMatrixOnly = true;
10993
+ }
10992
10994
  return result;
10993
10995
  }
10994
10996
  /**
@@ -11270,11 +11272,16 @@ stores.inject(MyMetaStore, storeInstance);
11270
11272
  compute: function (array, ...columns) {
11271
11273
  const _array = toMatrix(array);
11272
11274
  const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
11273
- assert(() => _columns.every((col) => col > 0 && col <= _array.length), _t("The columns arguments must be between 1 and %s (got %s).", _array.length.toString(), (_columns.find((col) => col <= 0 || col > _array.length) || 0).toString()));
11275
+ const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
11276
+ assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
11274
11277
  const result = Array(_columns.length);
11275
11278
  for (let col = 0; col < _columns.length; col++) {
11276
- const colIndex = _columns[col] - 1; // -1 because columns arguments are 1-indexed
11277
- result[col] = _array[colIndex];
11279
+ if (_columns[col] > 0) {
11280
+ result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
11281
+ }
11282
+ else {
11283
+ result[col] = _array[_array.length + _columns[col]];
11284
+ }
11278
11285
  }
11279
11286
  return result;
11280
11287
  },
@@ -11295,8 +11302,14 @@ stores.inject(MyMetaStore, storeInstance);
11295
11302
  const _array = toMatrix(array);
11296
11303
  const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
11297
11304
  const _nbColumns = _array.length;
11298
- assert(() => _rows.every((row) => row > 0 && row <= _array[0].length), _t("The rows arguments must be between 1 and %s (got %s).", _array[0].length.toString(), (_rows.find((row) => row <= 0 || row > _array[0].length) || 0).toString()));
11299
- return generateMatrix(_nbColumns, _rows.length, (col, row) => _array[col][_rows[row] - 1]); // -1 because rows arguments are 1-indexed
11305
+ const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
11306
+ assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
11307
+ return generateMatrix(_nbColumns, _rows.length, (col, row) => {
11308
+ if (_rows[row] > 0) {
11309
+ return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
11310
+ }
11311
+ return _array[col][_array[col].length + _rows[row]];
11312
+ });
11300
11313
  },
11301
11314
  isExported: true,
11302
11315
  };
@@ -19763,6 +19776,9 @@ stores.inject(MyMetaStore, storeInstance);
19763
19776
  }
19764
19777
  args[i] = arg[0][0];
19765
19778
  }
19779
+ if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
19780
+ throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
19781
+ }
19766
19782
  }
19767
19783
  return descr.compute.apply(this, args);
19768
19784
  }
@@ -21357,12 +21373,6 @@ stores.inject(MyMetaStore, storeInstance);
21357
21373
  // detect when an argument need to be evaluated as a meta argument
21358
21374
  const isMeta = argTypes.includes("META");
21359
21375
  const hasRange = argTypes.some((t) => isRangeType(t));
21360
- const isRangeOnly = argTypes.every((t) => isRangeType(t));
21361
- if (isRangeOnly) {
21362
- if (!isRangeInput(currentArg)) {
21363
- throw new BadExpressionError(_t("Function %(function_name)s expects the parameter %(arg_index)s to be a reference to a cell or a range.", { function_name: functionName, arg_index: i + 1 }));
21364
- }
21365
- }
21366
21376
  compiledArgs.push(compileAST(currentArg, isMeta, hasRange));
21367
21377
  }
21368
21378
  return compiledArgs;
@@ -21527,16 +21537,6 @@ stores.inject(MyMetaStore, storeInstance);
21527
21537
  function isRangeType(type) {
21528
21538
  return type.startsWith("RANGE");
21529
21539
  }
21530
- function isRangeInput(arg) {
21531
- if (arg.type === "REFERENCE") {
21532
- return true;
21533
- }
21534
- if (arg.type === "FUNCALL") {
21535
- const fnDef = functions$1[arg.value.toUpperCase()];
21536
- return fnDef && isRangeType(fnDef.returns[0]);
21537
- }
21538
- return false;
21539
- }
21540
21540
 
21541
21541
  const functions = functionRegistry.content;
21542
21542
  function isExportableToExcel(tokens) {
@@ -21965,7 +21965,9 @@ stores.inject(MyMetaStore, storeInstance);
21965
21965
  if (!groupByField) {
21966
21966
  return;
21967
21967
  }
21968
- return dataSource.getPossibleFieldValues(groupByField.split(":")[0]).map(({ value, label }) => {
21968
+ return dataSource
21969
+ .getPossibleFieldValues(groupByField.toString().split(":")[0])
21970
+ .map(({ value, label }) => {
21969
21971
  const isString = typeof value === "string";
21970
21972
  const text = isString ? `"${value}"` : value.toString();
21971
21973
  const color = isString ? tokenColors.STRING : tokenColors.NUMBER;
@@ -25451,7 +25453,7 @@ stores.inject(MyMetaStore, storeInstance);
25451
25453
  if (!anchor)
25452
25454
  return;
25453
25455
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
25454
- const elDims = {
25456
+ let elDims = {
25455
25457
  width: el.getBoundingClientRect().width,
25456
25458
  height: el.getBoundingClientRect().height,
25457
25459
  };
@@ -25459,7 +25461,14 @@ stores.inject(MyMetaStore, storeInstance);
25459
25461
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
25460
25462
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
25461
25463
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
25462
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25464
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
25465
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
25466
+ // Re-compute the dimensions after setting the max-width and max-height
25467
+ elDims = {
25468
+ width: el.getBoundingClientRect().width,
25469
+ height: el.getBoundingClientRect().height,
25470
+ };
25471
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25463
25472
  for (const property of Object.keys(style)) {
25464
25473
  el.style[property] = style[property];
25465
25474
  }
@@ -25522,8 +25531,6 @@ stores.inject(MyMetaStore, storeInstance);
25522
25531
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
25523
25532
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
25524
25533
  const cssProperties = {
25525
- "max-height": maxHeight + "px",
25526
- "max-width": maxWidth + "px",
25527
25534
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
25528
25535
  this.spreadsheetOffset.y -
25529
25536
  verticalOffset +
@@ -31337,10 +31344,8 @@ stores.inject(MyMetaStore, storeInstance);
31337
31344
 
31338
31345
  class AxisDesignEditor extends owl.Component {
31339
31346
  static template = "o-spreadsheet-AxisDesignEditor";
31340
- static components = {
31341
- Section,
31342
- ChartTitle,
31343
- };
31347
+ static components = { Section, ChartTitle };
31348
+ static props = { figureId: String, definition: Object, updateChart: Function, axesList: Array };
31344
31349
  state = owl.useState({ currentAxis: "x" });
31345
31350
  get axisTitleStyle() {
31346
31351
  const axisDesign = this.props.definition.axesDesign?.[this.state.currentAxis] ?? {};
@@ -31491,6 +31496,12 @@ stores.inject(MyMetaStore, storeInstance);
31491
31496
  AxisDesignEditor,
31492
31497
  RoundColorPicker,
31493
31498
  };
31499
+ static props = {
31500
+ figureId: String,
31501
+ definition: Object,
31502
+ canUpdateChart: Function,
31503
+ updateChart: Function,
31504
+ };
31494
31505
  state = owl.useState({ index: 0 });
31495
31506
  get axesList() {
31496
31507
  const { useLeftAxis, useRightAxis } = getDefinedAxis(this.props.definition);
@@ -31672,14 +31683,6 @@ stores.inject(MyMetaStore, storeInstance);
31672
31683
  const cancelledReasons = [...(this.state.sectionRuleDispatchResult?.reasons || [])];
31673
31684
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
31674
31685
  }
31675
- updateBackgroundColor(color) {
31676
- this.props.updateChart(this.props.figureId, {
31677
- background: color,
31678
- });
31679
- }
31680
- updateTitle(content) {
31681
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31682
- }
31683
31686
  isRangeMinInvalid() {
31684
31687
  return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause("EmptyGaugeRangeMin" /* CommandResult.EmptyGaugeRangeMin */) ||
31685
31688
  this.state.sectionRuleDispatchResult?.isCancelledBecause("GaugeRangeMinNaN" /* CommandResult.GaugeRangeMinNaN */) ||
@@ -31719,9 +31722,6 @@ stores.inject(MyMetaStore, storeInstance);
31719
31722
  sectionRule,
31720
31723
  });
31721
31724
  }
31722
- get backgroundColorTitle() {
31723
- return ChartTerms.BackgroundColor;
31724
- }
31725
31725
  }
31726
31726
 
31727
31727
  class LineConfigPanel extends GenericChartConfigPanel {
@@ -31904,9 +31904,6 @@ stores.inject(MyMetaStore, storeInstance);
31904
31904
  get humanizeNumbersLabel() {
31905
31905
  return _t("Humanize numbers");
31906
31906
  }
31907
- updateTitle(content) {
31908
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31909
- }
31910
31907
  updateHumanizeNumbers(humanize) {
31911
31908
  this.props.updateChart(this.props.figureId, { humanize });
31912
31909
  }
@@ -31929,9 +31926,6 @@ stores.inject(MyMetaStore, storeInstance);
31929
31926
  break;
31930
31927
  }
31931
31928
  }
31932
- get backgroundColorTitle() {
31933
- return ChartTerms.BackgroundColor;
31934
- }
31935
31929
  }
31936
31930
 
31937
31931
  class WaterfallChartDesignPanel extends owl.Component {
@@ -33432,13 +33426,17 @@ stores.inject(MyMetaStore, storeInstance);
33432
33426
  class: { type: String, optional: true },
33433
33427
  };
33434
33428
  static components = { Menu };
33429
+ menuId = new UuidGenerator().uuidv4();
33435
33430
  selectRef = owl.useRef("select");
33436
33431
  selectRect = useAbsoluteBoundingRect(this.selectRef);
33437
33432
  state = owl.useState({
33438
33433
  isMenuOpen: false,
33439
33434
  });
33440
- onClick() {
33441
- this.state.isMenuOpen = true;
33435
+ onClick(ev) {
33436
+ if (ev.closedMenuId === this.menuId) {
33437
+ return;
33438
+ }
33439
+ this.state.isMenuOpen = !this.state.isMenuOpen;
33442
33440
  }
33443
33441
  onMenuClosed() {
33444
33442
  this.state.isMenuOpen = false;
@@ -33446,7 +33444,7 @@ stores.inject(MyMetaStore, storeInstance);
33446
33444
  get menuPosition() {
33447
33445
  return {
33448
33446
  x: this.selectRect.x,
33449
- y: this.selectRect.y,
33447
+ y: this.selectRect.y + this.selectRect.height,
33450
33448
  };
33451
33449
  }
33452
33450
  }
@@ -34386,9 +34384,9 @@ stores.inject(MyMetaStore, storeInstance);
34386
34384
  static props = {
34387
34385
  onCloseSidePanel: Function,
34388
34386
  };
34389
- dataRange = "";
34390
34387
  searchInput = owl.useRef("searchInput");
34391
34388
  store;
34389
+ state;
34392
34390
  get hasSearchResult() {
34393
34391
  return this.store.selectedMatchIndex !== null;
34394
34392
  }
@@ -34418,6 +34416,7 @@ stores.inject(MyMetaStore, storeInstance);
34418
34416
  }
34419
34417
  setup() {
34420
34418
  this.store = useLocalStore(FindAndReplaceStore);
34419
+ this.state = owl.useState({ dataRange: "" });
34421
34420
  owl.onMounted(() => this.searchInput.el?.focus());
34422
34421
  }
34423
34422
  onFocusSearch() {
@@ -34454,13 +34453,13 @@ stores.inject(MyMetaStore, storeInstance);
34454
34453
  this.store.updateSearchOptions({ searchScope });
34455
34454
  }
34456
34455
  onSearchRangeChanged(ranges) {
34457
- this.dataRange = ranges[0];
34456
+ this.state.dataRange = ranges[0];
34458
34457
  }
34459
34458
  updateDataRange() {
34460
- if (!this.dataRange || this.searchOptions.searchScope !== "specificRange") {
34459
+ if (!this.state.dataRange || this.searchOptions.searchScope !== "specificRange") {
34461
34460
  return;
34462
34461
  }
34463
- const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange);
34462
+ const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
34464
34463
  this.store.updateSearchOptions({ specificRange });
34465
34464
  }
34466
34465
  }
@@ -36131,6 +36130,7 @@ stores.inject(MyMetaStore, storeInstance);
36131
36130
  class RemoveDuplicatesPanel extends owl.Component {
36132
36131
  static template = "o-spreadsheet-RemoveDuplicatesPanel";
36133
36132
  static components = { ValidationMessages, Section, Checkbox };
36133
+ static props = { onCloseSidePanel: Function };
36134
36134
  state = owl.useState({
36135
36135
  hasHeader: false,
36136
36136
  columns: {},
@@ -38555,7 +38555,7 @@ stores.inject(MyMetaStore, storeInstance);
38555
38555
  });
38556
38556
  }
38557
38557
  getContainerRect(container) {
38558
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
38558
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
38559
38559
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
38560
38560
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
38561
38561
  const width = viewWidth - x;
@@ -51160,22 +51160,6 @@ stores.inject(MyMetaStore, storeInstance);
51160
51160
  this.addPivotFormula(cellPosition, formulaId, pivotCell);
51161
51161
  }
51162
51162
  }
51163
- const pivotZone = {
51164
- top: position.row,
51165
- bottom: position.row + pivotCells[0].length - 1,
51166
- left: position.col,
51167
- right: position.col + pivotCells.length - 1,
51168
- };
51169
- const numberOfHeaders = table.columns.length - 1;
51170
- const cmdContent = {
51171
- sheetId: position.sheetId,
51172
- ranges: [this.getters.getRangeDataFromZone(position.sheetId, pivotZone)],
51173
- config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
51174
- tableType: "static",
51175
- };
51176
- if (this.canDispatch("CREATE_TABLE", cmdContent).isSuccessful) {
51177
- this.dispatch("CREATE_TABLE", cmdContent);
51178
- }
51179
51163
  }
51180
51164
  resizeSheet(sheetId, { col, row }, table) {
51181
51165
  const colLimit = table.getNumberOfDataColumns() + 1; // +1 for the Top-Left
@@ -55901,7 +55885,10 @@ stores.inject(MyMetaStore, storeInstance);
55901
55885
  /**
55902
55886
  * Notify the server that the user client left the collaborative session
55903
55887
  */
55904
- leave() {
55888
+ leave(data) {
55889
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
55890
+ this.snapshot(data);
55891
+ }
55905
55892
  delete this.clients[this.clientId];
55906
55893
  this.transportService.leave(this.clientId);
55907
55894
  this.transportService.sendMessage({
@@ -55914,6 +55901,9 @@ stores.inject(MyMetaStore, storeInstance);
55914
55901
  * Send a snapshot of the spreadsheet to the collaboration server
55915
55902
  */
55916
55903
  snapshot(data) {
55904
+ if (this.pendingMessages.length !== 0) {
55905
+ return;
55906
+ }
55917
55907
  const snapshotId = this.uuidGenerator.uuidv4();
55918
55908
  this.transportService.sendMessage({
55919
55909
  type: "SNAPSHOT",
@@ -66401,7 +66391,7 @@ stores.inject(MyMetaStore, storeInstance);
66401
66391
  this.session.join(this.config.client);
66402
66392
  }
66403
66393
  leaveSession() {
66404
- this.session.leave();
66394
+ this.session.leave(this.exportData());
66405
66395
  }
66406
66396
  setupUiPlugin(Plugin) {
66407
66397
  const plugin = new Plugin(this.uiPluginConfig);
@@ -66992,9 +66982,9 @@ stores.inject(MyMetaStore, storeInstance);
66992
66982
  exports.tokenize = tokenize;
66993
66983
 
66994
66984
 
66995
- __info__.version = "17.3.2";
66996
- __info__.date = "2024-06-10T09:38:56.657Z";
66997
- __info__.hash = "c3b358f";
66985
+ __info__.version = "17.3.3";
66986
+ __info__.date = "2024-06-14T10:02:58.082Z";
66987
+ __info__.hash = "c690e9f";
66998
66988
 
66999
66989
 
67000
66990
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);