@odoo/o-spreadsheet 17.4.6 → 17.4.7

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.6
6
- * @date 2024-08-26T13:50:49.623Z
7
- * @hash f5648d9
5
+ * @version 17.4.7
6
+ * @date 2024-09-05T09:32:00.461Z
7
+ * @hash c14a4c9
8
8
  */
9
9
 
10
10
  'use strict';
@@ -4561,6 +4561,17 @@ function reorderZone(zone) {
4561
4561
  }
4562
4562
  return zone;
4563
4563
  }
4564
+ function aggregatePositionsToZones(positions) {
4565
+ const result = {};
4566
+ for (const position of positions) {
4567
+ result[position.sheetId] ??= [];
4568
+ result[position.sheetId].push(positionToZone(position));
4569
+ }
4570
+ for (const sheetId in result) {
4571
+ result[sheetId] = recomputeZones(result[sheetId]);
4572
+ }
4573
+ return result;
4574
+ }
4564
4575
  /**
4565
4576
  * This function returns a zone with coordinates modified according to the change
4566
4577
  * applied to the zone. It may be possible to change the zone by resizing or moving
@@ -6776,9 +6787,11 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
6776
6787
  const targetCell = this.getters.getEvaluatedCell(target);
6777
6788
  const originFormat = origin.cell?.format ?? origin.evaluatedCell.format;
6778
6789
  if (clipboardOption?.pasteOption === "asValue") {
6779
- const locale = this.getters.getLocale();
6780
- const content = formatValue(origin.evaluatedCell.value, { locale });
6781
- this.dispatch("UPDATE_CELL", { ...target, content, format: originFormat });
6790
+ this.dispatch("UPDATE_CELL", {
6791
+ ...target,
6792
+ content: origin.evaluatedCell.value?.toString() || "",
6793
+ format: originFormat,
6794
+ });
6782
6795
  return;
6783
6796
  }
6784
6797
  if (clipboardOption?.pasteOption === "onlyFormat") {
@@ -28380,8 +28393,26 @@ const CREATE_PIVOT = (env) => {
28380
28393
  env.openSidePanel("PivotSidePanel", { pivotId });
28381
28394
  }
28382
28395
  };
28383
- const REINSERT_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28384
- id: `reinsert_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28396
+ const REINSERT_DYNAMIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28397
+ id: `reinsert_dynamic_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28398
+ name: env.model.getters.getPivotDisplayName(pivotId),
28399
+ sequence: index,
28400
+ execute: (env) => {
28401
+ const zone = env.model.getters.getSelectedZone();
28402
+ const table = env.model.getters.getPivot(pivotId).getTableStructure().export();
28403
+ env.model.dispatch("INSERT_PIVOT_WITH_TABLE", {
28404
+ pivotId,
28405
+ table,
28406
+ col: zone.left,
28407
+ row: zone.top,
28408
+ sheetId: env.model.getters.getActiveSheetId(),
28409
+ pivotMode: "dynamic",
28410
+ });
28411
+ env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
28412
+ },
28413
+ }));
28414
+ const REINSERT_STATIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28415
+ id: `reinsert_static_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28385
28416
  name: env.model.getters.getPivotDisplayName(pivotId),
28386
28417
  sequence: index,
28387
28418
  execute: (env) => {
@@ -28393,6 +28424,7 @@ const REINSERT_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pi
28393
28424
  col: zone.left,
28394
28425
  row: zone.top,
28395
28426
  sheetId: env.model.getters.getActiveSheetId(),
28427
+ pivotMode: "static",
28396
28428
  });
28397
28429
  env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
28398
28430
  },
@@ -29261,12 +29293,20 @@ const splitToColumns = {
29261
29293
  isEnabled: (env) => env.model.getters.isSingleColSelected(),
29262
29294
  icon: "o-spreadsheet-Icon.SPLIT_TEXT",
29263
29295
  };
29264
- const reinsertPivotMenu = {
29265
- id: "reinsert_pivot",
29266
- name: _t("Re-insert pivot"),
29296
+ const reinsertDynamicPivotMenu = {
29297
+ id: "reinsert_dynamic_pivot",
29298
+ name: _t("Re-insert dynamic pivot"),
29299
+ sequence: 1020,
29300
+ icon: "o-spreadsheet-Icon.INSERT_PIVOT",
29301
+ children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
29302
+ isVisible: (env) => env.model.getters.getPivotIds().length > 0,
29303
+ };
29304
+ const reinsertStaticPivotMenu = {
29305
+ id: "reinsert_static_pivot",
29306
+ name: _t("Re-insert static pivot"),
29267
29307
  sequence: 1020,
29268
29308
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
29269
- children: [REINSERT_PIVOT_CHILDREN],
29309
+ children: [REINSERT_STATIC_PIVOT_CHILDREN],
29270
29310
  isVisible: (env) => env.model.getters.getPivotIds().length > 0,
29271
29311
  };
29272
29312
 
@@ -29275,7 +29315,8 @@ var ACTION_DATA = /*#__PURE__*/Object.freeze({
29275
29315
  createRemoveFilter: createRemoveFilter,
29276
29316
  createRemoveFilterTool: createRemoveFilterTool,
29277
29317
  dataCleanup: dataCleanup,
29278
- reinsertPivotMenu: reinsertPivotMenu,
29318
+ reinsertDynamicPivotMenu: reinsertDynamicPivotMenu,
29319
+ reinsertStaticPivotMenu: reinsertStaticPivotMenu,
29279
29320
  removeDuplicates: removeDuplicates,
29280
29321
  sortAscending: sortAscending,
29281
29322
  sortDescending: sortDescending,
@@ -30757,7 +30798,8 @@ topbarMenuRegistry
30757
30798
  };
30758
30799
  });
30759
30800
  })
30760
- .addChild("reinsert_pivot", ["data"], reinsertPivotMenu);
30801
+ .addChild("reinsert_dynamic_pivot", ["data"], reinsertDynamicPivotMenu)
30802
+ .addChild("reinsert_static_pivot", ["data"], reinsertStaticPivotMenu);
30761
30803
 
30762
30804
  class OTRegistry extends Registry {
30763
30805
  /**
@@ -44067,6 +44109,18 @@ function convertOperator(operator) {
44067
44109
  // -------------------------------------
44068
44110
  // WORKSHEET HELPERS
44069
44111
  // -------------------------------------
44112
+ function getCellType(value) {
44113
+ switch (typeof value) {
44114
+ case "boolean":
44115
+ return "b";
44116
+ case "string":
44117
+ return "str";
44118
+ case "number":
44119
+ return "n";
44120
+ default:
44121
+ return undefined;
44122
+ }
44123
+ }
44070
44124
  function convertHeightToExcel(height) {
44071
44125
  return Math.round(HEIGHT_FACTOR * height * 100) / 100;
44072
44126
  }
@@ -54317,8 +54371,9 @@ class Evaluator {
54317
54371
  }
54318
54372
  getCellsDependingOn(positions) {
54319
54373
  const ranges = [];
54320
- for (const position of positions) {
54321
- ranges.push({ sheetId: position.sheetId, zone: positionToZone(position) });
54374
+ const zonesBySheetIds = aggregatePositionsToZones(positions);
54375
+ for (const sheetId in zonesBySheetIds) {
54376
+ ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
54322
54377
  }
54323
54378
  return this.formulaDependencies().getCellsDependingOn(ranges);
54324
54379
  }
@@ -57228,9 +57283,9 @@ class Session extends EventBus {
57228
57283
  /**
57229
57284
  * Notify the server that the user client left the collaborative session
57230
57285
  */
57231
- leave(data) {
57286
+ async leave(data) {
57232
57287
  if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57233
- this.snapshot(data());
57288
+ await this.snapshot(data());
57234
57289
  }
57235
57290
  delete this.clients[this.clientId];
57236
57291
  this.transportService.leave(this.clientId);
@@ -57243,12 +57298,12 @@ class Session extends EventBus {
57243
57298
  /**
57244
57299
  * Send a snapshot of the spreadsheet to the collaboration server
57245
57300
  */
57246
- snapshot(data) {
57301
+ async snapshot(data) {
57247
57302
  if (this.pendingMessages.length !== 0) {
57248
57303
  return;
57249
57304
  }
57250
57305
  const snapshotId = this.uuidGenerator.uuidv4();
57251
- this.transportService.sendMessage({
57306
+ await this.transportService.sendMessage({
57252
57307
  type: "SNAPSHOT",
57253
57308
  nextRevisionId: snapshotId,
57254
57309
  serverRevisionId: this.serverRevisionId,
@@ -57932,7 +57987,7 @@ class InsertPivotPlugin extends UIPlugin {
57932
57987
  this.duplicatePivotInNewSheet(cmd.pivotId, cmd.newPivotId, cmd.newSheetId);
57933
57988
  break;
57934
57989
  case "INSERT_PIVOT_WITH_TABLE":
57935
- this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table);
57990
+ this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table, cmd.pivotMode);
57936
57991
  break;
57937
57992
  }
57938
57993
  }
@@ -58008,26 +58063,44 @@ class InsertPivotPlugin extends UIPlugin {
58008
58063
  }
58009
58064
  return name;
58010
58065
  }
58011
- insertPivotWithTable(sheetId, col, row, pivotId, table) {
58066
+ insertPivotWithTable(sheetId, col, row, pivotId, table, mode) {
58012
58067
  const { cols, rows, measures, fieldsType } = table;
58013
58068
  const pivotTable = new SpreadsheetPivotTable(cols, rows, measures, fieldsType || {});
58069
+ const numberOfHeaders = pivotTable.columns.length - 1;
58014
58070
  this.resizeSheet(sheetId, col, row, pivotTable);
58015
58071
  const pivotFormulaId = this.getters.getPivotFormulaId(pivotId);
58016
- this.dispatch("UPDATE_CELL", {
58017
- sheetId,
58018
- col,
58019
- row,
58020
- content: `=PIVOT(${pivotFormulaId})`,
58021
- });
58022
- const zone = {
58023
- left: col,
58024
- right: col,
58025
- top: row,
58026
- bottom: row,
58027
- };
58028
- const numberOfHeaders = pivotTable.columns.length - 1;
58072
+ let zone;
58073
+ if (mode === "dynamic") {
58074
+ this.dispatch("UPDATE_CELL", {
58075
+ sheetId,
58076
+ col,
58077
+ row,
58078
+ content: `=PIVOT(${pivotFormulaId})`,
58079
+ });
58080
+ zone = {
58081
+ left: col,
58082
+ right: col,
58083
+ top: row,
58084
+ bottom: row,
58085
+ };
58086
+ }
58087
+ else {
58088
+ this.dispatch("INSERT_PIVOT", {
58089
+ sheetId,
58090
+ col,
58091
+ row,
58092
+ pivotId,
58093
+ table: pivotTable.export(),
58094
+ });
58095
+ zone = {
58096
+ left: col,
58097
+ right: col + pivotTable.getNumberOfDataColumns(),
58098
+ top: row,
58099
+ bottom: row + numberOfHeaders + pivotTable.rows.length,
58100
+ };
58101
+ }
58029
58102
  this.dispatch("CREATE_TABLE", {
58030
- tableType: "dynamic",
58103
+ tableType: mode,
58031
58104
  sheetId,
58032
58105
  ranges: [this.getters.getRangeDataFromZone(sheetId, zone)],
58033
58106
  config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
@@ -60229,6 +60302,8 @@ class GridSelectionPlugin extends UIPlugin {
60229
60302
  this.selectedFigureId = null;
60230
60303
  break;
60231
60304
  }
60305
+ }
60306
+ finalize() {
60232
60307
  /** Any change to the selection has to be reflected in the selection processor. */
60233
60308
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
60234
60309
  }
@@ -61010,7 +61085,6 @@ class SheetViewPlugin extends UIPlugin {
61010
61085
  }
61011
61086
  }
61012
61087
  handle(cmd) {
61013
- this.cleanViewports();
61014
61088
  // changing the evaluation can hide/show rows because of data filters
61015
61089
  if (invalidateEvaluationCommands.has(cmd.type)) {
61016
61090
  for (const sheetId of this.getters.getSheetIds()) {
@@ -61026,6 +61100,7 @@ class SheetViewPlugin extends UIPlugin {
61026
61100
  break;
61027
61101
  case "UNDO":
61028
61102
  case "REDO":
61103
+ this.cleanViewports();
61029
61104
  for (const sheetId of this.getters.getSheetIds()) {
61030
61105
  this.sheetsWithDirtyViewports.add(sheetId);
61031
61106
  }
@@ -61080,6 +61155,9 @@ class SheetViewPlugin extends UIPlugin {
61080
61155
  }
61081
61156
  }
61082
61157
  break;
61158
+ case "DELETE_SHEET":
61159
+ this.cleanViewports();
61160
+ break;
61083
61161
  case "ACTIVATE_SHEET":
61084
61162
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
61085
61163
  break;
@@ -62367,6 +62445,17 @@ css /* scss */ `
62367
62445
  .o-bottom-bar-fade-in {
62368
62446
  background-image: linear-gradient(90deg, #cfcfcf, transparent 1%);
62369
62447
  }
62448
+
62449
+ .o-sheet-list {
62450
+ overflow-y: hidden;
62451
+ overflow-x: auto;
62452
+
62453
+ &::-webkit-scrollbar {
62454
+ display: none; /* Chrome */
62455
+ }
62456
+ -ms-overflow-style: none; /* IE and Edge */
62457
+ scrollbar-width: none; /* Firefox */
62458
+ }
62370
62459
  }
62371
62460
 
62372
62461
  .o-bottom-bar-arrows {
@@ -64340,7 +64429,7 @@ class Spreadsheet extends owl.Component {
64340
64429
 
64341
64430
  class LocalTransportService {
64342
64431
  listeners = [];
64343
- sendMessage(message) {
64432
+ async sendMessage(message) {
64344
64433
  for (const { callback } of this.listeners) {
64345
64434
  callback(message);
64346
64435
  }
@@ -66433,17 +66522,13 @@ function addFormula(cell) {
66433
66522
  if (!formula) {
66434
66523
  return { attrs: [], node: escapeXml `` };
66435
66524
  }
66436
- const attrs = [];
66437
- let node = escapeXml ``;
66438
- let cycle = escapeXml ``;
66439
- const XlsxFormula = adaptFormulaToExcel(formula);
66440
- // hack for cycles : if we don't set a value (be it 0 or #VALUE!), it will appear as invisible on excel,
66441
- // Making it very hard for the client to find where the recursion is.
66442
- if (cell.value === CellErrorType.CircularDependency) {
66443
- attrs.push(["t", "str"]);
66444
- cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
66525
+ const type = getCellType(cell.value);
66526
+ if (type === undefined) {
66527
+ return { attrs: [], node: escapeXml `` };
66445
66528
  }
66446
- node = escapeXml /*xml*/ `<f>${XlsxFormula}</f>${cycle}`;
66529
+ const attrs = [["t", type]];
66530
+ const XlsxFormula = adaptFormulaToExcel(formula);
66531
+ const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${cell.value}</v>`;
66447
66532
  return { attrs, node };
66448
66533
  }
66449
66534
  function addContent(content, sharedStrings, forceString = false) {
@@ -67857,8 +67942,8 @@ class Model extends EventBus {
67857
67942
  joinSession() {
67858
67943
  this.session.join(this.config.client);
67859
67944
  }
67860
- leaveSession() {
67861
- this.session.leave(lazy(() => this.exportData()));
67945
+ async leaveSession() {
67946
+ await this.session.leave(lazy(() => this.exportData()));
67862
67947
  }
67863
67948
  setupUiPlugin(Plugin) {
67864
67949
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68460,6 +68545,6 @@ exports.tokenColors = tokenColors;
68460
68545
  exports.tokenize = tokenize;
68461
68546
 
68462
68547
 
68463
- __info__.version = "17.4.6";
68464
- __info__.date = "2024-08-26T13:50:49.623Z";
68465
- __info__.hash = "f5648d9";
68548
+ __info__.version = "17.4.7";
68549
+ __info__.date = "2024-09-05T09:32:00.461Z";
68550
+ __info__.hash = "c14a4c9";
@@ -1283,6 +1283,7 @@ interface InsertPivotWithTableCommand {
1283
1283
  row: HeaderIndex;
1284
1284
  pivotId: UID;
1285
1285
  table: PivotTableData;
1286
+ pivotMode: "static" | "dynamic";
1286
1287
  }
1287
1288
  type CoreCommand =
1288
1289
  /** CELLS */
@@ -3769,7 +3770,7 @@ interface TransportService<T = any> {
3769
3770
  /**
3770
3771
  * Send a message to all clients
3771
3772
  */
3772
- sendMessage: (message: T) => void;
3773
+ sendMessage: (message: T) => Promise<void>;
3773
3774
  /**
3774
3775
  * Register a callback function which will be called each time
3775
3776
  * a new message is received.
@@ -3866,11 +3867,11 @@ declare class Session extends EventBus<CollaborativeEvent> {
3866
3867
  /**
3867
3868
  * Notify the server that the user client left the collaborative session
3868
3869
  */
3869
- leave(data: Lazy<WorkbookData>): void;
3870
+ leave(data: Lazy<WorkbookData>): Promise<void>;
3870
3871
  /**
3871
3872
  * Send a snapshot of the spreadsheet to the collaboration server
3872
3873
  */
3873
- snapshot(data: WorkbookData): void;
3874
+ snapshot(data: WorkbookData): Promise<void>;
3874
3875
  getClient(): Client;
3875
3876
  getConnectedClients(): Set<Client>;
3876
3877
  getRevisionId(): UID;
@@ -4829,6 +4830,7 @@ declare class GridSelectionPlugin extends UIPlugin {
4829
4830
  allowDispatch(cmd: LocalCommand): CommandResult;
4830
4831
  private handleEvent;
4831
4832
  handle(cmd: Command): void;
4833
+ finalize(): void;
4832
4834
  isGridSelectionActive(): boolean;
4833
4835
  getActiveSheet(): Readonly<Sheet>;
4834
4836
  getActiveSheetId(): UID;
@@ -5780,7 +5782,7 @@ declare class Model extends EventBus<any> implements CommandDispatcher {
5780
5782
  private readonly coreHandlers;
5781
5783
  constructor(data?: any, config?: Partial<ModelConfig>, stateUpdateMessages?: StateUpdateMessage[], uuidGenerator?: UuidGenerator, verboseImport?: boolean);
5782
5784
  joinSession(): void;
5783
- leaveSession(): void;
5785
+ leaveSession(): Promise<void>;
5784
5786
  private setupUiPlugin;
5785
5787
  /**
5786
5788
  * Initialize and properly configure a plugin.
@@ -9929,12 +9931,14 @@ declare const sortDescending: ActionSpec;
9929
9931
  declare const createRemoveFilter: ActionSpec;
9930
9932
  declare const createRemoveFilterTool: ActionSpec;
9931
9933
  declare const splitToColumns: ActionSpec;
9932
- declare const reinsertPivotMenu: ActionSpec;
9934
+ declare const reinsertDynamicPivotMenu: ActionSpec;
9935
+ declare const reinsertStaticPivotMenu: ActionSpec;
9933
9936
 
9934
9937
  declare const ACTION_DATA_createRemoveFilter: typeof createRemoveFilter;
9935
9938
  declare const ACTION_DATA_createRemoveFilterTool: typeof createRemoveFilterTool;
9936
9939
  declare const ACTION_DATA_dataCleanup: typeof dataCleanup;
9937
- declare const ACTION_DATA_reinsertPivotMenu: typeof reinsertPivotMenu;
9940
+ declare const ACTION_DATA_reinsertDynamicPivotMenu: typeof reinsertDynamicPivotMenu;
9941
+ declare const ACTION_DATA_reinsertStaticPivotMenu: typeof reinsertStaticPivotMenu;
9938
9942
  declare const ACTION_DATA_removeDuplicates: typeof removeDuplicates;
9939
9943
  declare const ACTION_DATA_sortAscending: typeof sortAscending;
9940
9944
  declare const ACTION_DATA_sortDescending: typeof sortDescending;
@@ -9946,7 +9950,8 @@ declare namespace ACTION_DATA {
9946
9950
  ACTION_DATA_createRemoveFilter as createRemoveFilter,
9947
9951
  ACTION_DATA_createRemoveFilterTool as createRemoveFilterTool,
9948
9952
  ACTION_DATA_dataCleanup as dataCleanup,
9949
- ACTION_DATA_reinsertPivotMenu as reinsertPivotMenu,
9953
+ ACTION_DATA_reinsertDynamicPivotMenu as reinsertDynamicPivotMenu,
9954
+ ACTION_DATA_reinsertStaticPivotMenu as reinsertStaticPivotMenu,
9950
9955
  ACTION_DATA_removeDuplicates as removeDuplicates,
9951
9956
  ACTION_DATA_sortAscending as sortAscending,
9952
9957
  ACTION_DATA_sortDescending as sortDescending,