@odoo/o-spreadsheet 19.4.4 → 19.4.6

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 19.4.4
6
- * @date 2026-07-23T07:49:22.265Z
7
- * @hash 6b3c312
5
+ * @version 19.4.6
6
+ * @date 2026-08-10T12:33:32.728Z
7
+ * @hash 5c667fe
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -349,6 +349,19 @@ _odoo_owl = __toESM(_odoo_owl, 1);
349
349
  function isMobileOS() {
350
350
  return isAndroid() || isIOS() || isOtherMobileOS();
351
351
  }
352
+ const INTERACTIVE_ELEMENT_SELECTOR = "select, input, textarea, button, .o-select, .os-input, .o-input, .o-button, .o-button-icon, .o-button-link, .o-composer";
353
+ /** Check if there is an interactive element (input, select, button, ...) between the event.target and event.currentTarget (inclusive)*/
354
+ function hasInteractiveElementInEventTree(event) {
355
+ const target = event.target;
356
+ const root = event.currentTarget;
357
+ if (!root || !target || !root.contains(target)) return false;
358
+ let node = target;
359
+ while (node && node !== root) {
360
+ if (node.matches(INTERACTIVE_ELEMENT_SELECTOR)) return true;
361
+ node = node.parentElement;
362
+ }
363
+ return root.matches(INTERACTIVE_ELEMENT_SELECTOR);
364
+ }
352
365
 
353
366
  //#endregion
354
367
  //#region src/actions/action.ts
@@ -8904,6 +8917,25 @@ set(value) {
8904
8917
  };
8905
8918
  };
8906
8919
 
8920
+ //#endregion
8921
+ //#region src/components/figures/chart/chartJs/chartjs_geo_projection_plugin.ts
8922
+ /**
8923
+ * ChartJS plugin to apply custom changes to a d3 projection.
8924
+ *
8925
+ * We pass the projection as a string instead of a customized d3 object so
8926
+ * Chart.js creates a fresh projection instance. Custom changes (e.g. rotation)
8927
+ * are then applied in `beforeUpdate`.
8928
+ *
8929
+ * This is important because Chart.js mutates the projection instance at runtime,
8930
+ * and a customize d3 projection object would not be copied during deepCopy.
8931
+ */
8932
+ const geoProjectionPlugin = {
8933
+ id: "geoProjection",
8934
+ beforeUpdate(chart) {
8935
+ if (chart.options?.scales?.projection?.projection === "conicConformal") chart.scales?.projection?.projection?.rotate([100, 0]);
8936
+ }
8937
+ };
8938
+
8907
8939
  //#endregion
8908
8940
  //#region src/components/figures/chart/chartJs/chartjs_minor_grid_plugin.ts
8909
8941
  const chartMinorGridPlugin = {
@@ -10707,7 +10739,7 @@ set(value) {
10707
10739
  const format = axisFormats?.y || axisFormats?.y1;
10708
10740
  return {
10709
10741
  projection: {
10710
- projection: getGeoChartProjection(region?.defaultProjection || "mercator"),
10742
+ projection: region?.defaultProjection || "mercator",
10711
10743
  axis: "x"
10712
10744
  },
10713
10745
  color: {
@@ -10759,10 +10791,6 @@ set(value) {
10759
10791
  }
10760
10792
  };
10761
10793
  }
10762
- function getGeoChartProjection(projection) {
10763
- if (globalThis.ChartGeo && projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10764
- return projection;
10765
- }
10766
10794
  function getChartAxisTitleRuntime(design) {
10767
10795
  if (design?.title?.text) {
10768
10796
  const { text, color, align, italic, bold } = design.title;
@@ -10964,7 +10992,7 @@ set(value) {
10964
10992
  borderWidth: 1,
10965
10993
  barPercentage: 1,
10966
10994
  categoryPercentage: 1,
10967
- values: dataSetValues.data.map((cell) => isNumberResult(cell) ? cell.value : NaN)
10995
+ values: dataSetValues.data.map((cell) => isNumberResult(cell) ? cell.value : void 0)
10968
10996
  });
10969
10997
  return {
10970
10998
  labels,
@@ -11723,6 +11751,10 @@ set(value) {
11723
11751
  register: (Chart) => Chart.register(chartBackgroundPlugin),
11724
11752
  unregister: (Chart) => Chart.unregister(chartBackgroundPlugin)
11725
11753
  });
11754
+ chartJsExtensionRegistry.add("geoProjectionPlugin", {
11755
+ register: (Chart) => Chart.register(geoProjectionPlugin),
11756
+ unregister: (Chart) => Chart.unregister(geoProjectionPlugin)
11757
+ });
11726
11758
  var ChartJsComponent = class extends Component {
11727
11759
  static template = "o-spreadsheet-ChartJsComponent";
11728
11760
  props = (0, _odoo_owl.useProps)({
@@ -15572,7 +15604,7 @@ set(value) {
15572
15604
  figures.push({
15573
15605
  sheetId,
15574
15606
  figureId,
15575
- ...this.postionInBoundary(this.env.model.getters.getFigureUI(sheetId, figure), ev.key, ev.shiftKey)
15607
+ ...this.positionInBoundary(sheetId, this.env.model.getters.getFigureUI(sheetId, figure), ev.key, ev.shiftKey)
15576
15608
  });
15577
15609
  }
15578
15610
  this.env.model.dispatch("MOVE_FIGURES", { figures });
@@ -15592,21 +15624,23 @@ set(value) {
15592
15624
  break;
15593
15625
  }
15594
15626
  }
15595
- postionInBoundary(position, key, shift) {
15596
- const sheetId = this.env.model.getters.getActiveSheetId();
15627
+ positionInBoundary(sheetId, figure, key, shift) {
15597
15628
  const shiftAmount = shift ? 1 : 5;
15598
- let { col, row, offset } = position;
15629
+ let { col, row, offset } = figure;
15599
15630
  offset = { ...offset };
15631
+ const maxAnchor = this.env.model.getters.getMaxAnchorOffset(sheetId, figure.height, figure.width);
15600
15632
  switch (key) {
15601
15633
  case "ArrowUp":
15602
15634
  if (offset.y < shiftAmount) {
15603
15635
  row--;
15636
+ while (row > 0 && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row--;
15604
15637
  offset.y = this.env.model.getters.getRowSize(sheetId, row) - shiftAmount + offset.y;
15605
15638
  } else offset.y -= shiftAmount;
15606
15639
  break;
15607
15640
  case "ArrowLeft":
15608
15641
  if (offset.x < shiftAmount) {
15609
15642
  col--;
15643
+ while (col > 0 && this.env.model.getters.isColHiddenByUser(sheetId, col)) col--;
15610
15644
  offset.x = this.env.model.getters.getColSize(sheetId, col) - shiftAmount + offset.x;
15611
15645
  } else offset.x -= shiftAmount;
15612
15646
  break;
@@ -15614,6 +15648,7 @@ set(value) {
15614
15648
  const rowSize = this.env.model.getters.getRowSize(sheetId, row);
15615
15649
  if (offset.y + shiftAmount >= rowSize) {
15616
15650
  row++;
15651
+ while (row <= maxAnchor.row && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row++;
15617
15652
  offset.y = offset.y + shiftAmount - rowSize;
15618
15653
  } else offset.y += shiftAmount;
15619
15654
  break;
@@ -15621,9 +15656,24 @@ set(value) {
15621
15656
  const colSize = this.env.model.getters.getColSize(sheetId, col);
15622
15657
  if (offset.x + shiftAmount >= colSize) {
15623
15658
  col++;
15659
+ while (col <= maxAnchor.col && this.env.model.getters.isColHiddenByUser(sheetId, col)) col++;
15624
15660
  offset.x = offset.x + shiftAmount - colSize;
15625
15661
  } else offset.x += shiftAmount;
15626
15662
  }
15663
+ if (col < 0) {
15664
+ col = 0;
15665
+ offset.x = 0;
15666
+ } else if (col > maxAnchor.col || col === maxAnchor.col && offset.x > maxAnchor.offset.x) {
15667
+ col = maxAnchor.col;
15668
+ offset.x = maxAnchor.offset.x;
15669
+ }
15670
+ if (row < 0) {
15671
+ row = 0;
15672
+ offset.y = 0;
15673
+ } else if (row > maxAnchor.row || row === maxAnchor.row && offset.y > maxAnchor.offset.y) {
15674
+ row = maxAnchor.row;
15675
+ offset.y = maxAnchor.offset.y;
15676
+ }
15627
15677
  return {
15628
15678
  col,
15629
15679
  row,
@@ -39316,13 +39366,9 @@ set(value) {
39316
39366
  dimensionsRef = (0, _odoo_owl.signal)(null);
39317
39367
  dragAndDrop = useDragAndDropListItems();
39318
39368
  AGGREGATORS = AGGREGATORS;
39319
- composerFocus;
39320
39369
  isDateOrDatetimeField = isDateOrDatetimeField;
39321
- setup() {
39322
- this.composerFocus = useStore(ComposerFocusStore);
39323
- }
39324
39370
  startDragAndDrop(dimension, event) {
39325
- if (event.button !== 0 || event.target.tagName === "SELECT") return;
39371
+ if (event.button !== 0 || hasInteractiveElementInEventTree(event)) return;
39326
39372
  const rects = this.getDimensionElementsRects();
39327
39373
  const { columns, rows } = this.props.definition;
39328
39374
  const draggableIds = [
@@ -39362,7 +39408,7 @@ set(value) {
39362
39408
  return field.type === "date" ? this.props.dateGranularities : this.props.datetimeGranularities;
39363
39409
  }
39364
39410
  startDragAndDropMeasures(measure, event) {
39365
- if (event.button !== 0 || event.target.tagName === "SELECT" || event.target.tagName === "INPUT" || this.composerFocus.focusMode !== "inactive") return;
39411
+ if (event.button !== 0 || hasInteractiveElementInEventTree(event)) return;
39366
39412
  const rects = this.getDimensionElementsRects();
39367
39413
  const { measures, columns, rows } = this.props.definition;
39368
39414
  const draggableIds = measures.map((m) => m.id);
@@ -46013,7 +46059,13 @@ set(value) {
46013
46059
  const cell = this.getters.getEvaluatedCell(position);
46014
46060
  if (cell.link && !isFormula(content)) content = markdownLink(content, cell.link.url);
46015
46061
  const currentFormat = this.getters.getCell(position)?.format;
46016
- const afterFormat = currentFormat === "@" || currentFormat && isDateTimeFormat(currentFormat) ? void 0 : detectDateFormat(content, this.getters.getLocale());
46062
+ const isCurrentFormatDate = currentFormat && isDateTimeFormat(currentFormat);
46063
+ const contentDateFormat = detectDateFormat(content, this.getters.getLocale());
46064
+ let afterFormat;
46065
+ if (currentFormat !== "@") {
46066
+ if (contentDateFormat && !isCurrentFormatDate) afterFormat = contentDateFormat;
46067
+ else if (isCurrentFormatDate && isNumber(content, this.getters.getLocale())) afterFormat = "";
46068
+ }
46017
46069
  this.addHeadersForSpreadingFormula(content);
46018
46070
  result = this.model.dispatch("UPDATE_CELL", {
46019
46071
  ...this.currentEditedCell,
@@ -51720,7 +51772,7 @@ set(value) {
51720
51772
  positionsByStyle[styleId] ??= [];
51721
51773
  positionsByStyle[styleId].push(position);
51722
51774
  }
51723
- if (cell.format) {
51775
+ if (cell.format !== void 0) {
51724
51776
  const formatId = getItemId(cell.format, formats);
51725
51777
  positionsByFormat[formatId] ??= [];
51726
51778
  positionsByFormat[formatId].push(position);
@@ -52897,22 +52949,19 @@ set(value) {
52897
52949
  getDefaultFormatInCell(sheetId, zones, priorities) {
52898
52950
  const defaults = [];
52899
52951
  for (const position of zones.flatMap((zone) => cellPositions(sheetId, zone))) {
52900
- if (this.getters.getCell(position)?.format) continue;
52952
+ if (this.getters.getCell(position)?.format !== void 0) continue;
52901
52953
  const rowDefault = this.format[sheetId]?.rowDefault?.[position.row];
52902
- if (rowDefault) {
52954
+ if (rowDefault !== void 0) {
52903
52955
  if (priorities.shouldUseDefaultRow) defaults.push([position, rowDefault]);
52904
52956
  continue;
52905
52957
  }
52906
52958
  const colDefault = this.format[sheetId]?.colDefault?.[position.col];
52907
- if (colDefault) {
52959
+ if (colDefault !== void 0) {
52908
52960
  if (priorities.shouldUseDefaultCol) defaults.push([position, colDefault]);
52909
52961
  continue;
52910
52962
  }
52911
- const sheetDefault = this.format[sheetId]?.sheetDefault;
52912
- if (sheetDefault) {
52913
- if (priorities.shouldUseDefaultSheet) defaults.push([position, sheetDefault]);
52914
- continue;
52915
- }
52963
+ const sheetDefault = this.format[sheetId]?.sheetDefault ?? "";
52964
+ if (priorities.shouldUseDefaultSheet) defaults.push([position, sheetDefault]);
52916
52965
  }
52917
52966
  return defaults;
52918
52967
  }
@@ -64321,7 +64370,7 @@ set(value) {
64321
64370
  if (contentWidth === 0) return 0;
64322
64371
  contentWidth += 2 * 4;
64323
64372
  if (style.wrapping === "wrap") {
64324
- const colWidth = this.getters.getColSize(this.getters.getActiveSheetId(), position.col);
64373
+ const colWidth = this.getters.getColSize(position.sheetId, position.col);
64325
64374
  return Math.min(colWidth, contentWidth);
64326
64375
  }
64327
64376
  return contentWidth;
@@ -67687,6 +67736,10 @@ set(value) {
67687
67736
  }
67688
67737
  function inverseCreateChart(cmd) {
67689
67738
  return [{
67739
+ type: "DELETE_CHART",
67740
+ chartId: cmd.chartId,
67741
+ sheetId: cmd.sheetId
67742
+ }, {
67690
67743
  type: "DELETE_FIGURE",
67691
67744
  figureId: cmd.figureId,
67692
67745
  sheetId: cmd.sheetId
@@ -69564,6 +69617,7 @@ set(value) {
69564
69617
  return (0, _odoo_owl.toRaw)(this.clickableCellsStore.clickableCells);
69565
69618
  }
69566
69619
  selectClickableCell(ev, clickableCell) {
69620
+ if (![0, 1].includes(ev.button)) return;
69567
69621
  const { position, action } = clickableCell;
69568
69622
  action(position, this.env, isMiddleClickOrCtrlClick(ev));
69569
69623
  }
@@ -87522,7 +87576,8 @@ set(value) {
87522
87576
  FullScreenFigure,
87523
87577
  NumberInput,
87524
87578
  TopBar,
87525
- Composer
87579
+ Composer,
87580
+ CarouselFigure
87526
87581
  };
87527
87582
  const hooks = {
87528
87583
  useDragAndDropListItems,
@@ -87676,8 +87731,8 @@ exports.stores = stores;
87676
87731
  exports.tokenColors = tokenColors;
87677
87732
  exports.tokenize = tokenize;
87678
87733
 
87679
- __info__.version = "19.4.4";
87680
- __info__.date = "2026-07-23T07:49:22.265Z";
87681
- __info__.hash = "6b3c312";
87734
+ __info__.version = "19.4.6";
87735
+ __info__.date = "2026-08-10T12:33:32.728Z";
87736
+ __info__.hash = "5c667fe";
87682
87737
 
87683
87738
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);