@odoo/o-spreadsheet 16.3.31 → 16.3.34

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.
@@ -1124,7 +1124,7 @@
1124
1124
  if (typeof o1 !== typeof o2)
1125
1125
  return false;
1126
1126
  if (typeof o1 !== "object")
1127
- return o1 === o2;
1127
+ return false;
1128
1128
  // Objects can have different keys if the values are undefined
1129
1129
  const keys = new Set();
1130
1130
  Object.keys(o1).forEach((key) => keys.add(key));
@@ -6283,6 +6283,7 @@
6283
6283
  this.save();
6284
6284
  }
6285
6285
  ev.stopPropagation();
6286
+ ev.preventDefault();
6286
6287
  break;
6287
6288
  case "Escape":
6288
6289
  this.cancel();
@@ -6867,7 +6868,7 @@
6867
6868
  /**
6868
6869
  * Get a default chart js configuration
6869
6870
  */
6870
- function getDefaultChartJsRuntime(chart, labels, fontColor, dataSetsFormat) {
6871
+ function getDefaultChartJsRuntime(chart, labels, fontColor, dataSetsFormat, truncateLabels = true) {
6871
6872
  return {
6872
6873
  type: chart.type,
6873
6874
  options: {
@@ -6920,7 +6921,7 @@
6920
6921
  },
6921
6922
  },
6922
6923
  data: {
6923
- labels: labels.map(truncateLabel),
6924
+ labels: truncateLabels ? labels.map(truncateLabel) : labels,
6924
6925
  datasets: [],
6925
6926
  },
6926
6927
  };
@@ -7759,9 +7760,9 @@
7759
7760
  }
7760
7761
  return true;
7761
7762
  }
7762
- function getLineConfiguration(chart, labels, dataSetFormat) {
7763
+ function getLineConfiguration(chart, labels, dataSetFormat, truncateLabels) {
7763
7764
  const fontColor = chartFontColor(chart.background);
7764
- const config = getDefaultChartJsRuntime(chart, labels, fontColor, dataSetFormat);
7765
+ const config = getDefaultChartJsRuntime(chart, labels, fontColor, dataSetFormat, truncateLabels);
7765
7766
  const legend = {
7766
7767
  labels: {
7767
7768
  fontColor,
@@ -7836,8 +7837,9 @@
7836
7837
  if (chart.aggregated) {
7837
7838
  ({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
7838
7839
  }
7840
+ const truncateLabels = axisType === "category";
7839
7841
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
7840
- const config = getLineConfiguration(chart, labels, dataSetFormat);
7842
+ const config = getLineConfiguration(chart, labels, dataSetFormat, truncateLabels);
7841
7843
  const labelFormat = getChartLabelFormat(getters, chart.labelRange);
7842
7844
  if (axisType === "time") {
7843
7845
  config.options.scales.xAxes[0].type = "time";
@@ -9471,9 +9473,12 @@
9471
9473
  // Filters action
9472
9474
  //------------------------------------------------------------------------------
9473
9475
  const FILTERS_CREATE_FILTER_TABLE = (env) => {
9476
+ const zones = env.model.getters.getSelectedZones();
9477
+ if (zones.length === 1 && getZoneArea(zones[0]) === 1) {
9478
+ env.model.selection.selectTableAroundSelection();
9479
+ }
9474
9480
  const sheetId = env.model.getters.getActiveSheetId();
9475
- const selection = env.model.getters.getSelection().zones;
9476
- interactiveAddFilter(env, sheetId, selection);
9481
+ interactiveAddFilter(env, sheetId, env.model.getters.getSelectedZones());
9477
9482
  };
9478
9483
  const FILTERS_REMOVE_FILTER_TABLE = (env) => {
9479
9484
  const sheetId = env.model.getters.getActiveSheetId();
@@ -21337,6 +21342,11 @@
21337
21342
  onBlur() {
21338
21343
  this.isKeyStillDown = false;
21339
21344
  }
21345
+ onContextMenu(ev) {
21346
+ if (this.env.model.getters.getEditionMode() === "inactive") {
21347
+ this.props.onInputContextMenu?.(ev);
21348
+ }
21349
+ }
21340
21350
  // ---------------------------------------------------------------------------
21341
21351
  // Private
21342
21352
  // ---------------------------------------------------------------------------
@@ -21558,6 +21568,7 @@
21558
21568
  onComposerCellFocused: { type: Function, optional: true },
21559
21569
  onComposerContentFocused: Function,
21560
21570
  isDefaultFocus: { type: Boolean, optional: true },
21571
+ onInputContextMenu: { type: Function, optional: true },
21561
21572
  };
21562
21573
 
21563
21574
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
@@ -21634,6 +21645,7 @@
21634
21645
  isDefaultFocus: true,
21635
21646
  onComposerContentFocused: this.props.onComposerContentFocused,
21636
21647
  onComposerCellFocused: this.props.onComposerCellFocused,
21648
+ onInputContextMenu: this.props.onInputContextMenu,
21637
21649
  };
21638
21650
  }
21639
21651
  get containerStyle() {
@@ -21722,6 +21734,7 @@
21722
21734
  onComposerContentFocused: Function,
21723
21735
  gridDims: Object,
21724
21736
  onComposerCellFocused: Function,
21737
+ onInputContextMenu: Function,
21725
21738
  };
21726
21739
 
21727
21740
  const CSS$1 = css /* scss */ `
@@ -24057,8 +24070,8 @@
24057
24070
  else if (this.env.model.getters.getActiveRows().has(row)) {
24058
24071
  type = "ROW";
24059
24072
  }
24060
- const { x, y, width, height } = this.env.model.getters.getVisibleRect(lastZone);
24061
- this.toggleContextMenu(type, x + width, y + height);
24073
+ const { x, y, width } = this.env.model.getters.getVisibleRect(lastZone);
24074
+ this.toggleContextMenu(type, this.canvasPosition.x + x + width, this.canvasPosition.y + y);
24062
24075
  }
24063
24076
  onCellRightClicked(col, row, { x, y }) {
24064
24077
  const zones = this.env.model.getters.getSelectedZones();
@@ -26385,29 +26398,12 @@
26385
26398
  return width;
26386
26399
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
26387
26400
  }
26388
- function convertBorderDescr(descr) {
26389
- if (!descr) {
26390
- return undefined;
26391
- }
26392
- return {
26393
- style: descr.style,
26394
- color: { rgb: descr.color },
26395
- };
26396
- }
26397
26401
  function extractStyle(cell, data) {
26398
26402
  let style = {};
26399
26403
  if (cell.style) {
26400
26404
  style = data.styles[cell.style];
26401
26405
  }
26402
26406
  const format = extractFormat(cell, data);
26403
- const exportedBorder = {};
26404
- if (cell.border) {
26405
- const border = data.borders[cell.border];
26406
- exportedBorder.left = convertBorderDescr(border.left);
26407
- exportedBorder.right = convertBorderDescr(border.right);
26408
- exportedBorder.bottom = convertBorderDescr(border.bottom);
26409
- exportedBorder.top = convertBorderDescr(border.top);
26410
- }
26411
26407
  const styles = {
26412
26408
  font: {
26413
26409
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -26421,7 +26417,7 @@
26421
26417
  }
26422
26418
  : { reservedAttribute: "none" },
26423
26419
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
26424
- border: exportedBorder || {},
26420
+ border: cell.border || 0,
26425
26421
  alignment: {
26426
26422
  horizontal: style.align,
26427
26423
  vertical: style.verticalAlign
@@ -26453,15 +26449,12 @@
26453
26449
  return undefined;
26454
26450
  }
26455
26451
  function normalizeStyle(construct, styles) {
26456
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
26457
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
26458
- const { id: borderId } = pushElement(styles["border"], construct.borders);
26459
26452
  // Normalize this
26460
26453
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
26461
26454
  const style = {
26462
- fontId,
26463
- fillId,
26464
- borderId,
26455
+ fontId: pushElement(styles.font, construct.fonts),
26456
+ fillId: pushElement(styles.fill, construct.fills),
26457
+ borderId: styles.border,
26465
26458
  numFmtId,
26466
26459
  alignment: {
26467
26460
  vertical: styles.alignment.vertical,
@@ -26469,8 +26462,7 @@
26469
26462
  wrapText: styles.alignment.wrapText,
26470
26463
  },
26471
26464
  };
26472
- const { id } = pushElement(style, construct.styles);
26473
- return id;
26465
+ return pushElement(style, construct.styles);
26474
26466
  }
26475
26467
  function convertFormat(format, numFmtStructure) {
26476
26468
  if (!format) {
@@ -26478,8 +26470,7 @@
26478
26470
  }
26479
26471
  let formatId = XLSX_FORMAT_MAP[format.format];
26480
26472
  if (!formatId) {
26481
- const { id } = pushElement(format, numFmtStructure);
26482
- formatId = id + FIRST_NUMFMT_ID;
26473
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
26483
26474
  }
26484
26475
  return formatId;
26485
26476
  }
@@ -26504,20 +26495,15 @@
26504
26495
  return id;
26505
26496
  }
26506
26497
  function pushElement(property, propertyList) {
26507
- for (let [key, value] of Object.entries(propertyList)) {
26508
- if (JSON.stringify(value) === JSON.stringify(property)) {
26509
- return { id: parseInt(key, 10), list: propertyList };
26498
+ let len = propertyList.length;
26499
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
26500
+ for (let i = 0; i < len; i++) {
26501
+ if (operator(property, propertyList[i])) {
26502
+ return i;
26510
26503
  }
26511
26504
  }
26512
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
26513
- if (elemId === -1) {
26514
- propertyList.push(property);
26515
- elemId = propertyList.length - 1;
26516
- }
26517
- return {
26518
- id: elemId,
26519
- list: propertyList,
26520
- };
26505
+ propertyList[propertyList.length] = property;
26506
+ return propertyList.length - 1;
26521
26507
  }
26522
26508
  const chartIds = [];
26523
26509
  /**
@@ -27223,7 +27209,25 @@
27223
27209
  }
27224
27210
  return document;
27225
27211
  }
27226
- function getDefaultXLSXStructure() {
27212
+ function convertBorderDescr(descr) {
27213
+ if (!descr) {
27214
+ return undefined;
27215
+ }
27216
+ return {
27217
+ style: descr.style,
27218
+ color: { rgb: descr.color },
27219
+ };
27220
+ }
27221
+ function getDefaultXLSXStructure(data) {
27222
+ const xlsxBorders = Object.values(data.borders).map((border) => {
27223
+ return {
27224
+ left: convertBorderDescr(border.left),
27225
+ right: convertBorderDescr(border.right),
27226
+ bottom: convertBorderDescr(border.bottom),
27227
+ top: convertBorderDescr(border.top),
27228
+ };
27229
+ });
27230
+ const borders = [{}, ...xlsxBorders];
27227
27231
  return {
27228
27232
  relsFiles: [],
27229
27233
  sharedStrings: [],
@@ -27246,7 +27250,7 @@
27246
27250
  },
27247
27251
  ],
27248
27252
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
27249
- borders: [{}],
27253
+ borders,
27250
27254
  numFmts: [],
27251
27255
  dxfs: [],
27252
27256
  };
@@ -29244,7 +29248,7 @@
29244
29248
  this.clearBorders(cmd.sheetId, cmd.target);
29245
29249
  break;
29246
29250
  case "REMOVE_COLUMNS_ROWS":
29247
- for (let el of cmd.elements) {
29251
+ for (let el of [...cmd.elements].sort((a, b) => b - a)) {
29248
29252
  if (cmd.dimension === "COL") {
29249
29253
  this.shiftBordersHorizontally(cmd.sheetId, el + 1, -1);
29250
29254
  }
@@ -31197,7 +31201,17 @@
31197
31201
  }
31198
31202
  }
31199
31203
  exportForExcel(data) {
31200
- this.export(data);
31204
+ for (const sheet of data.sheets) {
31205
+ for (const filterTable of this.getFilterTables(sheet.id)) {
31206
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
31207
+ continue;
31208
+ }
31209
+ sheet.filterTables.push({
31210
+ range: zoneToXc(filterTable.zone),
31211
+ filters: [],
31212
+ });
31213
+ }
31214
+ }
31201
31215
  }
31202
31216
  }
31203
31217
 
@@ -35065,12 +35079,13 @@
35065
35079
  case "AlterZone":
35066
35080
  break;
35067
35081
  case "ZonesSelected":
35082
+ const sheetId = this.getters.getActiveSheetId();
35068
35083
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
35069
35084
  if (event.mode === "updateAnchor") {
35070
35085
  const oldZone = event.previousAnchor.zone;
35071
35086
  const newZone = event.anchor.zone;
35072
35087
  // altering a zone should not move the viewport in a dimension that wasn't changed
35073
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
35088
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
35074
35089
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
35075
35090
  col = left > col || col > right ? left : col;
35076
35091
  }
@@ -35078,10 +35093,9 @@
35078
35093
  row = top > row || row > bottom ? top : row;
35079
35094
  }
35080
35095
  }
35081
- const sheetId = this.getters.getActiveSheetId();
35082
35096
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
35083
35097
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
35084
- this.refreshViewport(this.getters.getActiveSheetId(), { col, row });
35098
+ this.refreshViewport(sheetId, { col, row });
35085
35099
  break;
35086
35100
  }
35087
35101
  }
@@ -35105,16 +35119,16 @@
35105
35119
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
35106
35120
  break;
35107
35121
  case "SHIFT_VIEWPORT_DOWN":
35108
- const { top } = this.getActiveMainViewport();
35109
35122
  const sheetId = this.getters.getActiveSheetId();
35110
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
35111
- this.shiftVertically(shiftedOffsetY);
35123
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
35124
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
35125
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
35112
35126
  break;
35113
35127
  case "SHIFT_VIEWPORT_UP": {
35114
- const { top } = this.getActiveMainViewport();
35115
35128
  const sheetId = this.getters.getActiveSheetId();
35116
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
35117
- this.shiftVertically(shiftedOffsetY);
35129
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
35130
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
35131
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
35118
35132
  break;
35119
35133
  }
35120
35134
  case "REMOVE_COLUMNS_ROWS":
@@ -35476,17 +35490,6 @@
35476
35490
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
35477
35491
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
35478
35492
  }
35479
- /**
35480
- * Clip the vertical offset within the allowed range.
35481
- * Not above the sheet, nor below the sheet.
35482
- */
35483
- clipOffsetY(offsetY) {
35484
- const { height } = this.getMainViewportRect();
35485
- const maxOffset = height - this.sheetViewHeight;
35486
- offsetY = Math.min(offsetY, maxOffset);
35487
- offsetY = Math.max(offsetY, 0);
35488
- return offsetY;
35489
- }
35490
35493
  getViewportOffset(sheetId) {
35491
35494
  return {
35492
35495
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -35542,12 +35545,15 @@
35542
35545
  * viewport top.
35543
35546
  */
35544
35547
  shiftVertically(offset) {
35545
- const { top } = this.getActiveMainViewport();
35548
+ const sheetId = this.getters.getActiveSheetId();
35549
+ const { top } = this.getMainInternalViewport(sheetId);
35546
35550
  const { scrollX } = this.getActiveSheetScrollInfo();
35547
35551
  this.setSheetViewOffset(scrollX, offset);
35548
35552
  const { anchor } = this.getters.getSelection();
35549
- const deltaRow = this.getActiveMainViewport().top - top;
35550
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
35553
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
35554
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
35555
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
35556
+ }
35551
35557
  }
35552
35558
  getVisibleFigures() {
35553
35559
  const sheetId = this.getters.getActiveSheetId();
@@ -43097,7 +43103,6 @@
43097
43103
  cursor: pointer;
43098
43104
  }
43099
43105
  `;
43100
- let tKey = 1;
43101
43106
  class SpreadsheetDashboard extends owl.Component {
43102
43107
  static template = "o-spreadsheet-SpreadsheetDashboard";
43103
43108
  static components = {
@@ -43175,13 +43180,9 @@
43175
43180
  coordinates: rect,
43176
43181
  position: { col, row },
43177
43182
  action,
43178
- // we can't rely on position only because a row or a column could
43179
- // be inserted at any time.
43180
- tKey: `${tKey}-${col}-${row}`,
43181
43183
  });
43182
43184
  }
43183
43185
  }
43184
- tKey++;
43185
43186
  return cells;
43186
43187
  }
43187
43188
  getClickableAction(position) {
@@ -46319,8 +46320,7 @@
46319
46320
  attrs.push(["t", "b"]);
46320
46321
  }
46321
46322
  else if (forceString || !isNumber(value)) {
46322
- const { id } = pushElement(content, sharedStrings);
46323
- value = id.toString();
46323
+ value = pushElement(content, sharedStrings);
46324
46324
  attrs.push(["t", "s"]);
46325
46325
  }
46326
46326
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -46445,8 +46445,7 @@
46445
46445
  if (rule.style.fillColor) {
46446
46446
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
46447
46447
  }
46448
- const { id } = pushElement(dxf, dxfs);
46449
- ruleAttributes.push(["dxfId", id]);
46448
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
46450
46449
  return escapeXml /*xml*/ `
46451
46450
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
46452
46451
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -47250,7 +47249,7 @@
47250
47249
  */
47251
47250
  function getXLSX(data) {
47252
47251
  const files = [];
47253
- const construct = getDefaultXLSXStructure();
47252
+ const construct = getDefaultXLSXStructure(data);
47254
47253
  files.push(createWorkbook(data, construct));
47255
47254
  files.push(...createWorksheets(data, construct));
47256
47255
  files.push(createStylesSheet(construct));
@@ -48093,9 +48092,9 @@
48093
48092
  Object.defineProperty(exports, '__esModule', { value: true });
48094
48093
 
48095
48094
 
48096
- __info__.version = '16.3.31';
48097
- __info__.date = '2024-04-05T13:57:05.657Z';
48098
- __info__.hash = '052efd4';
48095
+ __info__.version = '16.3.34';
48096
+ __info__.date = '2024-04-26T07:37:12.329Z';
48097
+ __info__.hash = '196324c';
48099
48098
 
48100
48099
 
48101
48100
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);