@odoo/o-spreadsheet 17.4.2 → 17.4.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.
@@ -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.4.2
6
- * @date 2024-07-24T10:26:00.237Z
7
- * @hash f5ede5b
5
+ * @version 17.4.3
6
+ * @date 2024-08-02T08:23:56.573Z
7
+ * @hash 40ecd1e
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2766,13 +2766,16 @@
2766
2766
  }
2767
2767
  return new RegExp("^" + exp + "$", "i");
2768
2768
  });
2769
- function evaluatePredicate(value = "", criterion) {
2769
+ function evaluatePredicate(value = "", criterion, locale) {
2770
2770
  const { operator, operand } = criterion;
2771
2771
  if (operand === undefined || value === null || operand === null) {
2772
2772
  return false;
2773
2773
  }
2774
2774
  if (typeof operand === "number" && operator === "=") {
2775
- return value.toString() === operand.toString();
2775
+ if (typeof value === "string" && (isNumber(value, locale) || isDateTime(value, locale))) {
2776
+ return toNumber(value, locale) === operand;
2777
+ }
2778
+ return value === operand;
2776
2779
  }
2777
2780
  if (operator === "<>" || operator === "=") {
2778
2781
  let result;
@@ -2854,7 +2857,7 @@
2854
2857
  for (let k = 0; k < countArg - 1; k += 2) {
2855
2858
  const criteriaValue = toMatrix(args[k])[i][j].value;
2856
2859
  const criterion = predicates[k / 2];
2857
- validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2860
+ validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion, locale);
2858
2861
  if (!validatedPredicates) {
2859
2862
  break;
2860
2863
  }
@@ -6545,6 +6548,9 @@
6545
6548
  const groupValueString = typeof groupValue === "boolean"
6546
6549
  ? toString(groupValue).toLocaleLowerCase()
6547
6550
  : toString(groupValue);
6551
+ if (groupValueString === "null") {
6552
+ return null;
6553
+ }
6548
6554
  if (!pivotNormalizationValueRegistry.contains(dimension.type)) {
6549
6555
  throw new EvaluationError(_t("Field %(field)s is not supported because of its type (%(type)s)", {
6550
6556
  field: dimension.displayName,
@@ -6565,6 +6571,9 @@
6565
6571
  return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
6566
6572
  }
6567
6573
  function toFunctionPivotValue(value, dimension) {
6574
+ if (value === null) {
6575
+ return `"null"`;
6576
+ }
6568
6577
  if (!pivotToFunctionValueRegistry.contains(dimension.type)) {
6569
6578
  return `"${value}"`;
6570
6579
  }
@@ -20780,6 +20789,78 @@ stores.inject(MyMetaStore, storeInstance);
20780
20789
  return isMacOS() ? ev.metaKey : ev.ctrlKey;
20781
20790
  }
20782
20791
 
20792
+ /**
20793
+ * Return the o-spreadsheet element position relative
20794
+ * to the browser viewport.
20795
+ */
20796
+ function useSpreadsheetRect() {
20797
+ const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
20798
+ let spreadsheetElement = null;
20799
+ function updatePosition() {
20800
+ if (!spreadsheetElement) {
20801
+ spreadsheetElement = document.querySelector(".o-spreadsheet");
20802
+ }
20803
+ if (spreadsheetElement) {
20804
+ const { top, left, width, height } = spreadsheetElement.getBoundingClientRect();
20805
+ position.x = left;
20806
+ position.y = top;
20807
+ position.width = width;
20808
+ position.height = height;
20809
+ }
20810
+ }
20811
+ owl.onMounted(updatePosition);
20812
+ owl.onPatched(updatePosition);
20813
+ return position;
20814
+ }
20815
+ /**
20816
+ * Return the component (or ref's component) BoundingRect, relative
20817
+ * to the upper left corner of the screen (<body> element).
20818
+ *
20819
+ * Note: when used with a <Portal/> component, it will
20820
+ * return the portal position, not the teleported position.
20821
+ */
20822
+ function useAbsoluteBoundingRect(ref) {
20823
+ const rect = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
20824
+ function updateElRect() {
20825
+ const el = ref.el;
20826
+ if (el === null) {
20827
+ return;
20828
+ }
20829
+ const { top, left, width, height } = el.getBoundingClientRect();
20830
+ rect.x = left;
20831
+ rect.y = top;
20832
+ rect.width = width;
20833
+ rect.height = height;
20834
+ }
20835
+ owl.onMounted(updateElRect);
20836
+ owl.onPatched(updateElRect);
20837
+ return rect;
20838
+ }
20839
+ /**
20840
+ * Get the rectangle inside which a popover should stay when being displayed.
20841
+ * It's the value defined in `env.getPopoverContainerRect`, or the Rect of the "o-spreadsheet"
20842
+ * element by default.
20843
+ *
20844
+ * Coordinates are expressed expressed as absolute DOM position.
20845
+ */
20846
+ function usePopoverContainer() {
20847
+ const container = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
20848
+ const component = owl.useComponent();
20849
+ const spreadsheetRect = useSpreadsheetRect();
20850
+ function updateRect() {
20851
+ const env = component.env;
20852
+ const newRect = "getPopoverContainerRect" in env ? env.getPopoverContainerRect() : spreadsheetRect;
20853
+ container.x = newRect.x;
20854
+ container.y = newRect.y;
20855
+ container.width = newRect.width;
20856
+ container.height = newRect.height;
20857
+ }
20858
+ updateRect();
20859
+ owl.onMounted(updateRect);
20860
+ owl.onPatched(updateRect);
20861
+ return container;
20862
+ }
20863
+
20783
20864
  const arrowMap = {
20784
20865
  ArrowDown: "down",
20785
20866
  ArrowLeft: "left",
@@ -21369,7 +21450,9 @@ stores.inject(MyMetaStore, storeInstance);
21369
21450
  argToFocus: 0,
21370
21451
  });
21371
21452
  compositionActive = false;
21453
+ spreadsheetRect = useSpreadsheetRect();
21372
21454
  get assistantStyle() {
21455
+ const composerRect = this.composerRef.el.getBoundingClientRect();
21373
21456
  const assistantStyle = {};
21374
21457
  assistantStyle["min-width"] = `${this.props.rect?.width || ASSISTANT_WIDTH}px`;
21375
21458
  const proposals = this.autoCompleteState.provider?.proposals;
@@ -21396,6 +21479,9 @@ stores.inject(MyMetaStore, storeInstance);
21396
21479
  }
21397
21480
  else if (this.props.delimitation) {
21398
21481
  assistantStyle["max-height"] = `${this.props.delimitation.height}px`;
21482
+ if (composerRect.left + ASSISTANT_WIDTH > this.spreadsheetRect.width) {
21483
+ assistantStyle.right = `0px`;
21484
+ }
21399
21485
  }
21400
21486
  return cssPropertiesToCss(assistantStyle);
21401
21487
  }
@@ -26238,78 +26324,6 @@ stores.inject(MyMetaStore, storeInstance);
26238
26324
  };
26239
26325
  }
26240
26326
 
26241
- /**
26242
- * Return the o-spreadsheet element position relative
26243
- * to the browser viewport.
26244
- */
26245
- function useSpreadsheetRect() {
26246
- const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
26247
- let spreadsheetElement = null;
26248
- function updatePosition() {
26249
- if (!spreadsheetElement) {
26250
- spreadsheetElement = document.querySelector(".o-spreadsheet");
26251
- }
26252
- if (spreadsheetElement) {
26253
- const { top, left, width, height } = spreadsheetElement.getBoundingClientRect();
26254
- position.x = left;
26255
- position.y = top;
26256
- position.width = width;
26257
- position.height = height;
26258
- }
26259
- }
26260
- owl.onMounted(updatePosition);
26261
- owl.onPatched(updatePosition);
26262
- return position;
26263
- }
26264
- /**
26265
- * Return the component (or ref's component) BoundingRect, relative
26266
- * to the upper left corner of the screen (<body> element).
26267
- *
26268
- * Note: when used with a <Portal/> component, it will
26269
- * return the portal position, not the teleported position.
26270
- */
26271
- function useAbsoluteBoundingRect(ref) {
26272
- const rect = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
26273
- function updateElRect() {
26274
- const el = ref.el;
26275
- if (el === null) {
26276
- return;
26277
- }
26278
- const { top, left, width, height } = el.getBoundingClientRect();
26279
- rect.x = left;
26280
- rect.y = top;
26281
- rect.width = width;
26282
- rect.height = height;
26283
- }
26284
- owl.onMounted(updateElRect);
26285
- owl.onPatched(updateElRect);
26286
- return rect;
26287
- }
26288
- /**
26289
- * Get the rectangle inside which a popover should stay when being displayed.
26290
- * It's the value defined in `env.getPopoverContainerRect`, or the Rect of the "o-spreadsheet"
26291
- * element by default.
26292
- *
26293
- * Coordinates are expressed expressed as absolute DOM position.
26294
- */
26295
- function usePopoverContainer() {
26296
- const container = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
26297
- const component = owl.useComponent();
26298
- const spreadsheetRect = useSpreadsheetRect();
26299
- function updateRect() {
26300
- const env = component.env;
26301
- const newRect = "getPopoverContainerRect" in env ? env.getPopoverContainerRect() : spreadsheetRect;
26302
- container.x = newRect.x;
26303
- container.y = newRect.y;
26304
- container.width = newRect.width;
26305
- container.height = newRect.height;
26306
- }
26307
- updateRect();
26308
- owl.onMounted(updateRect);
26309
- owl.onPatched(updateRect);
26310
- return container;
26311
- }
26312
-
26313
26327
  css /* scss */ `
26314
26328
  .o-popover {
26315
26329
  position: absolute;
@@ -35808,6 +35822,14 @@ stores.inject(MyMetaStore, storeInstance);
35808
35822
  .pivot-dim-operator-label {
35809
35823
  min-width: 120px;
35810
35824
  }
35825
+
35826
+ &.pivot-dimension-invalid {
35827
+ background-color: #ffdddd;
35828
+ border-color: red !important;
35829
+ select {
35830
+ background-color: #ffdddd;
35831
+ }
35832
+ }
35811
35833
  }
35812
35834
  `;
35813
35835
  class PivotDimension extends owl.Component {
@@ -47215,12 +47237,13 @@ stores.inject(MyMetaStore, storeInstance);
47215
47237
  this.clearBorders(cmd.sheetId, cmd.target);
47216
47238
  break;
47217
47239
  case "REMOVE_COLUMNS_ROWS":
47218
- for (let el of [...cmd.elements].sort((a, b) => b - a)) {
47240
+ const elements = [...cmd.elements].sort((a, b) => b - a);
47241
+ for (const group of groupConsecutive(elements)) {
47219
47242
  if (cmd.dimension === "COL") {
47220
- this.shiftBordersHorizontally(cmd.sheetId, el + 1, -1);
47243
+ this.shiftBordersHorizontally(cmd.sheetId, group[group.length - 1] + 1, -group.length);
47221
47244
  }
47222
47245
  else {
47223
- this.shiftBordersVertically(cmd.sheetId, el + 1, -1);
47246
+ this.shiftBordersVertically(cmd.sheetId, group[group.length - 1] + 1, -group.length);
47224
47247
  }
47225
47248
  }
47226
47249
  break;
@@ -51281,12 +51304,7 @@ stores.inject(MyMetaStore, storeInstance);
51281
51304
  });
51282
51305
  }
51283
51306
  if (colIndex > deletedColumn) {
51284
- this.dispatch("UPDATE_CELL_POSITION", {
51285
- sheetId: sheet.id,
51286
- cellId: cellId,
51287
- col: colIndex - 1,
51288
- row: rowIndex,
51289
- });
51307
+ this.setNewPosition(cellId, sheet.id, colIndex - 1, rowIndex);
51290
51308
  }
51291
51309
  }
51292
51310
  }
@@ -51296,7 +51314,7 @@ stores.inject(MyMetaStore, storeInstance);
51296
51314
  * Move the cells after a column or rows insertion
51297
51315
  */
51298
51316
  moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
51299
- const commands = [];
51317
+ const updates = [];
51300
51318
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
51301
51319
  const row = sheet.rows[rowIndex];
51302
51320
  if (dimension !== "rows" || rowIndex >= addedElement) {
@@ -51305,20 +51323,20 @@ stores.inject(MyMetaStore, storeInstance);
51305
51323
  const cellId = row.cells[i];
51306
51324
  if (cellId) {
51307
51325
  if (dimension === "rows" || colIndex >= addedElement) {
51308
- commands.push({
51309
- type: "UPDATE_CELL_POSITION",
51326
+ updates.push({
51310
51327
  sheetId: sheet.id,
51311
51328
  cellId: cellId,
51312
51329
  col: colIndex + (dimension === "columns" ? quantity : 0),
51313
51330
  row: rowIndex + (dimension === "rows" ? quantity : 0),
51331
+ type: "UPDATE_CELL_POSITION",
51314
51332
  });
51315
51333
  }
51316
51334
  }
51317
51335
  }
51318
51336
  }
51319
51337
  }
51320
- for (let cmd of commands.reverse()) {
51321
- this.dispatch(cmd.type, cmd);
51338
+ for (let update of updates.reverse()) {
51339
+ this.updateCellPosition(update);
51322
51340
  }
51323
51341
  }
51324
51342
  /**
@@ -51351,12 +51369,7 @@ stores.inject(MyMetaStore, storeInstance);
51351
51369
  const colIndex = Number(i);
51352
51370
  const cellId = row.cells[i];
51353
51371
  if (cellId) {
51354
- this.dispatch("UPDATE_CELL_POSITION", {
51355
- sheetId: sheet.id,
51356
- cellId: cellId,
51357
- col: colIndex,
51358
- row: rowIndex - numberRows,
51359
- });
51372
+ this.setNewPosition(cellId, sheet.id, colIndex, rowIndex - numberRows);
51360
51373
  }
51361
51374
  }
51362
51375
  }
@@ -54122,6 +54135,9 @@ stores.inject(MyMetaStore, storeInstance);
54122
54135
  if (!this.blockedArrayFormulas.has(position)) {
54123
54136
  this.invalidateSpreading(position);
54124
54137
  }
54138
+ if (this.spreadingRelations.isArrayFormula(position)) {
54139
+ this.spreadingRelations.removeNode(position);
54140
+ }
54125
54141
  const cell = this.getters.getCell(position);
54126
54142
  if (cell === undefined) {
54127
54143
  return EMPTY_CELL;
@@ -54164,7 +54180,6 @@ stores.inject(MyMetaStore, storeInstance);
54164
54180
  this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
54165
54181
  const nbColumns = formulaReturn.length;
54166
54182
  const nbRows = formulaReturn[0].length;
54167
- this.spreadingRelations.removeNode(formulaPosition);
54168
54183
  forEachSpreadPositionInMatrix(nbColumns, nbRows, this.updateSpreadRelation(formulaPosition));
54169
54184
  this.assertNoMergedCellsInSpreadZone(formulaPosition, formulaReturn);
54170
54185
  forEachSpreadPositionInMatrix(nbColumns, nbRows, this.checkCollision(formulaPosition));
@@ -63089,6 +63104,8 @@ stores.inject(MyMetaStore, storeInstance);
63089
63104
 
63090
63105
  .o-sidePanel-handle-container {
63091
63106
  width: 8px;
63107
+ position: fixed;
63108
+ top: 50%;
63092
63109
  }
63093
63110
  .o-sidePanel-handle {
63094
63111
  cursor: col-resize;
@@ -65708,7 +65725,7 @@ stores.inject(MyMetaStore, storeInstance);
65708
65725
  }
65709
65726
 
65710
65727
  class StateObserver {
65711
- changes = [];
65728
+ changes;
65712
65729
  commands = [];
65713
65730
  /**
65714
65731
  * Record the changes which could happen in the given callback, save them in a
@@ -65740,7 +65757,7 @@ stores.inject(MyMetaStore, storeInstance);
65740
65757
  if (value[key] === val) {
65741
65758
  return;
65742
65759
  }
65743
- this.changes.push({
65760
+ this.changes?.push({
65744
65761
  key,
65745
65762
  target: value,
65746
65763
  before: value[key],
@@ -68406,9 +68423,9 @@ stores.inject(MyMetaStore, storeInstance);
68406
68423
  exports.tokenize = tokenize;
68407
68424
 
68408
68425
 
68409
- __info__.version = "17.4.2";
68410
- __info__.date = "2024-07-24T10:26:00.237Z";
68411
- __info__.hash = "f5ede5b";
68426
+ __info__.version = "17.4.3";
68427
+ __info__.date = "2024-08-02T08:23:56.573Z";
68428
+ __info__.hash = "40ecd1e";
68412
68429
 
68413
68430
 
68414
68431
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);