@odoo/o-spreadsheet 17.0.44 → 17.0.46

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.0.44
6
- * @date 2024-12-19T07:46:10.942Z
7
- * @hash 820f3cf
5
+ * @version 17.0.46
6
+ * @date 2025-01-27T10:00:20.499Z
7
+ * @hash 1df062c
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -2695,15 +2695,18 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
2695
2695
  let currentIndex;
2696
2696
  let currentVal;
2697
2697
  let currentType;
2698
+ const getValue = sortOrder === "desc"
2699
+ ? (i) => normalizeValue(getValueInData(data, rangeLength - i - 1))
2700
+ : (i) => normalizeValue(getValueInData(data, i));
2698
2701
  while (indexRight - indexLeft >= 0) {
2699
2702
  indexMedian = Math.floor((indexLeft + indexRight) / 2);
2700
2703
  currentIndex = indexMedian;
2701
- currentVal = normalizeValue(getValueInData(data, currentIndex));
2704
+ currentVal = getValue(currentIndex);
2702
2705
  currentType = typeof currentVal;
2703
2706
  // 1 - linear search to find value with the same type
2704
2707
  while (indexLeft < currentIndex && targetType !== currentType) {
2705
2708
  currentIndex--;
2706
- currentVal = normalizeValue(getValueInData(data, currentIndex));
2709
+ currentVal = getValue(currentIndex);
2707
2710
  currentType = typeof currentVal;
2708
2711
  }
2709
2712
  if (currentType !== targetType || currentVal === undefined || currentVal === null) {
@@ -2719,8 +2722,7 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
2719
2722
  if (matchVal === undefined ||
2720
2723
  matchVal === null ||
2721
2724
  matchVal < currentVal ||
2722
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
2723
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
2725
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
2724
2726
  matchVal = currentVal;
2725
2727
  matchValIndex = currentIndex;
2726
2728
  }
@@ -2728,15 +2730,13 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
2728
2730
  else if (mode === "nextGreater" && currentVal >= _target) {
2729
2731
  if (matchVal === undefined ||
2730
2732
  matchVal > currentVal ||
2731
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
2732
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
2733
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
2733
2734
  matchVal = currentVal;
2734
2735
  matchValIndex = currentIndex;
2735
2736
  }
2736
2737
  }
2737
2738
  // 3 - give new indexes for the Binary search
2738
- if ((sortOrder === "asc" && currentVal > _target) ||
2739
- (sortOrder === "desc" && currentVal <= _target)) {
2739
+ if (currentVal > _target || (mode === "strict" && currentVal === _target)) {
2740
2740
  indexRight = currentIndex - 1;
2741
2741
  }
2742
2742
  else {
@@ -2744,7 +2744,10 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
2744
2744
  }
2745
2745
  }
2746
2746
  // note that valMinIndex could be 0
2747
- return matchValIndex !== undefined ? matchValIndex : -1;
2747
+ if (matchValIndex === undefined) {
2748
+ return -1;
2749
+ }
2750
+ return sortOrder === "desc" ? rangeLength - matchValIndex - 1 : matchValIndex;
2748
2751
  }
2749
2752
  /**
2750
2753
  * Perform a linear search and return the index of the match.
@@ -6938,6 +6941,10 @@ class Popover extends Component {
6938
6941
  this.currentDisplayValue = newDisplay;
6939
6942
  if (!anchor)
6940
6943
  return;
6944
+ el.style.top = "";
6945
+ el.style.left = "";
6946
+ el.style["max-height"] = "";
6947
+ el.style["max-width"] = "";
6941
6948
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
6942
6949
  let elDims = {
6943
6950
  width: el.getBoundingClientRect().width,
@@ -27452,7 +27459,7 @@ class GridComposer extends Component {
27452
27459
  return;
27453
27460
  }
27454
27461
  const sheetId = this.env.model.getters.getActiveSheetId();
27455
- const zone = this.env.model.getters.getSelectedZone();
27462
+ const zone = positionToZone(this.env.model.getters.getSelection().anchor.cell);
27456
27463
  const rect = this.env.model.getters.getVisibleRect(zone);
27457
27464
  if (!deepEquals(rect, this.rect) ||
27458
27465
  sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
@@ -31733,7 +31740,7 @@ function convertFigure(figure, id, sheetData) {
31733
31740
  return undefined;
31734
31741
  }
31735
31742
  function isChartData(data) {
31736
- return "dataSets" in data;
31743
+ return "dataSets" in data && data.dataSets.length > 0;
31737
31744
  }
31738
31745
  function isImageData(data) {
31739
31746
  return "imageSrc" in data;
@@ -34547,10 +34554,34 @@ class BordersPlugin extends CorePlugin {
34547
34554
  const elements = [...cmd.elements].sort((a, b) => b - a);
34548
34555
  for (const group of groupConsecutive(elements)) {
34549
34556
  if (cmd.dimension === "COL") {
34550
- this.shiftBordersHorizontally(cmd.sheetId, group[group.length - 1] + 1, -group.length);
34557
+ if (group[0] >= this.getters.getNumberCols(cmd.sheetId)) {
34558
+ for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
34559
+ this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
34560
+ }
34561
+ }
34562
+ if (group[group.length - 1] === 0) {
34563
+ for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
34564
+ this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
34565
+ }
34566
+ }
34567
+ const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
34568
+ this.clearInsideBorders(cmd.sheetId, [zone]);
34569
+ this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
34551
34570
  }
34552
34571
  else {
34553
- this.shiftBordersVertically(cmd.sheetId, group[group.length - 1] + 1, -group.length);
34572
+ if (group[0] >= this.getters.getNumberRows(cmd.sheetId)) {
34573
+ for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
34574
+ this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
34575
+ }
34576
+ }
34577
+ if (group[group.length - 1] === 0) {
34578
+ for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
34579
+ this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
34580
+ }
34581
+ }
34582
+ const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
34583
+ this.clearInsideBorders(cmd.sheetId, [zone]);
34584
+ this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
34554
34585
  }
34555
34586
  }
34556
34587
  break;
@@ -34857,6 +34888,18 @@ class BordersPlugin extends CorePlugin {
34857
34888
  }
34858
34889
  }
34859
34890
  }
34891
+ /**
34892
+ * Remove the borders inside of a zone
34893
+ */
34894
+ clearInsideBorders(sheetId, zones) {
34895
+ for (let zone of zones) {
34896
+ for (let row = zone.top; row <= zone.bottom; row++) {
34897
+ for (let col = zone.left; col <= zone.right; col++) {
34898
+ this.history.update("borders", sheetId, col, row, undefined);
34899
+ }
34900
+ }
34901
+ }
34902
+ }
34860
34903
  /**
34861
34904
  * Add a border to the existing one to a cell
34862
34905
  */
@@ -46223,13 +46266,23 @@ class RendererPlugin extends UIPlugin {
46223
46266
  drawGrid(renderingContext, layer) {
46224
46267
  switch (layer) {
46225
46268
  case 0 /* LAYERS.Background */:
46226
- this.boxes = this.getGridBoxes();
46227
- this.drawBackground(renderingContext);
46228
- this.drawOverflowingCellBackground(renderingContext);
46229
- this.drawCellBackground(renderingContext);
46230
- this.drawBorders(renderingContext);
46231
- this.drawTexts(renderingContext);
46232
- this.drawIcon(renderingContext);
46269
+ this.drawGlobalBackground(renderingContext);
46270
+ for (const zone of this.getters.getAllActiveViewportsZones()) {
46271
+ const { ctx } = renderingContext;
46272
+ ctx.save();
46273
+ ctx.beginPath();
46274
+ const rect = this.getters.getVisibleRect(zone);
46275
+ ctx.rect(rect.x, rect.y, rect.width, rect.height);
46276
+ ctx.clip();
46277
+ this.boxes = this.getGridBoxes(zone);
46278
+ this.drawBackground(renderingContext);
46279
+ this.drawOverflowingCellBackground(renderingContext);
46280
+ this.drawCellBackground(renderingContext);
46281
+ this.drawBorders(renderingContext);
46282
+ this.drawTexts(renderingContext);
46283
+ this.drawIcon(renderingContext);
46284
+ ctx.restore();
46285
+ }
46233
46286
  this.drawFrozenPanes(renderingContext);
46234
46287
  break;
46235
46288
  case 7 /* LAYERS.Headers */:
@@ -46240,12 +46293,15 @@ class RendererPlugin extends UIPlugin {
46240
46293
  break;
46241
46294
  }
46242
46295
  }
46243
- drawBackground(renderingContext) {
46244
- const { ctx, thinLineWidth } = renderingContext;
46296
+ drawGlobalBackground(renderingContext) {
46297
+ const { ctx } = renderingContext;
46245
46298
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
46246
46299
  // white background
46247
46300
  ctx.fillStyle = "#ffffff";
46248
46301
  ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
46302
+ }
46303
+ drawBackground(renderingContext) {
46304
+ const { ctx, thinLineWidth } = renderingContext;
46249
46305
  const areGridLinesVisible = !this.getters.isDashboard() &&
46250
46306
  this.getters.getGridLinesVisibility(this.getters.getActiveSheetId());
46251
46307
  const inset = areGridLinesVisible ? 0.1 * thinLineWidth : 0;
@@ -46676,7 +46732,7 @@ class RendererPlugin extends UIPlugin {
46676
46732
  const position = { sheetId, col, row };
46677
46733
  const cell = this.getters.getEvaluatedCell(position);
46678
46734
  const showFormula = this.getters.shouldShowFormulas();
46679
- const { x, y, width, height } = this.getters.getVisibleRect(zone);
46735
+ const { x, y, width, height } = this.getters.getRect(zone);
46680
46736
  const { verticalAlign } = this.getters.getCellStyle(position);
46681
46737
  const box = {
46682
46738
  x,
@@ -46791,12 +46847,16 @@ class RendererPlugin extends UIPlugin {
46791
46847
  }
46792
46848
  return box;
46793
46849
  }
46794
- getGridBoxes() {
46850
+ getGridBoxes(zone) {
46795
46851
  const boxes = [];
46796
- const visibleCols = this.getters.getSheetViewVisibleCols();
46852
+ const visibleCols = this.getters
46853
+ .getSheetViewVisibleCols()
46854
+ .filter((col) => col >= zone.left && col <= zone.right);
46797
46855
  const left = visibleCols[0];
46798
46856
  const right = visibleCols[visibleCols.length - 1];
46799
- const visibleRows = this.getters.getSheetViewVisibleRows();
46857
+ const visibleRows = this.getters
46858
+ .getSheetViewVisibleRows()
46859
+ .filter((row) => row >= zone.top && row <= zone.bottom);
46800
46860
  const top = visibleRows[0];
46801
46861
  const bottom = visibleRows[visibleRows.length - 1];
46802
46862
  const viewport = { left, right, top, bottom };
@@ -50323,7 +50383,7 @@ class GridSelectionPlugin extends UIPlugin {
50323
50383
  ];
50324
50384
  state.paste(pasteTarget, { selectTarget: true });
50325
50385
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
50326
- let currentIndex = cmd.base;
50386
+ let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
50327
50387
  for (const element of toRemove) {
50328
50388
  const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
50329
50389
  this.dispatch("RESIZE_COLUMNS_ROWS", {
@@ -50614,7 +50674,7 @@ class InternalViewport {
50614
50674
  * @param zone
50615
50675
  * @returns Computes the absolute coordinate of a given zone inside the viewport
50616
50676
  */
50617
- getRect(zone) {
50677
+ getVisibleRect(zone) {
50618
50678
  const targetZone = intersection(zone, this.zone);
50619
50679
  if (targetZone) {
50620
50680
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
@@ -50622,12 +50682,20 @@ class InternalViewport {
50622
50682
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
50623
50683
  const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
50624
50684
  const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
50625
- return {
50626
- x,
50627
- y,
50628
- width,
50629
- height,
50630
- };
50685
+ return { x, y, width, height };
50686
+ }
50687
+ else {
50688
+ return undefined;
50689
+ }
50690
+ }
50691
+ getFullRect(zone) {
50692
+ const targetZone = intersection(zone, this.zone);
50693
+ if (targetZone) {
50694
+ const x = this.getters.getColRowOffset("COL", this.zone.left, zone.left) + this.offsetCorrectionX;
50695
+ const y = this.getters.getColRowOffset("ROW", this.zone.top, zone.top) + this.offsetCorrectionY;
50696
+ const width = this.getters.getColRowOffset("COL", zone.left, zone.right + 1);
50697
+ const height = this.getters.getColRowOffset("ROW", zone.top, zone.bottom + 1);
50698
+ return { x, y, width, height };
50631
50699
  }
50632
50700
  else {
50633
50701
  return undefined;
@@ -50811,6 +50879,8 @@ class SheetViewPlugin extends UIPlugin {
50811
50879
  "getSheetViewVisibleRows",
50812
50880
  "getFrozenSheetViewRatio",
50813
50881
  "isPositionVisible",
50882
+ "getAllActiveViewportsZones",
50883
+ "getRect",
50814
50884
  ];
50815
50885
  viewports = {};
50816
50886
  /**
@@ -51198,16 +51268,27 @@ class SheetViewPlugin extends UIPlugin {
51198
51268
  getVisibleRectWithoutHeaders(zone) {
51199
51269
  const sheetId = this.getters.getActiveSheetId();
51200
51270
  const viewportRects = this.getSubViewports(sheetId)
51201
- .map((viewport) => viewport.getRect(zone))
51271
+ .map((viewport) => viewport.getVisibleRect(zone))
51202
51272
  .filter(isDefined$1);
51203
51273
  if (viewportRects.length === 0) {
51204
51274
  return { x: 0, y: 0, width: 0, height: 0 };
51205
51275
  }
51206
- const x = Math.min(...viewportRects.map((rect) => rect.x));
51207
- const y = Math.min(...viewportRects.map((rect) => rect.y));
51208
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
51209
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
51210
- return { x, y, width, height };
51276
+ return this.recomposeRect(viewportRects);
51277
+ }
51278
+ /**
51279
+ * Computes the actual size and position (:Rect) of the zone on the canvas
51280
+ * regardless of the viewport dimensions.
51281
+ */
51282
+ getRect(zone) {
51283
+ const sheetId = this.getters.getActiveSheetId();
51284
+ const viewportRects = this.getSubViewports(sheetId)
51285
+ .map((viewport) => viewport.getFullRect(zone))
51286
+ .filter(isDefined$1);
51287
+ if (viewportRects.length === 0) {
51288
+ return { x: 0, y: 0, width: 0, height: 0 };
51289
+ }
51290
+ const rect = this.recomposeRect(viewportRects);
51291
+ return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
51211
51292
  }
51212
51293
  /**
51213
51294
  * Returns the position of the MainViewport relatively to the start of the grid (without headers)
@@ -51221,6 +51302,10 @@ class SheetViewPlugin extends UIPlugin {
51221
51302
  const y = this.getters.getRowDimensions(sheetId, ySplit).start;
51222
51303
  return { x, y };
51223
51304
  }
51305
+ getAllActiveViewportsZones() {
51306
+ const sheetId = this.getters.getActiveSheetId();
51307
+ return this.getSubViewports(sheetId);
51308
+ }
51224
51309
  // ---------------------------------------------------------------------------
51225
51310
  // Private
51226
51311
  // ---------------------------------------------------------------------------
@@ -51405,6 +51490,13 @@ class SheetViewPlugin extends UIPlugin {
51405
51490
  const height = this.sheetViewHeight + this.gridOffsetY;
51406
51491
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
51407
51492
  }
51493
+ recomposeRect(viewportRects) {
51494
+ const x = Math.min(...viewportRects.map((rect) => rect.x));
51495
+ const y = Math.min(...viewportRects.map((rect) => rect.y));
51496
+ const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
51497
+ const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
51498
+ return { x, y, width, height };
51499
+ }
51408
51500
  }
51409
51501
 
51410
51502
  class HeaderPositionsUIPlugin extends UIPlugin {
@@ -51856,17 +51948,17 @@ class BottomBarSheet extends Component {
51856
51948
  sheetNameRef = useRef("sheetNameSpan");
51857
51949
  editionState = "initializing";
51858
51950
  setup() {
51859
- onMounted(() => {
51860
- if (this.isSheetActive) {
51861
- this.scrollToSheet();
51862
- }
51863
- });
51864
51951
  onPatched(() => {
51865
51952
  if (this.sheetNameRef.el && this.state.isEditing && this.editionState === "initializing") {
51866
51953
  this.editionState = "editing";
51867
51954
  this.focusInputAndSelectContent();
51868
51955
  }
51869
51956
  });
51957
+ useEffect((sheetId) => {
51958
+ if (this.props.sheetId === sheetId) {
51959
+ this.scrollToSheet();
51960
+ }
51961
+ }, () => [this.env.model.getters.getActiveSheetId()]);
51870
51962
  }
51871
51963
  focusInputAndSelectContent() {
51872
51964
  if (!this.state.isEditing || !this.sheetNameRef.el)
@@ -51878,7 +51970,10 @@ class BottomBarSheet extends Component {
51878
51970
  }
51879
51971
  }
51880
51972
  scrollToSheet() {
51881
- this.sheetDivRef.el?.scrollIntoView?.();
51973
+ this.sheetDivRef.el?.scrollIntoView?.({
51974
+ behavior: "smooth",
51975
+ inline: "nearest",
51976
+ });
51882
51977
  }
51883
51978
  onFocusOut() {
51884
51979
  if (this.state.isEditing && this.editionState !== "initializing") {
@@ -57629,6 +57724,8 @@ const helpers = {
57629
57724
  createActions,
57630
57725
  transformRangeData,
57631
57726
  deepEquals,
57727
+ isNumber,
57728
+ isDateTime,
57632
57729
  };
57633
57730
  const links = {
57634
57731
  isMarkdownLink,
@@ -57672,6 +57769,6 @@ const constants = {
57672
57769
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57673
57770
 
57674
57771
 
57675
- __info__.version = "17.0.44";
57676
- __info__.date = "2024-12-19T07:46:10.942Z";
57677
- __info__.hash = "820f3cf";
57772
+ __info__.version = "17.0.46";
57773
+ __info__.date = "2025-01-27T10:00:20.499Z";
57774
+ __info__.hash = "1df062c";