@odoo/o-spreadsheet 17.4.4 → 17.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 17.4.4
6
- * @date 2024-08-09T12:24:07.798Z
7
- * @hash a43e855
5
+ * @version 17.4.6
6
+ * @date 2024-08-26T13:50:49.623Z
7
+ * @hash f5648d9
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -240,6 +240,7 @@ const PIVOT_TABLE_CONFIG = {
240
240
  bandedRows: true,
241
241
  bandedColumns: false,
242
242
  styleId: "TableStyleMedium5",
243
+ automaticAutofill: true,
243
244
  };
244
245
 
245
246
  //------------------------------------------------------------------------------
@@ -2008,6 +2009,7 @@ const coreTypes = new Set([
2008
2009
  "UPDATE_CELL",
2009
2010
  "UPDATE_CELL_POSITION",
2010
2011
  "CLEAR_CELL",
2012
+ "CLEAR_CELLS",
2011
2013
  "DELETE_CONTENT",
2012
2014
  /** GRID SHAPE */
2013
2015
  "ADD_COLUMNS_ROWS",
@@ -6743,13 +6745,10 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
6743
6745
  * Clear the clipped zones: remove the cells and clear the formatting
6744
6746
  */
6745
6747
  clearClippedZones(content) {
6746
- for (const row of content.cells) {
6747
- for (const cell of row) {
6748
- if (cell.cell) {
6749
- this.dispatch("CLEAR_CELL", cell.position);
6750
- }
6751
- }
6752
- }
6748
+ this.dispatch("CLEAR_CELLS", {
6749
+ sheetId: content.sheetId,
6750
+ target: content.zones,
6751
+ });
6753
6752
  this.dispatch("CLEAR_FORMATTING", {
6754
6753
  sheetId: content.sheetId,
6755
6754
  target: content.zones,
@@ -7717,7 +7716,7 @@ function parse(str) {
7717
7716
  }
7718
7717
  function parseTokens(tokens) {
7719
7718
  tokens = tokens.filter((x) => x.type !== "SPACE");
7720
- if (tokens[0].value === "=") {
7719
+ if (tokens[0]?.value === "=") {
7721
7720
  tokens.splice(0, 1);
7722
7721
  }
7723
7722
  const result = parseExpression(tokens);
@@ -9951,7 +9950,7 @@ class ComposerStore extends SpreadsheetStore {
9951
9950
  if (pivotId && pivotCell.type !== "EMPTY" && !cell?.isFormula) {
9952
9951
  const formulaPivotId = this.getters.getPivotFormulaId(pivotId);
9953
9952
  const formula = createPivotFormula(formulaPivotId, pivotCell);
9954
- return formula.slice(1); // strip leading =
9953
+ return localizeFormula(formula, this.getters.getLocale()).slice(1); // strip leading =
9955
9954
  }
9956
9955
  }
9957
9956
  const range = this.getters.getRangeFromZone(sheetId, zone);
@@ -35173,7 +35172,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35173
35172
  searchScope: "activeSheet",
35174
35173
  specificRange: undefined,
35175
35174
  };
35176
- updateSearchContent = debounce(this._updateSearchContent.bind(this), 200);
35177
35175
  constructor(get) {
35178
35176
  super(get);
35179
35177
  this.initialShowFormulaState = this.model.getters.shouldShowFormulas();
@@ -35182,7 +35180,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35182
35180
  highlightStore.register(this);
35183
35181
  this.onDispose(() => {
35184
35182
  this.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
35185
- this.updateSearchContent.stopDebounce();
35186
35183
  highlightStore.unRegister(this);
35187
35184
  });
35188
35185
  }
@@ -35196,7 +35193,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
35196
35193
  return this.specificRangeMatches;
35197
35194
  }
35198
35195
  }
35199
- _updateSearchContent(toSearch) {
35196
+ updateSearchContent(toSearch) {
35200
35197
  this._updateSearch(toSearch, this.searchOptions);
35201
35198
  }
35202
35199
  updateSearchOptions(searchOptions) {
@@ -35212,9 +35209,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35212
35209
  selectNextMatch() {
35213
35210
  this.selectNextCell(Direction.next);
35214
35211
  }
35215
- get pendingSearch() {
35216
- return this.updateSearchContent.isDebouncePending();
35217
- }
35218
35212
  handle(cmd) {
35219
35213
  switch (cmd.type) {
35220
35214
  case "SET_FORMULA_VISIBILITY":
@@ -35540,6 +35534,7 @@ class FindAndReplacePanel extends Component {
35540
35534
  searchInput = useRef("searchInput");
35541
35535
  store;
35542
35536
  state;
35537
+ updateSearchContent;
35543
35538
  get hasSearchResult() {
35544
35539
  return this.store.selectedMatchIndex !== null;
35545
35540
  }
@@ -35571,12 +35566,14 @@ class FindAndReplacePanel extends Component {
35571
35566
  this.store = useLocalStore(FindAndReplaceStore);
35572
35567
  this.state = useState({ dataRange: "" });
35573
35568
  onMounted(() => this.searchInput.el?.focus());
35569
+ onWillUnmount(() => this.updateSearchContent.stopDebounce());
35570
+ this.updateSearchContent = debounce(this.store.updateSearchContent, 200);
35574
35571
  }
35575
35572
  onFocusSearch() {
35576
35573
  this.updateDataRange();
35577
35574
  }
35578
35575
  onSearchInput(ev) {
35579
- this.store.updateSearchContent(ev.target?.value || "");
35576
+ this.updateSearchContent(ev.target.value);
35580
35577
  }
35581
35578
  onKeydownSearch(ev) {
35582
35579
  if (ev.key === "Enter") {
@@ -35615,6 +35612,9 @@ class FindAndReplacePanel extends Component {
35615
35612
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
35616
35613
  this.store.updateSearchOptions({ specificRange });
35617
35614
  }
35615
+ get pendingSearch() {
35616
+ return this.updateSearchContent.isDebouncePending();
35617
+ }
35618
35618
  }
35619
35619
 
35620
35620
  css /* scss */ `
@@ -36668,6 +36668,12 @@ function orderDataEntriesKeys(groups, dimension) {
36668
36668
  * Used to order two values
36669
36669
  */
36670
36670
  function compareDimensionValues(dimension, a, b) {
36671
+ if (a === "null") {
36672
+ return dimension.order === "asc" ? 1 : -1;
36673
+ }
36674
+ if (b === "null") {
36675
+ return dimension.order === "asc" ? -1 : 1;
36676
+ }
36671
36677
  if (dimension.type === "integer" || dimension.type === "date") {
36672
36678
  return dimension.order === "asc" ? Number(a) - Number(b) : Number(b) - Number(a);
36673
36679
  }
@@ -37030,7 +37036,7 @@ class SpreadsheetPivot {
37030
37036
  if (cell.type === CellValueType.error) {
37031
37037
  throw new EvaluationError(_t("The pivot cannot be created because cell %s contains an error", toXC(col, row)));
37032
37038
  }
37033
- if (cell.type === CellValueType.empty) {
37039
+ if (cell.type === CellValueType.empty || cell.value === "") {
37034
37040
  throw new EvaluationError(_t("The pivot cannot be created because cell %s is empty", toXC(col, row)));
37035
37041
  }
37036
37042
  if (cell.value === "__count") {
@@ -37376,15 +37382,11 @@ class PivotSpreadsheetSidePanel extends Component {
37376
37382
  }
37377
37383
  onSelectionConfirmed() {
37378
37384
  if (this.state.range) {
37379
- const { sheetName, xc } = splitReference(this.state.range);
37380
- const sheetId = sheetName
37381
- ? this.env.model.getters.getSheetIdByName(sheetName)
37382
- : this.env.model.getters.getActiveSheetId();
37383
- if (!sheetId) {
37385
+ const range = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.range);
37386
+ if (range.invalidSheetName || range.invalidXc) {
37384
37387
  return;
37385
37388
  }
37386
- const zone = toZone(xc);
37387
- const dataSet = { sheetId, zone };
37389
+ const dataSet = { sheetId: range.sheetId, zone: range.zone };
37388
37390
  this.store.update({ dataSet });
37389
37391
  // Immediately apply the update to recompute the pivot fields
37390
37392
  this.store.applyUpdate();
@@ -38317,10 +38319,6 @@ class TablePanel extends Component {
38317
38319
  });
38318
38320
  }
38319
38321
  onRangeChanged(ranges) {
38320
- if (!ranges[0] || !ranges[0].match(rangeReference)) {
38321
- this.state.tableZoneErrors = ["InvalidRange" /* CommandResult.InvalidRange */];
38322
- return;
38323
- }
38324
38322
  const sheetId = this.env.model.getters.getActiveSheetId();
38325
38323
  this.state.tableXc = ranges[0];
38326
38324
  const newTableRange = this.env.model.getters.getRangeFromSheetXC(sheetId, this.state.tableXc);
@@ -38360,11 +38358,6 @@ class TablePanel extends Component {
38360
38358
  const newTableRange = updatedTable.range;
38361
38359
  this.state.tableXc = this.env.model.getters.getRangeString(newTableRange, sheetId);
38362
38360
  }
38363
- else {
38364
- const oldTableRange = this.props.table.range;
38365
- this.state.tableXc = this.env.model.getters.getRangeString(oldTableRange, sheetId);
38366
- }
38367
- this.state.tableZoneErrors = [];
38368
38361
  }
38369
38362
  deleteTable() {
38370
38363
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -44354,6 +44347,7 @@ function convertChartData(chartData) {
44354
44347
  return {
44355
44348
  dataRange: convertExcelRangeToSheetXC(data.range, dataSetsHaveTitle),
44356
44349
  label,
44350
+ backgroundColor: data.backgroundColor,
44357
44351
  };
44358
44352
  });
44359
44353
  // For doughnut charts, in chartJS first dataset = outer dataset, in excel first dataset = inner dataset
@@ -45547,11 +45541,13 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
45547
45541
  label = { text };
45548
45542
  }
45549
45543
  }
45544
+ const color = this.extractChildAttr(chartDataElement, "c:spPr a:solidFill a:srgbClr", "val");
45550
45545
  return {
45551
45546
  label,
45552
45547
  range: this.extractChildTextContent(chartDataElement, "c:val c:f", {
45553
45548
  required: true,
45554
45549
  }),
45550
+ backgroundColor: color ? `${toHex(color.asString())}` : undefined,
45555
45551
  };
45556
45552
  });
45557
45553
  })
@@ -47757,6 +47753,9 @@ class CellPlugin extends CorePlugin {
47757
47753
  format: "",
47758
47754
  });
47759
47755
  break;
47756
+ case "CLEAR_CELLS":
47757
+ this.clearCells(cmd.sheetId, cmd.target);
47758
+ break;
47760
47759
  case "DELETE_CONTENT":
47761
47760
  this.clearZones(cmd.sheetId, cmd.target);
47762
47761
  break;
@@ -47815,6 +47814,25 @@ class CellPlugin extends CorePlugin {
47815
47814
  }
47816
47815
  }
47817
47816
  }
47817
+ /**
47818
+ * Clear the styles, the format and the content of zones
47819
+ */
47820
+ clearCells(sheetId, zones) {
47821
+ for (const zone of zones) {
47822
+ for (let col = zone.left; col <= zone.right; col++) {
47823
+ for (let row = zone.top; row <= zone.bottom; row++) {
47824
+ this.dispatch("UPDATE_CELL", {
47825
+ sheetId: sheetId,
47826
+ col,
47827
+ row,
47828
+ content: "",
47829
+ style: null,
47830
+ format: "",
47831
+ });
47832
+ }
47833
+ }
47834
+ }
47835
+ }
47818
47836
  /**
47819
47837
  * Copy the style of the reference column/row to the new columns/rows.
47820
47838
  */
@@ -49226,7 +49244,10 @@ class HeaderSizePlugin extends CorePlugin {
49226
49244
  handle(cmd) {
49227
49245
  switch (cmd.type) {
49228
49246
  case "CREATE_SHEET": {
49229
- this.history.update("sizes", cmd.sheetId, { COL: [], ROW: [] });
49247
+ this.history.update("sizes", cmd.sheetId, {
49248
+ COL: Array(this.getters.getNumberCols(cmd.sheetId)).fill(undefined),
49249
+ ROW: Array(this.getters.getNumberRows(cmd.sheetId)).fill(undefined),
49250
+ });
49230
49251
  break;
49231
49252
  }
49232
49253
  case "DUPLICATE_SHEET":
@@ -51275,19 +51296,23 @@ class SheetPlugin extends CorePlugin {
51275
51296
  }
51276
51297
  }
51277
51298
  moveCellOnColumnsDeletion(sheet, deletedColumn) {
51299
+ this.dispatch("CLEAR_CELLS", {
51300
+ sheetId: sheet.id,
51301
+ target: [
51302
+ {
51303
+ left: deletedColumn,
51304
+ top: 0,
51305
+ right: deletedColumn,
51306
+ bottom: sheet.rows.length - 1,
51307
+ },
51308
+ ],
51309
+ });
51278
51310
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
51279
51311
  const row = sheet.rows[rowIndex];
51280
51312
  for (let i in row.cells) {
51281
51313
  const colIndex = Number(i);
51282
51314
  const cellId = row.cells[i];
51283
51315
  if (cellId) {
51284
- if (colIndex === deletedColumn) {
51285
- this.dispatch("CLEAR_CELL", {
51286
- sheetId: sheet.id,
51287
- col: colIndex,
51288
- row: rowIndex,
51289
- });
51290
- }
51291
51316
  if (colIndex > deletedColumn) {
51292
51317
  this.setNewPosition(cellId, sheet.id, colIndex - 1, rowIndex);
51293
51318
  }
@@ -51333,22 +51358,20 @@ class SheetPlugin extends CorePlugin {
51333
51358
  *
51334
51359
  */
51335
51360
  moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
51361
+ this.dispatch("CLEAR_CELLS", {
51362
+ sheetId: sheet.id,
51363
+ target: [
51364
+ {
51365
+ left: 0,
51366
+ top: deleteFromRow,
51367
+ right: this.getters.getNumberCols(sheet.id),
51368
+ bottom: deleteToRow,
51369
+ },
51370
+ ],
51371
+ });
51336
51372
  const numberRows = deleteToRow - deleteFromRow + 1;
51337
51373
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
51338
51374
  const row = sheet.rows[rowIndex];
51339
- if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
51340
- for (let i in row.cells) {
51341
- const colIndex = Number(i);
51342
- const cellId = row.cells[i];
51343
- if (cellId) {
51344
- this.dispatch("CLEAR_CELL", {
51345
- sheetId: sheet.id,
51346
- col: colIndex,
51347
- row: rowIndex,
51348
- });
51349
- }
51350
- }
51351
- }
51352
51375
  if (rowIndex > deleteToRow) {
51353
51376
  for (let i in row.cells) {
51354
51377
  const colIndex = Number(i);
@@ -55909,6 +55932,9 @@ class PivotUIPlugin extends UIPlugin {
55909
55932
  }
55910
55933
  }
55911
55934
  getPivot(pivotId) {
55935
+ if (!this.getters.isExistingPivot(pivotId)) {
55936
+ throw new Error(`pivot ${pivotId} not found`);
55937
+ }
55912
55938
  return this.pivots[pivotId];
55913
55939
  }
55914
55940
  isPivotUnused(pivotId) {
@@ -57202,7 +57228,7 @@ class Session extends EventBus {
57202
57228
  */
57203
57229
  leave(data) {
57204
57230
  if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57205
- this.snapshot(data);
57231
+ this.snapshot(data());
57206
57232
  }
57207
57233
  delete this.clients[this.clientId];
57208
57234
  this.transportService.leave(this.clientId);
@@ -57624,9 +57650,7 @@ class DataCleanupPlugin extends UIPlugin {
57624
57650
  if (!data) {
57625
57651
  return;
57626
57652
  }
57627
- for (const { col, row } of positions(zone)) {
57628
- this.dispatch("CLEAR_CELL", { col, row, sheetId });
57629
- }
57653
+ this.dispatch("CLEAR_CELLS", { target: [zone], sheetId });
57630
57654
  const zonePasted = {
57631
57655
  left: zone.left,
57632
57656
  top: zone.top,
@@ -57991,7 +58015,7 @@ class InsertPivotPlugin extends UIPlugin {
57991
58015
  sheetId,
57992
58016
  col,
57993
58017
  row,
57994
- content: `=PIVOT("${pivotFormulaId}")`,
58018
+ content: `=PIVOT(${pivotFormulaId})`,
57995
58019
  });
57996
58020
  const zone = {
57997
58021
  left: col,
@@ -58299,6 +58323,9 @@ class SheetUIPlugin extends UIPlugin {
58299
58323
  if (showFormula && cell?.isFormula) {
58300
58324
  return localizeFormula(cell.content, this.getters.getLocale());
58301
58325
  }
58326
+ else if (showFormula && !cell?.content) {
58327
+ return "";
58328
+ }
58302
58329
  else {
58303
58330
  return this.getters.getEvaluatedCell(position).formattedValue;
58304
58331
  }
@@ -58797,6 +58824,7 @@ function repeatGroupHeadersCommand(getters, cmd) {
58797
58824
  const repeatCommandTransformRegistry = new Registry();
58798
58825
  repeatCommandTransformRegistry.add("UPDATE_CELL", genericRepeat);
58799
58826
  repeatCommandTransformRegistry.add("CLEAR_CELL", genericRepeat);
58827
+ repeatCommandTransformRegistry.add("CLEAR_CELLS", genericRepeat);
58800
58828
  repeatCommandTransformRegistry.add("DELETE_CONTENT", genericRepeat);
58801
58829
  repeatCommandTransformRegistry.add("ADD_MERGE", genericRepeat);
58802
58830
  repeatCommandTransformRegistry.add("REMOVE_MERGE", genericRepeat);
@@ -59378,6 +59406,7 @@ class ClipboardPlugin extends UIPlugin {
59378
59406
  this.status = "invisible";
59379
59407
  if (this._isCutOperation) {
59380
59408
  this.copiedData = undefined;
59409
+ this._isCutOperation = false;
59381
59410
  }
59382
59411
  break;
59383
59412
  }
@@ -59421,9 +59450,10 @@ class ClipboardPlugin extends UIPlugin {
59421
59450
  case "DELETE_CELL": {
59422
59451
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
59423
59452
  if (!isZoneValid(cut[0])) {
59424
- for (const { col, row } of positions(cmd.zone)) {
59425
- this.dispatch("CLEAR_CELL", { col, row, sheetId: this.getters.getActiveSheetId() });
59426
- }
59453
+ this.dispatch("CLEAR_CELLS", {
59454
+ target: [cmd.zone],
59455
+ sheetId: this.getters.getActiveSheetId(),
59456
+ });
59427
59457
  break;
59428
59458
  }
59429
59459
  const copiedData = this.copy(cut);
@@ -59474,6 +59504,7 @@ class ClipboardPlugin extends UIPlugin {
59474
59504
  }
59475
59505
  case "ACTIVATE_PAINT_FORMAT": {
59476
59506
  const zones = this.getters.getSelectedZones();
59507
+ this._isCutOperation = false;
59477
59508
  this.copiedData = this.copy(zones);
59478
59509
  this.status = "visible";
59479
59510
  if (cmd.persistent) {
@@ -67825,7 +67856,7 @@ class Model extends EventBus {
67825
67856
  this.session.join(this.config.client);
67826
67857
  }
67827
67858
  leaveSession() {
67828
- this.session.leave(this.exportData());
67859
+ this.session.leave(lazy(() => this.exportData()));
67829
67860
  }
67830
67861
  setupUiPlugin(Plugin) {
67831
67862
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68384,6 +68415,6 @@ const constants = {
68384
68415
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
68385
68416
 
68386
68417
 
68387
- __info__.version = "17.4.4";
68388
- __info__.date = "2024-08-09T12:24:07.798Z";
68389
- __info__.hash = "a43e855";
68418
+ __info__.version = "17.4.6";
68419
+ __info__.date = "2024-08-26T13:50:49.623Z";
68420
+ __info__.hash = "f5648d9";