@odoo/o-spreadsheet 18.1.0 → 18.1.1

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.1.0
6
- * @date 2024-12-26T06:37:07.879Z
7
- * @hash c520e89
5
+ * @version 18.1.1
6
+ * @date 2025-01-14T11:43:19.116Z
7
+ * @hash d0fa5de
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -3710,6 +3710,7 @@
3710
3710
  CommandResult["SheetIsHidden"] = "SheetIsHidden";
3711
3711
  CommandResult["InvalidTableResize"] = "InvalidTableResize";
3712
3712
  CommandResult["PivotIdNotFound"] = "PivotIdNotFound";
3713
+ CommandResult["PivotInError"] = "PivotInError";
3713
3714
  CommandResult["EmptyName"] = "EmptyName";
3714
3715
  CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
3715
3716
  CommandResult["InvalidDefinition"] = "InvalidDefinition";
@@ -7478,18 +7479,18 @@
7478
7479
  });
7479
7480
  return newY.length === newX.length ? newY : transposeMatrix(newY);
7480
7481
  }
7481
- function getMovingAverageValues(dataset, windowSize = DEFAULT_WINDOW_SIZE) {
7482
+ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZE) {
7482
7483
  const values = [];
7483
7484
  // Fill the starting values with null until we have a full window
7484
7485
  for (let i = 0; i < windowSize - 1; i++) {
7485
- values.push(null);
7486
+ values.push({ x: labels[i], y: NaN });
7486
7487
  }
7487
7488
  for (let i = 0; i <= dataset.length - windowSize; i++) {
7488
7489
  let sum = 0;
7489
7490
  for (let j = i; j < i + windowSize; j++) {
7490
7491
  sum += dataset[j];
7491
7492
  }
7492
- values.push(sum / windowSize);
7493
+ values.push({ x: labels[i + windowSize - 1], y: sum / windowSize });
7493
7494
  }
7494
7495
  return values;
7495
7496
  }
@@ -19931,6 +19932,17 @@ stores.inject(MyMetaStore, storeInstance);
19931
19932
  },
19932
19933
  isExported: true,
19933
19934
  };
19935
+ // -----------------------------------------------------------------------------
19936
+ // VALUE
19937
+ // -----------------------------------------------------------------------------
19938
+ const VALUE = {
19939
+ description: _t("Converts a string to a numeric value."),
19940
+ args: [arg("value (number)", _t("the string to be converted"))],
19941
+ compute: function (value) {
19942
+ return toNumber(value, this.locale);
19943
+ },
19944
+ isExported: true,
19945
+ };
19934
19946
 
19935
19947
  var text = /*#__PURE__*/Object.freeze({
19936
19948
  __proto__: null,
@@ -19953,7 +19965,8 @@ stores.inject(MyMetaStore, storeInstance);
19953
19965
  TEXT: TEXT,
19954
19966
  TEXTJOIN: TEXTJOIN,
19955
19967
  TRIM: TRIM,
19956
- UPPER: UPPER
19968
+ UPPER: UPPER,
19969
+ VALUE: VALUE
19957
19970
  });
19958
19971
 
19959
19972
  // -----------------------------------------------------------------------------
@@ -24141,7 +24154,7 @@ stores.inject(MyMetaStore, storeInstance);
24141
24154
  return width;
24142
24155
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
24143
24156
  }
24144
- function extractStyle(data, styleId, formatId, borderId) {
24157
+ function extractStyle(data, content, styleId, formatId, borderId) {
24145
24158
  const style = styleId ? data.styles[styleId] : {};
24146
24159
  const format = formatId ? data.formats[formatId] : undefined;
24147
24160
  const styles = {
@@ -24163,7 +24176,7 @@ stores.inject(MyMetaStore, storeInstance);
24163
24176
  vertical: style.verticalAlign
24164
24177
  ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
24165
24178
  : undefined,
24166
- wrapText: style.wrapping === "wrap" || undefined,
24179
+ wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
24167
24180
  },
24168
24181
  };
24169
24182
  styles.font["strike"] = !!style?.strikethrough || undefined;
@@ -24394,7 +24407,7 @@ stores.inject(MyMetaStore, storeInstance);
24394
24407
  return undefined;
24395
24408
  }
24396
24409
  function isChartData(data) {
24397
- return "dataSets" in data;
24410
+ return "dataSets" in data && data.dataSets.length > 0;
24398
24411
  }
24399
24412
  function isImageData(data) {
24400
24413
  return "imageSrc" in data;
@@ -24740,9 +24753,8 @@ stores.inject(MyMetaStore, storeInstance);
24740
24753
  }
24741
24754
  return rows;
24742
24755
  }
24743
- /** Remove newlines (\n) in shared strings, We do not support them */
24744
24756
  function convertSharedStrings(xlsxSharedStrings) {
24745
- return xlsxSharedStrings.map((str) => str.replace(/\n/g, ""));
24757
+ return xlsxSharedStrings.map(replaceNewLines);
24746
24758
  }
24747
24759
  function convertCells(sheet, data, sheetDims, warningManager) {
24748
24760
  const cells = {};
@@ -25830,15 +25842,10 @@ stores.inject(MyMetaStore, storeInstance);
25830
25842
  getSharedStrings() {
25831
25843
  return this.mapOnElements({ parent: this.rootFile.file.xml, query: "si" }, (ssElement) => {
25832
25844
  // Shared string can either be a simple text, or a rich text (text with formatting, possibly in multiple parts)
25833
- if (ssElement.children[0].tagName === "t") {
25834
- return this.extractTextContent(ssElement) || "";
25835
- }
25836
25845
  // We don't support rich text formatting, we'll only extract the text
25837
- else {
25838
- return this.mapOnElements({ parent: ssElement, query: "t" }, (textElement) => {
25839
- return this.extractTextContent(textElement) || "";
25840
- }).join("");
25841
- }
25846
+ return this.mapOnElements({ parent: ssElement, query: "t" }, (textElement) => {
25847
+ return this.extractTextContent(textElement) || "";
25848
+ }).join("");
25842
25849
  });
25843
25850
  }
25844
25851
  }
@@ -27479,6 +27486,13 @@ stores.inject(MyMetaStore, storeInstance);
27479
27486
  }
27480
27487
  return data;
27481
27488
  },
27489
+ })
27490
+ .add("migration_24", {
27491
+ // Empty migration to allow odoo migrate pivot custom sorting.
27492
+ versionFrom: "24",
27493
+ migrate(data) {
27494
+ return data;
27495
+ },
27482
27496
  });
27483
27497
  function fixOverlappingFilters(data) {
27484
27498
  for (let sheet of data.sheets || []) {
@@ -27506,7 +27520,7 @@ stores.inject(MyMetaStore, storeInstance);
27506
27520
  * a breaking change is made in the way the state is handled, and an upgrade
27507
27521
  * function should be defined
27508
27522
  */
27509
- const CURRENT_VERSION = 24;
27523
+ const CURRENT_VERSION = 25;
27510
27524
  const INITIAL_SHEET_ID = "Sheet1";
27511
27525
  /**
27512
27526
  * This function tries to load anything that could look like a valid
@@ -28407,12 +28421,12 @@ stores.inject(MyMetaStore, storeInstance);
28407
28421
  }
28408
28422
  const numberOfStep = 5 * trendLabels.length;
28409
28423
  const step = (xmax - xmin) / numberOfStep;
28410
- const newLabels = range(xmin, xmax + step / 2, step);
28411
- const newValues = interpolateData(config, filteredValues, filteredLabels, newLabels);
28412
- if (!newValues.length) {
28424
+ const trendNewLabels = range(xmin, xmax + step / 2, step);
28425
+ const trendValues = interpolateData(config, filteredValues, filteredLabels, trendNewLabels);
28426
+ if (!trendValues.length) {
28413
28427
  return;
28414
28428
  }
28415
- return newValues;
28429
+ return trendValues;
28416
28430
  }
28417
28431
  function interpolateData(config, values, labels, newLabels) {
28418
28432
  if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
@@ -28428,13 +28442,16 @@ stores.inject(MyMetaStore, storeInstance);
28428
28442
  case "polynomial": {
28429
28443
  const order = config.order;
28430
28444
  if (!order) {
28431
- return Array.from({ length: newLabels.length }, () => NaN);
28445
+ return newLabels.map((x) => ({ x, y: NaN }));
28432
28446
  }
28433
28447
  if (order === 1) {
28434
- return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0];
28448
+ return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0].map((y, i) => ({ x: newLabels[i], y }));
28435
28449
  }
28436
28450
  const coeffs = polynomialRegression(values, normalizedLabels, order, true).flat();
28437
- return normalizedNewLabels.map((v) => evaluatePolynomial(coeffs, v, order));
28451
+ return normalizedNewLabels.map((x, i) => ({
28452
+ x: newLabels[i],
28453
+ y: evaluatePolynomial(coeffs, x, order),
28454
+ }));
28438
28455
  }
28439
28456
  case "exponential": {
28440
28457
  const positiveLogValues = [];
@@ -28446,22 +28463,22 @@ stores.inject(MyMetaStore, storeInstance);
28446
28463
  }
28447
28464
  }
28448
28465
  if (!filteredLabels.length) {
28449
- return Array.from({ length: newLabels.length }, () => NaN);
28466
+ return newLabels.map((x) => ({ x, y: NaN }));
28450
28467
  }
28451
- return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0];
28468
+ return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0].map((y, i) => ({ x: newLabels[i], y }));
28452
28469
  }
28453
28470
  case "logarithmic": {
28454
- return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0];
28471
+ return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0].map((y, i) => ({ x: newLabels[i], y }));
28455
28472
  }
28456
28473
  case "trailingMovingAverage": {
28457
- return getMovingAverageValues(values, config.window);
28474
+ return getMovingAverageValues(values, labels, config.window);
28458
28475
  }
28459
28476
  default:
28460
- return Array.from({ length: newLabels.length }, () => NaN);
28477
+ return newLabels.map((x) => ({ x, y: NaN }));
28461
28478
  }
28462
28479
  }
28463
28480
  catch (e) {
28464
- return Array.from({ length: newLabels.length }, () => NaN);
28481
+ return newLabels.map((x) => ({ x, y: NaN }));
28465
28482
  }
28466
28483
  }
28467
28484
  function getChartAxisType(chart, labelRange, getters) {
@@ -28697,7 +28714,7 @@ stores.inject(MyMetaStore, storeInstance);
28697
28714
  // then using the classical aggregation method to sum the values.
28698
28715
  data.fill(1);
28699
28716
  }
28700
- else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), getters.getLocale()))) {
28717
+ else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
28701
28718
  continue;
28702
28719
  }
28703
28720
  datasetValues.push({ data, label });
@@ -29091,6 +29108,7 @@ stores.inject(MyMetaStore, storeInstance);
29091
29108
  return legendValues;
29092
29109
  },
29093
29110
  },
29111
+ onClick: () => { }, // Disables click interaction with the waterfall chart legend items
29094
29112
  };
29095
29113
  }
29096
29114
  function getRadarChartLegend(definition, args) {
@@ -29232,14 +29250,19 @@ stores.inject(MyMetaStore, storeInstance);
29232
29250
  /* We add a second x axis here to draw the trend lines, with the labels length being
29233
29251
  * set so that the second axis points match the classical x axis
29234
29252
  */
29235
- const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
29236
29253
  scales[TREND_LINE_XAXIS_ID] = {
29237
29254
  ...scales.x,
29238
- type: "category",
29239
- labels: range(0, maxLength).map((x) => x.toString()),
29240
- offset: false,
29241
29255
  display: false,
29242
29256
  };
29257
+ if (axisType === "category" || axisType === "time") {
29258
+ /* We add a second x axis here to draw the trend lines, with the labels length being
29259
+ * set so that the second axis points match the classical x axis
29260
+ */
29261
+ const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
29262
+ scales[TREND_LINE_XAXIS_ID]["type"] = "category";
29263
+ scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
29264
+ scales[TREND_LINE_XAXIS_ID]["offset"] = false;
29265
+ }
29243
29266
  }
29244
29267
  return scales;
29245
29268
  }
@@ -29509,7 +29532,9 @@ stores.inject(MyMetaStore, storeInstance);
29509
29532
  if (axisType === "linear") {
29510
29533
  tooltip.callbacks.label = (tooltipItem) => {
29511
29534
  const dataSetPoint = tooltipItem.parsed.y;
29512
- let label = tooltipItem.parsed.x;
29535
+ let label = tooltipItem.dataset.xAxisID === TREND_LINE_XAXIS_ID
29536
+ ? ""
29537
+ : tooltipItem.parsed.x;
29513
29538
  if (typeof label === "string" && isNumber(label, locale)) {
29514
29539
  label = toNumber(label, locale);
29515
29540
  }
@@ -30202,7 +30227,11 @@ stores.inject(MyMetaStore, storeInstance);
30202
30227
  colors.push(chartColors.upperColor);
30203
30228
  return {
30204
30229
  background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
30205
- title: chart.title ?? { text: "" },
30230
+ title: {
30231
+ ...chart.title,
30232
+ // chart titles are extracted from .json files and they are translated at runtime here
30233
+ text: _t(chart.title.text ?? ""),
30234
+ },
30206
30235
  minValue: {
30207
30236
  value: minValue,
30208
30237
  label: formatValue(minValue, { locale, format }),
@@ -35333,12 +35362,20 @@ stores.inject(MyMetaStore, storeInstance);
35333
35362
  });
35334
35363
  }
35335
35364
  function isAutomaticFormatSelected(env) {
35336
- const activeCell = env.model.getters.getCell(env.model.getters.getActivePosition());
35337
- return !activeCell || !activeCell.format;
35365
+ const activePosition = env.model.getters.getActivePosition();
35366
+ const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
35367
+ if (pivotCell.type === "VALUE") {
35368
+ return !env.model.getters.getEvaluatedCell(activePosition).format;
35369
+ }
35370
+ return !env.model.getters.getCell(activePosition)?.format;
35338
35371
  }
35339
35372
  function isFormatSelected(env, format) {
35340
- const activeCell = env.model.getters.getCell(env.model.getters.getActivePosition());
35341
- return activeCell?.format === format;
35373
+ const activePosition = env.model.getters.getActivePosition();
35374
+ const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
35375
+ if (pivotCell.type === "VALUE") {
35376
+ return env.model.getters.getEvaluatedCell(activePosition).format === format;
35377
+ }
35378
+ return env.model.getters.getCell(activePosition)?.format === format;
35342
35379
  }
35343
35380
  function isFontSizeSelected(env, fontSize) {
35344
35381
  const currentFontSize = env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
@@ -39677,14 +39714,11 @@ stores.inject(MyMetaStore, storeInstance);
39677
39714
  }
39678
39715
 
39679
39716
  class DOMFocusableElementStore {
39680
- mutators = ["setFocusableElement", "focus"];
39717
+ mutators = ["setFocusableElement"];
39681
39718
  focusableElement = undefined;
39682
39719
  setFocusableElement(element) {
39683
39720
  this.focusableElement = element;
39684
39721
  }
39685
- focus() {
39686
- this.focusableElement?.focus();
39687
- }
39688
39722
  }
39689
39723
 
39690
39724
  css /* scss */ `
@@ -40332,7 +40366,7 @@ stores.inject(MyMetaStore, storeInstance);
40332
40366
  if (document.activeElement === this.contentHelper.el &&
40333
40367
  this.props.composerStore.editionMode === "inactive" &&
40334
40368
  !this.props.isDefaultFocus) {
40335
- this.DOMFocusableElementStore.focus();
40369
+ this.DOMFocusableElementStore.focusableElement?.focus();
40336
40370
  }
40337
40371
  });
40338
40372
  owl.useEffect(() => {
@@ -44313,16 +44347,21 @@ stores.inject(MyMetaStore, storeInstance);
44313
44347
  }
44314
44348
  this.inputRef.el?.blur();
44315
44349
  }
44316
- focusInputAndSelectContent() {
44317
- const inputEl = this.inputRef.el;
44318
- if (!inputEl)
44319
- return;
44320
- // The onFocus event selects all text in the input.
44321
- // The subsequent mouseup event can deselect this text,
44322
- // so t-on-mouseup.prevent.stop is used to prevent this
44323
- // default behavior and preserve the selection.
44324
- inputEl.focus();
44325
- inputEl.select();
44350
+ onMouseDown(ev) {
44351
+ // Stop the event if the input is not focused, we handle everything in onMouseUp
44352
+ if (ev.target !== document.activeElement) {
44353
+ ev.preventDefault();
44354
+ ev.stopPropagation();
44355
+ }
44356
+ }
44357
+ onMouseUp(ev) {
44358
+ const target = ev.target;
44359
+ if (target !== document.activeElement) {
44360
+ target.focus();
44361
+ target.select();
44362
+ ev.preventDefault();
44363
+ ev.stopPropagation();
44364
+ }
44326
44365
  }
44327
44366
  }
44328
44367
 
@@ -44875,7 +44914,16 @@ stores.inject(MyMetaStore, storeInstance);
44875
44914
  newPivotId,
44876
44915
  newSheetId,
44877
44916
  });
44878
- const text = result.isSuccessful ? _t("Pivot duplicated.") : _t("Pivot duplication failed");
44917
+ let text;
44918
+ if (result.isSuccessful) {
44919
+ text = _t("Pivot duplicated.");
44920
+ }
44921
+ else if (result.isCancelledBecause("PivotInError" /* CommandResult.PivotInError */)) {
44922
+ text = _t("Cannot duplicate a pivot in error.");
44923
+ }
44924
+ else {
44925
+ text = _t("Pivot duplication failed.");
44926
+ }
44879
44927
  const type = result.isSuccessful ? "success" : "danger";
44880
44928
  this.env.notifyUser({
44881
44929
  text,
@@ -46214,7 +46262,9 @@ stores.inject(MyMetaStore, storeInstance);
46214
46262
  pivot: this.draft,
46215
46263
  });
46216
46264
  this.draft = null;
46217
- if (!this.alreadyNotified && !this.isDynamicPivotInViewport()) {
46265
+ if (!this.alreadyNotified &&
46266
+ !this.isDynamicPivotInViewport() &&
46267
+ this.isStaticPivotInViewport()) {
46218
46268
  const formulaId = this.getters.getPivotFormulaId(this.pivotId);
46219
46269
  const pivotExample = `=PIVOT(${formulaId})`;
46220
46270
  this.alreadyNotified = true;
@@ -46282,6 +46332,18 @@ stores.inject(MyMetaStore, storeInstance);
46282
46332
  }
46283
46333
  return false;
46284
46334
  }
46335
+ isStaticPivotInViewport() {
46336
+ for (const position of this.getters.getVisibleCellPositions()) {
46337
+ const cell = this.getters.getCell(position);
46338
+ if (cell?.isFormula) {
46339
+ const pivotFunction = getFirstPivotFunction(cell.compiledFormula.tokens);
46340
+ if (pivotFunction && pivotFunction.functionName !== "PIVOT") {
46341
+ return true;
46342
+ }
46343
+ }
46344
+ }
46345
+ return false;
46346
+ }
46285
46347
  addDefaultDateTimeGranularity(fields, definition) {
46286
46348
  const { columns, rows } = definition;
46287
46349
  const columnsWithGranularity = deepCopy(columns);
@@ -51694,7 +51756,7 @@ stores.inject(MyMetaStore, storeInstance);
51694
51756
  this.cellPopovers = useStore(CellPopoverStore);
51695
51757
  owl.useEffect(() => {
51696
51758
  if (!this.sidePanel.isOpen) {
51697
- this.DOMFocusableElementStore.focus();
51759
+ this.DOMFocusableElementStore.focusableElement?.focus();
51698
51760
  }
51699
51761
  }, () => [this.sidePanel.isOpen]);
51700
51762
  }
@@ -51900,7 +51962,7 @@ stores.inject(MyMetaStore, storeInstance);
51900
51962
  focusDefaultElement() {
51901
51963
  if (!this.env.model.getters.getSelectedFigureId() &&
51902
51964
  this.composerFocusStore.activeComposer.editionMode === "inactive") {
51903
- this.DOMFocusableElementStore.focus();
51965
+ this.DOMFocusableElementStore.focusableElement?.focus();
51904
51966
  }
51905
51967
  }
51906
51968
  get gridEl() {
@@ -52437,10 +52499,34 @@ stores.inject(MyMetaStore, storeInstance);
52437
52499
  const elements = [...cmd.elements].sort((a, b) => b - a);
52438
52500
  for (const group of groupConsecutive(elements)) {
52439
52501
  if (cmd.dimension === "COL") {
52440
- this.shiftBordersHorizontally(cmd.sheetId, group[group.length - 1] + 1, -group.length);
52502
+ if (group[0] >= this.getters.getNumberCols(cmd.sheetId)) {
52503
+ for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
52504
+ this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
52505
+ }
52506
+ }
52507
+ if (group[group.length - 1] === 0) {
52508
+ for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
52509
+ this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
52510
+ }
52511
+ }
52512
+ const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
52513
+ this.clearInsideBorders(cmd.sheetId, [zone]);
52514
+ this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
52441
52515
  }
52442
52516
  else {
52443
- this.shiftBordersVertically(cmd.sheetId, group[group.length - 1] + 1, -group.length);
52517
+ if (group[0] >= this.getters.getNumberRows(cmd.sheetId)) {
52518
+ for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
52519
+ this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
52520
+ }
52521
+ }
52522
+ if (group[group.length - 1] === 0) {
52523
+ for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
52524
+ this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
52525
+ }
52526
+ }
52527
+ const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
52528
+ this.clearInsideBorders(cmd.sheetId, [zone]);
52529
+ this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
52444
52530
  }
52445
52531
  }
52446
52532
  break;
@@ -52747,6 +52833,18 @@ stores.inject(MyMetaStore, storeInstance);
52747
52833
  }
52748
52834
  }
52749
52835
  }
52836
+ /**
52837
+ * Remove the borders inside of a zone
52838
+ */
52839
+ clearInsideBorders(sheetId, zones) {
52840
+ for (let zone of zones) {
52841
+ for (let row = zone.top; row <= zone.bottom; row++) {
52842
+ for (let col = zone.left; col <= zone.right; col++) {
52843
+ this.history.update("borders", sheetId, col, row, undefined);
52844
+ }
52845
+ }
52846
+ }
52847
+ }
52750
52848
  /**
52751
52849
  * Add a border to the existing one to a cell
52752
52850
  */
@@ -63293,6 +63391,9 @@ stores.inject(MyMetaStore, storeInstance);
63293
63391
  }
63294
63392
  }
63295
63393
  this.acknowledge(message);
63394
+ if (message.type === "REMOTE_REVISION" && message.clientId === this.clientId) {
63395
+ return;
63396
+ }
63296
63397
  this.trigger("collaborative-event-received");
63297
63398
  }
63298
63399
  onClientMoved(message) {
@@ -63943,6 +64044,19 @@ stores.inject(MyMetaStore, storeInstance);
63943
64044
 
63944
64045
  class InsertPivotPlugin extends UIPlugin {
63945
64046
  static getters = [];
64047
+ allowDispatch(cmd) {
64048
+ switch (cmd.type) {
64049
+ case "DUPLICATE_PIVOT_IN_NEW_SHEET":
64050
+ if (!this.getters.isExistingPivot(cmd.pivotId)) {
64051
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
64052
+ }
64053
+ if (!this.getters.getPivot(cmd.pivotId).isValid()) {
64054
+ return "PivotInError" /* CommandResult.PivotInError */;
64055
+ }
64056
+ break;
64057
+ }
64058
+ return "Success" /* CommandResult.Success */;
64059
+ }
63946
64060
  handle(cmd) {
63947
64061
  switch (cmd.type) {
63948
64062
  case "INSERT_NEW_PIVOT":
@@ -68179,11 +68293,6 @@ stores.inject(MyMetaStore, storeInstance);
68179
68293
  editionState = "initializing";
68180
68294
  DOMFocusableElementStore;
68181
68295
  setup() {
68182
- owl.onMounted(() => {
68183
- if (this.isSheetActive) {
68184
- this.scrollToSheet();
68185
- }
68186
- });
68187
68296
  owl.onPatched(() => {
68188
68297
  if (this.sheetNameRef.el && this.state.isEditing && this.editionState === "initializing") {
68189
68298
  this.editionState = "editing";
@@ -68192,6 +68301,11 @@ stores.inject(MyMetaStore, storeInstance);
68192
68301
  });
68193
68302
  this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
68194
68303
  owl.useExternalListener(window, "click", () => (this.state.pickerOpened = false));
68304
+ owl.useEffect((sheetId) => {
68305
+ if (this.props.sheetId === sheetId) {
68306
+ this.scrollToSheet();
68307
+ }
68308
+ }, () => [this.env.model.getters.getActiveSheetId()]);
68195
68309
  }
68196
68310
  focusInputAndSelectContent() {
68197
68311
  if (!this.state.isEditing || !this.sheetNameRef.el)
@@ -68203,7 +68317,10 @@ stores.inject(MyMetaStore, storeInstance);
68203
68317
  }
68204
68318
  }
68205
68319
  scrollToSheet() {
68206
- this.sheetDivRef.el?.scrollIntoView?.();
68320
+ this.sheetDivRef.el?.scrollIntoView?.({
68321
+ behavior: "smooth",
68322
+ inline: "nearest",
68323
+ });
68207
68324
  }
68208
68325
  onFocusOut() {
68209
68326
  if (this.state.isEditing && this.editionState !== "initializing") {
@@ -68233,11 +68350,11 @@ stores.inject(MyMetaStore, storeInstance);
68233
68350
  if (ev.key === "Enter") {
68234
68351
  ev.preventDefault();
68235
68352
  this.stopEdition();
68236
- this.DOMFocusableElementStore.focus();
68353
+ this.DOMFocusableElementStore.focusableElement?.focus();
68237
68354
  }
68238
68355
  if (ev.key === "Escape") {
68239
68356
  this.cancelEdition();
68240
- this.DOMFocusableElementStore.focus();
68357
+ this.DOMFocusableElementStore.focusableElement?.focus();
68241
68358
  }
68242
68359
  }
68243
68360
  onMouseEventSheetName(ev) {
@@ -73613,7 +73730,7 @@ stores.inject(MyMetaStore, storeInstance);
73613
73730
  if (content || styleId || formatId || borderId || value !== undefined) {
73614
73731
  const attributes = [["r", xc]];
73615
73732
  // style
73616
- const id = normalizeStyle(construct, extractStyle(data, styleId, formatId, borderId));
73733
+ const id = normalizeStyle(construct, extractStyle(data, content, styleId, formatId, borderId));
73617
73734
  // don't add style if default
73618
73735
  if (id) {
73619
73736
  attributes.push(["s", id]);
@@ -73967,7 +74084,12 @@ stores.inject(MyMetaStore, storeInstance);
73967
74084
  ["count", strings.length],
73968
74085
  ["uniqueCount", strings.length],
73969
74086
  ];
73970
- const stringNodes = strings.map((string) => escapeXml /*xml*/ `<si><t>${string}</t></si>`);
74087
+ const stringNodes = strings.map((string) => {
74088
+ if (string.trim() !== string) {
74089
+ return escapeXml /*xml*/ `<si><t xml:space="preserve">${string}</t></si>`;
74090
+ }
74091
+ return escapeXml /*xml*/ `<si><t>${string}</t></si>`;
74092
+ });
73971
74093
  const xml = escapeXml /*xml*/ `
73972
74094
  <sst ${formatAttributes(namespaces)}>
73973
74095
  ${joinXmlNodes(stringNodes)}
@@ -74207,7 +74329,7 @@ stores.inject(MyMetaStore, storeInstance);
74207
74329
  // events
74208
74330
  this.setupSessionEvents();
74209
74331
  this.joinSession();
74210
- if (config.snapshotRequested) {
74332
+ if (config.snapshotRequested || (data["[Content_Types].xml"] && !this.getters.isReadonly())) {
74211
74333
  const startSnapshot = performance.now();
74212
74334
  console.debug("Snapshot requested");
74213
74335
  this.session.snapshot(this.exportData());
@@ -74694,6 +74816,8 @@ stores.inject(MyMetaStore, storeInstance);
74694
74816
  areDomainArgsFieldsValid,
74695
74817
  splitReference,
74696
74818
  sanitizeSheetName,
74819
+ isNumber,
74820
+ isDateTime,
74697
74821
  };
74698
74822
  const links = {
74699
74823
  isMarkdownLink,
@@ -74832,9 +74956,9 @@ stores.inject(MyMetaStore, storeInstance);
74832
74956
  exports.tokenize = tokenize;
74833
74957
 
74834
74958
 
74835
- __info__.version = "18.1.0";
74836
- __info__.date = "2024-12-26T06:37:07.879Z";
74837
- __info__.hash = "c520e89";
74959
+ __info__.version = "18.1.1";
74960
+ __info__.date = "2025-01-14T11:43:19.116Z";
74961
+ __info__.hash = "d0fa5de";
74838
74962
 
74839
74963
 
74840
74964
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);