@odoo/o-spreadsheet 18.0.50 → 18.0.53

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.0.50
6
- * @date 2025-12-02T05:32:00.480Z
7
- * @hash 7ed20c4
5
+ * @version 18.0.53
6
+ * @date 2025-12-26T10:18:09.933Z
7
+ * @hash 7ca8390
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -5839,17 +5839,41 @@
5839
5839
  const today = DateTime.now();
5840
5840
  switch (dateValue) {
5841
5841
  case "today":
5842
- return jsDateToNumber(today);
5843
- case "yesterday":
5844
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 1)));
5845
- case "tomorrow":
5846
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() + 1)));
5842
+ return Math.floor(jsDateToNumber(today));
5843
+ case "yesterday": {
5844
+ today.setDate(today.getDate() - 1);
5845
+ return Math.floor(jsDateToNumber(today));
5846
+ }
5847
+ case "tomorrow": {
5848
+ today.setDate(today.getDate() + 1);
5849
+ return Math.floor(jsDateToNumber(today));
5850
+ }
5847
5851
  case "lastWeek":
5848
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 7)));
5849
- case "lastMonth":
5850
- return jsDateToNumber(DateTime.fromTimestamp(today.setMonth(today.getMonth() - 1)));
5852
+ today.setDate(today.getDate() - 6);
5853
+ return Math.floor(jsDateToNumber(today));
5854
+ case "lastMonth": {
5855
+ const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
5856
+ const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
5857
+ if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
5858
+ today.setDate(1);
5859
+ }
5860
+ else {
5861
+ today.setDate(today.getDate() + 1);
5862
+ today.setMonth(today.getMonth() - 1);
5863
+ }
5864
+ return Math.floor(jsDateToNumber(today));
5865
+ }
5851
5866
  case "lastYear":
5852
- return jsDateToNumber(DateTime.fromTimestamp(today.setFullYear(today.getFullYear() - 1)));
5867
+ // Handle leap year case
5868
+ if (today.getMonth() === 1 && today.getDate() === 29) {
5869
+ today.setDate(28);
5870
+ today.setFullYear(today.getFullYear() - 1);
5871
+ }
5872
+ else {
5873
+ today.setDate(today.getDate() + 1);
5874
+ today.setFullYear(today.getFullYear() - 1);
5875
+ }
5876
+ return Math.floor(jsDateToNumber(today));
5853
5877
  }
5854
5878
  }
5855
5879
  /** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
@@ -40346,14 +40370,15 @@ stores.inject(MyMetaStore, storeInstance);
40346
40370
  }
40347
40371
 
40348
40372
  css /* scss */ `
40349
- .o-cf-preview {
40373
+ .o-spreadsheet .o-cf-preview {
40350
40374
  &.o-cf-cursor-ptr {
40351
40375
  cursor: pointer;
40352
40376
  }
40353
40377
 
40354
40378
  border-bottom: 1px solid ${GRAY_300};
40355
- height: 60px;
40379
+ height: 80px;
40356
40380
  padding: 10px;
40381
+ box-sizing: border-box;
40357
40382
  position: relative;
40358
40383
  cursor: pointer;
40359
40384
  &:hover,
@@ -40367,7 +40392,6 @@ stores.inject(MyMetaStore, storeInstance);
40367
40392
  .o-cf-preview-icon {
40368
40393
  border: 1px solid ${GRAY_300};
40369
40394
  background-color: #fff;
40370
- position: absolute;
40371
40395
  height: 50px;
40372
40396
  width: 50px;
40373
40397
  .o-icon {
@@ -40376,12 +40400,6 @@ stores.inject(MyMetaStore, storeInstance);
40376
40400
  }
40377
40401
  }
40378
40402
  .o-cf-preview-description {
40379
- left: 65px;
40380
- margin-bottom: auto;
40381
- margin-right: 8px;
40382
- margin-top: auto;
40383
- position: relative;
40384
- width: 142px;
40385
40403
  .o-cf-preview-description-rule {
40386
40404
  margin-bottom: 4px;
40387
40405
  max-height: 2.8em;
@@ -40391,16 +40409,11 @@ stores.inject(MyMetaStore, storeInstance);
40391
40409
  font-size: 12px;
40392
40410
  }
40393
40411
  }
40394
- .o-cf-delete {
40395
- left: 90%;
40396
- top: 39%;
40397
- position: absolute;
40398
- }
40399
40412
  &:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
40400
40413
  display: none !important;
40401
40414
  }
40402
40415
  .o-cf-drag-handle {
40403
- left: -8px;
40416
+ left: 2px;
40404
40417
  cursor: move;
40405
40418
  .o-icon {
40406
40419
  width: 6px;
@@ -41285,7 +41298,7 @@ stores.inject(MyMetaStore, storeInstance);
41285
41298
  return false;
41286
41299
  }
41287
41300
  if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
41288
- const today = jsDateToRoundNumber(DateTime.now());
41301
+ const today = Math.floor(jsDateToNumber(DateTime.now()));
41289
41302
  return isDateBetween(dateValue, today, criterionValue);
41290
41303
  }
41291
41304
  return areDatesSameDay(dateValue, criterionValue);
@@ -44989,7 +45002,37 @@ stores.inject(MyMetaStore, storeInstance);
44989
45002
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
44990
45003
  isMeasureCandidate: (field) => !["datetime", "boolean"].includes(field.type),
44991
45004
  isGroupable: () => true,
45005
+ adaptRanges: (getters, definition, applyChange) => {
45006
+ if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
45007
+ return definition;
45008
+ }
45009
+ const { sheetId, zone } = definition.dataSet;
45010
+ const range = getters.getRangeFromZone(sheetId, zone);
45011
+ const adaptedRange = adaptPivotRange(range, applyChange);
45012
+ if (adaptedRange === range) {
45013
+ return definition;
45014
+ }
45015
+ const dataSet = adaptedRange && {
45016
+ sheetId: adaptedRange.sheetId,
45017
+ zone: adaptedRange.zone,
45018
+ };
45019
+ return { ...definition, dataSet };
45020
+ },
44992
45021
  });
45022
+ function adaptPivotRange(range, applyChange) {
45023
+ if (!range) {
45024
+ return undefined;
45025
+ }
45026
+ const change = applyChange(range);
45027
+ switch (change.changeType) {
45028
+ case "NONE":
45029
+ return range;
45030
+ case "REMOVE":
45031
+ return undefined;
45032
+ default:
45033
+ return change.range;
45034
+ }
45035
+ }
44993
45036
 
44994
45037
  class PivotSidePanelStore extends SpreadsheetStore {
44995
45038
  pivotId;
@@ -46876,21 +46919,20 @@ stores.inject(MyMetaStore, storeInstance);
46876
46919
  this.highlightStore.register(this);
46877
46920
  }
46878
46921
  get highlights() {
46879
- let zone;
46880
46922
  const position = this.model.getters.getActivePosition();
46881
- const cell = this.getters.getEvaluatedCell(position);
46882
46923
  const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
46883
- zone = spreader
46924
+ const zone = spreader
46884
46925
  ? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
46885
46926
  : this.model.getters.getSpreadZone(position, { ignoreSpillError: true });
46886
46927
  if (!zone) {
46887
46928
  return [];
46888
46929
  }
46930
+ const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
46889
46931
  return [
46890
46932
  {
46891
46933
  sheetId: position.sheetId,
46892
46934
  zone,
46893
- dashed: cell.value === CellErrorType.SpilledBlocked,
46935
+ dashed: isArrayFormulaBlocked,
46894
46936
  color: "#17A2B8",
46895
46937
  noFill: true,
46896
46938
  thinLine: true,
@@ -54951,6 +54993,7 @@ stores.inject(MyMetaStore, storeInstance);
54951
54993
  class RangeAdapter {
54952
54994
  getters;
54953
54995
  providers = [];
54996
+ isAdaptingRanges = false;
54954
54997
  constructor(getters) {
54955
54998
  this.getters = getters;
54956
54999
  }
@@ -54979,6 +55022,9 @@ stores.inject(MyMetaStore, storeInstance);
54979
55022
  }
54980
55023
  beforeHandle(command) { }
54981
55024
  handle(cmd) {
55025
+ if (this.isAdaptingRanges) {
55026
+ throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
55027
+ }
54982
55028
  switch (cmd.type) {
54983
55029
  case "REMOVE_COLUMNS_ROWS": {
54984
55030
  let start = cmd.dimension === "COL" ? "left" : "top";
@@ -55134,10 +55180,12 @@ stores.inject(MyMetaStore, storeInstance);
55134
55180
  return adaptedRange;
55135
55181
  }
55136
55182
  executeOnAllRanges(adaptRange, sheetId) {
55183
+ this.isAdaptingRanges = true;
55137
55184
  const func = this.verifyRangeRemoved(adaptRange);
55138
55185
  for (const provider of this.providers) {
55139
55186
  provider(func, sheetId);
55140
55187
  }
55188
+ this.isAdaptingRanges = false;
55141
55189
  }
55142
55190
  /**
55143
55191
  * Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
@@ -57244,6 +57292,18 @@ stores.inject(MyMetaStore, storeInstance);
57244
57292
  }
57245
57293
  }
57246
57294
  adaptRanges(applyChange) {
57295
+ for (const pivotId in this.pivots) {
57296
+ const definition = deepCopy(this.pivots[pivotId]?.definition);
57297
+ if (!definition) {
57298
+ continue;
57299
+ }
57300
+ const newDefinition = pivotRegistry
57301
+ .get(definition.type)
57302
+ ?.adaptRanges?.(this.getters, definition, applyChange);
57303
+ if (newDefinition && !deepEquals(definition, newDefinition)) {
57304
+ this.history.update("pivots", pivotId, "definition", newDefinition);
57305
+ }
57306
+ }
57247
57307
  for (const sheetId in this.compiledMeasureFormulas) {
57248
57308
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
57249
57309
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -57386,17 +57446,10 @@ stores.inject(MyMetaStore, storeInstance);
57386
57446
  if (!pivot) {
57387
57447
  continue;
57388
57448
  }
57389
- const def = deepCopy(pivot.definition);
57390
- for (const measure of def.measures) {
57449
+ for (const measure of pivot.definition.measures) {
57391
57450
  if (measure.computedBy?.formula === formulaString) {
57392
- const measureIndex = def.measures.indexOf(measure);
57393
- if (measureIndex !== -1) {
57394
- def.measures[measureIndex].computedBy = {
57395
- formula: newFormulaString,
57396
- sheetId,
57397
- };
57398
- }
57399
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
57451
+ const measureIndex = pivot.definition.measures.indexOf(measure);
57452
+ this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
57400
57453
  }
57401
57454
  }
57402
57455
  }
@@ -57495,20 +57548,6 @@ stores.inject(MyMetaStore, storeInstance);
57495
57548
  }
57496
57549
  }
57497
57550
 
57498
- function adaptPivotRange(range, applyChange) {
57499
- if (!range) {
57500
- return undefined;
57501
- }
57502
- const change = applyChange(range);
57503
- switch (change.changeType) {
57504
- case "NONE":
57505
- return range;
57506
- case "REMOVE":
57507
- return undefined;
57508
- default:
57509
- return change.range;
57510
- }
57511
- }
57512
57551
  class SpreadsheetPivotCorePlugin extends CorePlugin {
57513
57552
  allowDispatch(cmd) {
57514
57553
  switch (cmd.type) {
@@ -57519,27 +57558,6 @@ stores.inject(MyMetaStore, storeInstance);
57519
57558
  }
57520
57559
  return "Success" /* CommandResult.Success */;
57521
57560
  }
57522
- adaptRanges(applyChange) {
57523
- for (const pivotId of this.getters.getPivotIds()) {
57524
- const definition = this.getters.getPivotCoreDefinition(pivotId);
57525
- if (definition.type !== "SPREADSHEET") {
57526
- continue;
57527
- }
57528
- if (definition.dataSet) {
57529
- const { sheetId, zone } = definition.dataSet;
57530
- const range = this.getters.getRangeFromZone(sheetId, zone);
57531
- const adaptedRange = adaptPivotRange(range, applyChange);
57532
- if (adaptedRange === range) {
57533
- return;
57534
- }
57535
- const dataSet = adaptedRange && {
57536
- sheetId: adaptedRange.sheetId,
57537
- zone: adaptedRange.zone,
57538
- };
57539
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
57540
- }
57541
- }
57542
- }
57543
57561
  checkDataSetValidity(definition) {
57544
57562
  if (definition.type === "SPREADSHEET" && definition.dataSet) {
57545
57563
  const { zone, sheetId } = definition.dataSet;
@@ -58897,6 +58915,9 @@ stores.inject(MyMetaStore, storeInstance);
58897
58915
  const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
58898
58916
  return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
58899
58917
  }
58918
+ isArrayFormulaSpillBlocked(position) {
58919
+ return this.blockedArrayFormulas.has(position);
58920
+ }
58900
58921
  updateDependencies(position) {
58901
58922
  // removing dependencies is slow because it requires
58902
58923
  // to traverse the entire r-tree.
@@ -58908,13 +58929,8 @@ stores.inject(MyMetaStore, storeInstance);
58908
58929
  addDependencies(position, dependencies) {
58909
58930
  this.formulaDependencies().addDependencies(position, dependencies);
58910
58931
  for (const range of dependencies) {
58911
- const sheetId = range.sheetId;
58912
- const { left, bottom, right, top } = range.zone;
58913
- for (let col = left; col <= right; col++) {
58914
- for (let row = top; row <= bottom; row++) {
58915
- this.computeAndSave({ sheetId, col, row });
58916
- }
58917
- }
58932
+ // ensure that all ranges are computed
58933
+ this.compilationParams.ensureRange(range);
58918
58934
  }
58919
58935
  }
58920
58936
  updateCompilationParameters() {
@@ -59113,6 +59129,10 @@ stores.inject(MyMetaStore, storeInstance);
59113
59129
  this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
59114
59130
  const nbColumns = formulaReturn.length;
59115
59131
  const nbRows = formulaReturn[0].length;
59132
+ if (nbRows === 0) {
59133
+ // empty matrix
59134
+ return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
59135
+ }
59116
59136
  const resultZone = {
59117
59137
  top: formulaPosition.row,
59118
59138
  bottom: formulaPosition.row + nbRows - 1,
@@ -59385,6 +59405,7 @@ stores.inject(MyMetaStore, storeInstance);
59385
59405
  "getEvaluatedCellsPositions",
59386
59406
  "getSpreadZone",
59387
59407
  "getArrayFormulaSpreadingOn",
59408
+ "isArrayFormulaSpillBlocked",
59388
59409
  "isEmpty",
59389
59410
  ];
59390
59411
  shouldRebuildDependenciesGraph = true;
@@ -59497,6 +59518,9 @@ stores.inject(MyMetaStore, storeInstance);
59497
59518
  getArrayFormulaSpreadingOn(position) {
59498
59519
  return this.evaluator.getArrayFormulaSpreadingOn(position);
59499
59520
  }
59521
+ isArrayFormulaSpillBlocked(position) {
59522
+ return this.evaluator.isArrayFormulaSpillBlocked(position);
59523
+ }
59500
59524
  /**
59501
59525
  * Check if a zone only contains empty cells
59502
59526
  */
@@ -74769,9 +74793,9 @@ stores.inject(MyMetaStore, storeInstance);
74769
74793
  exports.tokenize = tokenize;
74770
74794
 
74771
74795
 
74772
- __info__.version = "18.0.50";
74773
- __info__.date = "2025-12-02T05:32:00.480Z";
74774
- __info__.hash = "7ed20c4";
74796
+ __info__.version = "18.0.53";
74797
+ __info__.date = "2025-12-26T10:18:09.933Z";
74798
+ __info__.hash = "7ca8390";
74775
74799
 
74776
74800
 
74777
74801
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);