@odoo/o-spreadsheet 18.4.5 → 18.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.5
6
- * @date 2025-08-04T06:54:49.107Z
7
- * @hash 358931f
5
+ * @version 18.4.7
6
+ * @date 2025-08-21T06:42:12.438Z
7
+ * @hash d5eb3a6
8
8
  */
9
9
 
10
10
  'use strict';
@@ -2781,6 +2781,7 @@ exports.CommandResult = void 0;
2781
2781
  CommandResult["Success"] = "Success";
2782
2782
  CommandResult["CancelledForUnknownReason"] = "CancelledForUnknownReason";
2783
2783
  CommandResult["WillRemoveExistingMerge"] = "WillRemoveExistingMerge";
2784
+ CommandResult["CannotMoveTableHeader"] = "CannotMoveTableHeader";
2784
2785
  CommandResult["MergeIsDestructive"] = "MergeIsDestructive";
2785
2786
  CommandResult["CellIsMerged"] = "CellIsMerged";
2786
2787
  CommandResult["InvalidTarget"] = "InvalidTarget";
@@ -7256,15 +7257,18 @@ function parseOSClipboardContent(content, clipboardId) {
7256
7257
  ?.getAttribute("data-osheet-clipboard");
7257
7258
  spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
7258
7259
  }
7260
+ const textContent = content[ClipboardMIMEType.PlainText] || "";
7259
7261
  let imageBlob = undefined;
7260
- for (const type of AllowedImageMimeTypes) {
7261
- if (content[type]) {
7262
- imageBlob = content[type];
7263
- break;
7262
+ if (!textContent.trim()) {
7263
+ for (const type of AllowedImageMimeTypes) {
7264
+ if (content[type]) {
7265
+ imageBlob = content[type];
7266
+ break;
7267
+ }
7264
7268
  }
7265
7269
  }
7266
7270
  const osClipboardContent = {
7267
- text: content[ClipboardMIMEType.PlainText],
7271
+ text: textContent,
7268
7272
  data: spreadsheetContent,
7269
7273
  imageBlob,
7270
7274
  };
@@ -19641,7 +19645,7 @@ const OFFSET = {
19641
19645
  right: startingCol + offsetWidth - 1,
19642
19646
  bottom: startingRow + offsetHeight - 1,
19643
19647
  };
19644
- const range = this.getters.getRangeFromZone(this.__originSheetId, dependencyZone);
19648
+ const range = this.getters.getRangeFromZone(sheetId, dependencyZone);
19645
19649
  if (range.invalidXc || range.invalidSheetName) {
19646
19650
  return new InvalidReferenceError();
19647
19651
  }
@@ -24286,6 +24290,7 @@ const CustomCurrencyTerms = {
24286
24290
  Custom: _t("Custom"),
24287
24291
  };
24288
24292
  const MergeErrorMessage = _t("Merged cells are preventing this operation. Unmerge those cells and try again.");
24293
+ const TableHeaderMoveErrorMessage = _t("The header row of a table can't be moved.");
24289
24294
  const SplitToColumnsTerms = {
24290
24295
  Errors: {
24291
24296
  Unexpected: _t("Cannot split the selection for an unknown reason"),
@@ -28183,9 +28188,6 @@ class RadarChart extends AbstractChart {
28183
28188
  };
28184
28189
  }
28185
28190
  getDefinitionForExcel() {
28186
- if (this.aggregated) {
28187
- return undefined;
28188
- }
28189
28191
  const dataSets = this.dataSets
28190
28192
  .map((ds) => toExcelDataset(this.getters, ds))
28191
28193
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -43833,7 +43835,7 @@ const insertDropdown = {
43833
43835
  env.openSidePanel("DataValidationEditor", {
43834
43836
  rule: localizeDataValidationRule(rule, env.model.getters.getLocale()),
43835
43837
  onExit: () => {
43836
- env.openSidePanel("DataValidation");
43838
+ env.replaceSidePanel("DataValidation", "DataValidationEditor");
43837
43839
  },
43838
43840
  });
43839
43841
  },
@@ -47707,8 +47709,13 @@ class RowResizer extends AbstractResizer {
47707
47709
  elements,
47708
47710
  position: this.state.position,
47709
47711
  });
47710
- if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47711
- this.env.raiseError(MergeErrorMessage);
47712
+ if (!result.isSuccessful) {
47713
+ if (result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47714
+ this.env.raiseError(MergeErrorMessage);
47715
+ }
47716
+ else if (result.reasons.includes("CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */)) {
47717
+ this.env.raiseError(TableHeaderMoveErrorMessage);
47718
+ }
47712
47719
  }
47713
47720
  }
47714
47721
  _selectElement(index, addDistinctHeader) {
@@ -53653,11 +53660,15 @@ class PivotMeasureDisplayPanel extends owl.Component {
53653
53660
  this.store = useLocalStore(PivotMeasureDisplayPanelStore, this.props.pivotId, this.props.measure);
53654
53661
  }
53655
53662
  onSave() {
53656
- this.env.openSidePanel("PivotSidePanel", { pivotId: this.props.pivotId });
53663
+ this.env.replaceSidePanel("PivotSidePanel", `pivot_measure_display_${this.props.pivotId}_${this.props.measure.id}`, {
53664
+ pivotId: this.props.pivotId,
53665
+ });
53657
53666
  }
53658
53667
  onCancel() {
53659
53668
  this.store.cancelMeasureDisplayEdition();
53660
- this.env.openSidePanel("PivotSidePanel", { pivotId: this.props.pivotId });
53669
+ this.env.replaceSidePanel("PivotSidePanel", `pivot_measure_display_${this.props.pivotId}_${this.props.measure.id}`, {
53670
+ pivotId: this.props.pivotId,
53671
+ });
53661
53672
  }
53662
53673
  get fieldChoices() {
53663
53674
  return this.store.fields.map((field) => ({
@@ -54119,7 +54130,7 @@ class PivotMeasureEditor extends owl.Component {
54119
54130
  });
54120
54131
  }
54121
54132
  openShowValuesAs() {
54122
- this.env.openSidePanel("PivotMeasureDisplayPanel", {
54133
+ this.env.replaceSidePanel("PivotMeasureDisplayPanel", `pivot_key_${this.props.pivotId}`, {
54123
54134
  pivotId: this.props.pivotId,
54124
54135
  measure: this.props.measure,
54125
54136
  });
@@ -54379,7 +54390,7 @@ class PivotLayoutConfigurator extends owl.Component {
54379
54390
  this.props.onDimensionsUpdated(update);
54380
54391
  }
54381
54392
  getMeasureId(fieldName, aggregator) {
54382
- const baseId = fieldName + (aggregator ? `:${aggregator}` : "");
54393
+ const baseId = fieldName.replaceAll("'", "") + (aggregator ? `:${aggregator}` : "");
54383
54394
  let id = baseId;
54384
54395
  let i = 2;
54385
54396
  while (this.props.definition.measures.some((m) => m.id === id)) {
@@ -57218,7 +57229,11 @@ sidePanelRegistry.add("PivotMeasureDisplayPanel", {
57218
57229
  try {
57219
57230
  // This will throw if the pivot or measure does not exist
57220
57231
  getters.getPivot(props.pivotId).getMeasure(props.measure.id);
57221
- return { isOpen: true, props, key: "pivot_measure_display" };
57232
+ return {
57233
+ isOpen: true,
57234
+ props,
57235
+ key: `pivot_measure_display_${props.pivotId}_${props.measure.id}`,
57236
+ };
57222
57237
  }
57223
57238
  catch (e) {
57224
57239
  return { isOpen: false };
@@ -57243,6 +57258,7 @@ const MIN_SHEET_VIEW_WIDTH = 150;
57243
57258
  class SidePanelStore extends SpreadsheetStore {
57244
57259
  mutators = [
57245
57260
  "open",
57261
+ "replace",
57246
57262
  "toggle",
57247
57263
  "close",
57248
57264
  "changePanelSize",
@@ -57304,8 +57320,7 @@ class SidePanelStore extends SpreadsheetStore {
57304
57320
  if (!state.isOpen) {
57305
57321
  return;
57306
57322
  }
57307
- const mainPanelKey = this.mainPanel ? this.getPanelKey(this.mainPanel) : undefined;
57308
- if (!this.mainPanel || !this.mainPanel.isPinned || mainPanelKey === state.key) {
57323
+ if (!this.mainPanel || !this.mainPanel.isPinned || this.mainPanelKey === state.key) {
57309
57324
  this._openPanel("mainPanel", newPanelInfo, state);
57310
57325
  return;
57311
57326
  }
@@ -57324,6 +57339,34 @@ class SidePanelStore extends SpreadsheetStore {
57324
57339
  }
57325
57340
  this._openPanel("secondaryPanel", newPanelInfo, state);
57326
57341
  }
57342
+ replace(componentTag, currentPanelKey, initialPanelProps = {}) {
57343
+ const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
57344
+ const state = this.computeState(newPanelInfo);
57345
+ if (!state.isOpen) {
57346
+ return;
57347
+ }
57348
+ const ensureMainPanelExpanded = () => {
57349
+ if (this.mainPanel?.isCollapsed) {
57350
+ this.toggleCollapsePanel("mainPanel");
57351
+ }
57352
+ };
57353
+ // Close the current panel if the target panel is already open
57354
+ const isMainPanel = this.mainPanelKey === state.key;
57355
+ const isSecondaryPanel = this.secondaryPanelKey === state.key;
57356
+ if (isMainPanel && this.secondaryPanel) {
57357
+ this.close();
57358
+ ensureMainPanelExpanded();
57359
+ return;
57360
+ }
57361
+ if (isSecondaryPanel) {
57362
+ this.closeMainPanel();
57363
+ this.togglePinPanel();
57364
+ ensureMainPanelExpanded();
57365
+ return;
57366
+ }
57367
+ const targetPanel = this.mainPanelKey === currentPanelKey ? "mainPanel" : "secondaryPanel";
57368
+ this._openPanel(targetPanel, newPanelInfo, state);
57369
+ }
57327
57370
  _openPanel(panel, newPanel, state) {
57328
57371
  const currentPanel = this[panel];
57329
57372
  if (currentPanel && newPanel.componentTag !== currentPanel.componentTag) {
@@ -57383,11 +57426,9 @@ class SidePanelStore extends SpreadsheetStore {
57383
57426
  panelInfo.size = size;
57384
57427
  }
57385
57428
  resetPanelSize(panel) {
57386
- const panelInfo = this[panel];
57387
- if (!panelInfo) {
57388
- return;
57429
+ if (this[panel]) {
57430
+ this[panel].size = DEFAULT_SIDE_PANEL_SIZE;
57389
57431
  }
57390
- panelInfo.size = DEFAULT_SIDE_PANEL_SIZE;
57391
57432
  }
57392
57433
  togglePinPanel() {
57393
57434
  if (!this.mainPanel) {
@@ -68353,7 +68394,7 @@ function withPivotPresentationLayer (PivotClass) {
68353
68394
  return PivotPresentationLayer;
68354
68395
  }
68355
68396
 
68356
- const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
68397
+ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT", "REMOVE_PIVOT"];
68357
68398
  function isPivotCommand(cmd) {
68358
68399
  return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
68359
68400
  }
@@ -74321,8 +74362,33 @@ class GridSelectionPlugin extends UIPlugin {
74321
74362
  if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
74322
74363
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
74323
74364
  }
74365
+ if (!isCol && !this.isTableRowMoveAllowed(id, cmd.elements)) {
74366
+ return "CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */;
74367
+ }
74324
74368
  return "Success" /* CommandResult.Success */;
74325
74369
  }
74370
+ isTableRowMoveAllowed(sheetId, selectedRows) {
74371
+ const tables = this.getters.getCoreTables(sheetId);
74372
+ if (tables.length === 0) {
74373
+ return true;
74374
+ }
74375
+ const selectedRowSet = new Set(selectedRows);
74376
+ return tables.every(({ range: { zone }, config }) => {
74377
+ const { top, bottom } = zone;
74378
+ if (config.numberOfHeaders === 0) {
74379
+ return true;
74380
+ }
74381
+ const headerRowEnd = top + config.numberOfHeaders - 1;
74382
+ // Moving the table is allowed if table header rows are not part of the selection
74383
+ // Or if the entire table (including header) is selected
74384
+ const isHeaderSelected = selectedRows.some((row) => row >= top && row <= headerRowEnd);
74385
+ if (!isHeaderSelected) {
74386
+ return true;
74387
+ }
74388
+ const isWholeTableSelected = range(top, bottom + 1).every((r) => selectedRowSet.has(r));
74389
+ return isWholeTableSelected;
74390
+ });
74391
+ }
74326
74392
  fallbackToVisibleSheet() {
74327
74393
  if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
74328
74394
  const currentSheetIds = this.getters.getVisibleSheetIds();
@@ -77781,9 +77847,7 @@ class ClickableCellsStore extends SpreadsheetStore {
77781
77847
  }
77782
77848
  if (!(xc in clickableCells[sheetId])) {
77783
77849
  const clickableCell = this.findClickableItem(position);
77784
- if (clickableCell) {
77785
- clickableCells[sheetId][xc] = clickableCell;
77786
- }
77850
+ clickableCells[sheetId][xc] = clickableCell;
77787
77851
  }
77788
77852
  return clickableCells[sheetId][xc];
77789
77853
  }
@@ -80025,6 +80089,7 @@ class Spreadsheet extends owl.Component {
80025
80089
  loadLocales: this.model.config.external.loadLocales,
80026
80090
  isDashboard: () => this.model.getters.isDashboard(),
80027
80091
  openSidePanel: this.sidePanel.open.bind(this.sidePanel),
80092
+ replaceSidePanel: this.sidePanel.replace.bind(this.sidePanel),
80028
80093
  toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
80029
80094
  clipboard: this.env.clipboard || instantiateClipboard(),
80030
80095
  startCellEdition: (content) => this.composerFocusStore.focusActiveComposer({ content }),
@@ -84686,6 +84751,6 @@ exports.tokenColors = tokenColors;
84686
84751
  exports.tokenize = tokenize;
84687
84752
 
84688
84753
 
84689
- __info__.version = "18.4.5";
84690
- __info__.date = "2025-08-04T06:54:49.107Z";
84691
- __info__.hash = "358931f";
84754
+ __info__.version = "18.4.7";
84755
+ __info__.date = "2025-08-21T06:42:12.438Z";
84756
+ __info__.hash = "d5eb3a6";
@@ -2312,6 +2312,7 @@ declare class GridSelectionPlugin extends UIPlugin {
2312
2312
  private getFiguresUpdates;
2313
2313
  private applyFigureUpdates;
2314
2314
  private isMoveElementAllowed;
2315
+ private isTableRowMoveAllowed;
2315
2316
  private fallbackToVisibleSheet;
2316
2317
  /**
2317
2318
  * Clip the selection if it spans outside the sheet
@@ -3327,6 +3328,7 @@ declare const enum CommandResult {
3327
3328
  Success = "Success",
3328
3329
  CancelledForUnknownReason = "CancelledForUnknownReason",
3329
3330
  WillRemoveExistingMerge = "WillRemoveExistingMerge",
3331
+ CannotMoveTableHeader = "CannotMoveTableHeader",
3330
3332
  MergeIsDestructive = "MergeIsDestructive",
3331
3333
  CellIsMerged = "CellIsMerged",
3332
3334
  InvalidTarget = "InvalidTarget",
@@ -4294,6 +4296,7 @@ interface SpreadsheetChildEnv extends NotificationStoreMethods {
4294
4296
  imageProvider?: ImageProviderInterface;
4295
4297
  isDashboard: () => boolean;
4296
4298
  openSidePanel: (panel: string, panelProps?: any) => void;
4299
+ replaceSidePanel: (panel: string, currentPanel: string, panelProps?: any) => void;
4297
4300
  toggleSidePanel: (panel: string, panelProps?: any) => void;
4298
4301
  clipboard: ClipboardInterface;
4299
4302
  startCellEdition: (content?: string) => void;
@@ -9139,7 +9142,7 @@ interface PanelInfo {
9139
9142
  isCollapsed?: boolean;
9140
9143
  }
9141
9144
  declare class SidePanelStore extends SpreadsheetStore {
9142
- mutators: readonly ["open", "toggle", "close", "changePanelSize", "resetPanelSize", "togglePinPanel", "closeMainPanel", "changeSpreadsheetWidth", "toggleCollapsePanel"];
9145
+ mutators: readonly ["open", "replace", "toggle", "close", "changePanelSize", "resetPanelSize", "togglePinPanel", "closeMainPanel", "changeSpreadsheetWidth", "toggleCollapsePanel"];
9143
9146
  mainPanel: (PanelInfo & {
9144
9147
  isCollapsed?: boolean;
9145
9148
  isPinned?: boolean;
@@ -9161,6 +9164,7 @@ declare class SidePanelStore extends SpreadsheetStore {
9161
9164
  private getPanelProps;
9162
9165
  private getPanelKey;
9163
9166
  open(componentTag: string, initialPanelProps?: SidePanelComponentProps): void;
9167
+ replace(componentTag: string, currentPanelKey: string, initialPanelProps?: SidePanelComponentProps): void;
9164
9168
  private _openPanel;
9165
9169
  toggle(componentTag: string, panelProps: SidePanelComponentProps): void;
9166
9170
  close(): void;
@@ -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.5
6
- * @date 2025-08-04T06:54:49.107Z
7
- * @hash 358931f
5
+ * @version 18.4.7
6
+ * @date 2025-08-21T06:42:12.438Z
7
+ * @hash d5eb3a6
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';
@@ -2779,6 +2779,7 @@ var CommandResult;
2779
2779
  CommandResult["Success"] = "Success";
2780
2780
  CommandResult["CancelledForUnknownReason"] = "CancelledForUnknownReason";
2781
2781
  CommandResult["WillRemoveExistingMerge"] = "WillRemoveExistingMerge";
2782
+ CommandResult["CannotMoveTableHeader"] = "CannotMoveTableHeader";
2782
2783
  CommandResult["MergeIsDestructive"] = "MergeIsDestructive";
2783
2784
  CommandResult["CellIsMerged"] = "CellIsMerged";
2784
2785
  CommandResult["InvalidTarget"] = "InvalidTarget";
@@ -7254,15 +7255,18 @@ function parseOSClipboardContent(content, clipboardId) {
7254
7255
  ?.getAttribute("data-osheet-clipboard");
7255
7256
  spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
7256
7257
  }
7258
+ const textContent = content[ClipboardMIMEType.PlainText] || "";
7257
7259
  let imageBlob = undefined;
7258
- for (const type of AllowedImageMimeTypes) {
7259
- if (content[type]) {
7260
- imageBlob = content[type];
7261
- break;
7260
+ if (!textContent.trim()) {
7261
+ for (const type of AllowedImageMimeTypes) {
7262
+ if (content[type]) {
7263
+ imageBlob = content[type];
7264
+ break;
7265
+ }
7262
7266
  }
7263
7267
  }
7264
7268
  const osClipboardContent = {
7265
- text: content[ClipboardMIMEType.PlainText],
7269
+ text: textContent,
7266
7270
  data: spreadsheetContent,
7267
7271
  imageBlob,
7268
7272
  };
@@ -19639,7 +19643,7 @@ const OFFSET = {
19639
19643
  right: startingCol + offsetWidth - 1,
19640
19644
  bottom: startingRow + offsetHeight - 1,
19641
19645
  };
19642
- const range = this.getters.getRangeFromZone(this.__originSheetId, dependencyZone);
19646
+ const range = this.getters.getRangeFromZone(sheetId, dependencyZone);
19643
19647
  if (range.invalidXc || range.invalidSheetName) {
19644
19648
  return new InvalidReferenceError();
19645
19649
  }
@@ -24284,6 +24288,7 @@ const CustomCurrencyTerms = {
24284
24288
  Custom: _t("Custom"),
24285
24289
  };
24286
24290
  const MergeErrorMessage = _t("Merged cells are preventing this operation. Unmerge those cells and try again.");
24291
+ const TableHeaderMoveErrorMessage = _t("The header row of a table can't be moved.");
24287
24292
  const SplitToColumnsTerms = {
24288
24293
  Errors: {
24289
24294
  Unexpected: _t("Cannot split the selection for an unknown reason"),
@@ -28181,9 +28186,6 @@ class RadarChart extends AbstractChart {
28181
28186
  };
28182
28187
  }
28183
28188
  getDefinitionForExcel() {
28184
- if (this.aggregated) {
28185
- return undefined;
28186
- }
28187
28189
  const dataSets = this.dataSets
28188
28190
  .map((ds) => toExcelDataset(this.getters, ds))
28189
28191
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -43831,7 +43833,7 @@ const insertDropdown = {
43831
43833
  env.openSidePanel("DataValidationEditor", {
43832
43834
  rule: localizeDataValidationRule(rule, env.model.getters.getLocale()),
43833
43835
  onExit: () => {
43834
- env.openSidePanel("DataValidation");
43836
+ env.replaceSidePanel("DataValidation", "DataValidationEditor");
43835
43837
  },
43836
43838
  });
43837
43839
  },
@@ -47705,8 +47707,13 @@ class RowResizer extends AbstractResizer {
47705
47707
  elements,
47706
47708
  position: this.state.position,
47707
47709
  });
47708
- if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47709
- this.env.raiseError(MergeErrorMessage);
47710
+ if (!result.isSuccessful) {
47711
+ if (result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47712
+ this.env.raiseError(MergeErrorMessage);
47713
+ }
47714
+ else if (result.reasons.includes("CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */)) {
47715
+ this.env.raiseError(TableHeaderMoveErrorMessage);
47716
+ }
47710
47717
  }
47711
47718
  }
47712
47719
  _selectElement(index, addDistinctHeader) {
@@ -53651,11 +53658,15 @@ class PivotMeasureDisplayPanel extends Component {
53651
53658
  this.store = useLocalStore(PivotMeasureDisplayPanelStore, this.props.pivotId, this.props.measure);
53652
53659
  }
53653
53660
  onSave() {
53654
- this.env.openSidePanel("PivotSidePanel", { pivotId: this.props.pivotId });
53661
+ this.env.replaceSidePanel("PivotSidePanel", `pivot_measure_display_${this.props.pivotId}_${this.props.measure.id}`, {
53662
+ pivotId: this.props.pivotId,
53663
+ });
53655
53664
  }
53656
53665
  onCancel() {
53657
53666
  this.store.cancelMeasureDisplayEdition();
53658
- this.env.openSidePanel("PivotSidePanel", { pivotId: this.props.pivotId });
53667
+ this.env.replaceSidePanel("PivotSidePanel", `pivot_measure_display_${this.props.pivotId}_${this.props.measure.id}`, {
53668
+ pivotId: this.props.pivotId,
53669
+ });
53659
53670
  }
53660
53671
  get fieldChoices() {
53661
53672
  return this.store.fields.map((field) => ({
@@ -54117,7 +54128,7 @@ class PivotMeasureEditor extends Component {
54117
54128
  });
54118
54129
  }
54119
54130
  openShowValuesAs() {
54120
- this.env.openSidePanel("PivotMeasureDisplayPanel", {
54131
+ this.env.replaceSidePanel("PivotMeasureDisplayPanel", `pivot_key_${this.props.pivotId}`, {
54121
54132
  pivotId: this.props.pivotId,
54122
54133
  measure: this.props.measure,
54123
54134
  });
@@ -54377,7 +54388,7 @@ class PivotLayoutConfigurator extends Component {
54377
54388
  this.props.onDimensionsUpdated(update);
54378
54389
  }
54379
54390
  getMeasureId(fieldName, aggregator) {
54380
- const baseId = fieldName + (aggregator ? `:${aggregator}` : "");
54391
+ const baseId = fieldName.replaceAll("'", "") + (aggregator ? `:${aggregator}` : "");
54381
54392
  let id = baseId;
54382
54393
  let i = 2;
54383
54394
  while (this.props.definition.measures.some((m) => m.id === id)) {
@@ -57216,7 +57227,11 @@ sidePanelRegistry.add("PivotMeasureDisplayPanel", {
57216
57227
  try {
57217
57228
  // This will throw if the pivot or measure does not exist
57218
57229
  getters.getPivot(props.pivotId).getMeasure(props.measure.id);
57219
- return { isOpen: true, props, key: "pivot_measure_display" };
57230
+ return {
57231
+ isOpen: true,
57232
+ props,
57233
+ key: `pivot_measure_display_${props.pivotId}_${props.measure.id}`,
57234
+ };
57220
57235
  }
57221
57236
  catch (e) {
57222
57237
  return { isOpen: false };
@@ -57241,6 +57256,7 @@ const MIN_SHEET_VIEW_WIDTH = 150;
57241
57256
  class SidePanelStore extends SpreadsheetStore {
57242
57257
  mutators = [
57243
57258
  "open",
57259
+ "replace",
57244
57260
  "toggle",
57245
57261
  "close",
57246
57262
  "changePanelSize",
@@ -57302,8 +57318,7 @@ class SidePanelStore extends SpreadsheetStore {
57302
57318
  if (!state.isOpen) {
57303
57319
  return;
57304
57320
  }
57305
- const mainPanelKey = this.mainPanel ? this.getPanelKey(this.mainPanel) : undefined;
57306
- if (!this.mainPanel || !this.mainPanel.isPinned || mainPanelKey === state.key) {
57321
+ if (!this.mainPanel || !this.mainPanel.isPinned || this.mainPanelKey === state.key) {
57307
57322
  this._openPanel("mainPanel", newPanelInfo, state);
57308
57323
  return;
57309
57324
  }
@@ -57322,6 +57337,34 @@ class SidePanelStore extends SpreadsheetStore {
57322
57337
  }
57323
57338
  this._openPanel("secondaryPanel", newPanelInfo, state);
57324
57339
  }
57340
+ replace(componentTag, currentPanelKey, initialPanelProps = {}) {
57341
+ const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
57342
+ const state = this.computeState(newPanelInfo);
57343
+ if (!state.isOpen) {
57344
+ return;
57345
+ }
57346
+ const ensureMainPanelExpanded = () => {
57347
+ if (this.mainPanel?.isCollapsed) {
57348
+ this.toggleCollapsePanel("mainPanel");
57349
+ }
57350
+ };
57351
+ // Close the current panel if the target panel is already open
57352
+ const isMainPanel = this.mainPanelKey === state.key;
57353
+ const isSecondaryPanel = this.secondaryPanelKey === state.key;
57354
+ if (isMainPanel && this.secondaryPanel) {
57355
+ this.close();
57356
+ ensureMainPanelExpanded();
57357
+ return;
57358
+ }
57359
+ if (isSecondaryPanel) {
57360
+ this.closeMainPanel();
57361
+ this.togglePinPanel();
57362
+ ensureMainPanelExpanded();
57363
+ return;
57364
+ }
57365
+ const targetPanel = this.mainPanelKey === currentPanelKey ? "mainPanel" : "secondaryPanel";
57366
+ this._openPanel(targetPanel, newPanelInfo, state);
57367
+ }
57325
57368
  _openPanel(panel, newPanel, state) {
57326
57369
  const currentPanel = this[panel];
57327
57370
  if (currentPanel && newPanel.componentTag !== currentPanel.componentTag) {
@@ -57381,11 +57424,9 @@ class SidePanelStore extends SpreadsheetStore {
57381
57424
  panelInfo.size = size;
57382
57425
  }
57383
57426
  resetPanelSize(panel) {
57384
- const panelInfo = this[panel];
57385
- if (!panelInfo) {
57386
- return;
57427
+ if (this[panel]) {
57428
+ this[panel].size = DEFAULT_SIDE_PANEL_SIZE;
57387
57429
  }
57388
- panelInfo.size = DEFAULT_SIDE_PANEL_SIZE;
57389
57430
  }
57390
57431
  togglePinPanel() {
57391
57432
  if (!this.mainPanel) {
@@ -68351,7 +68392,7 @@ function withPivotPresentationLayer (PivotClass) {
68351
68392
  return PivotPresentationLayer;
68352
68393
  }
68353
68394
 
68354
- const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
68395
+ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT", "REMOVE_PIVOT"];
68355
68396
  function isPivotCommand(cmd) {
68356
68397
  return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
68357
68398
  }
@@ -74319,8 +74360,33 @@ class GridSelectionPlugin extends UIPlugin {
74319
74360
  if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
74320
74361
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
74321
74362
  }
74363
+ if (!isCol && !this.isTableRowMoveAllowed(id, cmd.elements)) {
74364
+ return "CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */;
74365
+ }
74322
74366
  return "Success" /* CommandResult.Success */;
74323
74367
  }
74368
+ isTableRowMoveAllowed(sheetId, selectedRows) {
74369
+ const tables = this.getters.getCoreTables(sheetId);
74370
+ if (tables.length === 0) {
74371
+ return true;
74372
+ }
74373
+ const selectedRowSet = new Set(selectedRows);
74374
+ return tables.every(({ range: { zone }, config }) => {
74375
+ const { top, bottom } = zone;
74376
+ if (config.numberOfHeaders === 0) {
74377
+ return true;
74378
+ }
74379
+ const headerRowEnd = top + config.numberOfHeaders - 1;
74380
+ // Moving the table is allowed if table header rows are not part of the selection
74381
+ // Or if the entire table (including header) is selected
74382
+ const isHeaderSelected = selectedRows.some((row) => row >= top && row <= headerRowEnd);
74383
+ if (!isHeaderSelected) {
74384
+ return true;
74385
+ }
74386
+ const isWholeTableSelected = range(top, bottom + 1).every((r) => selectedRowSet.has(r));
74387
+ return isWholeTableSelected;
74388
+ });
74389
+ }
74324
74390
  fallbackToVisibleSheet() {
74325
74391
  if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
74326
74392
  const currentSheetIds = this.getters.getVisibleSheetIds();
@@ -77779,9 +77845,7 @@ class ClickableCellsStore extends SpreadsheetStore {
77779
77845
  }
77780
77846
  if (!(xc in clickableCells[sheetId])) {
77781
77847
  const clickableCell = this.findClickableItem(position);
77782
- if (clickableCell) {
77783
- clickableCells[sheetId][xc] = clickableCell;
77784
- }
77848
+ clickableCells[sheetId][xc] = clickableCell;
77785
77849
  }
77786
77850
  return clickableCells[sheetId][xc];
77787
77851
  }
@@ -80023,6 +80087,7 @@ class Spreadsheet extends Component {
80023
80087
  loadLocales: this.model.config.external.loadLocales,
80024
80088
  isDashboard: () => this.model.getters.isDashboard(),
80025
80089
  openSidePanel: this.sidePanel.open.bind(this.sidePanel),
80090
+ replaceSidePanel: this.sidePanel.replace.bind(this.sidePanel),
80026
80091
  toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
80027
80092
  clipboard: this.env.clipboard || instantiateClipboard(),
80028
80093
  startCellEdition: (content) => this.composerFocusStore.focusActiveComposer({ content }),
@@ -84636,6 +84701,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84636
84701
  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 };
84637
84702
 
84638
84703
 
84639
- __info__.version = "18.4.5";
84640
- __info__.date = "2025-08-04T06:54:49.107Z";
84641
- __info__.hash = "358931f";
84704
+ __info__.version = "18.4.7";
84705
+ __info__.date = "2025-08-21T06:42:12.438Z";
84706
+ __info__.hash = "d5eb3a6";