@odoo/o-spreadsheet 18.4.18 → 18.4.19

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.4.18
6
- * @date 2025-11-24T07:42:07.821Z
7
- * @hash 4f83667
5
+ * @version 18.4.19
6
+ * @date 2025-12-02T05:34:03.902Z
7
+ * @hash 95b1252
8
8
  */
9
9
 
10
10
  'use strict';
@@ -2615,7 +2615,6 @@ const invalidateEvaluationCommands = new Set([
2615
2615
  "REDO",
2616
2616
  "ADD_MERGE",
2617
2617
  "REMOVE_MERGE",
2618
- "DUPLICATE_SHEET",
2619
2618
  "UPDATE_LOCALE",
2620
2619
  "ADD_PIVOT",
2621
2620
  "UPDATE_PIVOT",
@@ -22584,6 +22583,9 @@ function getTreeMapGroupColors(definition, tree) {
22584
22583
  }));
22585
22584
  }
22586
22585
  function getTreeMapColorScale(tree, coloringOption) {
22586
+ if (tree.length === 0) {
22587
+ return undefined;
22588
+ }
22587
22589
  const treeNodesByLevel = pyramidizeTree(tree);
22588
22590
  const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
22589
22591
  const minValue = Math.min(...nodes.map((node) => node.value));
@@ -24253,11 +24255,18 @@ function chartToImageUrl(runtime, figure, type) {
24253
24255
  // we have to add the canvas to the DOM otherwise it won't be rendered
24254
24256
  document.body.append(div);
24255
24257
  if ("chartJsConfig" in runtime) {
24258
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24259
+ if (!extensionsLoaded) {
24260
+ registerChartJSExtensions();
24261
+ }
24256
24262
  const config = deepCopy(runtime.chartJsConfig);
24257
24263
  config.plugins = [backgroundColorChartJSPlugin];
24258
24264
  const chart = new window.Chart(canvas, config);
24259
24265
  imageContent = chart.toBase64Image();
24260
24266
  chart.destroy();
24267
+ if (!extensionsLoaded) {
24268
+ unregisterChartJsExtensions();
24269
+ }
24261
24270
  }
24262
24271
  else if (type === "scorecard") {
24263
24272
  const design = getScorecardConfiguration(figure, runtime);
@@ -24287,11 +24296,18 @@ async function chartToImageFile(runtime, figure, type) {
24287
24296
  document.body.append(div);
24288
24297
  let chartBlob = null;
24289
24298
  if ("chartJsConfig" in runtime) {
24299
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24300
+ if (!extensionsLoaded) {
24301
+ registerChartJSExtensions();
24302
+ }
24290
24303
  const config = deepCopy(runtime.chartJsConfig);
24291
24304
  config.plugins = [backgroundColorChartJSPlugin];
24292
24305
  const chart = new window.Chart(canvas, config);
24293
24306
  chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
24294
24307
  chart.destroy();
24308
+ if (!extensionsLoaded) {
24309
+ unregisterChartJsExtensions();
24310
+ }
24295
24311
  }
24296
24312
  else if (type === "scorecard") {
24297
24313
  const design = getScorecardConfiguration(figure, runtime);
@@ -32644,7 +32660,7 @@ class AbstractComposerStore extends SpreadsheetStore {
32644
32660
  }
32645
32661
  this.selectionStart = start;
32646
32662
  this.selectionEnd = end;
32647
- this.editionMode = "editing";
32663
+ this.stopComposerRangeSelection();
32648
32664
  this.computeFormulaCursorContext();
32649
32665
  this.computeParenthesisRelatedToCursor();
32650
32666
  this.updateAutoCompleteProvider();
@@ -33549,7 +33565,8 @@ class Composer extends owl.Component {
33549
33565
  assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
33550
33566
  // render top
33551
33567
  // We compensate 2 px of margin on the assistant style + 1px for design reasons
33552
- assistantStyle.transform = `translate(0, calc(-100% - ${cellHeight + 3}px))`;
33568
+ assistantStyle.top = `-3px`;
33569
+ assistantStyle.transform = `translate(0, -100%)`;
33553
33570
  }
33554
33571
  if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
33555
33572
  // render left
@@ -56041,7 +56058,6 @@ const dateGranularities = [
56041
56058
  pivotRegistry.add("SPREADSHEET", {
56042
56059
  ui: SpreadsheetPivot,
56043
56060
  definition: SpreadsheetPivotRuntimeDefinition,
56044
- externalData: false,
56045
56061
  dateGranularities: [...dateGranularities],
56046
56062
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
56047
56063
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64435,10 +64451,17 @@ class PivotCorePlugin extends CorePlugin {
64435
64451
  if (!pivot) {
64436
64452
  continue;
64437
64453
  }
64438
- for (const measure of pivot.definition.measures) {
64454
+ const def = deepCopy(pivot.definition);
64455
+ for (const measure of def.measures) {
64439
64456
  if (measure.computedBy?.formula === formulaString) {
64440
- const measureIndex = pivot.definition.measures.indexOf(measure);
64441
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
64457
+ const measureIndex = def.measures.indexOf(measure);
64458
+ if (measureIndex !== -1) {
64459
+ def.measures[measureIndex].computedBy = {
64460
+ formula: newFormulaString,
64461
+ sheetId,
64462
+ };
64463
+ }
64464
+ this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
64442
64465
  }
64443
64466
  }
64444
64467
  }
@@ -64576,6 +64599,9 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
64576
64599
  const { sheetId, zone } = definition.dataSet;
64577
64600
  const range = this.getters.getRangeFromZone(sheetId, zone);
64578
64601
  const adaptedRange = adaptPivotRange(range, applyChange);
64602
+ if (adaptedRange === range) {
64603
+ return;
64604
+ }
64579
64605
  const dataSet = adaptedRange && {
64580
64606
  sheetId: adaptedRange.sheetId,
64581
64607
  zone: adaptedRange.zone,
@@ -68581,9 +68607,7 @@ class PivotUIPlugin extends CoreViewPlugin {
68581
68607
  handle(cmd) {
68582
68608
  if (invalidateEvaluationCommands.has(cmd.type)) {
68583
68609
  for (const pivotId of this.getters.getPivotIds()) {
68584
- if (!pivotRegistry.get(this.getters.getPivotCoreDefinition(pivotId).type).externalData) {
68585
- this.setupPivot(pivotId, { recreate: true });
68586
- }
68610
+ this.setupPivot(pivotId, { recreate: true });
68587
68611
  }
68588
68612
  }
68589
68613
  switch (cmd.type) {
@@ -68791,7 +68815,7 @@ class PivotUIPlugin extends CoreViewPlugin {
68791
68815
  pivot.init({ reload: true });
68792
68816
  }
68793
68817
  setupPivot(pivotId, { recreate } = { recreate: false }) {
68794
- const definition = this.getters.getPivotCoreDefinition(pivotId);
68818
+ const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
68795
68819
  if (!(pivotId in this.pivots)) {
68796
68820
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
68797
68821
  this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
@@ -78044,16 +78068,18 @@ class ClickableCellsStore extends SpreadsheetStore {
78044
78068
  get clickableCells() {
78045
78069
  const cells = [];
78046
78070
  const getters = this.getters;
78047
- const sheetId = getters.getActiveSheetId();
78048
78071
  for (const position of this.getters.getVisibleCellPositions()) {
78049
78072
  const item = this.getClickableItem(position);
78050
78073
  if (!item) {
78051
78074
  continue;
78052
78075
  }
78053
78076
  const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
78054
- const zone = getters.expandZone(sheetId, positionToZone(position));
78077
+ const rect = this.getClickableCellRect(position);
78078
+ if (!rect) {
78079
+ continue;
78080
+ }
78055
78081
  cells.push({
78056
- coordinates: getters.getVisibleRect(zone),
78082
+ coordinates: rect,
78057
78083
  position,
78058
78084
  action: item.execute,
78059
78085
  title: title || "",
@@ -78061,6 +78087,31 @@ class ClickableCellsStore extends SpreadsheetStore {
78061
78087
  }
78062
78088
  return cells;
78063
78089
  }
78090
+ getClickableCellRect(position) {
78091
+ const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
78092
+ const clickableRect = this.getters.getVisibleRect(zone);
78093
+ const icons = this.getters.getCellIcons(position);
78094
+ const iconsAtPosition = {
78095
+ center: icons.find((icon) => icon.horizontalAlign === "center"),
78096
+ left: icons.find((icon) => icon.horizontalAlign === "left"),
78097
+ right: icons.find((icon) => icon.horizontalAlign === "right"),
78098
+ };
78099
+ if (iconsAtPosition.center?.onClick) {
78100
+ return undefined;
78101
+ }
78102
+ if (iconsAtPosition.right?.onClick) {
78103
+ const cellRect = this.getters.getRect(zone);
78104
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
78105
+ clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
78106
+ }
78107
+ if (iconsAtPosition.left?.onClick) {
78108
+ const cellRect = this.getters.getRect(zone);
78109
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
78110
+ clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
78111
+ clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
78112
+ }
78113
+ return clickableRect;
78114
+ }
78064
78115
  }
78065
78116
 
78066
78117
  css /* scss */ `
@@ -78817,7 +78868,7 @@ class SmallBottomBar extends owl.Component {
78817
78868
  height: this.focus === "inactive" ? "26px" : "fit-content",
78818
78869
  "max-height": `130px`,
78819
78870
  }),
78820
- showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
78871
+ showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
78821
78872
  placeholder: this.composerStore.placeholder,
78822
78873
  };
78823
78874
  }
@@ -84950,6 +85001,6 @@ exports.tokenColors = tokenColors;
84950
85001
  exports.tokenize = tokenize;
84951
85002
 
84952
85003
 
84953
- __info__.version = "18.4.18";
84954
- __info__.date = "2025-11-24T07:42:07.821Z";
84955
- __info__.hash = "4f83667";
85004
+ __info__.version = "18.4.19";
85005
+ __info__.date = "2025-12-02T05:34:03.902Z";
85006
+ __info__.hash = "95b1252";
@@ -6766,7 +6766,6 @@ type PivotDefinitionConstructor = new (definition: PivotCoreDefinition, fields:
6766
6766
  interface PivotRegistryItem {
6767
6767
  ui: PivotUIConstructor;
6768
6768
  definition: PivotDefinitionConstructor;
6769
- externalData: boolean;
6770
6769
  dateGranularities: string[];
6771
6770
  datetimeGranularities: string[];
6772
6771
  isMeasureCandidate: (field: PivotField) => boolean;
@@ -11990,6 +11989,7 @@ declare class ClickableCellsStore extends SpreadsheetStore {
11990
11989
  private getClickableItem;
11991
11990
  private findClickableItem;
11992
11991
  get clickableCells(): ClickableCell[];
11992
+ private getClickableCellRect;
11993
11993
  }
11994
11994
 
11995
11995
  interface Props$4 {
@@ -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.4.18
6
- * @date 2025-11-24T07:42:07.821Z
7
- * @hash 4f83667
5
+ * @version 18.4.19
6
+ * @date 2025-12-02T05:34:03.902Z
7
+ * @hash 95b1252
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -2613,7 +2613,6 @@ const invalidateEvaluationCommands = new Set([
2613
2613
  "REDO",
2614
2614
  "ADD_MERGE",
2615
2615
  "REMOVE_MERGE",
2616
- "DUPLICATE_SHEET",
2617
2616
  "UPDATE_LOCALE",
2618
2617
  "ADD_PIVOT",
2619
2618
  "UPDATE_PIVOT",
@@ -22582,6 +22581,9 @@ function getTreeMapGroupColors(definition, tree) {
22582
22581
  }));
22583
22582
  }
22584
22583
  function getTreeMapColorScale(tree, coloringOption) {
22584
+ if (tree.length === 0) {
22585
+ return undefined;
22586
+ }
22585
22587
  const treeNodesByLevel = pyramidizeTree(tree);
22586
22588
  const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
22587
22589
  const minValue = Math.min(...nodes.map((node) => node.value));
@@ -24251,11 +24253,18 @@ function chartToImageUrl(runtime, figure, type) {
24251
24253
  // we have to add the canvas to the DOM otherwise it won't be rendered
24252
24254
  document.body.append(div);
24253
24255
  if ("chartJsConfig" in runtime) {
24256
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24257
+ if (!extensionsLoaded) {
24258
+ registerChartJSExtensions();
24259
+ }
24254
24260
  const config = deepCopy(runtime.chartJsConfig);
24255
24261
  config.plugins = [backgroundColorChartJSPlugin];
24256
24262
  const chart = new window.Chart(canvas, config);
24257
24263
  imageContent = chart.toBase64Image();
24258
24264
  chart.destroy();
24265
+ if (!extensionsLoaded) {
24266
+ unregisterChartJsExtensions();
24267
+ }
24259
24268
  }
24260
24269
  else if (type === "scorecard") {
24261
24270
  const design = getScorecardConfiguration(figure, runtime);
@@ -24285,11 +24294,18 @@ async function chartToImageFile(runtime, figure, type) {
24285
24294
  document.body.append(div);
24286
24295
  let chartBlob = null;
24287
24296
  if ("chartJsConfig" in runtime) {
24297
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24298
+ if (!extensionsLoaded) {
24299
+ registerChartJSExtensions();
24300
+ }
24288
24301
  const config = deepCopy(runtime.chartJsConfig);
24289
24302
  config.plugins = [backgroundColorChartJSPlugin];
24290
24303
  const chart = new window.Chart(canvas, config);
24291
24304
  chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
24292
24305
  chart.destroy();
24306
+ if (!extensionsLoaded) {
24307
+ unregisterChartJsExtensions();
24308
+ }
24293
24309
  }
24294
24310
  else if (type === "scorecard") {
24295
24311
  const design = getScorecardConfiguration(figure, runtime);
@@ -32642,7 +32658,7 @@ class AbstractComposerStore extends SpreadsheetStore {
32642
32658
  }
32643
32659
  this.selectionStart = start;
32644
32660
  this.selectionEnd = end;
32645
- this.editionMode = "editing";
32661
+ this.stopComposerRangeSelection();
32646
32662
  this.computeFormulaCursorContext();
32647
32663
  this.computeParenthesisRelatedToCursor();
32648
32664
  this.updateAutoCompleteProvider();
@@ -33547,7 +33563,8 @@ class Composer extends Component {
33547
33563
  assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
33548
33564
  // render top
33549
33565
  // We compensate 2 px of margin on the assistant style + 1px for design reasons
33550
- assistantStyle.transform = `translate(0, calc(-100% - ${cellHeight + 3}px))`;
33566
+ assistantStyle.top = `-3px`;
33567
+ assistantStyle.transform = `translate(0, -100%)`;
33551
33568
  }
33552
33569
  if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
33553
33570
  // render left
@@ -56039,7 +56056,6 @@ const dateGranularities = [
56039
56056
  pivotRegistry.add("SPREADSHEET", {
56040
56057
  ui: SpreadsheetPivot,
56041
56058
  definition: SpreadsheetPivotRuntimeDefinition,
56042
- externalData: false,
56043
56059
  dateGranularities: [...dateGranularities],
56044
56060
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
56045
56061
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64433,10 +64449,17 @@ class PivotCorePlugin extends CorePlugin {
64433
64449
  if (!pivot) {
64434
64450
  continue;
64435
64451
  }
64436
- for (const measure of pivot.definition.measures) {
64452
+ const def = deepCopy(pivot.definition);
64453
+ for (const measure of def.measures) {
64437
64454
  if (measure.computedBy?.formula === formulaString) {
64438
- const measureIndex = pivot.definition.measures.indexOf(measure);
64439
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
64455
+ const measureIndex = def.measures.indexOf(measure);
64456
+ if (measureIndex !== -1) {
64457
+ def.measures[measureIndex].computedBy = {
64458
+ formula: newFormulaString,
64459
+ sheetId,
64460
+ };
64461
+ }
64462
+ this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
64440
64463
  }
64441
64464
  }
64442
64465
  }
@@ -64574,6 +64597,9 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
64574
64597
  const { sheetId, zone } = definition.dataSet;
64575
64598
  const range = this.getters.getRangeFromZone(sheetId, zone);
64576
64599
  const adaptedRange = adaptPivotRange(range, applyChange);
64600
+ if (adaptedRange === range) {
64601
+ return;
64602
+ }
64577
64603
  const dataSet = adaptedRange && {
64578
64604
  sheetId: adaptedRange.sheetId,
64579
64605
  zone: adaptedRange.zone,
@@ -68579,9 +68605,7 @@ class PivotUIPlugin extends CoreViewPlugin {
68579
68605
  handle(cmd) {
68580
68606
  if (invalidateEvaluationCommands.has(cmd.type)) {
68581
68607
  for (const pivotId of this.getters.getPivotIds()) {
68582
- if (!pivotRegistry.get(this.getters.getPivotCoreDefinition(pivotId).type).externalData) {
68583
- this.setupPivot(pivotId, { recreate: true });
68584
- }
68608
+ this.setupPivot(pivotId, { recreate: true });
68585
68609
  }
68586
68610
  }
68587
68611
  switch (cmd.type) {
@@ -68789,7 +68813,7 @@ class PivotUIPlugin extends CoreViewPlugin {
68789
68813
  pivot.init({ reload: true });
68790
68814
  }
68791
68815
  setupPivot(pivotId, { recreate } = { recreate: false }) {
68792
- const definition = this.getters.getPivotCoreDefinition(pivotId);
68816
+ const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
68793
68817
  if (!(pivotId in this.pivots)) {
68794
68818
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
68795
68819
  this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
@@ -78042,16 +78066,18 @@ class ClickableCellsStore extends SpreadsheetStore {
78042
78066
  get clickableCells() {
78043
78067
  const cells = [];
78044
78068
  const getters = this.getters;
78045
- const sheetId = getters.getActiveSheetId();
78046
78069
  for (const position of this.getters.getVisibleCellPositions()) {
78047
78070
  const item = this.getClickableItem(position);
78048
78071
  if (!item) {
78049
78072
  continue;
78050
78073
  }
78051
78074
  const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
78052
- const zone = getters.expandZone(sheetId, positionToZone(position));
78075
+ const rect = this.getClickableCellRect(position);
78076
+ if (!rect) {
78077
+ continue;
78078
+ }
78053
78079
  cells.push({
78054
- coordinates: getters.getVisibleRect(zone),
78080
+ coordinates: rect,
78055
78081
  position,
78056
78082
  action: item.execute,
78057
78083
  title: title || "",
@@ -78059,6 +78085,31 @@ class ClickableCellsStore extends SpreadsheetStore {
78059
78085
  }
78060
78086
  return cells;
78061
78087
  }
78088
+ getClickableCellRect(position) {
78089
+ const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
78090
+ const clickableRect = this.getters.getVisibleRect(zone);
78091
+ const icons = this.getters.getCellIcons(position);
78092
+ const iconsAtPosition = {
78093
+ center: icons.find((icon) => icon.horizontalAlign === "center"),
78094
+ left: icons.find((icon) => icon.horizontalAlign === "left"),
78095
+ right: icons.find((icon) => icon.horizontalAlign === "right"),
78096
+ };
78097
+ if (iconsAtPosition.center?.onClick) {
78098
+ return undefined;
78099
+ }
78100
+ if (iconsAtPosition.right?.onClick) {
78101
+ const cellRect = this.getters.getRect(zone);
78102
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
78103
+ clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
78104
+ }
78105
+ if (iconsAtPosition.left?.onClick) {
78106
+ const cellRect = this.getters.getRect(zone);
78107
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
78108
+ clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
78109
+ clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
78110
+ }
78111
+ return clickableRect;
78112
+ }
78062
78113
  }
78063
78114
 
78064
78115
  css /* scss */ `
@@ -78815,7 +78866,7 @@ class SmallBottomBar extends Component {
78815
78866
  height: this.focus === "inactive" ? "26px" : "fit-content",
78816
78867
  "max-height": `130px`,
78817
78868
  }),
78818
- showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
78869
+ showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
78819
78870
  placeholder: this.composerStore.placeholder,
78820
78871
  };
78821
78872
  }
@@ -84900,6 +84951,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84900
84951
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84901
84952
 
84902
84953
 
84903
- __info__.version = "18.4.18";
84904
- __info__.date = "2025-11-24T07:42:07.821Z";
84905
- __info__.hash = "4f83667";
84954
+ __info__.version = "18.4.19";
84955
+ __info__.date = "2025-12-02T05:34:03.902Z";
84956
+ __info__.hash = "95b1252";
@@ -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.4.18
6
- * @date 2025-11-24T07:42:07.821Z
7
- * @hash 4f83667
5
+ * @version 18.4.19
6
+ * @date 2025-12-02T05:34:03.902Z
7
+ * @hash 95b1252
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2614,7 +2614,6 @@
2614
2614
  "REDO",
2615
2615
  "ADD_MERGE",
2616
2616
  "REMOVE_MERGE",
2617
- "DUPLICATE_SHEET",
2618
2617
  "UPDATE_LOCALE",
2619
2618
  "ADD_PIVOT",
2620
2619
  "UPDATE_PIVOT",
@@ -22583,6 +22582,9 @@ stores.inject(MyMetaStore, storeInstance);
22583
22582
  }));
22584
22583
  }
22585
22584
  function getTreeMapColorScale(tree, coloringOption) {
22585
+ if (tree.length === 0) {
22586
+ return undefined;
22587
+ }
22586
22588
  const treeNodesByLevel = pyramidizeTree(tree);
22587
22589
  const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
22588
22590
  const minValue = Math.min(...nodes.map((node) => node.value));
@@ -24252,11 +24254,18 @@ stores.inject(MyMetaStore, storeInstance);
24252
24254
  // we have to add the canvas to the DOM otherwise it won't be rendered
24253
24255
  document.body.append(div);
24254
24256
  if ("chartJsConfig" in runtime) {
24257
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24258
+ if (!extensionsLoaded) {
24259
+ registerChartJSExtensions();
24260
+ }
24255
24261
  const config = deepCopy(runtime.chartJsConfig);
24256
24262
  config.plugins = [backgroundColorChartJSPlugin];
24257
24263
  const chart = new window.Chart(canvas, config);
24258
24264
  imageContent = chart.toBase64Image();
24259
24265
  chart.destroy();
24266
+ if (!extensionsLoaded) {
24267
+ unregisterChartJsExtensions();
24268
+ }
24260
24269
  }
24261
24270
  else if (type === "scorecard") {
24262
24271
  const design = getScorecardConfiguration(figure, runtime);
@@ -24286,11 +24295,18 @@ stores.inject(MyMetaStore, storeInstance);
24286
24295
  document.body.append(div);
24287
24296
  let chartBlob = null;
24288
24297
  if ("chartJsConfig" in runtime) {
24298
+ const extensionsLoaded = areChartJSExtensionsLoaded();
24299
+ if (!extensionsLoaded) {
24300
+ registerChartJSExtensions();
24301
+ }
24289
24302
  const config = deepCopy(runtime.chartJsConfig);
24290
24303
  config.plugins = [backgroundColorChartJSPlugin];
24291
24304
  const chart = new window.Chart(canvas, config);
24292
24305
  chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
24293
24306
  chart.destroy();
24307
+ if (!extensionsLoaded) {
24308
+ unregisterChartJsExtensions();
24309
+ }
24294
24310
  }
24295
24311
  else if (type === "scorecard") {
24296
24312
  const design = getScorecardConfiguration(figure, runtime);
@@ -32643,7 +32659,7 @@ stores.inject(MyMetaStore, storeInstance);
32643
32659
  }
32644
32660
  this.selectionStart = start;
32645
32661
  this.selectionEnd = end;
32646
- this.editionMode = "editing";
32662
+ this.stopComposerRangeSelection();
32647
32663
  this.computeFormulaCursorContext();
32648
32664
  this.computeParenthesisRelatedToCursor();
32649
32665
  this.updateAutoCompleteProvider();
@@ -33548,7 +33564,8 @@ stores.inject(MyMetaStore, storeInstance);
33548
33564
  assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
33549
33565
  // render top
33550
33566
  // We compensate 2 px of margin on the assistant style + 1px for design reasons
33551
- assistantStyle.transform = `translate(0, calc(-100% - ${cellHeight + 3}px))`;
33567
+ assistantStyle.top = `-3px`;
33568
+ assistantStyle.transform = `translate(0, -100%)`;
33552
33569
  }
33553
33570
  if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
33554
33571
  // render left
@@ -56040,7 +56057,6 @@ stores.inject(MyMetaStore, storeInstance);
56040
56057
  pivotRegistry.add("SPREADSHEET", {
56041
56058
  ui: SpreadsheetPivot,
56042
56059
  definition: SpreadsheetPivotRuntimeDefinition,
56043
- externalData: false,
56044
56060
  dateGranularities: [...dateGranularities],
56045
56061
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
56046
56062
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64434,10 +64450,17 @@ stores.inject(MyMetaStore, storeInstance);
64434
64450
  if (!pivot) {
64435
64451
  continue;
64436
64452
  }
64437
- for (const measure of pivot.definition.measures) {
64453
+ const def = deepCopy(pivot.definition);
64454
+ for (const measure of def.measures) {
64438
64455
  if (measure.computedBy?.formula === formulaString) {
64439
- const measureIndex = pivot.definition.measures.indexOf(measure);
64440
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
64456
+ const measureIndex = def.measures.indexOf(measure);
64457
+ if (measureIndex !== -1) {
64458
+ def.measures[measureIndex].computedBy = {
64459
+ formula: newFormulaString,
64460
+ sheetId,
64461
+ };
64462
+ }
64463
+ this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
64441
64464
  }
64442
64465
  }
64443
64466
  }
@@ -64575,6 +64598,9 @@ stores.inject(MyMetaStore, storeInstance);
64575
64598
  const { sheetId, zone } = definition.dataSet;
64576
64599
  const range = this.getters.getRangeFromZone(sheetId, zone);
64577
64600
  const adaptedRange = adaptPivotRange(range, applyChange);
64601
+ if (adaptedRange === range) {
64602
+ return;
64603
+ }
64578
64604
  const dataSet = adaptedRange && {
64579
64605
  sheetId: adaptedRange.sheetId,
64580
64606
  zone: adaptedRange.zone,
@@ -68580,9 +68606,7 @@ stores.inject(MyMetaStore, storeInstance);
68580
68606
  handle(cmd) {
68581
68607
  if (invalidateEvaluationCommands.has(cmd.type)) {
68582
68608
  for (const pivotId of this.getters.getPivotIds()) {
68583
- if (!pivotRegistry.get(this.getters.getPivotCoreDefinition(pivotId).type).externalData) {
68584
- this.setupPivot(pivotId, { recreate: true });
68585
- }
68609
+ this.setupPivot(pivotId, { recreate: true });
68586
68610
  }
68587
68611
  }
68588
68612
  switch (cmd.type) {
@@ -68790,7 +68814,7 @@ stores.inject(MyMetaStore, storeInstance);
68790
68814
  pivot.init({ reload: true });
68791
68815
  }
68792
68816
  setupPivot(pivotId, { recreate } = { recreate: false }) {
68793
- const definition = this.getters.getPivotCoreDefinition(pivotId);
68817
+ const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
68794
68818
  if (!(pivotId in this.pivots)) {
68795
68819
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
68796
68820
  this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
@@ -78043,16 +78067,18 @@ stores.inject(MyMetaStore, storeInstance);
78043
78067
  get clickableCells() {
78044
78068
  const cells = [];
78045
78069
  const getters = this.getters;
78046
- const sheetId = getters.getActiveSheetId();
78047
78070
  for (const position of this.getters.getVisibleCellPositions()) {
78048
78071
  const item = this.getClickableItem(position);
78049
78072
  if (!item) {
78050
78073
  continue;
78051
78074
  }
78052
78075
  const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
78053
- const zone = getters.expandZone(sheetId, positionToZone(position));
78076
+ const rect = this.getClickableCellRect(position);
78077
+ if (!rect) {
78078
+ continue;
78079
+ }
78054
78080
  cells.push({
78055
- coordinates: getters.getVisibleRect(zone),
78081
+ coordinates: rect,
78056
78082
  position,
78057
78083
  action: item.execute,
78058
78084
  title: title || "",
@@ -78060,6 +78086,31 @@ stores.inject(MyMetaStore, storeInstance);
78060
78086
  }
78061
78087
  return cells;
78062
78088
  }
78089
+ getClickableCellRect(position) {
78090
+ const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
78091
+ const clickableRect = this.getters.getVisibleRect(zone);
78092
+ const icons = this.getters.getCellIcons(position);
78093
+ const iconsAtPosition = {
78094
+ center: icons.find((icon) => icon.horizontalAlign === "center"),
78095
+ left: icons.find((icon) => icon.horizontalAlign === "left"),
78096
+ right: icons.find((icon) => icon.horizontalAlign === "right"),
78097
+ };
78098
+ if (iconsAtPosition.center?.onClick) {
78099
+ return undefined;
78100
+ }
78101
+ if (iconsAtPosition.right?.onClick) {
78102
+ const cellRect = this.getters.getRect(zone);
78103
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
78104
+ clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
78105
+ }
78106
+ if (iconsAtPosition.left?.onClick) {
78107
+ const cellRect = this.getters.getRect(zone);
78108
+ const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
78109
+ clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
78110
+ clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
78111
+ }
78112
+ return clickableRect;
78113
+ }
78063
78114
  }
78064
78115
 
78065
78116
  css /* scss */ `
@@ -78816,7 +78867,7 @@ stores.inject(MyMetaStore, storeInstance);
78816
78867
  height: this.focus === "inactive" ? "26px" : "fit-content",
78817
78868
  "max-height": `130px`,
78818
78869
  }),
78819
- showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
78870
+ showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
78820
78871
  placeholder: this.composerStore.placeholder,
78821
78872
  };
78822
78873
  }
@@ -84949,9 +85000,9 @@ stores.inject(MyMetaStore, storeInstance);
84949
85000
  exports.tokenize = tokenize;
84950
85001
 
84951
85002
 
84952
- __info__.version = "18.4.18";
84953
- __info__.date = "2025-11-24T07:42:07.821Z";
84954
- __info__.hash = "4f83667";
85003
+ __info__.version = "18.4.19";
85004
+ __info__.date = "2025-12-02T05:34:03.902Z";
85005
+ __info__.hash = "95b1252";
84955
85006
 
84956
85007
 
84957
85008
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);