@odoo/o-spreadsheet 18.3.9 → 18.3.11

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.3.9
6
- * @date 2025-06-19T18:24:02.754Z
7
- * @hash a820230
5
+ * @version 18.3.11
6
+ * @date 2025-06-27T09:13:07.206Z
7
+ * @hash 460d5d0
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -142,6 +142,7 @@
142
142
  const FROZEN_PANE_BORDER_COLOR = "#DADFE8";
143
143
  const COMPOSER_ASSISTANT_COLOR = "#9B359B";
144
144
  const COLOR_TRANSPARENT = "#00000000";
145
+ const TABLE_HOVER_BACKGROUND_COLOR = "#017E8414";
145
146
  const CHART_WATERFALL_POSITIVE_COLOR = "#4EA7F2";
146
147
  const CHART_WATERFALL_NEGATIVE_COLOR = "#EA6175";
147
148
  const CHART_WATERFALL_SUBTOTAL_COLOR = "#AAAAAA";
@@ -7121,6 +7122,63 @@
7121
7122
  };
7122
7123
  return osClipboardContent;
7123
7124
  }
7125
+ /**
7126
+ * Applies each clipboard handler to paste its corresponding data into the target.
7127
+ */
7128
+ const applyClipboardHandlersPaste = (handlers, copiedData, target, options) => {
7129
+ handlers.forEach(({ handlerName, handler }) => {
7130
+ const data = copiedData[handlerName];
7131
+ if (data) {
7132
+ handler.paste(target, data, options);
7133
+ }
7134
+ });
7135
+ };
7136
+ /**
7137
+ * Returns the paste target based on clipboard handlers.
7138
+ * Also includes the full affected zone and the list of pasted zones for selection.
7139
+ */
7140
+ function getPasteTargetFromHandlers(sheetId, zones, copiedData, handlers, options) {
7141
+ let zone = undefined;
7142
+ let selectedZones = [];
7143
+ let target = {
7144
+ sheetId,
7145
+ zones,
7146
+ };
7147
+ for (const { handlerName, handler } of handlers) {
7148
+ const handlerData = copiedData[handlerName];
7149
+ if (!handlerData) {
7150
+ continue;
7151
+ }
7152
+ const currentTarget = handler.getPasteTarget(sheetId, zones, handlerData, options);
7153
+ if (currentTarget.figureId) {
7154
+ target.figureId = currentTarget.figureId;
7155
+ }
7156
+ for (const targetZone of currentTarget.zones) {
7157
+ selectedZones.push(targetZone);
7158
+ if (zone === undefined) {
7159
+ zone = targetZone;
7160
+ continue;
7161
+ }
7162
+ zone = union(zone, targetZone);
7163
+ }
7164
+ }
7165
+ return {
7166
+ target,
7167
+ zone,
7168
+ selectedZones,
7169
+ };
7170
+ }
7171
+ /**
7172
+ * Updates the selection after a paste operation.
7173
+ */
7174
+ const selectPastedZone = (selection, sourceZones, pastedZones) => {
7175
+ const anchorCell = {
7176
+ col: sourceZones[0].left,
7177
+ row: sourceZones[0].top,
7178
+ };
7179
+ selection.getBackToDefault();
7180
+ selection.selectZone({ cell: anchorCell, zone: union(...pastedZones) }, { scrollIntoView: false });
7181
+ };
7124
7182
 
7125
7183
  class ClipboardHandler {
7126
7184
  getters;
@@ -23038,7 +23096,7 @@ stores.inject(MyMetaStore, storeInstance);
23038
23096
  }
23039
23097
  captureSelection(zone, col, row) {
23040
23098
  this.model.selection.capture(this, {
23041
- cell: { col: col || zone.left, row: row || zone.right },
23099
+ cell: { col: col ?? zone.left, row: row ?? zone.right },
23042
23100
  zone,
23043
23101
  }, {
23044
23102
  handleEvent: this.handleEvent.bind(this),
@@ -45799,6 +45857,9 @@ stores.inject(MyMetaStore, storeInstance);
45799
45857
  this.switchToList();
45800
45858
  }
45801
45859
  }
45860
+ else if (!this.editedCF) {
45861
+ this.switchToList();
45862
+ }
45802
45863
  });
45803
45864
  }
45804
45865
  get conditionalFormats() {
@@ -49822,7 +49883,7 @@ stores.inject(MyMetaStore, storeInstance);
49822
49883
  }
49823
49884
  getTypeFromZone(sheetId, zone) {
49824
49885
  const cells = this.getters.getEvaluatedCellsInZone(sheetId, zone);
49825
- const nonEmptyCells = cells.filter((cell) => cell.type !== CellValueType.empty);
49886
+ const nonEmptyCells = cells.filter((cell) => !(cell.type === CellValueType.empty || cell.value === ""));
49826
49887
  if (nonEmptyCells.length === 0) {
49827
49888
  return "integer";
49828
49889
  }
@@ -53539,15 +53600,16 @@ stores.inject(MyMetaStore, storeInstance);
53539
53600
  }
53540
53601
  }
53541
53602
 
53603
+ const PAINT_FORMAT_HANDLER_KEYS = [
53604
+ "cell",
53605
+ "border",
53606
+ "table",
53607
+ "conditionalFormat",
53608
+ "merge",
53609
+ ];
53542
53610
  class PaintFormatStore extends SpreadsheetStore {
53543
53611
  mutators = ["activate", "cancel", "pasteFormat"];
53544
53612
  highlightStore = this.get(HighlightStore);
53545
- clipboardHandlers = [
53546
- new CellClipboardHandler(this.getters, this.model.dispatch),
53547
- new BorderClipboardHandler(this.getters, this.model.dispatch),
53548
- new TableClipboardHandler(this.getters, this.model.dispatch),
53549
- new ConditionalFormatClipboardHandler(this.getters, this.model.dispatch),
53550
- ];
53551
53613
  status = "inactive";
53552
53614
  copiedData;
53553
53615
  constructor(get) {
@@ -53578,24 +53640,38 @@ stores.inject(MyMetaStore, storeInstance);
53578
53640
  get isActive() {
53579
53641
  return this.status !== "inactive";
53580
53642
  }
53643
+ get clipboardHandlers() {
53644
+ return PAINT_FORMAT_HANDLER_KEYS.map((handlerName) => {
53645
+ const HandlerClass = clipboardHandlersRegistries.cellHandlers.get(handlerName);
53646
+ return {
53647
+ handlerName,
53648
+ handler: new HandlerClass(this.getters, this.model.dispatch),
53649
+ };
53650
+ });
53651
+ }
53581
53652
  copyFormats() {
53582
53653
  const sheetId = this.getters.getActiveSheetId();
53583
53654
  const zones = this.getters.getSelectedZones();
53584
- const copiedData = {};
53585
- for (const handler of this.clipboardHandlers) {
53586
- Object.assign(copiedData, handler.copy(getClipboardDataPositions(sheetId, zones), false));
53655
+ const copiedData = { zones, sheetId };
53656
+ for (const { handlerName, handler } of this.clipboardHandlers) {
53657
+ const handlerResult = handler.copy(getClipboardDataPositions(sheetId, zones), false);
53658
+ if (handlerResult !== undefined) {
53659
+ copiedData[handlerName] = handlerResult;
53660
+ }
53587
53661
  }
53588
53662
  return copiedData;
53589
53663
  }
53590
53664
  paintFormat(sheetId, target) {
53591
- if (this.copiedData) {
53592
- for (const handler of this.clipboardHandlers) {
53593
- handler.paste({ zones: target, sheetId }, this.copiedData, {
53594
- isCutOperation: false,
53595
- pasteOption: "onlyFormat",
53596
- });
53597
- }
53665
+ if (!this.copiedData) {
53666
+ return;
53598
53667
  }
53668
+ const options = {
53669
+ isCutOperation: false,
53670
+ pasteOption: "onlyFormat",
53671
+ };
53672
+ const { target: pasteTarget, selectedZones } = getPasteTargetFromHandlers(sheetId, target, this.copiedData, this.clipboardHandlers, options);
53673
+ applyClipboardHandlersPaste(this.clipboardHandlers, this.copiedData, pasteTarget, options);
53674
+ selectPastedZone(this.model.selection, target, selectedZones);
53599
53675
  if (this.status === "oneOff") {
53600
53676
  this.cancel();
53601
53677
  }
@@ -53642,12 +53718,8 @@ stores.inject(MyMetaStore, storeInstance);
53642
53718
  this.row = undefined;
53643
53719
  }
53644
53720
  computeOverlay() {
53645
- if (!this.getters.isDashboard()) {
53646
- return;
53647
- }
53648
53721
  this.overlayColors = new PositionMap();
53649
- const col = this.col;
53650
- const row = this.row;
53722
+ const { col, row } = this;
53651
53723
  if (col === undefined || row === undefined) {
53652
53724
  return;
53653
53725
  }
@@ -53656,9 +53728,16 @@ stores.inject(MyMetaStore, storeInstance);
53656
53728
  if (!table) {
53657
53729
  return;
53658
53730
  }
53659
- const { left, right } = table.range.zone;
53660
- for (let c = left; c <= right; c++) {
53661
- this.overlayColors.set({ sheetId, col: c, row }, setColorAlpha("#017E84", 0.08));
53731
+ const { left, right, top } = table.range.zone;
53732
+ const isTableHeader = row < top + table.config.numberOfHeaders;
53733
+ const doesTableRowHaveContent = range(left, right + 1).some((col) => {
53734
+ return (!this.getters.isColHidden(sheetId, col) &&
53735
+ this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
53736
+ });
53737
+ if (!isTableHeader && doesTableRowHaveContent) {
53738
+ for (let col = left; col <= right; col++) {
53739
+ this.overlayColors.set({ sheetId, col, row }, TABLE_HOVER_BACKGROUND_COLOR);
53740
+ }
53662
53741
  }
53663
53742
  }
53664
53743
  }
@@ -59005,7 +59084,7 @@ stores.inject(MyMetaStore, storeInstance);
59005
59084
  else if (newRule.criterion.type === "isValueInList") {
59006
59085
  newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
59007
59086
  }
59008
- const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
59087
+ const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules, newRule.id);
59009
59088
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
59010
59089
  if (ruleIndex !== -1) {
59011
59090
  adaptedRules[ruleIndex] = newRule;
@@ -59015,9 +59094,12 @@ stores.inject(MyMetaStore, storeInstance);
59015
59094
  this.history.update("rules", sheetId, [...adaptedRules, newRule]);
59016
59095
  }
59017
59096
  }
59018
- removeRangesFromRules(sheetId, ranges, rules) {
59097
+ removeRangesFromRules(sheetId, ranges, rules, editingRuleId) {
59019
59098
  rules = deepCopy(rules);
59020
59099
  for (const rule of rules) {
59100
+ if (rule.id === editingRuleId) {
59101
+ continue; // Skip the rule being edited to preserve its place in the list
59102
+ }
59021
59103
  rule.ranges = this.getters.recomputeRanges(rule.ranges, ranges);
59022
59104
  }
59023
59105
  return rules.filter((rule) => rule.ranges.length > 0);
@@ -70845,49 +70927,17 @@ stores.inject(MyMetaStore, storeInstance);
70845
70927
  if (!copiedData) {
70846
70928
  return;
70847
70929
  }
70848
- let zone = undefined;
70849
- let selectedZones = [];
70850
70930
  const sheetId = this.getters.getActiveSheetId();
70851
- let target = {
70852
- sheetId,
70853
- zones,
70854
- };
70855
70931
  const handlers = this.selectClipboardHandlers(copiedData);
70856
- for (const { handlerName, handler } of handlers) {
70857
- const handlerData = copiedData[handlerName];
70858
- if (!handlerData) {
70859
- continue;
70860
- }
70861
- const currentTarget = handler.getPasteTarget(sheetId, zones, handlerData, options);
70862
- if (currentTarget.figureId) {
70863
- target.figureId = currentTarget.figureId;
70864
- }
70865
- for (const targetZone of currentTarget.zones) {
70866
- selectedZones.push(targetZone);
70867
- if (zone === undefined) {
70868
- zone = targetZone;
70869
- continue;
70870
- }
70871
- zone = union(zone, targetZone);
70872
- }
70873
- }
70932
+ const { target, zone, selectedZones } = getPasteTargetFromHandlers(sheetId, zones, copiedData, handlers, options);
70874
70933
  if (zone !== undefined) {
70875
- this.addMissingDimensions(this.getters.getActiveSheetId(), zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
70934
+ this.addMissingDimensions(sheetId, zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
70876
70935
  }
70877
- handlers.forEach(({ handlerName, handler }) => {
70878
- const handlerData = copiedData[handlerName];
70879
- if (handlerData) {
70880
- handler.paste(target, handlerData, options);
70881
- }
70882
- });
70936
+ applyClipboardHandlersPaste(handlers, copiedData, target, options);
70883
70937
  if (!options?.selectTarget) {
70884
70938
  return;
70885
70939
  }
70886
- const selection = zones[0];
70887
- const col = selection.left;
70888
- const row = selection.top;
70889
- this.selection.getBackToDefault();
70890
- this.selection.selectZone({ cell: { col, row }, zone: union(...selectedZones) }, { scrollIntoView: false });
70940
+ selectPastedZone(this.selection, zones, selectedZones);
70891
70941
  }
70892
70942
  /**
70893
70943
  * Add columns and/or rows to ensure that col + width and row + height are still
@@ -77294,26 +77344,28 @@ stores.inject(MyMetaStore, storeInstance);
77294
77344
  bottom: Math.min(this.getters.getNumberRows(sheetId) - 1, bottom),
77295
77345
  };
77296
77346
  };
77297
- const { col: refCol, row: refRow } = this.getReferencePosition();
77347
+ const { cell: refCell, zone: refZone } = this.getReferenceAnchor();
77348
+ const { col: refCol, row: refRow } = refCell;
77298
77349
  // check if we can shrink selection
77299
77350
  let n = 0;
77300
77351
  while (result !== null) {
77301
77352
  n++;
77302
77353
  if (deltaCol < 0) {
77303
77354
  const newRight = this.getNextAvailableCol(deltaCol, right - (n - 1), refRow);
77304
- result = refCol <= right - n ? expand({ top, left, bottom, right: newRight }) : null;
77355
+ result = refZone.right <= right - n ? expand({ top, left, bottom, right: newRight }) : null;
77305
77356
  }
77306
77357
  if (deltaCol > 0) {
77307
77358
  const newLeft = this.getNextAvailableCol(deltaCol, left + (n - 1), refRow);
77308
- result = left + n <= refCol ? expand({ top, left: newLeft, bottom, right }) : null;
77359
+ result = left + n <= refZone.left ? expand({ top, left: newLeft, bottom, right }) : null;
77309
77360
  }
77310
77361
  if (deltaRow < 0) {
77311
77362
  const newBottom = this.getNextAvailableRow(deltaRow, refCol, bottom - (n - 1));
77312
- result = refRow <= bottom - n ? expand({ top, left, bottom: newBottom, right }) : null;
77363
+ result =
77364
+ refZone.bottom <= bottom - n ? expand({ top, left, bottom: newBottom, right }) : null;
77313
77365
  }
77314
77366
  if (deltaRow > 0) {
77315
77367
  const newTop = this.getNextAvailableRow(deltaRow, refCol, top + (n - 1));
77316
- result = top + n <= refRow ? expand({ top: newTop, left, bottom, right }) : null;
77368
+ result = top + n <= refZone.top ? expand({ top: newTop, left, bottom, right }) : null;
77317
77369
  }
77318
77370
  result = result ? reorderZone(result) : result;
77319
77371
  if (result && !isEqual(result, anchor.zone)) {
@@ -77543,18 +77595,26 @@ stores.inject(MyMetaStore, storeInstance);
77543
77595
  * If the anchor is hidden, browses from left to right and top to bottom to
77544
77596
  * find a visible cell.
77545
77597
  */
77546
- getReferencePosition() {
77598
+ getReferenceAnchor() {
77547
77599
  const sheetId = this.getters.getActiveSheetId();
77548
77600
  const anchor = this.anchor;
77549
77601
  const { left, right, top, bottom } = anchor.zone;
77550
77602
  const { col: anchorCol, row: anchorRow } = anchor.cell;
77603
+ const col = this.getters.isColHidden(sheetId, anchorCol)
77604
+ ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
77605
+ : anchorCol;
77606
+ const row = this.getters.isRowHidden(sheetId, anchorRow)
77607
+ ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
77608
+ : anchorRow;
77609
+ const zone = this.getters.expandZone(sheetId, {
77610
+ left: col,
77611
+ right: col,
77612
+ top: row,
77613
+ bottom: row,
77614
+ });
77551
77615
  return {
77552
- col: this.getters.isColHidden(sheetId, anchorCol)
77553
- ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
77554
- : anchorCol,
77555
- row: this.getters.isRowHidden(sheetId, anchorRow)
77556
- ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
77557
- : anchorRow,
77616
+ cell: { col, row },
77617
+ zone,
77558
77618
  };
77559
77619
  }
77560
77620
  deltaToTarget(position, direction, step) {
@@ -80710,9 +80770,9 @@ stores.inject(MyMetaStore, storeInstance);
80710
80770
  exports.tokenize = tokenize;
80711
80771
 
80712
80772
 
80713
- __info__.version = "18.3.9";
80714
- __info__.date = "2025-06-19T18:24:02.754Z";
80715
- __info__.hash = "a820230";
80773
+ __info__.version = "18.3.11";
80774
+ __info__.date = "2025-06-27T09:13:07.206Z";
80775
+ __info__.hash = "460d5d0";
80716
80776
 
80717
80777
 
80718
80778
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);