@odoo/o-spreadsheet 19.5.0-alpha.19 → 19.5.0-alpha.20

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.5.0-alpha.19
6
- * @date 2026-09-10T05:38:44.935Z
7
- * @hash 2b1e397
5
+ * @version 19.5.0-alpha.20
6
+ * @date 2026-09-16T08:02:11.430Z
7
+ * @hash 4784627
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -8830,7 +8830,7 @@ set(value) {
8830
8830
  * stored in the theme so that, after the dark-mode CSS filter is applied, the
8831
8831
  * desired color is actually shown.
8832
8832
  *
8833
- * This function computes the exact inverse of the DARK_MODE_FILTER chain.
8833
+ * This function computes an approximate inverse of the DARK_MODE_FILTER chain.
8834
8834
  */
8835
8835
  function adaptForDarkMode(displayedColor) {
8836
8836
  const { r, g, b, a } = colorToRGBA(displayedColor);
@@ -9978,34 +9978,49 @@ set(value) {
9978
9978
  const BACKGROUND_HEADER_COLOR = "#F8F9FA";
9979
9979
  const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
9980
9980
  const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
9981
+ function adaptColorsForDarkMode(colors) {
9982
+ return Object.fromEntries(Object.entries(colors).map(([key, color]) => [key, adaptForDarkMode(color)]));
9983
+ }
9984
+ const LIGHT_COLORS = {
9985
+ chartBackgroundColor: "#FFFFFF",
9986
+ gridBorderColor: "#CECFCF",
9987
+ gridBorderColorOnDefaultBackground: "#E2E3E3",
9988
+ headerBackgroundColor: BACKGROUND_HEADER_COLOR,
9989
+ headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
9990
+ headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
9991
+ headerTextColor: TEXT_HEADER_COLOR,
9992
+ headerBorderColor: HEADER_BORDER_COLOR,
9993
+ frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
9994
+ frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
9995
+ singleCellSelectionBackgroundColor: "#D2E1FB44",
9996
+ multipleCellsSelectionBackgroundColor: "#ACC7FF44"
9997
+ };
9998
+ /** Every color defined explicitely in the dark theme is expected to be subject to color-inverter mask applied
9999
+ * through the css class `os-theme-dependant`. They are therefore pre-inverted for dark mode.
10000
+ * Note that according to `adaptForDarkMode` documentation, the resulting color will be an approximation of the pre-inverted color.
10001
+ */
10002
+ const DARK_DISPLAYED_COLORS = {
10003
+ chartBackgroundColor: "#25262b",
10004
+ gridBorderColor: "#6B706F",
10005
+ gridBorderColorOnDefaultBackground: "#4F5254",
10006
+ headerBackgroundColor: "#262A36",
10007
+ headerActiveBackgroundColor: "#3A4052",
10008
+ headerSelectedBackgroundColor: "#4E566E",
10009
+ headerTextColor: "#A1A6B3",
10010
+ headerBorderColor: "#7A7F91",
10011
+ frozenPaneBorderColor: "#7A7F91",
10012
+ frozenPaneHeaderBorderColor: "#9FA5BD",
10013
+ singleCellSelectionBackgroundColor: "#696E8044",
10014
+ multipleCellsSelectionBackgroundColor: "#828AA044"
10015
+ };
9981
10016
  const COLOR_THEMES = {
9982
10017
  light: {
9983
10018
  colorThemeName: "light",
9984
- backgroundColor: "#FFFFFF",
9985
- gridBorderColor: "#CECFCF",
9986
- headerBackgroundColor: BACKGROUND_HEADER_COLOR,
9987
- headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
9988
- headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
9989
- headerTextColor: TEXT_HEADER_COLOR,
9990
- headerBorderColor: HEADER_BORDER_COLOR,
9991
- frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
9992
- frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
9993
- singleCellSelectionBackgroundColor: "#F3F7FE",
9994
- multipleCellsSelectionBackgroundColor: "#E9F0FF"
10019
+ ...LIGHT_COLORS
9995
10020
  },
9996
10021
  dark: {
9997
10022
  colorThemeName: "dark",
9998
- backgroundColor: adaptForDarkMode("#1A1C2E"),
9999
- gridBorderColor: adaptForDarkMode("#6B706F"),
10000
- headerBackgroundColor: adaptForDarkMode("#262A36"),
10001
- headerActiveBackgroundColor: adaptForDarkMode("#3A4052"),
10002
- headerSelectedBackgroundColor: adaptForDarkMode("#4E566E"),
10003
- headerTextColor: adaptForDarkMode("#A1A6B3"),
10004
- headerBorderColor: adaptForDarkMode("#7A7F91"),
10005
- frozenPaneBorderColor: adaptForDarkMode("#7A7F91"),
10006
- frozenPaneHeaderBorderColor: adaptForDarkMode("#9FA5BD"),
10007
- singleCellSelectionBackgroundColor: adaptForDarkMode("#696E8044"),
10008
- multipleCellsSelectionBackgroundColor: adaptForDarkMode("#828AA044")
10023
+ ...adaptColorsForDarkMode(DARK_DISPLAYED_COLORS)
10009
10024
  }
10010
10025
  };
10011
10026
 
@@ -10231,7 +10246,7 @@ set(value) {
10231
10246
  return axisID === "x1" || axisID === "xMovingAverage";
10232
10247
  }
10233
10248
  function getChartBackgroundColor({ background }, colorThemeName) {
10234
- if (!background) return COLOR_THEMES[colorThemeName].backgroundColor;
10249
+ if (!background) return COLOR_THEMES[colorThemeName].chartBackgroundColor;
10235
10250
  return background;
10236
10251
  }
10237
10252
 
@@ -14204,7 +14219,7 @@ set(value) {
14204
14219
  const GAUGE_PADDING_BOTTOM = 20;
14205
14220
  const GAUGE_LABELS_FONT_SIZE = 12;
14206
14221
  const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
14207
- const GAUGE_BACKGROUND_COLOR = "#F3F2F1";
14222
+ const GAUGE_BACKGROUND_COLOR = "#F8F8F8";
14208
14223
  const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
14209
14224
  const GAUGE_TITLE_SECTION_HEIGHT = 25;
14210
14225
  function drawGaugeChart(canvas, runtime, zoom = 1, dimensions, options) {
@@ -24539,8 +24554,8 @@ set(value) {
24539
24554
  }
24540
24555
  getBackgroundColor(cellStyle) {
24541
24556
  const overlayColor = this.hoveredCellOverlayStore.overlayColors.get(this.props.position);
24542
- if (overlayColor) return blendColors(cellStyle.fillColor || "#FFFFFF", overlayColor);
24543
- return cellStyle.fillColor || "#FFFFFF";
24557
+ if (overlayColor) return cellStyle.fillColor ? blendColors(cellStyle.fillColor, overlayColor) : overlayColor;
24558
+ return cellStyle.fillColor;
24544
24559
  }
24545
24560
  };
24546
24561
 
@@ -28302,8 +28317,11 @@ set(value) {
28302
28317
  drawGlobalBackground(renderingContext) {
28303
28318
  const { ctx, viewports } = renderingContext;
28304
28319
  const { width, height } = viewports.getSheetViewDimensionWithHeaders();
28305
- ctx.fillStyle = this.getBackgroundColor(renderingContext);
28306
- ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28320
+ const fillStyle = this.getBackgroundColor(renderingContext);
28321
+ if (fillStyle) {
28322
+ ctx.fillStyle = fillStyle;
28323
+ ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28324
+ } else ctx.clearRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28307
28325
  }
28308
28326
  drawBackground(renderingContext, boxes) {
28309
28327
  const { ctx, thinLineWidth } = renderingContext;
@@ -28312,7 +28330,8 @@ set(value) {
28312
28330
  if (areGridLinesVisible) {
28313
28331
  const theme = this.getters.getSpreadsheetTheme();
28314
28332
  const background = this.getBackgroundColor(renderingContext);
28315
- ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", background + "50"), 1);
28333
+ if (background) ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", toHex(background) + "50"), 1);
28334
+ else ctx.strokeStyle = theme.gridBorderColorOnDefaultBackground;
28316
28335
  ctx.lineWidth = thinLineWidth;
28317
28336
  for (const box of boxes) {
28318
28337
  if (box.style.hideGridLines) continue;
@@ -28322,9 +28341,11 @@ set(value) {
28322
28341
  }
28323
28342
  drawCellBackground(renderingContext, boxes) {
28324
28343
  const { ctx } = renderingContext;
28344
+ const backgroundColor = this.getBackgroundColor(renderingContext);
28345
+ const background = backgroundColor ? toHex(backgroundColor) : void 0;
28325
28346
  for (const box of boxes) {
28326
28347
  const style = box.style;
28327
- if (style.fillColor && toHex(style.fillColor) !== toHex(this.getBackgroundColor(renderingContext))) {
28348
+ if (style.fillColor && toHex(style.fillColor) !== background) {
28328
28349
  ctx.fillStyle = toHex(style.fillColor);
28329
28350
  ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
28330
28351
  }
@@ -28338,7 +28359,8 @@ set(value) {
28338
28359
  ctx.fillRect(box.x, y, width, height);
28339
28360
  }
28340
28361
  if (box.overlayColor) {
28341
- ctx.fillStyle = blendColors(style.fillColor || this.getBackgroundColor(renderingContext), box.overlayColor);
28362
+ const backdrop = style.fillColor || this.getBackgroundColor(renderingContext);
28363
+ ctx.fillStyle = backdrop ? blendColors(backdrop, box.overlayColor) : box.overlayColor;
28342
28364
  ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
28343
28365
  }
28344
28366
  if (box?.chip) {
@@ -28366,6 +28388,7 @@ set(value) {
28366
28388
  }
28367
28389
  drawOverflowingCellBackground(renderingContext, boxes) {
28368
28390
  const { ctx, thinLineWidth } = renderingContext;
28391
+ const background = this.getBackgroundColor(renderingContext);
28369
28392
  for (const box of boxes) if (box.content && box.isOverflow) {
28370
28393
  const align = box.content.align || "left";
28371
28394
  let x;
@@ -28383,8 +28406,10 @@ set(value) {
28383
28406
  x = (box.clipRect?.x || box.x + box.width / 2 - box.content.width / 2) + thinLineWidth / 2;
28384
28407
  width = clipWidth - 2 * thinLineWidth;
28385
28408
  }
28386
- ctx.fillStyle = this.getBackgroundColor(renderingContext);
28387
- ctx.fillRect(x, y, width, height);
28409
+ if (background) {
28410
+ ctx.fillStyle = background;
28411
+ ctx.fillRect(x, y, width, height);
28412
+ } else ctx.clearRect(x, y, width, height);
28388
28413
  }
28389
28414
  }
28390
28415
  drawBorders(renderingContext, boxes) {
@@ -28554,7 +28579,7 @@ set(value) {
28554
28579
  ctx.textBaseline = "middle";
28555
28580
  ctx.lineWidth = thinLineWidth;
28556
28581
  ctx.strokeStyle = theme.headerTextColor;
28557
- ctx.fillStyle = this.getters.getSpreadsheetTheme().backgroundColor;
28582
+ ctx.fillStyle = theme.headerBackgroundColor;
28558
28583
  ctx.fillRect(0, 0, 48, height);
28559
28584
  ctx.fillRect(0, 0, width, 26);
28560
28585
  for (const col of visibleCols) {
@@ -29003,7 +29028,7 @@ set(value) {
29003
29028
  }
29004
29029
  }
29005
29030
  getBackgroundColor(renderingContext) {
29006
- return this.getters.getSheet(renderingContext.sheetId).backgroundColor || this.getters.getSpreadsheetTheme().backgroundColor;
29031
+ return this.getters.getSheet(renderingContext.sheetId).backgroundColor;
29007
29032
  }
29008
29033
  };
29009
29034
 
@@ -29016,7 +29041,7 @@ set(value) {
29016
29041
  function drawGrid() {
29017
29042
  const canvas = canvasRef();
29018
29043
  if (!canvas) return;
29019
- const ctx = canvas.getContext("2d", { alpha: false });
29044
+ const ctx = canvas.getContext("2d", { alpha: true });
29020
29045
  const renderingContext = {
29021
29046
  ctx,
29022
29047
  thinLineWidth: .4,
@@ -29259,7 +29284,7 @@ set(value) {
29259
29284
  viewports: this.viewStore.viewports,
29260
29285
  hideGridLines: this.getters.isDashboard(),
29261
29286
  hideFrozenPaneBorder: true,
29262
- dpr: 1,
29287
+ dpr: window.devicePixelRatio || 1,
29263
29288
  selectedZones: [],
29264
29289
  activeCols: /* @__PURE__ */ new Set(),
29265
29290
  activeRows: /* @__PURE__ */ new Set(),
@@ -29821,7 +29846,7 @@ set(value) {
29821
29846
  }
29822
29847
  get carouselStyle() {
29823
29848
  const cssProperties = {};
29824
- const backgroundColor = this.env.model.getters.getSpreadsheetTheme().backgroundColor;
29849
+ const backgroundColor = this.env.model.getters.getSpreadsheetTheme().chartBackgroundColor;
29825
29850
  if (this.selectedCarouselItem?.type === "chart") {
29826
29851
  const chart = this.env.model.getters.getChartRuntime(this.selectedCarouselItem.chartId);
29827
29852
  if ("background" in chart && chart.background) cssProperties["background-color"] = chart.background;
@@ -42778,7 +42803,7 @@ set(value) {
42778
42803
  if (!cells.length) return {
42779
42804
  zone,
42780
42805
  type: "empty",
42781
- hasHeader: false,
42806
+ headerInZone: false,
42782
42807
  rowCount: 0,
42783
42808
  uniqueCount: 0,
42784
42809
  uniqueRatio: 0,
@@ -42786,16 +42811,34 @@ set(value) {
42786
42811
  };
42787
42812
  const firstCell = cells[0];
42788
42813
  const rest = cells.slice(1);
42789
- const hasHeader = firstCell.type === "text" && rest.some((c) => c.type !== "text");
42790
- const dataCells = hasHeader ? rest : cells;
42814
+ let title;
42815
+ let dataCells = [];
42816
+ let headerInZone = false;
42817
+ let analyzedZone = zone;
42818
+ const tableHeaderPosition = getColumnTableHeaderPosition(sheetId, zone, getters);
42819
+ if (tableHeaderPosition) {
42820
+ title = getters.getCellText(tableHeaderPosition) || void 0;
42821
+ dataCells = cells.filter((c) => c.position && c.position.row > tableHeaderPosition.row);
42822
+ headerInZone = !!title && tableHeaderPosition.row >= zone.top && tableHeaderPosition.row <= zone.bottom;
42823
+ if (headerInZone) analyzedZone = {
42824
+ top: tableHeaderPosition.row,
42825
+ bottom: zone.bottom,
42826
+ left: zone.left,
42827
+ right: zone.right
42828
+ };
42829
+ } else if (firstCell.type === "text" && rest.some((c) => c.type !== "text")) {
42830
+ title = firstCell.value;
42831
+ dataCells = rest;
42832
+ headerInZone = true;
42833
+ } else dataCells = cells;
42791
42834
  const numericValues = dataCells.filter((c) => c.type === "number").map((c) => c.value);
42792
42835
  const allVals = dataCells.map((c) => String(c.value ?? ""));
42793
42836
  const uniqueCount = new Set(allVals).size;
42794
42837
  return {
42795
- zone,
42838
+ zone: analyzedZone,
42796
42839
  type: computeColumnType(dataCells),
42797
- header: hasHeader ? firstCell.value : void 0,
42798
- hasHeader,
42840
+ title,
42841
+ headerInZone,
42799
42842
  rowCount: dataCells.length,
42800
42843
  uniqueCount,
42801
42844
  uniqueRatio: allVals.length > 0 ? uniqueCount / allVals.length : 0,
@@ -42821,6 +42864,33 @@ set(value) {
42821
42864
  }
42822
42865
  return "empty";
42823
42866
  }
42867
+ function getColumnTableHeaderPosition(sheetId, zone, getters) {
42868
+ if (zone.left !== zone.right) return;
42869
+ const tables = getters.getTablesOverlappingZones(sheetId, [zone]);
42870
+ if (tables.length !== 1) return;
42871
+ const table = tables[0];
42872
+ const firstCell = {
42873
+ sheetId,
42874
+ col: zone.left,
42875
+ row: zone.top
42876
+ };
42877
+ const lastCell = {
42878
+ sheetId,
42879
+ col: zone.left,
42880
+ row: zone.bottom
42881
+ };
42882
+ if (firstCell.row < table.range.zone.top || lastCell.row > table.range.zone.bottom) {
42883
+ const cells = getters.getEvaluatedCellsInZone(sheetId, zone).filter((c) => c.type !== "empty");
42884
+ for (const cell of cells) if (cell.position && !isInside(cell.position.col, cell.position.row, table.range.zone)) return;
42885
+ }
42886
+ const numberOfHeaders = table.config.numberOfHeaders;
42887
+ if (numberOfHeaders === 0) return;
42888
+ return {
42889
+ sheetId,
42890
+ col: zone.left,
42891
+ row: table.range.zone.top + numberOfHeaders - 1
42892
+ };
42893
+ }
42824
42894
 
42825
42895
  //#endregion
42826
42896
  //#region src/helpers/figures/charts/charts_suggestions_constants.ts
@@ -43065,6 +43135,10 @@ set(value) {
43065
43135
  description: _t("Shows the last date value."),
43066
43136
  isApplicable: ({ rowCount }) => rowCount === 1,
43067
43137
  build: (ctx) => scorecardChart(ctx.title, `=${ctx.lastCellXC}`)
43138
+ }, {
43139
+ description: _t("Shows occurrences for each time slot."),
43140
+ isApplicable: ({ rowCount }) => rowCount > 1,
43141
+ build: (ctx) => calendarChart(ctx.title, ctx.source)
43068
43142
  }];
43069
43143
  /** Pattern D — Single categorical column */
43070
43144
  const SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS = [
@@ -43375,7 +43449,7 @@ set(value) {
43375
43449
  isApplicable: ({ numColsCount }) => numColsCount === 3,
43376
43450
  build: (ctx) => {
43377
43451
  const bubble = ctx.bubble;
43378
- return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.hasTitle);
43452
+ return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.headerInZone);
43379
43453
  }
43380
43454
  }
43381
43455
  ];
@@ -43472,8 +43546,8 @@ set(value) {
43472
43546
  });
43473
43547
  }
43474
43548
  function isPyramidLike(numCol1, numCol2) {
43475
- const h1 = numCol1.header ?? "";
43476
- const h2 = numCol2.header ?? "";
43549
+ const h1 = numCol1.title ?? "";
43550
+ const h2 = numCol2.title ?? "";
43477
43551
  return PYRAMID_HEADER_KEYWORD_PATTERNS.some((re) => re.test(h1) || re.test(h2));
43478
43552
  }
43479
43553
  /** Returns the first and last cell XC coordinates, and the second-to-last cell XC coordinate if it exists. */
@@ -43494,25 +43568,26 @@ set(value) {
43494
43568
  prevCellXC: prevCellPosition ? toXC(prevCellPosition?.col, prevCellPosition?.row) : void 0
43495
43569
  };
43496
43570
  }
43497
- function getCategoryHeader(getters, catCol) {
43498
- let catHeader = catCol.header ?? "";
43499
- if (!catHeader && catCol.rowCount > 0) {
43571
+ function getCategoryHeader(getters, catCol, headerInZone) {
43572
+ if (catCol.title) return catCol.title;
43573
+ if (headerInZone && catCol.rowCount > 0) {
43500
43574
  const { left, top } = catCol.zone;
43501
- catHeader = (getters.getEvaluatedCell({
43575
+ const cellValue = getters.getEvaluatedCell({
43502
43576
  sheetId: getters.getActiveSheetId(),
43503
43577
  col: left,
43504
43578
  row: top
43505
- })?.value || _t("Category")).toString();
43579
+ })?.value;
43580
+ if (cellValue) return cellValue.toString();
43506
43581
  }
43507
- return catHeader;
43582
+ return _t("Category");
43508
43583
  }
43509
43584
  /** Pattern A — Single numeric column */
43510
43585
  function buildSingleNumberContext([col], getters) {
43511
- const title = col.header ?? "";
43586
+ const title = col.title ?? "";
43512
43587
  const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
43513
43588
  return {
43514
43589
  title,
43515
- source: rangeSource([dataset(col.zone, getters)], col.hasHeader),
43590
+ source: rangeSource([dataset(col.zone, getters)], col.headerInZone),
43516
43591
  rowCount: col.rowCount,
43517
43592
  firstCellXC,
43518
43593
  lastCellXC,
@@ -43521,10 +43596,9 @@ set(value) {
43521
43596
  }
43522
43597
  /** Pattern B — Single percentage column */
43523
43598
  function buildSinglePercentageContext([col], getters) {
43524
- const hasTitle = col.hasHeader;
43525
- const title = col.header ?? "";
43599
+ const title = col.title ?? "";
43526
43600
  const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
43527
- const source = rangeSource([dataset(col.zone, getters)], hasTitle);
43601
+ const source = rangeSource([dataset(col.zone, getters)], col.headerInZone);
43528
43602
  const isAboveOne = (col.maxValue ?? 0) > 1;
43529
43603
  return {
43530
43604
  title,
@@ -43537,22 +43611,24 @@ set(value) {
43537
43611
  };
43538
43612
  }
43539
43613
  /** Pattern C — Single date column */
43540
- function buildSingleDateContext([col]) {
43614
+ function buildSingleDateContext([col], getters) {
43541
43615
  const { lastCellXC } = interestingCellsXc(col);
43616
+ const labelRange = getUnboundRange(getters, col.zone);
43617
+ const source = rangeSource([dataset(col.zone, getters)], col.headerInZone, labelRange);
43542
43618
  return {
43543
- title: col.header ?? "",
43619
+ title: col.title ?? "",
43544
43620
  lastCellXC,
43545
- rowCount: col.rowCount
43621
+ rowCount: col.rowCount,
43622
+ source
43546
43623
  };
43547
43624
  }
43548
43625
  /** Pattern D — Single categorical column */
43549
43626
  function buildSingleCategoricalContext([col], getters) {
43550
- const hasTitle = col.hasHeader;
43551
- const title = col.header ?? "";
43627
+ const title = col.title ?? "";
43552
43628
  const range = getUnboundRange(getters, col.zone);
43553
43629
  return {
43554
43630
  title,
43555
- source: rangeSource([dataset(col.zone, getters)], hasTitle, range),
43631
+ source: rangeSource([dataset(col.zone, getters)], col.headerInZone, range),
43556
43632
  range
43557
43633
  };
43558
43634
  }
@@ -43560,7 +43636,7 @@ set(value) {
43560
43636
  function buildSingleLabelContext([col]) {
43561
43637
  const { lastCellXC } = interestingCellsXc(col);
43562
43638
  return {
43563
- title: "",
43639
+ title: col.title ?? "",
43564
43640
  lastCellXC,
43565
43641
  rowCount: col.rowCount
43566
43642
  };
@@ -43568,37 +43644,37 @@ set(value) {
43568
43644
  /** Pattern F — Categorical + Number */
43569
43645
  function buildCategoricalVsNumberContext([catCol, numCol], getters) {
43570
43646
  const labelRange = getUnboundRange(getters, catCol.zone);
43571
- const hasTitle = numCol.hasHeader;
43572
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43647
+ const headerInZone = numCol.headerInZone;
43648
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43573
43649
  return {
43574
- title: numCol.header ? _t("%(numberHeader)s by %(categoryHeader)s", {
43575
- numberHeader: numCol.header,
43650
+ title: numCol.title ? _t("%(numberHeader)s by %(categoryHeader)s", {
43651
+ numberHeader: numCol.title,
43576
43652
  categoryHeader
43577
43653
  }) : "",
43578
- source: rangeSource([dataset(numCol.zone, getters)], hasTitle, labelRange),
43579
- treemapSource: rangeSource([dataset(catCol.zone, getters)], hasTitle, getUnboundRange(getters, numCol.zone))
43654
+ source: rangeSource([dataset(numCol.zone, getters)], headerInZone, labelRange),
43655
+ treemapSource: rangeSource([dataset(catCol.zone, getters)], headerInZone, getUnboundRange(getters, numCol.zone))
43580
43656
  };
43581
43657
  }
43582
43658
  /** Patterns G & J — Date + Number or Date + Percentage */
43583
43659
  function buildDateVsSeriesContext([dateCol, seriesCol], getters) {
43584
43660
  const isPercentage = seriesCol.type === "percentage";
43585
43661
  const labelRange = getUnboundRange(getters, dateCol.zone);
43586
- const hasTitle = isDatasetTitled(getters, dateCol.zone);
43662
+ const headerInZone = isDatasetTitled(getters, dateCol.zone);
43587
43663
  return {
43588
- title: seriesCol.header ? _t("%(seriesHeader)s over time", { seriesHeader: seriesCol.header }) : "",
43589
- source: rangeSource([dataset(seriesCol.zone, getters)], hasTitle, labelRange),
43664
+ title: seriesCol.title ? _t("%(seriesHeader)s over time", { seriesHeader: seriesCol.title }) : "",
43665
+ source: rangeSource([dataset(seriesCol.zone, getters)], headerInZone, labelRange),
43590
43666
  isPercentage
43591
43667
  };
43592
43668
  }
43593
43669
  /** Pattern H — Number + Number */
43594
43670
  function buildNumberVsNumberContext([col1, col2], getters) {
43595
- const title = col1.header && col2.header ? _t("%(col2Header)s vs %(col1Header)s", {
43596
- col2Header: col2.header,
43597
- col1Header: col1.header
43671
+ const title = col1.title && col2.title ? _t("%(col2Header)s vs %(col1Header)s", {
43672
+ col2Header: col2.title,
43673
+ col1Header: col1.title
43598
43674
  }) : "";
43599
- const hasTitle = col1.hasHeader || col2.hasHeader;
43600
- const source2 = rangeSource([dataset(col2.zone, getters)], col2.hasHeader, getUnboundRange(getters, col1.zone));
43601
- const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")], hasTitle);
43675
+ const headerInZone = col1.headerInZone || col2.headerInZone;
43676
+ const source2 = rangeSource([dataset(col2.zone, getters)], col2.headerInZone, getUnboundRange(getters, col1.zone));
43677
+ const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")], headerInZone);
43602
43678
  const { lastCellXC } = interestingCellsXc(col2);
43603
43679
  const { lastCellXC: prevCellXC } = interestingCellsXc(col1);
43604
43680
  return {
@@ -43614,26 +43690,25 @@ set(value) {
43614
43690
  /** Pattern I — Categorical + Percentage */
43615
43691
  function buildCategoricalVsPercentageContext([catCol, pctCol], getters) {
43616
43692
  const labelRange = getUnboundRange(getters, catCol.zone);
43617
- const hasTitle = pctCol.hasHeader;
43618
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43693
+ const headerInZone = pctCol.headerInZone;
43694
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43619
43695
  return {
43620
- title: pctCol.header ? _t("%(percentageHeader)s by %(categoryHeader)s", {
43621
- percentageHeader: pctCol.header,
43696
+ title: pctCol.title ? _t("%(percentageHeader)s by %(categoryHeader)s", {
43697
+ percentageHeader: pctCol.title,
43622
43698
  categoryHeader
43623
43699
  }) : "",
43624
- source: rangeSource([dataset(pctCol.zone, getters)], hasTitle, labelRange),
43700
+ source: rangeSource([dataset(pctCol.zone, getters)], headerInZone, labelRange),
43625
43701
  rowCount: catCol.rowCount
43626
43702
  };
43627
43703
  }
43628
43704
  /** Pattern K — Label + Number */
43629
43705
  function buildLabelVsNumberContext([labelCol, numCol], getters) {
43630
43706
  const labelRange = getUnboundRange(getters, labelCol.zone);
43631
- const hasTitle = numCol.hasHeader;
43632
- const title = numCol.header ? _t("%(numberHeader)s by %(labelHeader)s", {
43633
- numberHeader: numCol.header,
43634
- labelHeader: labelCol.header ?? _t("Name")
43707
+ const title = numCol.title ? _t("%(numberHeader)s by %(labelHeader)s", {
43708
+ numberHeader: numCol.title,
43709
+ labelHeader: labelCol.title ?? _t("Name")
43635
43710
  }) : "";
43636
- const source = rangeSource([dataset(numCol.zone, getters)], hasTitle, labelRange);
43711
+ const source = rangeSource([dataset(numCol.zone, getters)], numCol.headerInZone, labelRange);
43637
43712
  const { lastCellXC } = interestingCellsXc(numCol);
43638
43713
  const { lastCellXC: prevCellXC } = interestingCellsXc(labelCol);
43639
43714
  return {
@@ -43647,66 +43722,66 @@ set(value) {
43647
43722
  /** Pattern M — Categorical + Multiple Numbers */
43648
43723
  function buildCategoricalVsMultipleNumbersContext([catCol, ...numCols], getters) {
43649
43724
  const labelRange = getUnboundRange(getters, catCol.zone);
43650
- const hasTitle = numCols.some((c) => c.hasHeader);
43651
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : "";
43725
+ const headerInZone = numCols.some((c) => c.headerInZone);
43726
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43652
43727
  return {
43653
- title: hasTitle ? _t("Multi-series By %(categoryHeader)s", { categoryHeader }) : "",
43654
- source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange),
43728
+ title: headerInZone ? _t("Multi-series By %(categoryHeader)s", { categoryHeader }) : "",
43729
+ source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange),
43655
43730
  rowCount: catCol.rowCount
43656
43731
  };
43657
43732
  }
43658
43733
  /** Pattern N — Date + Multiple Numbers */
43659
43734
  function buildDateVsMultipleNumbersContext([dateCol, ...numCols], getters) {
43660
43735
  const labelRange = getUnboundRange(getters, dateCol.zone);
43661
- const hasTitle = numCols.some((c) => c.hasHeader) || isDatasetTitled(getters, dateCol.zone);
43736
+ const headerInZone = numCols.some((c) => c.headerInZone) || isDatasetTitled(getters, dateCol.zone);
43662
43737
  return {
43663
- title: numCols.length === 1 && numCols[0].header ? _t("%(header)s over time", { header: numCols[0].header }) : "",
43664
- source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange)
43738
+ title: numCols.length === 1 && numCols[0].title ? _t("%(header)s over time", { header: numCols[0].title }) : "",
43739
+ source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange)
43665
43740
  };
43666
43741
  }
43667
43742
  /** Pattern O — Categorical + Categorical + Number */
43668
43743
  function buildMultipleCategoricalsVsNumberContext([cat1, cat2, numCol], getters) {
43669
- const title = numCol.header ? _t("%(numHeader)s by %(cat1Header)s and %(cat2Header)s", {
43670
- numHeader: numCol.header,
43671
- cat1Header: cat1.header ?? _t("Level 1"),
43672
- cat2Header: cat2.header ?? _t("Level 2")
43744
+ const title = numCol.title ? _t("%(numHeader)s by %(cat1Header)s and %(cat2Header)s", {
43745
+ numHeader: numCol.title,
43746
+ cat1Header: cat1.title ?? _t("Level 1"),
43747
+ cat2Header: cat2.title ?? _t("Level 2")
43673
43748
  }) : "";
43674
- const hasTitle = numCol.hasHeader;
43749
+ const headerInZone = numCol.headerInZone;
43675
43750
  return {
43676
43751
  title,
43677
- hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")], hasTitle, getUnboundRange(getters, numCol.zone)),
43678
- barSource: rangeSource([dataset(numCol.zone, getters)], hasTitle, getUnboundRange(getters, cat1.zone))
43752
+ hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")], headerInZone, getUnboundRange(getters, numCol.zone)),
43753
+ barSource: rangeSource([dataset(numCol.zone, getters)], headerInZone, getUnboundRange(getters, cat1.zone))
43679
43754
  };
43680
43755
  }
43681
43756
  /** Pattern P — Categorical + Date + Number */
43682
43757
  function buildCategoricalDateNumberContext([catCol, dateCol, numCol], getters) {
43683
43758
  const dateRange = getUnboundRange(getters, dateCol.zone);
43684
43759
  const catRange = getUnboundRange(getters, catCol.zone);
43685
- const hasTitle = numCol.hasHeader;
43686
- const catHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43760
+ const headerInZone = numCol.headerInZone;
43761
+ const catHeader = getCategoryHeader(getters, catCol, headerInZone);
43687
43762
  return {
43688
- title: numCol.header ? _t("%(numHeader)s by %(catHeader)s over %(dateHeader)s", {
43689
- numHeader: numCol.header,
43763
+ title: numCol.title ? _t("%(numHeader)s by %(catHeader)s over %(dateHeader)s", {
43764
+ numHeader: numCol.title,
43690
43765
  catHeader,
43691
- dateHeader: dateCol.header ?? _t("Time")
43766
+ dateHeader: dateCol.title ?? _t("Time")
43692
43767
  }) : "",
43693
- sourceByDate: rangeSource([dataset(numCol.zone, getters)], hasTitle, dateRange),
43694
- sourceByCat: rangeSource([dataset(numCol.zone, getters)], hasTitle, catRange)
43768
+ sourceByDate: rangeSource([dataset(numCol.zone, getters)], headerInZone, dateRange),
43769
+ sourceByCat: rangeSource([dataset(numCol.zone, getters)], headerInZone, catRange)
43695
43770
  };
43696
43771
  }
43697
43772
  /** Pattern Q — Label + Multiple Numbers */
43698
43773
  function buildLabelVsMultipleNumbersContext([labelCol, ...numCols], getters) {
43699
43774
  const labelRange = getUnboundRange(getters, labelCol.zone);
43700
- const hasTitle = numCols.some((c) => c.hasHeader);
43701
- const title = labelCol.header ? _t("By %(header)s", { header: labelCol.header }) : "";
43702
- const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange);
43703
- const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].hasHeader, getUnboundRange(getters, numCols[0].zone));
43775
+ const headerInZone = numCols.some((c) => c.headerInZone);
43776
+ const title = labelCol.title ? _t("By %(title)s", { title: labelCol.title }) : "";
43777
+ const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange);
43778
+ const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].headerInZone, getUnboundRange(getters, numCols[0].zone));
43704
43779
  const bubble = numCols.length === 3 ? {
43705
43780
  xRange: getUnboundRange(getters, numCols[0].zone),
43706
43781
  yRanges: [getUnboundRange(getters, numCols[1].zone)],
43707
43782
  sizeRange: getUnboundRange(getters, numCols[2].zone),
43708
43783
  labelRange,
43709
- hasTitle
43784
+ headerInZone
43710
43785
  } : void 0;
43711
43786
  return {
43712
43787
  title,
@@ -43720,25 +43795,25 @@ set(value) {
43720
43795
  /** Pattern R — Categorical + Two Numbers (Population Pyramid or Grouped) */
43721
43796
  function buildCategoricalTwoNumbersContext([catCol, numCol1, numCol2], getters) {
43722
43797
  const catRange = getUnboundRange(getters, catCol.zone);
43723
- const hasTitle = numCol1.hasHeader || numCol2.hasHeader;
43724
- const catHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43725
- const title = numCol1.header && numCol2.header ? _t("%(num1Header)s vs %(num2Header)s by %(catHeader)s", {
43726
- num1Header: numCol1.header,
43727
- num2Header: numCol2.header,
43798
+ const headerInZone = numCol1.headerInZone || numCol2.headerInZone;
43799
+ const catHeader = getCategoryHeader(getters, catCol, headerInZone);
43800
+ const title = numCol1.title && numCol2.title ? _t("%(num1Header)s vs %(num2Header)s by %(catHeader)s", {
43801
+ num1Header: numCol1.title,
43802
+ num2Header: numCol2.title,
43728
43803
  catHeader
43729
43804
  }) : "";
43730
43805
  const isPyramid = isPyramidLike(numCol1, numCol2);
43731
43806
  return {
43732
43807
  title,
43733
- sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")], hasTitle, catRange),
43808
+ sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")], headerInZone, catRange),
43734
43809
  isPyramid
43735
43810
  };
43736
43811
  }
43737
43812
  /** Pattern S — Many Numbers (3+ numeric columns, no categorical/date) */
43738
43813
  function buildManyNumbersContext(cols, getters) {
43739
- const title = cols.every((c) => c.hasHeader) ? cols.map((c) => c.header).join(" / ") : "";
43740
- const hasTitle = cols.some((c) => c.hasHeader);
43741
- const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle);
43814
+ const title = cols.every((c) => c.headerInZone) ? cols.map((c) => c.title).join(" / ") : "";
43815
+ const headerInZone = cols.some((c) => c.headerInZone);
43816
+ const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone);
43742
43817
  const { lastCellXC } = interestingCellsXc(cols[2]);
43743
43818
  const { lastCellXC: firstCellXC } = interestingCellsXc(cols[0]);
43744
43819
  const { lastCellXC: secondCellXC } = interestingCellsXc(cols[1]);
@@ -43753,6 +43828,7 @@ set(value) {
43753
43828
  };
43754
43829
  }
43755
43830
  const NUMBER_OR_PERCENTAGE = ["number", "percentage"];
43831
+ const CATEGORICAL_OR_BOOLEAN = ["categorical", "boolean"];
43756
43832
  const EXACT_PATTERNS = [
43757
43833
  {
43758
43834
  pattern: { leadingTypes: ["number"] },
@@ -43770,7 +43846,7 @@ set(value) {
43770
43846
  suggestions: SINGLE_DATE_COLUMN_SUGGESTIONS
43771
43847
  },
43772
43848
  {
43773
- pattern: { leadingTypes: ["categorical"] },
43849
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN] },
43774
43850
  buildContext: buildSingleCategoricalContext,
43775
43851
  suggestions: SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS
43776
43852
  },
@@ -43780,7 +43856,7 @@ set(value) {
43780
43856
  suggestions: SINGLE_LABEL_COLUMN_SUGGESTIONS
43781
43857
  },
43782
43858
  {
43783
- pattern: { leadingTypes: ["categorical", "number"] },
43859
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "number"] },
43784
43860
  buildContext: buildCategoricalVsNumberContext,
43785
43861
  suggestions: CATEGORICAL_VS_NUMBER_SUGGESTIONS
43786
43862
  },
@@ -43795,7 +43871,7 @@ set(value) {
43795
43871
  suggestions: NUMBER_VS_NUMBER_SUGGESTIONS
43796
43872
  },
43797
43873
  {
43798
- pattern: { leadingTypes: ["categorical", "percentage"] },
43874
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "percentage"] },
43799
43875
  buildContext: buildCategoricalVsPercentageContext,
43800
43876
  suggestions: CATEGORICAL_VS_PERCENTAGE_SUGGESTIONS
43801
43877
  },
@@ -43811,8 +43887,8 @@ set(value) {
43811
43887
  },
43812
43888
  {
43813
43889
  pattern: { leadingTypes: [
43814
- "categorical",
43815
- "categorical",
43890
+ CATEGORICAL_OR_BOOLEAN,
43891
+ CATEGORICAL_OR_BOOLEAN,
43816
43892
  "number"
43817
43893
  ] },
43818
43894
  buildContext: buildMultipleCategoricalsVsNumberContext,
@@ -43820,7 +43896,7 @@ set(value) {
43820
43896
  },
43821
43897
  {
43822
43898
  pattern: { leadingTypes: [
43823
- "categorical",
43899
+ CATEGORICAL_OR_BOOLEAN,
43824
43900
  "label",
43825
43901
  "number"
43826
43902
  ] },
@@ -43829,7 +43905,7 @@ set(value) {
43829
43905
  },
43830
43906
  {
43831
43907
  pattern: { leadingTypes: [
43832
- "categorical",
43908
+ CATEGORICAL_OR_BOOLEAN,
43833
43909
  "date",
43834
43910
  NUMBER_OR_PERCENTAGE
43835
43911
  ] },
@@ -43838,7 +43914,7 @@ set(value) {
43838
43914
  },
43839
43915
  {
43840
43916
  pattern: { leadingTypes: [
43841
- "categorical",
43917
+ CATEGORICAL_OR_BOOLEAN,
43842
43918
  NUMBER_OR_PERCENTAGE,
43843
43919
  NUMBER_OR_PERCENTAGE
43844
43920
  ] },
@@ -57233,7 +57309,7 @@ set(value) {
57233
57309
  return this.strictMeasureValueToNumber(comparedValue);
57234
57310
  }
57235
57311
  getPivotValueCells(measureId) {
57236
- return this.getCollapsedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
57312
+ return this.getExpandedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
57237
57313
  }
57238
57314
  measureValueToNumber(result) {
57239
57315
  if (typeof result.value === "number") return result.value;
@@ -65929,7 +66005,7 @@ set(value) {
65929
66005
  * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
65930
66006
  */
65931
66007
  getStyleOfSingleCellChart(chartBackground, mainRange, colorThemeName) {
65932
- const themeBackground = COLOR_THEMES[colorThemeName].backgroundColor;
66008
+ const themeBackground = COLOR_THEMES[colorThemeName].chartBackgroundColor;
65933
66009
  if (chartBackground) return {
65934
66010
  background: chartBackground,
65935
66011
  fontColor: chartFontColor(chartBackground)
@@ -66983,14 +67059,12 @@ set(value) {
66983
67059
  var UIPlugin = class extends BasePlugin {
66984
67060
  static layers = [];
66985
67061
  getters;
66986
- ui;
66987
67062
  selection;
66988
67063
  dispatch;
66989
67064
  canDispatch;
66990
- constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection }) {
67065
+ constructor({ getters, stateObserver, dispatch, canDispatch, selection }) {
66991
67066
  super(stateObserver);
66992
67067
  this.getters = getters;
66993
- this.ui = uiActions;
66994
67068
  this.selection = selection;
66995
67069
  this.dispatch = dispatch;
66996
67070
  this.canDispatch = canDispatch;
@@ -72459,9 +72533,7 @@ set(value) {
72459
72533
  return cssPropertiesToCss({ zoom: this.zoomStore.cssZoom });
72460
72534
  }
72461
72535
  get backgroundStyle() {
72462
- const sheet = this.env.model.getters.getActiveSheet();
72463
- const theme = this.env.model.getters.getSpreadsheetTheme();
72464
- return cssPropertiesToCss({ "background-color": sheet.backgroundColor || theme.backgroundColor });
72536
+ return cssPropertiesToCss({ "background-color": this.env.model.getters.getActiveSheet().backgroundColor });
72465
72537
  }
72466
72538
  };
72467
72539
 
@@ -73067,7 +73139,7 @@ set(value) {
73067
73139
  ctx.beginPath();
73068
73140
  ctx.rect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
73069
73141
  ctx.clip();
73070
- ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().backgroundColor;
73142
+ ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().chartBackgroundColor;
73071
73143
  ctx.fillRect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
73072
73144
  const title = {
73073
73145
  ...DEFAULT_CAROUSEL_TITLE_STYLE,
@@ -74975,14 +75047,10 @@ set(value) {
74975
75047
  sticky: false
74976
75048
  });
74977
75049
  });
74978
- this.model.on("notify-ui", this, (notification) => this.notificationStore.notifyUser(notification));
74979
- this.model.on("raise-error-ui", this, ({ text }) => this.notificationStore.raiseError(text));
74980
75050
  }
74981
75051
  unbindModelEvents() {
74982
75052
  this.model.off("update", this);
74983
75053
  this.model.off("command-rejected", this);
74984
- this.model.off("notify-ui", this);
74985
- this.model.off("raise-error-ui", this);
74986
75054
  }
74987
75055
  checkViewportSize() {
74988
75056
  const { xRatio, yRatio } = this.viewStore.viewports.getFrozenSheetViewRatio(this.viewStore.displayedSheetId);
@@ -79397,8 +79465,6 @@ set(value) {
79397
79465
  client,
79398
79466
  moveClient: () => {},
79399
79467
  snapshotRequested: false,
79400
- notifyUI: (payload) => this.trigger("notify-ui", payload),
79401
- raiseBlockingErrorUI: (text) => this.trigger("raise-error-ui", { text }),
79402
79468
  customColors: config.customColors || []
79403
79469
  };
79404
79470
  }
@@ -79442,7 +79508,6 @@ set(value) {
79442
79508
  selection: this.selection,
79443
79509
  moveClient: this.session.move.bind(this.session),
79444
79510
  custom: this.config.custom,
79445
- uiActions: this.config,
79446
79511
  session: this.session,
79447
79512
  defaultCurrency: this.config.defaultCurrency,
79448
79513
  customColors: this.config.customColors || [],
@@ -79578,7 +79643,15 @@ set(value) {
79578
79643
  dispatchFromEvaluationPlugin = (type, payload) => {
79579
79644
  const command = createCommand(type, payload);
79580
79645
  if (!isDispatcheableEvaluationCommand(command)) throw new Error(`An evaluation plugin cannot dispatch non-evaluation commands (${type})`);
79646
+ if (this.status !== 0) {
79647
+ this.dispatchToHandlers(this.evaluationHandlers, command);
79648
+ return DispatchResult.Success;
79649
+ }
79650
+ this.status = 3;
79581
79651
  this.dispatchToHandlers(this.evaluationHandlers, command);
79652
+ this.finalize();
79653
+ this.status = 0;
79654
+ this.trigger("update");
79582
79655
  return DispatchResult.Success;
79583
79656
  };
79584
79657
  /**
@@ -82118,7 +82191,7 @@ set(value) {
82118
82191
  legend: getBubbleChartLegend(definition, chartData),
82119
82192
  tooltip: getBubbleChartTooltip(definition, chartData),
82120
82193
  chartShowValuesPlugin: getChartShowValues(definition, chartData),
82121
- background: { color: definition.background }
82194
+ background: { color: chartData.background }
82122
82195
  }
82123
82196
  }
82124
82197
  } };
@@ -91457,8 +91530,8 @@ exports.stores = stores;
91457
91530
  exports.tokenColors = tokenColors;
91458
91531
  exports.tokenize = tokenize;
91459
91532
 
91460
- __info__.version = "19.5.0-alpha.19";
91461
- __info__.date = "2026-09-10T05:38:44.935Z";
91462
- __info__.hash = "2b1e397";
91533
+ __info__.version = "19.5.0-alpha.20";
91534
+ __info__.date = "2026-09-16T08:02:11.430Z";
91535
+ __info__.hash = "4784627";
91463
91536
 
91464
91537
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);