@odoo/o-spreadsheet 16.2.14 → 16.2.16

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.
@@ -987,13 +987,17 @@ function getAddHeaderStartIndex(position, base) {
987
987
  return position === "after" ? base + 1 : base;
988
988
  }
989
989
  /**
990
- * Compare two objects.
990
+ * Compares two objects.
991
991
  */
992
992
  function deepEquals(o1, o2) {
993
993
  if (o1 === o2)
994
994
  return true;
995
995
  if ((o1 && !o2) || (o2 && !o1))
996
996
  return false;
997
+ if (typeof o1 !== typeof o2)
998
+ return false;
999
+ if (typeof o1 !== "object")
1000
+ return o1 === o2;
997
1001
  // Objects can have different keys if the values are undefined
998
1002
  const keys = new Set();
999
1003
  Object.keys(o1).forEach((key) => keys.add(key));
@@ -4679,6 +4683,7 @@ css /* scss */ `
4679
4683
  padding: 10px;
4680
4684
  width: ${ERROR_TOOLTIP_WIDTH}px;
4681
4685
  box-sizing: border-box !important;
4686
+ overflow-wrap: break-word;
4682
4687
  }
4683
4688
  `;
4684
4689
  class ErrorToolTip extends Component {
@@ -7241,6 +7246,7 @@ class LineChart extends AbstractChart {
7241
7246
  this.labelsAsText = definition.labelsAsText;
7242
7247
  this.stacked = definition.stacked;
7243
7248
  this.aggregated = definition.aggregated;
7249
+ this.cumulative = definition.cumulative;
7244
7250
  }
7245
7251
  static validateChartDefinition(validator, definition) {
7246
7252
  return validator.checkValidations(definition, checkDataset, checkLabelRange);
@@ -7261,6 +7267,7 @@ class LineChart extends AbstractChart {
7261
7267
  labelRange: context.auxiliaryRange || undefined,
7262
7268
  stacked: false,
7263
7269
  aggregated: false,
7270
+ cumulative: false,
7264
7271
  };
7265
7272
  }
7266
7273
  getDefinition() {
@@ -7281,6 +7288,7 @@ class LineChart extends AbstractChart {
7281
7288
  labelsAsText: this.labelsAsText,
7282
7289
  stacked: this.stacked,
7283
7290
  aggregated: this.aggregated,
7291
+ cumulative: this.cumulative,
7284
7292
  };
7285
7293
  }
7286
7294
  getContextCreation() {
@@ -7484,6 +7492,16 @@ function createLineChartRuntime(chart, getters) {
7484
7492
  if (chart.stacked) {
7485
7493
  backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
7486
7494
  }
7495
+ if (chart.cumulative) {
7496
+ let accumulator = 0;
7497
+ data = data.map((value) => {
7498
+ if (!isNaN(value)) {
7499
+ accumulator += parseFloat(value);
7500
+ return accumulator;
7501
+ }
7502
+ return value;
7503
+ });
7504
+ }
7487
7505
  const backgroundColor = rgbaToHex(backgroundRGBA);
7488
7506
  const dataset = {
7489
7507
  label,
@@ -8266,6 +8284,7 @@ function getSmartChartDefinition(zone, getters) {
8266
8284
  labelsAsText: false,
8267
8285
  stacked: false,
8268
8286
  aggregated: false,
8287
+ cumulative: false,
8269
8288
  labelRange: labelRangeXc,
8270
8289
  type: "line",
8271
8290
  dataSetsHaveTitle,
@@ -8628,6 +8647,13 @@ const REMOVE_ROWS_ACTION = (env) => {
8628
8647
  elements: rows,
8629
8648
  });
8630
8649
  };
8650
+ const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
8651
+ const sheetId = env.model.getters.getActiveSheetId();
8652
+ const selectedElements = env.model.getters.getElementsFromSelection(dimension);
8653
+ const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
8654
+ const includesAllNonFrozenHeaders = env.model.getters.checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, selectedElements);
8655
+ return !includesAllVisibleHeaders && !includesAllNonFrozenHeaders;
8656
+ };
8631
8657
  const REMOVE_COLUMNS_NAME = (env) => {
8632
8658
  if (env.model.getters.getSelectedZones().length > 1) {
8633
8659
  return _lt("Delete columns");
@@ -9218,11 +9244,7 @@ colMenuRegistry
9218
9244
  name: REMOVE_COLUMNS_NAME,
9219
9245
  sequence: 90,
9220
9246
  action: REMOVE_COLUMNS_ACTION,
9221
- isVisible: (env) => {
9222
- const sheetId = env.model.getters.getActiveSheetId();
9223
- const selectedCols = env.model.getters.getElementsFromSelection("COL");
9224
- return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
9225
- },
9247
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("COL", env),
9226
9248
  })
9227
9249
  .add("clear_column", {
9228
9250
  name: DELETE_CONTENT_COLUMNS_NAME,
@@ -9236,7 +9258,7 @@ colMenuRegistry
9236
9258
  isVisible: (env) => {
9237
9259
  const sheetId = env.model.getters.getActiveSheetId();
9238
9260
  const selectedCols = env.model.getters.getElementsFromSelection("COL");
9239
- return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
9261
+ return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "COL", selectedCols);
9240
9262
  },
9241
9263
  separator: true,
9242
9264
  })
@@ -9310,11 +9332,7 @@ rowMenuRegistry
9310
9332
  name: REMOVE_ROWS_NAME,
9311
9333
  sequence: 70,
9312
9334
  action: REMOVE_ROWS_ACTION,
9313
- isVisible: (env) => {
9314
- const sheetId = env.model.getters.getActiveSheetId();
9315
- const selectedRows = env.model.getters.getElementsFromSelection("ROW");
9316
- return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
9317
- },
9335
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("ROW", env),
9318
9336
  })
9319
9337
  .add("clear_row", {
9320
9338
  name: DELETE_CONTENT_ROWS_NAME,
@@ -9328,7 +9346,7 @@ rowMenuRegistry
9328
9346
  isVisible: (env) => {
9329
9347
  const sheetId = env.model.getters.getActiveSheetId();
9330
9348
  const selectedRows = env.model.getters.getElementsFromSelection("ROW");
9331
- return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
9349
+ return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "ROW", selectedRows);
9332
9350
  },
9333
9351
  separator: true,
9334
9352
  })
@@ -16174,11 +16192,13 @@ topbarMenuRegistry
16174
16192
  name: REMOVE_ROWS_NAME,
16175
16193
  sequence: 80,
16176
16194
  action: REMOVE_ROWS_ACTION,
16195
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("ROW", env),
16177
16196
  })
16178
16197
  .addChild("edit_delete_column", ["edit"], {
16179
16198
  name: REMOVE_COLUMNS_NAME,
16180
16199
  sequence: 90,
16181
16200
  action: REMOVE_COLUMNS_ACTION,
16201
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("COL", env),
16182
16202
  })
16183
16203
  .addChild("edit_delete_cell_shift_up", ["edit"], {
16184
16204
  name: _lt("Delete cell and shift up"),
@@ -17491,6 +17511,11 @@ class LineConfigPanel extends LineBarPieConfigPanel {
17491
17511
  aggregated: ev.target.checked,
17492
17512
  });
17493
17513
  }
17514
+ onUpdateCumulative(ev) {
17515
+ this.props.updateChart(this.props.figureId, {
17516
+ cumulative: ev.target.checked,
17517
+ });
17518
+ }
17494
17519
  }
17495
17520
  LineConfigPanel.template = "o-spreadsheet-LineConfigPanel";
17496
17521
 
@@ -20850,9 +20875,11 @@ function useCellHovered(env, gridRef, callback) {
20850
20875
  }
20851
20876
  }
20852
20877
  function updateMousePosition(e) {
20853
- x = e.offsetX;
20854
- y = e.offsetY;
20855
- lastMoved = Date.now();
20878
+ if (gridRef.el === e.target) {
20879
+ x = e.offsetX;
20880
+ y = e.offsetY;
20881
+ lastMoved = Date.now();
20882
+ }
20856
20883
  }
20857
20884
  function recompute() {
20858
20885
  const { col, row } = getPosition();
@@ -24965,6 +24992,7 @@ function convertChartData(chartData) {
24965
24992
  legendPosition: chartData.legendPosition,
24966
24993
  stacked: chartData.stacked || false,
24967
24994
  aggregated: false,
24995
+ cumulative: chartData.cumulative || false,
24968
24996
  labelsAsText: false,
24969
24997
  };
24970
24998
  }
@@ -29619,7 +29647,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
29619
29647
  if (!this.getters.tryGetSheet(cmd.sheetId)) {
29620
29648
  return 27 /* CommandResult.InvalidSheetId */;
29621
29649
  }
29622
- if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
29650
+ if (this.checkElementsIncludeAllVisibleHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
29623
29651
  return 8 /* CommandResult.NotEnoughElements */;
29624
29652
  }
29625
29653
  return 0 /* CommandResult.Success */;
@@ -29669,9 +29697,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
29669
29697
  }
29670
29698
  return;
29671
29699
  }
29672
- canRemoveHeaders(sheetId, dimension, elements) {
29700
+ checkElementsIncludeAllVisibleHeaders(sheetId, dimension, elements) {
29673
29701
  const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
29674
- return !includesAll(elements, visibleHeaders);
29702
+ return includesAll(elements, visibleHeaders);
29675
29703
  }
29676
29704
  isRowHiddenByUser(sheetId, index) {
29677
29705
  return this.hiddenHeaders[sheetId].ROW[index];
@@ -29767,7 +29795,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
29767
29795
  }
29768
29796
  }
29769
29797
  HeaderVisibilityPlugin.getters = [
29770
- "canRemoveHeaders",
29798
+ "checkElementsIncludeAllVisibleHeaders",
29771
29799
  "getHiddenColsGroups",
29772
29800
  "getHiddenRowsGroups",
29773
29801
  "isRowHiddenByUser",
@@ -30804,6 +30832,9 @@ class SheetPlugin extends CorePlugin {
30804
30832
  if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
30805
30833
  return 86 /* CommandResult.InvalidHeaderIndex */;
30806
30834
  }
30835
+ else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
30836
+ return 8 /* CommandResult.NotEnoughElements */;
30837
+ }
30807
30838
  else {
30808
30839
  return 0 /* CommandResult.Success */;
30809
30840
  }
@@ -31090,6 +31121,20 @@ class SheetPlugin extends CorePlugin {
31090
31121
  }
31091
31122
  this.history.update("sheets", sheetId, "panes", panes);
31092
31123
  }
31124
+ /**
31125
+ * Checks if all non-frozen header indices are present in the provided elements of selected rows/columns.
31126
+ * This validation ensures that all rows or columns cannot be deleted when frozen panes exist.
31127
+ */
31128
+ checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, elements) {
31129
+ const paneDivisions = this.getters.getPaneDivisions(sheetId);
31130
+ const startIndex = dimension === "ROW" ? paneDivisions.ySplit : paneDivisions.xSplit;
31131
+ const endIndex = this.getters.getNumberHeaders(sheetId, dimension);
31132
+ if (!startIndex) {
31133
+ return false;
31134
+ }
31135
+ const indicesToCheck = range(startIndex, endIndex);
31136
+ return includesAll(elements, indicesToCheck);
31137
+ }
31093
31138
  // ---------------------------------------------------------------------------
31094
31139
  // Row/Col manipulation
31095
31140
  // ---------------------------------------------------------------------------
@@ -31618,6 +31663,7 @@ SheetPlugin.getters = [
31618
31663
  "getSheetSize",
31619
31664
  "getSheetZone",
31620
31665
  "getPaneDivisions",
31666
+ "checkElementsIncludeAllNonFrozenHeaders",
31621
31667
  ];
31622
31668
 
31623
31669
  /**
@@ -32184,6 +32230,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32184
32230
  // stores the computed styles in the format of computedStyles.sheetName[col][row] = Style
32185
32231
  this.computedStyles = {};
32186
32232
  this.computedIcons = {};
32233
+ this.uuidGenerator = new UuidGenerator();
32187
32234
  /**
32188
32235
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
32189
32236
  */
@@ -32536,13 +32583,20 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32536
32583
  this.adaptRules(origin.sheetId, cf, [xc], toRemoveRange);
32537
32584
  }
32538
32585
  else {
32539
- this.adaptRules(target.sheetId, cf, [xc], []);
32540
32586
  this.adaptRules(origin.sheetId, cf, [], toRemoveRange);
32587
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
32588
+ this.adaptRules(target.sheetId, cfToCopyTo, [xc], []);
32541
32589
  }
32542
32590
  }
32543
32591
  }
32544
32592
  }
32545
32593
  }
32594
+ getCFToCopyTo(targetSheetId, originCF) {
32595
+ const cfInTarget = this.getters
32596
+ .getConditionalFormats(targetSheetId)
32597
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
32598
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
32599
+ }
32546
32600
  }
32547
32601
  EvaluationConditionalFormatPlugin.getters = ["getConditionalIcon", "getCellComputedStyle"];
32548
32602
 
@@ -33064,6 +33118,9 @@ class InternalViewport {
33064
33118
  const sheetId = this.sheetId;
33065
33119
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
33066
33120
  this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
33121
+ if (this.left === -1) {
33122
+ this.left = this.boundaries.left;
33123
+ }
33067
33124
  if (this.right === -1) {
33068
33125
  this.right = this.getters.getNumberCols(sheetId) - 1;
33069
33126
  }
@@ -33077,6 +33134,9 @@ class InternalViewport {
33077
33134
  const sheetId = this.sheetId;
33078
33135
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
33079
33136
  this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
33137
+ if (this.top === -1) {
33138
+ this.top = this.boundaries.top;
33139
+ }
33080
33140
  if (this.bottom === -1) {
33081
33141
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
33082
33142
  }
@@ -37998,7 +38058,7 @@ class ClipboardPlugin extends UIPlugin {
37998
38058
  allowDispatch(cmd) {
37999
38059
  switch (cmd.type) {
38000
38060
  case "CUT":
38001
- const zones = cmd.target || this.getters.getSelectedZones();
38061
+ const zones = this.getters.getSelectedZones();
38002
38062
  const state = this.getClipboardState(zones, cmd.type);
38003
38063
  return state.isCutAllowed(zones);
38004
38064
  case "PASTE":
@@ -38029,7 +38089,7 @@ class ClipboardPlugin extends UIPlugin {
38029
38089
  switch (cmd.type) {
38030
38090
  case "COPY":
38031
38091
  case "CUT":
38032
- const zones = ("target" in cmd && cmd.target) || this.getters.getSelectedZones();
38092
+ const zones = this.getters.getSelectedZones();
38033
38093
  this.state = this.getClipboardState(zones, cmd.type);
38034
38094
  this.status = "visible";
38035
38095
  break;
@@ -39409,26 +39469,24 @@ class GridSelectionPlugin extends UIPlugin {
39409
39469
  const isBasedBefore = cmd.base < start;
39410
39470
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
39411
39471
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
39412
- this.dispatch("CUT", {
39413
- target: [
39414
- {
39415
- left: isCol ? start + deltaCol : 0,
39416
- right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
39417
- top: !isCol ? start + deltaRow : 0,
39418
- bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
39419
- },
39420
- ],
39421
- });
39422
- this.dispatch("PASTE", {
39423
- target: [
39424
- {
39425
- left: isCol ? cmd.base : 0,
39426
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39427
- top: !isCol ? cmd.base : 0,
39428
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39429
- },
39430
- ],
39431
- });
39472
+ const target = [
39473
+ {
39474
+ left: isCol ? start + deltaCol : 0,
39475
+ right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
39476
+ top: !isCol ? start + deltaRow : 0,
39477
+ bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
39478
+ },
39479
+ ];
39480
+ const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39481
+ const pasteTarget = [
39482
+ {
39483
+ left: isCol ? cmd.base : 0,
39484
+ right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39485
+ top: !isCol ? cmd.base : 0,
39486
+ bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39487
+ },
39488
+ ];
39489
+ state.paste(pasteTarget, { selectTarget: true });
39432
39490
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
39433
39491
  let currentIndex = cmd.base;
39434
39492
  for (const element of toRemove) {
@@ -45368,6 +45426,6 @@ function addFunction(functionName, functionDescription) {
45368
45426
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
45369
45427
 
45370
45428
 
45371
- __info__.version = '16.2.14';
45372
- __info__.date = '2023-08-29T13:54:14.962Z';
45373
- __info__.hash = 'ad037b1';
45429
+ __info__.version = '16.2.16';
45430
+ __info__.date = '2023-09-21T15:56:53.639Z';
45431
+ __info__.hash = '1a70819';