@odoo/o-spreadsheet 19.4.0-alpha.11 → 19.4.0-alpha.13

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 19.4.0-alpha.11
6
- * @date 2026-06-03T11:42:34.595Z
7
- * @hash 6f35bc7
5
+ * @version 19.4.0-alpha.13
6
+ * @date 2026-06-06T09:34:53.140Z
7
+ * @hash af3c199
8
8
  */
9
9
 
10
10
  import { App, Component, EnvPlugin, Plugin, __ODOO_COMPATIBILITY_LAYER_ADDED__, blockDom, config, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, plugin, props, providePlugins, proxy, signal, status, toRaw, types, useChildEnv, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useLayoutEffect, useListener, useScope, useSubEnv, whenReady, xml } from "@odoo/owl";
@@ -4322,6 +4322,7 @@ const DEFAULT_LOCALE_DIGIT_GROUPING = "[3,0]";
4322
4322
  //#endregion
4323
4323
  //#region src/helpers/format/format_tokenizer.ts
4324
4324
  function tokenizeFormat(str) {
4325
+ str = str.replace(/\s/g, " ");
4325
4326
  const chars = new TokenizingChars(str);
4326
4327
  const result = [];
4327
4328
  let currentFormatPart = [];
@@ -10556,7 +10557,7 @@ function getFunnelChartScales(definition, args) {
10556
10557
  };
10557
10558
  }
10558
10559
  function getGeoChartProjection(projection) {
10559
- if (projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10560
+ if (globalThis.ChartGeo && projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10560
10561
  return projection;
10561
10562
  }
10562
10563
  function getChartAxisTitleRuntime(design) {
@@ -10569,7 +10570,7 @@ function getChartAxisTitleRuntime(design) {
10569
10570
  font: {
10570
10571
  style: italic ? "italic" : "normal",
10571
10572
  weight: bold ? "bold" : "normal",
10572
- size: design.title.fontSize ?? 12
10573
+ size: fontSizeInPixels(design.title.fontSize ?? 12)
10573
10574
  },
10574
10575
  align: align === "left" ? "start" : align === "right" ? "end" : "center"
10575
10576
  };
@@ -11191,7 +11192,7 @@ function getTextStyle(design, defaultDesign) {
11191
11192
  font: {
11192
11193
  weight: design?.bold ?? defaultDesign?.bold ? "bold" : "normal",
11193
11194
  style: design?.italic ?? defaultDesign?.italic ? "italic" : "normal",
11194
- size: design?.fontSize ?? defaultDesign?.fontSize
11195
+ size: fontSizeInPixels(design?.fontSize ?? defaultDesign.fontSize)
11195
11196
  }
11196
11197
  };
11197
11198
  }
@@ -12127,35 +12128,35 @@ var ScorecardChartConfigBuilder = class {
12127
12128
  if (this.runtime.progressBar) baselineValueFontSize /= 1.5;
12128
12129
  return {
12129
12130
  title: {
12130
- font: getDefaultContextFont(this.runtime.title.fontSize ?? 14, this.runtime.title.bold, this.runtime.title.italic),
12131
+ font: getDefaultContextFont(fontSizeInPixels(this.runtime.title.fontSize ?? 14), this.runtime.title.bold, this.runtime.title.italic),
12131
12132
  color: this.runtime.title.color ?? this.secondaryFontColor
12132
12133
  },
12133
12134
  keyValue: {
12134
12135
  color: this.runtime.keyValueStyle?.textColor || this.runtime.fontColor,
12135
- font: getDefaultContextFont(keyValueFontSize, this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12136
+ font: getDefaultContextFont(fontSizeInPixels(keyValueFontSize), this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12136
12137
  strikethrough: this.runtime.keyValueStyle?.strikethrough,
12137
12138
  underline: this.runtime.keyValueStyle?.underline
12138
12139
  },
12139
12140
  keyDescr: {
12140
12141
  color: this.runtime.keyValueDescrStyle?.textColor || this.runtime.fontColor,
12141
- font: getDefaultContextFont(keyValueDescrFontSize, this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12142
+ font: getDefaultContextFont(fontSizeInPixels(keyValueDescrFontSize), this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12142
12143
  strikethrough: this.runtime.keyValueDescrStyle?.strikethrough,
12143
12144
  underline: this.runtime.keyValueDescrStyle?.underline
12144
12145
  },
12145
12146
  baselineValue: {
12146
- font: getDefaultContextFont(baselineValueFontSize, this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12147
+ font: getDefaultContextFont(fontSizeInPixels(baselineValueFontSize), this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12147
12148
  strikethrough: this.runtime.baselineStyle?.strikethrough,
12148
12149
  underline: this.runtime.baselineStyle?.underline,
12149
12150
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12150
12151
  },
12151
12152
  baselineDescr: {
12152
- font: getDefaultContextFont(baselineDescrFontSize, this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12153
+ font: getDefaultContextFont(fontSizeInPixels(baselineDescrFontSize), this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12153
12154
  strikethrough: this.runtime.baselineDescrStyle?.strikethrough,
12154
12155
  underline: this.runtime.baselineDescrStyle?.underline,
12155
12156
  color: this.runtime.baselineDescrStyle?.textColor ?? this.secondaryFontColor
12156
12157
  },
12157
12158
  baselineArrow: this.baselineArrow === "neutral" || this.runtime.progressBar ? void 0 : {
12158
- size: this.keyValue ? .8 * baselineValueFontSize : 0,
12159
+ size: this.keyValue ? .8 * fontSizeInPixels(baselineValueFontSize) : 0,
12159
12160
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12160
12161
  }
12161
12162
  };
@@ -12365,7 +12366,7 @@ function drawInflectionValues(ctx, config) {
12365
12366
  function drawTitle(ctx, config) {
12366
12367
  ctx.save();
12367
12368
  const title = config.title;
12368
- ctx.font = getDefaultContextFont(title.fontSize, title.bold, title.italic);
12369
+ ctx.font = getDefaultContextFont(fontSizeInPixels(title.fontSize), title.bold, title.italic);
12369
12370
  ctx.textBaseline = "middle";
12370
12371
  ctx.fillStyle = title.color;
12371
12372
  ctx.fillText(title.label, title.textPosition.x, title.textPosition.y);
@@ -12399,8 +12400,8 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12399
12400
  const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
12400
12401
  let x = 0, titleWidth = 0, titleHeight = 0;
12401
12402
  if (runtime.title.text) ({width: titleWidth, height: titleHeight} = computeTextDimension(ctx, runtime.title.text, {
12402
- fontSize: 16,
12403
- ...runtime.title
12403
+ ...runtime.title,
12404
+ fontSize: fontSizeInPixels(runtime.title.fontSize ?? 16)
12404
12405
  }, "px"));
12405
12406
  switch (runtime.title.align) {
12406
12407
  case "right":
@@ -13923,10 +13924,10 @@ var GaugeChartComponent = class extends Component$1 {
13923
13924
  let animation = null;
13924
13925
  let lastRuntime = void 0;
13925
13926
  useLayoutEffect$1(() => {
13926
- if (this.env.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13927
+ if (this.env.model.getters.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13927
13928
  animation = this.drawGaugeWithAnimation();
13928
13929
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13929
- } else if (this.env.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13930
+ } else if (this.env.model.getters.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13930
13931
  animation = this.drawGaugeWithAnimation();
13931
13932
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13932
13933
  } else {
@@ -15217,10 +15218,12 @@ var CarouselFigure = class extends Component$1 {
15217
15218
  return this.carousel.title?.text ?? "";
15218
15219
  }
15219
15220
  get titleStyle() {
15220
- return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle({
15221
+ const style = {
15221
15222
  ...DEFAULT_CAROUSEL_TITLE_STYLE,
15222
15223
  ...this.carousel.title
15223
- })));
15224
+ };
15225
+ style.fontSize = fontSizeInPixels(style.fontSize ?? 16);
15226
+ return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle(style)));
15224
15227
  }
15225
15228
  updateTabsVisibility() {
15226
15229
  const tabsContainerEl = this.carouselTabsRef();
@@ -15383,7 +15386,7 @@ var FigureComponent = class extends Component$1 {
15383
15386
  return figureRegistry;
15384
15387
  }
15385
15388
  getBorderWidth() {
15386
- if (this.env.isDashboard()) return 0;
15389
+ if (this.env.model.getters.isDashboard()) return 0;
15387
15390
  return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
15388
15391
  }
15389
15392
  getBorderStyle(position) {
@@ -15525,7 +15528,7 @@ var FigureComponent = class extends Component$1 {
15525
15528
  };
15526
15529
  }
15527
15530
  onContextMenu(ev) {
15528
- if (this.env.isDashboard()) return;
15531
+ if (this.env.model.getters.isDashboard()) return;
15529
15532
  const zoomedMouseEvent = withZoom(this.env, ev);
15530
15533
  this.openContextMenu({
15531
15534
  x: zoomedMouseEvent.clientX,
@@ -15551,7 +15554,7 @@ var FigureComponent = class extends Component$1 {
15551
15554
  if (el) for (const property in properties) el.style.setProperty(property, properties[property] || null);
15552
15555
  }
15553
15556
  get isFigureResizable() {
15554
- return this.isSelected && !this.env.isMobile() && !this.env.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15557
+ return this.isSelected && !this.env.isMobile() && !this.env.model.getters.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15555
15558
  }
15556
15559
  };
15557
15560
 
@@ -24801,6 +24804,18 @@ var ColorPicker = class extends Component$1 {
24801
24804
  isSameColor(color1, color2) {
24802
24805
  return isSameColor(color1, color2);
24803
24806
  }
24807
+ get canUseEyeDropper() {
24808
+ return !!globalThis.EyeDropper && !this.env.model.getters.isDarkMode();
24809
+ }
24810
+ async activateEyedropper() {
24811
+ if (!globalThis.EyeDropper) return;
24812
+ try {
24813
+ const result = await new globalThis.EyeDropper().open();
24814
+ if (result && result.sRGBHex) this.props.onColorPicked(toHex(result.sRGBHex));
24815
+ } catch (error) {
24816
+ if (error.name !== "AbortError") throw error;
24817
+ }
24818
+ }
24804
24819
  };
24805
24820
 
24806
24821
  //#endregion
@@ -28480,7 +28495,7 @@ function getSunburstShowValues(definition, args) {
28480
28495
  showLabels: definition.showLabels ?? SunburstChartDefaults.showLabels,
28481
28496
  showValues: definition.showValues ?? SunburstChartDefaults.showValues,
28482
28497
  style: {
28483
- fontSize: definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize,
28498
+ fontSize: fontSizeInPixels(definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize),
28484
28499
  align: definition.valuesDesign?.align ?? SunburstChartDefaults.valuesDesign.align,
28485
28500
  bold: definition.valuesDesign?.bold ?? SunburstChartDefaults.valuesDesign.bold,
28486
28501
  italic: definition.valuesDesign?.italic ?? SunburstChartDefaults.valuesDesign.italic,
@@ -28535,7 +28550,7 @@ function getChartTitle({ title, legendPosition, background }, getters) {
28535
28550
  color: title?.color ?? fontColor,
28536
28551
  align: title.align === "center" ? "center" : title.align === "right" ? "end" : "start",
28537
28552
  font: {
28538
- size: title.fontSize ?? 16,
28553
+ size: fontSizeInPixels(title.fontSize ?? 16),
28539
28554
  weight: title.bold ? "bold" : "normal",
28540
28555
  style: title.italic ? "italic" : "normal"
28541
28556
  },
@@ -38784,7 +38799,8 @@ var PivotDimensionOrder = class extends Component$1 {
38784
38799
  static template = "o-spreadsheet-PivotDimensionOrder";
38785
38800
  props = props({
38786
38801
  dimension: types$1.PivotDimension(),
38787
- onUpdated: types$1.function([types$1.PivotDimension(), types$1.instanceOf(InputEvent)])
38802
+ onUpdated: types$1.function([types$1.PivotDimension(), types$1.instanceOf(InputEvent)]),
38803
+ "isMeasureSorted?": types$1.boolean()
38788
38804
  });
38789
38805
  static components = { Select };
38790
38806
  get orderSelectOptions() {
@@ -38795,12 +38811,20 @@ var PivotDimensionOrder = class extends Component$1 {
38795
38811
  value: "desc",
38796
38812
  label: _t("Descending")
38797
38813
  }];
38814
+ if (this.props.isMeasureSorted) options.unshift({
38815
+ value: "measures",
38816
+ label: _t("Sorted by measure")
38817
+ });
38798
38818
  if (this.props.dimension.type === "date") return options;
38799
38819
  return [{
38800
38820
  value: "",
38801
38821
  label: _t("Unsorted")
38802
38822
  }, ...options];
38803
38823
  }
38824
+ get selectedValue() {
38825
+ if (this.props.isMeasureSorted) return "measures";
38826
+ return this.props.dimension.order || "";
38827
+ }
38804
38828
  };
38805
38829
 
38806
38830
  //#endregion
@@ -39171,7 +39195,8 @@ var PivotLayoutConfigurator = class extends Component$1 {
39171
39195
  return this.env.model.getters.getPivotCoreDefinition(this.props.pivotId).customFields?.[dimension.nameWithGranularity];
39172
39196
  }
39173
39197
  updateOrder(updateDimension, order) {
39174
- const { rows, columns } = this.props.definition;
39198
+ const { rows, columns, sortedColumn } = this.props.definition;
39199
+ const isRow = rows.some((row) => row.nameWithGranularity === updateDimension.nameWithGranularity);
39175
39200
  this.props.onDimensionsUpdated({
39176
39201
  rows: rows.map((row) => {
39177
39202
  if (row.nameWithGranularity === updateDimension.nameWithGranularity) return {
@@ -39186,7 +39211,8 @@ var PivotLayoutConfigurator = class extends Component$1 {
39186
39211
  order: order || void 0
39187
39212
  };
39188
39213
  return col;
39189
- })
39214
+ }),
39215
+ sortedColumn: isRow ? void 0 : sortedColumn
39190
39216
  });
39191
39217
  }
39192
39218
  updateGranularity(dimension, granularity) {
@@ -39212,6 +39238,9 @@ var PivotLayoutConfigurator = class extends Component$1 {
39212
39238
  const possibleValues = this.env.model.getters.getPivot(this.props.pivotId).getPossibleFieldValues(dimension);
39213
39239
  return possibleValues.length > 100 ? _t("This dimension contains a lot of values (%s), and might slow down the pivot table.", possibleValues.length) : void 0;
39214
39240
  }
39241
+ get hasSortedColumn() {
39242
+ return !!this.props.definition.sortedColumn;
39243
+ }
39215
39244
  };
39216
39245
 
39217
39246
  //#endregion
@@ -58826,9 +58855,11 @@ var PivotUIPlugin = class extends CoreViewPlugin {
58826
58855
  this.refreshPivot(cmd.id);
58827
58856
  break;
58828
58857
  case "ADD_PIVOT":
58858
+ this.unusedPivotsInFormulas?.push(cmd.pivotId);
58829
58859
  this.setupPivot(cmd.pivotId);
58830
58860
  break;
58831
58861
  case "DUPLICATE_PIVOT":
58862
+ this.unusedPivotsInFormulas?.push(cmd.newPivotId);
58832
58863
  this.setupPivot(cmd.newPivotId);
58833
58864
  break;
58834
58865
  case "UPDATE_PIVOT":
@@ -59020,8 +59051,8 @@ var PivotUIPlugin = class extends CoreViewPlugin {
59020
59051
  }
59021
59052
  }
59022
59053
  for (const pivotId of this.getters.getPivotIds()) {
59023
- const pivot = this.getters.getPivot(pivotId);
59024
- for (const measure of pivot.definition.measures) if (measure.computedBy) {
59054
+ const pivot = this.getters.getPivotCoreDefinition(pivotId);
59055
+ for (const measure of pivot.measures) if (measure.computedBy) {
59025
59056
  const { sheetId } = measure.computedBy;
59026
59057
  const formula = this.getters.getMeasureCompiledFormula(pivotId, measure);
59027
59058
  const relatedPivotIds = this.getPivotIdsFromFormula(sheetId, formula);
@@ -62363,6 +62394,7 @@ var GeoFeaturePlugin = class extends UIPlugin {
62363
62394
  convertToGeoJson(json) {
62364
62395
  if (!json) return null;
62365
62396
  if (json.type === "Topology") {
62397
+ if (!globalThis.ChartGeo) return null;
62366
62398
  const features = globalThis.ChartGeo.topojson.feature(json, Object.values(json.objects)[0]);
62367
62399
  return features.type === "FeatureCollection" ? features.features : [features];
62368
62400
  } else if (json.type === "FeatureCollection") return json.features;
@@ -70783,7 +70815,7 @@ var Spreadsheet = class extends Component$1 {
70783
70815
  properties["color-scheme"] = this.props.model.getters.isDarkMode() ? "dark" : "light";
70784
70816
  if (this.state.printModeEnabled) properties["display"] = `block`;
70785
70817
  else {
70786
- if (this.env.isDashboard()) properties["grid-template-rows"] = `auto`;
70818
+ if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
70787
70819
  else properties["grid-template-rows"] = `min-content auto min-content`;
70788
70820
  properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || 350}px` : "auto"}`;
70789
70821
  }
@@ -70811,7 +70843,6 @@ var Spreadsheet = class extends Component$1 {
70811
70843
  imageProvider: fileStore ? new ImageProvider(fileStore) : void 0,
70812
70844
  loadCurrencies: this.model.config.external.loadCurrencies,
70813
70845
  loadLocales: this.model.config.external.loadLocales,
70814
- isDashboard: () => this.model.getters.isDashboard(),
70815
70846
  openSidePanel: this.sidePanel.open.bind(this.sidePanel),
70816
70847
  replaceSidePanel: this.sidePanel.replace.bind(this.sidePanel),
70817
70848
  toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
@@ -86060,7 +86091,8 @@ const registries = {
86060
86091
  pivotToFunctionValueRegistry,
86061
86092
  migrationStepRegistry,
86062
86093
  chartJsExtensionRegistry,
86063
- onIterationEndEvaluationRegistry
86094
+ onIterationEndEvaluationRegistry,
86095
+ specificRangeTransformRegistry
86064
86096
  };
86065
86097
  const helpers = {
86066
86098
  arg,
@@ -86266,6 +86298,6 @@ const chartHelpers = {
86266
86298
  //#endregion
86267
86299
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, BadExpressionError, CHART_TYPES, CellErrorType, CellValueType, CircularDependencyError, ClientDisconnectedError, ClipboardMIMEType, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DEFAULT_LOCALE_DIGIT_GROUPING, DIRECTION, DispatchResult, DivisionByZeroError, EvaluationError, InvalidReferenceError, LocalTransportService, Model, NEXT_VALUE, NotAvailableError, NumberTooLargeError, OrderedLayers, PREVIOUS_VALUE, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, SplillBlockedError, Spreadsheet, SpreadsheetPivotTable, UIPlugin, UnknownFunctionError, __info__, addFunction, addRenderingLayer, astToFormula, availableConditionalFormatOperators, availableDataValidationOperators, availableFiltersOperators, borderPositions, borderStyles, canExecuteInReadonly, categories, chartHelpers, compatibility, components, composerFocusTypes, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, errorTypes, filterDateCriterionOperators, filterNumberCriterionOperators, filterTextCriterionOperators, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidSubtotalFormulasCommands, invalidateBordersCommands, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isHeadersDependant, isMatrix, isPositionDependent, isRangeDependant, isSheetDependent, isTargetDependent, isZoneDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, schemeToColorScale, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
86268
86300
 
86269
- __info__.version = "19.4.0-alpha.11";
86270
- __info__.date = "2026-06-03T11:42:34.595Z";
86271
- __info__.hash = "6f35bc7";
86301
+ __info__.version = "19.4.0-alpha.13";
86302
+ __info__.date = "2026-06-06T09:34:53.140Z";
86303
+ __info__.hash = "af3c199";
@@ -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 19.4.0-alpha.11
6
- * @date 2026-06-03T11:42:34.595Z
7
- * @hash 6f35bc7
5
+ * @version 19.4.0-alpha.13
6
+ * @date 2026-06-06T09:34:53.140Z
7
+ * @hash af3c199
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -4324,6 +4324,7 @@ set(value) {
4324
4324
  //#endregion
4325
4325
  //#region src/helpers/format/format_tokenizer.ts
4326
4326
  function tokenizeFormat(str) {
4327
+ str = str.replace(/\s/g, " ");
4327
4328
  const chars = new TokenizingChars(str);
4328
4329
  const result = [];
4329
4330
  let currentFormatPart = [];
@@ -10558,7 +10559,7 @@ set(value) {
10558
10559
  };
10559
10560
  }
10560
10561
  function getGeoChartProjection(projection) {
10561
- if (projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10562
+ if (globalThis.ChartGeo && projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10562
10563
  return projection;
10563
10564
  }
10564
10565
  function getChartAxisTitleRuntime(design) {
@@ -10571,7 +10572,7 @@ set(value) {
10571
10572
  font: {
10572
10573
  style: italic ? "italic" : "normal",
10573
10574
  weight: bold ? "bold" : "normal",
10574
- size: design.title.fontSize ?? 12
10575
+ size: fontSizeInPixels(design.title.fontSize ?? 12)
10575
10576
  },
10576
10577
  align: align === "left" ? "start" : align === "right" ? "end" : "center"
10577
10578
  };
@@ -11193,7 +11194,7 @@ set(value) {
11193
11194
  font: {
11194
11195
  weight: design?.bold ?? defaultDesign?.bold ? "bold" : "normal",
11195
11196
  style: design?.italic ?? defaultDesign?.italic ? "italic" : "normal",
11196
- size: design?.fontSize ?? defaultDesign?.fontSize
11197
+ size: fontSizeInPixels(design?.fontSize ?? defaultDesign.fontSize)
11197
11198
  }
11198
11199
  };
11199
11200
  }
@@ -12129,35 +12130,35 @@ set(value) {
12129
12130
  if (this.runtime.progressBar) baselineValueFontSize /= 1.5;
12130
12131
  return {
12131
12132
  title: {
12132
- font: getDefaultContextFont(this.runtime.title.fontSize ?? 14, this.runtime.title.bold, this.runtime.title.italic),
12133
+ font: getDefaultContextFont(fontSizeInPixels(this.runtime.title.fontSize ?? 14), this.runtime.title.bold, this.runtime.title.italic),
12133
12134
  color: this.runtime.title.color ?? this.secondaryFontColor
12134
12135
  },
12135
12136
  keyValue: {
12136
12137
  color: this.runtime.keyValueStyle?.textColor || this.runtime.fontColor,
12137
- font: getDefaultContextFont(keyValueFontSize, this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12138
+ font: getDefaultContextFont(fontSizeInPixels(keyValueFontSize), this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12138
12139
  strikethrough: this.runtime.keyValueStyle?.strikethrough,
12139
12140
  underline: this.runtime.keyValueStyle?.underline
12140
12141
  },
12141
12142
  keyDescr: {
12142
12143
  color: this.runtime.keyValueDescrStyle?.textColor || this.runtime.fontColor,
12143
- font: getDefaultContextFont(keyValueDescrFontSize, this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12144
+ font: getDefaultContextFont(fontSizeInPixels(keyValueDescrFontSize), this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12144
12145
  strikethrough: this.runtime.keyValueDescrStyle?.strikethrough,
12145
12146
  underline: this.runtime.keyValueDescrStyle?.underline
12146
12147
  },
12147
12148
  baselineValue: {
12148
- font: getDefaultContextFont(baselineValueFontSize, this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12149
+ font: getDefaultContextFont(fontSizeInPixels(baselineValueFontSize), this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12149
12150
  strikethrough: this.runtime.baselineStyle?.strikethrough,
12150
12151
  underline: this.runtime.baselineStyle?.underline,
12151
12152
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12152
12153
  },
12153
12154
  baselineDescr: {
12154
- font: getDefaultContextFont(baselineDescrFontSize, this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12155
+ font: getDefaultContextFont(fontSizeInPixels(baselineDescrFontSize), this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12155
12156
  strikethrough: this.runtime.baselineDescrStyle?.strikethrough,
12156
12157
  underline: this.runtime.baselineDescrStyle?.underline,
12157
12158
  color: this.runtime.baselineDescrStyle?.textColor ?? this.secondaryFontColor
12158
12159
  },
12159
12160
  baselineArrow: this.baselineArrow === "neutral" || this.runtime.progressBar ? void 0 : {
12160
- size: this.keyValue ? .8 * baselineValueFontSize : 0,
12161
+ size: this.keyValue ? .8 * fontSizeInPixels(baselineValueFontSize) : 0,
12161
12162
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12162
12163
  }
12163
12164
  };
@@ -12367,7 +12368,7 @@ set(value) {
12367
12368
  function drawTitle(ctx, config) {
12368
12369
  ctx.save();
12369
12370
  const title = config.title;
12370
- ctx.font = getDefaultContextFont(title.fontSize, title.bold, title.italic);
12371
+ ctx.font = getDefaultContextFont(fontSizeInPixels(title.fontSize), title.bold, title.italic);
12371
12372
  ctx.textBaseline = "middle";
12372
12373
  ctx.fillStyle = title.color;
12373
12374
  ctx.fillText(title.label, title.textPosition.x, title.textPosition.y);
@@ -12401,8 +12402,8 @@ set(value) {
12401
12402
  const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
12402
12403
  let x = 0, titleWidth = 0, titleHeight = 0;
12403
12404
  if (runtime.title.text) ({width: titleWidth, height: titleHeight} = computeTextDimension(ctx, runtime.title.text, {
12404
- fontSize: 16,
12405
- ...runtime.title
12405
+ ...runtime.title,
12406
+ fontSize: fontSizeInPixels(runtime.title.fontSize ?? 16)
12406
12407
  }, "px"));
12407
12408
  switch (runtime.title.align) {
12408
12409
  case "right":
@@ -13925,10 +13926,10 @@ set(value) {
13925
13926
  let animation = null;
13926
13927
  let lastRuntime = void 0;
13927
13928
  useLayoutEffect(() => {
13928
- if (this.env.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13929
+ if (this.env.model.getters.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13929
13930
  animation = this.drawGaugeWithAnimation();
13930
13931
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13931
- } else if (this.env.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13932
+ } else if (this.env.model.getters.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13932
13933
  animation = this.drawGaugeWithAnimation();
13933
13934
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13934
13935
  } else {
@@ -15219,10 +15220,12 @@ set(value) {
15219
15220
  return this.carousel.title?.text ?? "";
15220
15221
  }
15221
15222
  get titleStyle() {
15222
- return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle({
15223
+ const style = {
15223
15224
  ...DEFAULT_CAROUSEL_TITLE_STYLE,
15224
15225
  ...this.carousel.title
15225
- })));
15226
+ };
15227
+ style.fontSize = fontSizeInPixels(style.fontSize ?? 16);
15228
+ return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle(style)));
15226
15229
  }
15227
15230
  updateTabsVisibility() {
15228
15231
  const tabsContainerEl = this.carouselTabsRef();
@@ -15385,7 +15388,7 @@ set(value) {
15385
15388
  return figureRegistry;
15386
15389
  }
15387
15390
  getBorderWidth() {
15388
- if (this.env.isDashboard()) return 0;
15391
+ if (this.env.model.getters.isDashboard()) return 0;
15389
15392
  return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
15390
15393
  }
15391
15394
  getBorderStyle(position) {
@@ -15527,7 +15530,7 @@ set(value) {
15527
15530
  };
15528
15531
  }
15529
15532
  onContextMenu(ev) {
15530
- if (this.env.isDashboard()) return;
15533
+ if (this.env.model.getters.isDashboard()) return;
15531
15534
  const zoomedMouseEvent = withZoom(this.env, ev);
15532
15535
  this.openContextMenu({
15533
15536
  x: zoomedMouseEvent.clientX,
@@ -15553,7 +15556,7 @@ set(value) {
15553
15556
  if (el) for (const property in properties) el.style.setProperty(property, properties[property] || null);
15554
15557
  }
15555
15558
  get isFigureResizable() {
15556
- return this.isSelected && !this.env.isMobile() && !this.env.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15559
+ return this.isSelected && !this.env.isMobile() && !this.env.model.getters.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15557
15560
  }
15558
15561
  };
15559
15562
 
@@ -24803,6 +24806,18 @@ set(value) {
24803
24806
  isSameColor(color1, color2) {
24804
24807
  return isSameColor(color1, color2);
24805
24808
  }
24809
+ get canUseEyeDropper() {
24810
+ return !!globalThis.EyeDropper && !this.env.model.getters.isDarkMode();
24811
+ }
24812
+ async activateEyedropper() {
24813
+ if (!globalThis.EyeDropper) return;
24814
+ try {
24815
+ const result = await new globalThis.EyeDropper().open();
24816
+ if (result && result.sRGBHex) this.props.onColorPicked(toHex(result.sRGBHex));
24817
+ } catch (error) {
24818
+ if (error.name !== "AbortError") throw error;
24819
+ }
24820
+ }
24806
24821
  };
24807
24822
 
24808
24823
  //#endregion
@@ -28482,7 +28497,7 @@ set(value) {
28482
28497
  showLabels: definition.showLabels ?? SunburstChartDefaults.showLabels,
28483
28498
  showValues: definition.showValues ?? SunburstChartDefaults.showValues,
28484
28499
  style: {
28485
- fontSize: definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize,
28500
+ fontSize: fontSizeInPixels(definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize),
28486
28501
  align: definition.valuesDesign?.align ?? SunburstChartDefaults.valuesDesign.align,
28487
28502
  bold: definition.valuesDesign?.bold ?? SunburstChartDefaults.valuesDesign.bold,
28488
28503
  italic: definition.valuesDesign?.italic ?? SunburstChartDefaults.valuesDesign.italic,
@@ -28537,7 +28552,7 @@ set(value) {
28537
28552
  color: title?.color ?? fontColor,
28538
28553
  align: title.align === "center" ? "center" : title.align === "right" ? "end" : "start",
28539
28554
  font: {
28540
- size: title.fontSize ?? 16,
28555
+ size: fontSizeInPixels(title.fontSize ?? 16),
28541
28556
  weight: title.bold ? "bold" : "normal",
28542
28557
  style: title.italic ? "italic" : "normal"
28543
28558
  },
@@ -38786,7 +38801,8 @@ set(value) {
38786
38801
  static template = "o-spreadsheet-PivotDimensionOrder";
38787
38802
  props = (0, _odoo_owl.props)({
38788
38803
  dimension: types$6.PivotDimension(),
38789
- onUpdated: types$6.function([types$6.PivotDimension(), types$6.instanceOf(InputEvent)])
38804
+ onUpdated: types$6.function([types$6.PivotDimension(), types$6.instanceOf(InputEvent)]),
38805
+ "isMeasureSorted?": types$6.boolean()
38790
38806
  });
38791
38807
  static components = { Select };
38792
38808
  get orderSelectOptions() {
@@ -38797,12 +38813,20 @@ set(value) {
38797
38813
  value: "desc",
38798
38814
  label: _t("Descending")
38799
38815
  }];
38816
+ if (this.props.isMeasureSorted) options.unshift({
38817
+ value: "measures",
38818
+ label: _t("Sorted by measure")
38819
+ });
38800
38820
  if (this.props.dimension.type === "date") return options;
38801
38821
  return [{
38802
38822
  value: "",
38803
38823
  label: _t("Unsorted")
38804
38824
  }, ...options];
38805
38825
  }
38826
+ get selectedValue() {
38827
+ if (this.props.isMeasureSorted) return "measures";
38828
+ return this.props.dimension.order || "";
38829
+ }
38806
38830
  };
38807
38831
 
38808
38832
  //#endregion
@@ -39173,7 +39197,8 @@ set(value) {
39173
39197
  return this.env.model.getters.getPivotCoreDefinition(this.props.pivotId).customFields?.[dimension.nameWithGranularity];
39174
39198
  }
39175
39199
  updateOrder(updateDimension, order) {
39176
- const { rows, columns } = this.props.definition;
39200
+ const { rows, columns, sortedColumn } = this.props.definition;
39201
+ const isRow = rows.some((row) => row.nameWithGranularity === updateDimension.nameWithGranularity);
39177
39202
  this.props.onDimensionsUpdated({
39178
39203
  rows: rows.map((row) => {
39179
39204
  if (row.nameWithGranularity === updateDimension.nameWithGranularity) return {
@@ -39188,7 +39213,8 @@ set(value) {
39188
39213
  order: order || void 0
39189
39214
  };
39190
39215
  return col;
39191
- })
39216
+ }),
39217
+ sortedColumn: isRow ? void 0 : sortedColumn
39192
39218
  });
39193
39219
  }
39194
39220
  updateGranularity(dimension, granularity) {
@@ -39214,6 +39240,9 @@ set(value) {
39214
39240
  const possibleValues = this.env.model.getters.getPivot(this.props.pivotId).getPossibleFieldValues(dimension);
39215
39241
  return possibleValues.length > 100 ? _t("This dimension contains a lot of values (%s), and might slow down the pivot table.", possibleValues.length) : void 0;
39216
39242
  }
39243
+ get hasSortedColumn() {
39244
+ return !!this.props.definition.sortedColumn;
39245
+ }
39217
39246
  };
39218
39247
 
39219
39248
  //#endregion
@@ -58828,9 +58857,11 @@ set(value) {
58828
58857
  this.refreshPivot(cmd.id);
58829
58858
  break;
58830
58859
  case "ADD_PIVOT":
58860
+ this.unusedPivotsInFormulas?.push(cmd.pivotId);
58831
58861
  this.setupPivot(cmd.pivotId);
58832
58862
  break;
58833
58863
  case "DUPLICATE_PIVOT":
58864
+ this.unusedPivotsInFormulas?.push(cmd.newPivotId);
58834
58865
  this.setupPivot(cmd.newPivotId);
58835
58866
  break;
58836
58867
  case "UPDATE_PIVOT":
@@ -59022,8 +59053,8 @@ set(value) {
59022
59053
  }
59023
59054
  }
59024
59055
  for (const pivotId of this.getters.getPivotIds()) {
59025
- const pivot = this.getters.getPivot(pivotId);
59026
- for (const measure of pivot.definition.measures) if (measure.computedBy) {
59056
+ const pivot = this.getters.getPivotCoreDefinition(pivotId);
59057
+ for (const measure of pivot.measures) if (measure.computedBy) {
59027
59058
  const { sheetId } = measure.computedBy;
59028
59059
  const formula = this.getters.getMeasureCompiledFormula(pivotId, measure);
59029
59060
  const relatedPivotIds = this.getPivotIdsFromFormula(sheetId, formula);
@@ -62365,6 +62396,7 @@ set(value) {
62365
62396
  convertToGeoJson(json) {
62366
62397
  if (!json) return null;
62367
62398
  if (json.type === "Topology") {
62399
+ if (!globalThis.ChartGeo) return null;
62368
62400
  const features = globalThis.ChartGeo.topojson.feature(json, Object.values(json.objects)[0]);
62369
62401
  return features.type === "FeatureCollection" ? features.features : [features];
62370
62402
  } else if (json.type === "FeatureCollection") return json.features;
@@ -70785,7 +70817,7 @@ set(value) {
70785
70817
  properties["color-scheme"] = this.props.model.getters.isDarkMode() ? "dark" : "light";
70786
70818
  if (this.state.printModeEnabled) properties["display"] = `block`;
70787
70819
  else {
70788
- if (this.env.isDashboard()) properties["grid-template-rows"] = `auto`;
70820
+ if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
70789
70821
  else properties["grid-template-rows"] = `min-content auto min-content`;
70790
70822
  properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || 350}px` : "auto"}`;
70791
70823
  }
@@ -70813,7 +70845,6 @@ set(value) {
70813
70845
  imageProvider: fileStore ? new ImageProvider(fileStore) : void 0,
70814
70846
  loadCurrencies: this.model.config.external.loadCurrencies,
70815
70847
  loadLocales: this.model.config.external.loadLocales,
70816
- isDashboard: () => this.model.getters.isDashboard(),
70817
70848
  openSidePanel: this.sidePanel.open.bind(this.sidePanel),
70818
70849
  replaceSidePanel: this.sidePanel.replace.bind(this.sidePanel),
70819
70850
  toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
@@ -86062,7 +86093,8 @@ set(value) {
86062
86093
  pivotToFunctionValueRegistry,
86063
86094
  migrationStepRegistry,
86064
86095
  chartJsExtensionRegistry,
86065
- onIterationEndEvaluationRegistry
86096
+ onIterationEndEvaluationRegistry,
86097
+ specificRangeTransformRegistry
86066
86098
  };
86067
86099
  const helpers = {
86068
86100
  arg,
@@ -86362,8 +86394,8 @@ exports.stores = stores;
86362
86394
  exports.tokenColors = tokenColors;
86363
86395
  exports.tokenize = tokenize;
86364
86396
 
86365
- __info__.version = "19.4.0-alpha.11";
86366
- __info__.date = "2026-06-03T11:42:34.595Z";
86367
- __info__.hash = "6f35bc7";
86397
+ __info__.version = "19.4.0-alpha.13";
86398
+ __info__.date = "2026-06-06T09:34:53.140Z";
86399
+ __info__.hash = "af3c199";
86368
86400
 
86369
86401
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);