@odoo/o-spreadsheet 16.4.29 → 16.4.31

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.
@@ -16383,7 +16383,7 @@
16383
16383
  /**
16384
16384
  * Get a default chart js configuration
16385
16385
  */
16386
- function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }) {
16386
+ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }, truncateLabels = true) {
16387
16387
  return {
16388
16388
  type: chart.type,
16389
16389
  options: {
@@ -16436,7 +16436,7 @@
16436
16436
  },
16437
16437
  },
16438
16438
  data: {
16439
- labels: labels.map(truncateLabel),
16439
+ labels: truncateLabels ? labels.map(truncateLabel) : labels,
16440
16440
  datasets: [],
16441
16441
  },
16442
16442
  };
@@ -17279,9 +17279,9 @@
17279
17279
  }
17280
17280
  return true;
17281
17281
  }
17282
- function getLineConfiguration(chart, labels, localeFormat) {
17282
+ function getLineConfiguration(chart, labels, localeFormat, truncateLabels = true) {
17283
17283
  const fontColor = chartFontColor(chart.background);
17284
- const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
17284
+ const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat, truncateLabels);
17285
17285
  const legend = {
17286
17286
  labels: {
17287
17287
  fontColor,
@@ -17357,9 +17357,10 @@
17357
17357
  ({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
17358
17358
  }
17359
17359
  const locale = getters.getLocale();
17360
+ const truncateLabels = axisType === "category";
17360
17361
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
17361
17362
  const localeFormat = { format: dataSetFormat, locale };
17362
- const config = getLineConfiguration(chart, labels, localeFormat);
17363
+ const config = getLineConfiguration(chart, labels, localeFormat, truncateLabels);
17363
17364
  const labelFormat = getChartLabelFormat(getters, chart.labelRange);
17364
17365
  if (axisType === "time") {
17365
17366
  config.options.scales.xAxes[0].type = "time";
@@ -19338,6 +19339,243 @@
19338
19339
  }
19339
19340
  }
19340
19341
 
19342
+ function interactiveFreezeColumnsRows(env, dimension, base) {
19343
+ const sheetId = env.model.getters.getActiveSheetId();
19344
+ const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
19345
+ const result = env.model.dispatch(cmd, { sheetId, quantity: base });
19346
+ if (result.isCancelledBecause(68 /* CommandResult.MergeOverlap */)) {
19347
+ env.raiseError(MergeErrorMessage);
19348
+ }
19349
+ }
19350
+
19351
+ const hideCols = {
19352
+ name: HIDE_COLUMNS_NAME,
19353
+ execute: (env) => {
19354
+ const columns = env.model.getters.getElementsFromSelection("COL");
19355
+ env.model.dispatch("HIDE_COLUMNS_ROWS", {
19356
+ sheetId: env.model.getters.getActiveSheetId(),
19357
+ dimension: "COL",
19358
+ elements: columns,
19359
+ });
19360
+ },
19361
+ isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
19362
+ icon: "o-spreadsheet-Icon.HIDE_COL",
19363
+ };
19364
+ const unhideCols = {
19365
+ name: _lt("Unhide columns"),
19366
+ execute: (env) => {
19367
+ const columns = env.model.getters.getElementsFromSelection("COL");
19368
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19369
+ sheetId: env.model.getters.getActiveSheetId(),
19370
+ dimension: "COL",
19371
+ elements: columns,
19372
+ });
19373
+ },
19374
+ isVisible: (env) => {
19375
+ const hiddenCols = env.model.getters
19376
+ .getHiddenColsGroups(env.model.getters.getActiveSheetId())
19377
+ .flat();
19378
+ const currentCols = env.model.getters.getElementsFromSelection("COL");
19379
+ return currentCols.some((col) => hiddenCols.includes(col));
19380
+ },
19381
+ };
19382
+ const unhideAllCols = {
19383
+ name: _lt("Unhide all columns"),
19384
+ execute: (env) => {
19385
+ const sheetId = env.model.getters.getActiveSheetId();
19386
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19387
+ sheetId,
19388
+ dimension: "COL",
19389
+ elements: Array.from(Array(env.model.getters.getNumberCols(sheetId)).keys()),
19390
+ });
19391
+ },
19392
+ isVisible: (env) => env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId()).length > 0,
19393
+ };
19394
+ const hideRows = {
19395
+ name: HIDE_ROWS_NAME,
19396
+ execute: (env) => {
19397
+ const rows = env.model.getters.getElementsFromSelection("ROW");
19398
+ env.model.dispatch("HIDE_COLUMNS_ROWS", {
19399
+ sheetId: env.model.getters.getActiveSheetId(),
19400
+ dimension: "ROW",
19401
+ elements: rows,
19402
+ });
19403
+ },
19404
+ isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
19405
+ icon: "o-spreadsheet-Icon.HIDE_ROW",
19406
+ };
19407
+ const unhideRows = {
19408
+ name: _lt("Unhide rows"),
19409
+ execute: (env) => {
19410
+ const columns = env.model.getters.getElementsFromSelection("ROW");
19411
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19412
+ sheetId: env.model.getters.getActiveSheetId(),
19413
+ dimension: "ROW",
19414
+ elements: columns,
19415
+ });
19416
+ },
19417
+ isVisible: (env) => {
19418
+ const hiddenRows = env.model.getters
19419
+ .getHiddenRowsGroups(env.model.getters.getActiveSheetId())
19420
+ .flat();
19421
+ const currentRows = env.model.getters.getElementsFromSelection("ROW");
19422
+ return currentRows.some((col) => hiddenRows.includes(col));
19423
+ },
19424
+ };
19425
+ const unhideAllRows = {
19426
+ name: _lt("Unhide all rows"),
19427
+ execute: (env) => {
19428
+ const sheetId = env.model.getters.getActiveSheetId();
19429
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19430
+ sheetId,
19431
+ dimension: "ROW",
19432
+ elements: Array.from(Array(env.model.getters.getNumberRows(sheetId)).keys()),
19433
+ });
19434
+ },
19435
+ isVisible: (env) => env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId()).length > 0,
19436
+ };
19437
+ const unFreezePane = {
19438
+ name: _lt("Unfreeze"),
19439
+ isVisible: (env) => {
19440
+ const { xSplit, ySplit } = env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId());
19441
+ return xSplit + ySplit > 0;
19442
+ },
19443
+ execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS_ROWS", {
19444
+ sheetId: env.model.getters.getActiveSheetId(),
19445
+ }),
19446
+ icon: "o-spreadsheet-Icon.UNFREEZE",
19447
+ };
19448
+ const freezePane = {
19449
+ name: _lt("Freeze"),
19450
+ icon: "o-spreadsheet-Icon.FREEZE",
19451
+ };
19452
+ const unFreezeRows = {
19453
+ name: _lt("No rows"),
19454
+ execute: (env) => env.model.dispatch("UNFREEZE_ROWS", {
19455
+ sheetId: env.model.getters.getActiveSheetId(),
19456
+ }),
19457
+ isReadonlyAllowed: true,
19458
+ isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).ySplit,
19459
+ };
19460
+ const freezeFirstRow = {
19461
+ name: _lt("1 row"),
19462
+ execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 1),
19463
+ isReadonlyAllowed: true,
19464
+ };
19465
+ const freezeSecondRow = {
19466
+ name: _lt("2 rows"),
19467
+ execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 2),
19468
+ isReadonlyAllowed: true,
19469
+ };
19470
+ const freezeCurrentRow = {
19471
+ name: _lt("Up to current row"),
19472
+ execute: (env) => {
19473
+ const { bottom } = env.model.getters.getSelectedZone();
19474
+ interactiveFreezeColumnsRows(env, "ROW", bottom + 1);
19475
+ },
19476
+ isReadonlyAllowed: true,
19477
+ };
19478
+ const unFreezeCols = {
19479
+ name: _lt("No columns"),
19480
+ execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS", {
19481
+ sheetId: env.model.getters.getActiveSheetId(),
19482
+ }),
19483
+ isReadonlyAllowed: true,
19484
+ isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).xSplit,
19485
+ };
19486
+ const freezeFirstCol = {
19487
+ name: _lt("1 column"),
19488
+ execute: (env) => interactiveFreezeColumnsRows(env, "COL", 1),
19489
+ isReadonlyAllowed: true,
19490
+ };
19491
+ const freezeSecondCol = {
19492
+ name: _lt("2 columns"),
19493
+ execute: (env) => interactiveFreezeColumnsRows(env, "COL", 2),
19494
+ isReadonlyAllowed: true,
19495
+ };
19496
+ const freezeCurrentCol = {
19497
+ name: _lt("Up to current column"),
19498
+ execute: (env) => {
19499
+ const { right } = env.model.getters.getSelectedZone();
19500
+ interactiveFreezeColumnsRows(env, "COL", right + 1);
19501
+ },
19502
+ isReadonlyAllowed: true,
19503
+ };
19504
+ const viewGridlines = {
19505
+ name: (env) => env.model.getters.getGridLinesVisibility(env.model.getters.getActiveSheetId())
19506
+ ? _lt("Hide gridlines")
19507
+ : _lt("Show gridlines"),
19508
+ execute: (env) => {
19509
+ const sheetId = env.model.getters.getActiveSheetId();
19510
+ env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
19511
+ sheetId,
19512
+ areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
19513
+ });
19514
+ },
19515
+ icon: "o-spreadsheet-Icon.SHOW_HIDE_GRID",
19516
+ };
19517
+ const viewFormulas = {
19518
+ name: (env) => env.model.getters.shouldShowFormulas() ? _lt("Hide formulas") : _lt("Show formulas"),
19519
+ execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
19520
+ isReadonlyAllowed: true,
19521
+ icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
19522
+ };
19523
+ const createRemoveFilter = {
19524
+ name: (env) => selectionContainsFilter(env) ? _lt("Remove selected filters") : _lt("Create filter"),
19525
+ isActive: (env) => selectionContainsFilter(env),
19526
+ isEnabled: (env) => !cannotCreateFilter(env),
19527
+ execute: (env) => createRemoveFilterAction(env),
19528
+ icon: "o-spreadsheet-Icon.FILTER_ICON_INACTIVE",
19529
+ };
19530
+ function selectionContainsFilter(env) {
19531
+ const sheetId = env.model.getters.getActiveSheetId();
19532
+ const selectedZones = env.model.getters.getSelectedZones();
19533
+ return env.model.getters.doesZonesContainFilter(sheetId, selectedZones);
19534
+ }
19535
+ function cannotCreateFilter(env) {
19536
+ return !areZonesContinuous(...env.model.getters.getSelectedZones());
19537
+ }
19538
+ function createRemoveFilterAction(env) {
19539
+ if (selectionContainsFilter(env)) {
19540
+ env.model.dispatch("REMOVE_FILTER_TABLE", {
19541
+ sheetId: env.model.getters.getActiveSheetId(),
19542
+ target: env.model.getters.getSelectedZones(),
19543
+ });
19544
+ return;
19545
+ }
19546
+ if (cannotCreateFilter(env)) {
19547
+ return;
19548
+ }
19549
+ env.model.selection.selectTableAroundSelection();
19550
+ const sheetId = env.model.getters.getActiveSheetId();
19551
+ const selection = env.model.getters.getSelectedZones();
19552
+ interactiveAddFilter(env, sheetId, selection);
19553
+ }
19554
+
19555
+ var ACTION_VIEW = /*#__PURE__*/Object.freeze({
19556
+ __proto__: null,
19557
+ hideCols: hideCols,
19558
+ unhideCols: unhideCols,
19559
+ unhideAllCols: unhideAllCols,
19560
+ hideRows: hideRows,
19561
+ unhideRows: unhideRows,
19562
+ unhideAllRows: unhideAllRows,
19563
+ unFreezePane: unFreezePane,
19564
+ freezePane: freezePane,
19565
+ unFreezeRows: unFreezeRows,
19566
+ freezeFirstRow: freezeFirstRow,
19567
+ freezeSecondRow: freezeSecondRow,
19568
+ freezeCurrentRow: freezeCurrentRow,
19569
+ unFreezeCols: unFreezeCols,
19570
+ freezeFirstCol: freezeFirstCol,
19571
+ freezeSecondCol: freezeSecondCol,
19572
+ freezeCurrentCol: freezeCurrentCol,
19573
+ viewGridlines: viewGridlines,
19574
+ viewFormulas: viewFormulas,
19575
+ createRemoveFilter: createRemoveFilter,
19576
+ createRemoveFilterAction: createRemoveFilterAction
19577
+ });
19578
+
19341
19579
  const sortRange = {
19342
19580
  name: _lt("Sort range"),
19343
19581
  isVisible: IS_ONLY_ONE_RANGE,
@@ -19361,32 +19599,15 @@
19361
19599
  },
19362
19600
  icon: "o-spreadsheet-Icon.SORT_DESCENDING",
19363
19601
  };
19364
- const addDataFilter = {
19365
- name: _lt("Create filter"),
19366
- execute: (env) => {
19367
- const sheetId = env.model.getters.getActiveSheetId();
19368
- const selection = env.model.getters.getSelection().zones;
19369
- interactiveAddFilter(env, sheetId, selection);
19370
- },
19371
- isVisible: (env) => !SELECTION_CONTAINS_FILTER(env),
19602
+ const addRemoveDataFilter = {
19603
+ name: (env) => SELECTION_CONTAINS_FILTER(env) ? _lt("Remove filter") : _lt("Create filter"),
19604
+ execute: (env) => createRemoveFilterAction(env),
19372
19605
  isEnabled: (env) => {
19373
19606
  const selectedZones = env.model.getters.getSelectedZones();
19374
19607
  return areZonesContinuous(...selectedZones);
19375
19608
  },
19376
19609
  icon: "o-spreadsheet-Icon.MENU_FILTER_ICON",
19377
19610
  };
19378
- const removeDataFilter = {
19379
- name: _lt("Remove filter"),
19380
- execute: (env) => {
19381
- const sheetId = env.model.getters.getActiveSheetId();
19382
- env.model.dispatch("REMOVE_FILTER_TABLE", {
19383
- sheetId,
19384
- target: env.model.getters.getSelectedZones(),
19385
- });
19386
- },
19387
- isVisible: SELECTION_CONTAINS_FILTER,
19388
- icon: "o-spreadsheet-Icon.MENU_FILTER_ICON",
19389
- };
19390
19611
  const splitToColumns = {
19391
19612
  name: _lt("Split text to columns"),
19392
19613
  sequence: 1,
@@ -19766,242 +19987,6 @@
19766
19987
  clearFormat: clearFormat
19767
19988
  });
19768
19989
 
19769
- function interactiveFreezeColumnsRows(env, dimension, base) {
19770
- const sheetId = env.model.getters.getActiveSheetId();
19771
- const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
19772
- const result = env.model.dispatch(cmd, { sheetId, quantity: base });
19773
- if (result.isCancelledBecause(68 /* CommandResult.MergeOverlap */)) {
19774
- env.raiseError(MergeErrorMessage);
19775
- }
19776
- }
19777
-
19778
- const hideCols = {
19779
- name: HIDE_COLUMNS_NAME,
19780
- execute: (env) => {
19781
- const columns = env.model.getters.getElementsFromSelection("COL");
19782
- env.model.dispatch("HIDE_COLUMNS_ROWS", {
19783
- sheetId: env.model.getters.getActiveSheetId(),
19784
- dimension: "COL",
19785
- elements: columns,
19786
- });
19787
- },
19788
- isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
19789
- icon: "o-spreadsheet-Icon.HIDE_COL",
19790
- };
19791
- const unhideCols = {
19792
- name: _lt("Unhide columns"),
19793
- execute: (env) => {
19794
- const columns = env.model.getters.getElementsFromSelection("COL");
19795
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19796
- sheetId: env.model.getters.getActiveSheetId(),
19797
- dimension: "COL",
19798
- elements: columns,
19799
- });
19800
- },
19801
- isVisible: (env) => {
19802
- const hiddenCols = env.model.getters
19803
- .getHiddenColsGroups(env.model.getters.getActiveSheetId())
19804
- .flat();
19805
- const currentCols = env.model.getters.getElementsFromSelection("COL");
19806
- return currentCols.some((col) => hiddenCols.includes(col));
19807
- },
19808
- };
19809
- const unhideAllCols = {
19810
- name: _lt("Unhide all columns"),
19811
- execute: (env) => {
19812
- const sheetId = env.model.getters.getActiveSheetId();
19813
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19814
- sheetId,
19815
- dimension: "COL",
19816
- elements: Array.from(Array(env.model.getters.getNumberCols(sheetId)).keys()),
19817
- });
19818
- },
19819
- isVisible: (env) => env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId()).length > 0,
19820
- };
19821
- const hideRows = {
19822
- name: HIDE_ROWS_NAME,
19823
- execute: (env) => {
19824
- const rows = env.model.getters.getElementsFromSelection("ROW");
19825
- env.model.dispatch("HIDE_COLUMNS_ROWS", {
19826
- sheetId: env.model.getters.getActiveSheetId(),
19827
- dimension: "ROW",
19828
- elements: rows,
19829
- });
19830
- },
19831
- isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
19832
- icon: "o-spreadsheet-Icon.HIDE_ROW",
19833
- };
19834
- const unhideRows = {
19835
- name: _lt("Unhide rows"),
19836
- execute: (env) => {
19837
- const columns = env.model.getters.getElementsFromSelection("ROW");
19838
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19839
- sheetId: env.model.getters.getActiveSheetId(),
19840
- dimension: "ROW",
19841
- elements: columns,
19842
- });
19843
- },
19844
- isVisible: (env) => {
19845
- const hiddenRows = env.model.getters
19846
- .getHiddenRowsGroups(env.model.getters.getActiveSheetId())
19847
- .flat();
19848
- const currentRows = env.model.getters.getElementsFromSelection("ROW");
19849
- return currentRows.some((col) => hiddenRows.includes(col));
19850
- },
19851
- };
19852
- const unhideAllRows = {
19853
- name: _lt("Unhide all rows"),
19854
- execute: (env) => {
19855
- const sheetId = env.model.getters.getActiveSheetId();
19856
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
19857
- sheetId,
19858
- dimension: "ROW",
19859
- elements: Array.from(Array(env.model.getters.getNumberRows(sheetId)).keys()),
19860
- });
19861
- },
19862
- isVisible: (env) => env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId()).length > 0,
19863
- };
19864
- const unFreezePane = {
19865
- name: _lt("Unfreeze"),
19866
- isVisible: (env) => {
19867
- const { xSplit, ySplit } = env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId());
19868
- return xSplit + ySplit > 0;
19869
- },
19870
- execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS_ROWS", {
19871
- sheetId: env.model.getters.getActiveSheetId(),
19872
- }),
19873
- icon: "o-spreadsheet-Icon.UNFREEZE",
19874
- };
19875
- const freezePane = {
19876
- name: _lt("Freeze"),
19877
- icon: "o-spreadsheet-Icon.FREEZE",
19878
- };
19879
- const unFreezeRows = {
19880
- name: _lt("No rows"),
19881
- execute: (env) => env.model.dispatch("UNFREEZE_ROWS", {
19882
- sheetId: env.model.getters.getActiveSheetId(),
19883
- }),
19884
- isReadonlyAllowed: true,
19885
- isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).ySplit,
19886
- };
19887
- const freezeFirstRow = {
19888
- name: _lt("1 row"),
19889
- execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 1),
19890
- isReadonlyAllowed: true,
19891
- };
19892
- const freezeSecondRow = {
19893
- name: _lt("2 rows"),
19894
- execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 2),
19895
- isReadonlyAllowed: true,
19896
- };
19897
- const freezeCurrentRow = {
19898
- name: _lt("Up to current row"),
19899
- execute: (env) => {
19900
- const { bottom } = env.model.getters.getSelectedZone();
19901
- interactiveFreezeColumnsRows(env, "ROW", bottom + 1);
19902
- },
19903
- isReadonlyAllowed: true,
19904
- };
19905
- const unFreezeCols = {
19906
- name: _lt("No columns"),
19907
- execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS", {
19908
- sheetId: env.model.getters.getActiveSheetId(),
19909
- }),
19910
- isReadonlyAllowed: true,
19911
- isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).xSplit,
19912
- };
19913
- const freezeFirstCol = {
19914
- name: _lt("1 column"),
19915
- execute: (env) => interactiveFreezeColumnsRows(env, "COL", 1),
19916
- isReadonlyAllowed: true,
19917
- };
19918
- const freezeSecondCol = {
19919
- name: _lt("2 columns"),
19920
- execute: (env) => interactiveFreezeColumnsRows(env, "COL", 2),
19921
- isReadonlyAllowed: true,
19922
- };
19923
- const freezeCurrentCol = {
19924
- name: _lt("Up to current column"),
19925
- execute: (env) => {
19926
- const { right } = env.model.getters.getSelectedZone();
19927
- interactiveFreezeColumnsRows(env, "COL", right + 1);
19928
- },
19929
- isReadonlyAllowed: true,
19930
- };
19931
- const viewGridlines = {
19932
- name: (env) => env.model.getters.getGridLinesVisibility(env.model.getters.getActiveSheetId())
19933
- ? _lt("Hide gridlines")
19934
- : _lt("Show gridlines"),
19935
- execute: (env) => {
19936
- const sheetId = env.model.getters.getActiveSheetId();
19937
- env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
19938
- sheetId,
19939
- areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
19940
- });
19941
- },
19942
- icon: "o-spreadsheet-Icon.SHOW_HIDE_GRID",
19943
- };
19944
- const viewFormulas = {
19945
- name: (env) => env.model.getters.shouldShowFormulas() ? _lt("Hide formulas") : _lt("Show formulas"),
19946
- execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
19947
- isReadonlyAllowed: true,
19948
- icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
19949
- };
19950
- const createRemoveFilter = {
19951
- name: (env) => selectionContainsFilter(env) ? _lt("Remove selected filters") : _lt("Create filter"),
19952
- isActive: (env) => selectionContainsFilter(env),
19953
- isEnabled: (env) => !cannotCreateFilter(env),
19954
- execute: (env) => createRemoveFilterAction(env),
19955
- icon: "o-spreadsheet-Icon.FILTER_ICON_INACTIVE",
19956
- };
19957
- function selectionContainsFilter(env) {
19958
- const sheetId = env.model.getters.getActiveSheetId();
19959
- const selectedZones = env.model.getters.getSelectedZones();
19960
- return env.model.getters.doesZonesContainFilter(sheetId, selectedZones);
19961
- }
19962
- function cannotCreateFilter(env) {
19963
- return !areZonesContinuous(...env.model.getters.getSelectedZones());
19964
- }
19965
- function createRemoveFilterAction(env) {
19966
- if (selectionContainsFilter(env)) {
19967
- env.model.dispatch("REMOVE_FILTER_TABLE", {
19968
- sheetId: env.model.getters.getActiveSheetId(),
19969
- target: env.model.getters.getSelectedZones(),
19970
- });
19971
- return;
19972
- }
19973
- if (cannotCreateFilter(env)) {
19974
- return;
19975
- }
19976
- env.model.selection.selectTableAroundSelection();
19977
- const sheetId = env.model.getters.getActiveSheetId();
19978
- const selection = env.model.getters.getSelectedZones();
19979
- interactiveAddFilter(env, sheetId, selection);
19980
- }
19981
-
19982
- var ACTION_VIEW = /*#__PURE__*/Object.freeze({
19983
- __proto__: null,
19984
- hideCols: hideCols,
19985
- unhideCols: unhideCols,
19986
- unhideAllCols: unhideAllCols,
19987
- hideRows: hideRows,
19988
- unhideRows: unhideRows,
19989
- unhideAllRows: unhideAllRows,
19990
- unFreezePane: unFreezePane,
19991
- freezePane: freezePane,
19992
- unFreezeRows: unFreezeRows,
19993
- freezeFirstRow: freezeFirstRow,
19994
- freezeSecondRow: freezeSecondRow,
19995
- freezeCurrentRow: freezeCurrentRow,
19996
- unFreezeCols: unFreezeCols,
19997
- freezeFirstCol: freezeFirstCol,
19998
- freezeSecondCol: freezeSecondCol,
19999
- freezeCurrentCol: freezeCurrentCol,
20000
- viewGridlines: viewGridlines,
20001
- viewFormulas: viewFormulas,
20002
- createRemoveFilter: createRemoveFilter
20003
- });
20004
-
20005
19990
  const colMenuRegistry = new MenuItemRegistry();
20006
19991
  colMenuRegistry
20007
19992
  .add("cut", {
@@ -20576,12 +20561,8 @@
20576
20561
  sequence: 20,
20577
20562
  separator: true,
20578
20563
  })
20579
- .addChild("add_data_filter", ["data"], {
20580
- ...addDataFilter,
20581
- sequence: 30,
20582
- })
20583
- .addChild("remove_data_filter", ["data"], {
20584
- ...removeDataFilter,
20564
+ .addChild("add_remove_data_filter", ["data"], {
20565
+ ...addRemoveDataFilter,
20585
20566
  sequence: 30,
20586
20567
  });
20587
20568
 
@@ -31419,7 +31400,7 @@
31419
31400
  this.clearBorders(cmd.sheetId, cmd.target);
31420
31401
  break;
31421
31402
  case "REMOVE_COLUMNS_ROWS":
31422
- for (let el of cmd.elements) {
31403
+ for (let el of [...cmd.elements].sort((a, b) => b - a)) {
31423
31404
  if (cmd.dimension === "COL") {
31424
31405
  this.shiftBordersHorizontally(cmd.sheetId, el + 1, -1);
31425
31406
  }
@@ -35790,6 +35771,353 @@
35790
35771
  }
35791
35772
  }
35792
35773
 
35774
+ /**
35775
+ * ####################################################
35776
+ * # INTRODUCTION
35777
+ * ####################################################
35778
+ *
35779
+ * This file contain the function recomputeZones.
35780
+ * This function try to recompute in a performant way
35781
+ * an ensemble of zones possibly overlapping to avoid
35782
+ * overlapping and to reduce the number of zones.
35783
+ *
35784
+ * It also allows to remove some zones from the ensemble.
35785
+ *
35786
+ * In the following example, 2 zones are overlapping.
35787
+ * Applying recomputeZones will return zones without
35788
+ * overlapping:
35789
+ *
35790
+ * ["B3:D4", "D2:E3"] ["B3:C4", "D2:D4", "E2:E3"]
35791
+ *
35792
+ * A B C D E A B C D E
35793
+ * 1 ___ 1 ___
35794
+ * 2 ___|_ | 2 ___| | |
35795
+ * 3 | |_|_| ---> 3 | | |_|
35796
+ * 4 |_____| 4 |___|_|
35797
+ * 6 6
35798
+ * 7 7
35799
+ *
35800
+ *
35801
+ * In the following example, 2 zones are contiguous.
35802
+ * Applying recomputeZones will return only one zone:
35803
+ *
35804
+ * ["B2:B3", "C2:D3"] ["B2:D3"]
35805
+ *
35806
+ * A B C D E A B C D E
35807
+ * 1 _ ___ 1 _____
35808
+ * 2 | | | ---> 2 | |
35809
+ * 3 |_|___| 3 |_____|
35810
+ * 4 4
35811
+ *
35812
+ *
35813
+ * In the following example, we want to remove a zone
35814
+ * from the ensemble. Applying recomputeZones will
35815
+ * return the ensemble without the zone to remove:
35816
+ *
35817
+ * remove ["C3:D3"] ["B2:B4", "C2:D2",
35818
+ * "C4:D4", "E2:E4"]
35819
+ *
35820
+ * A B C D E F A B C D E F
35821
+ * 1 _______ 1 _______
35822
+ * 2 | | ---> 2 | |___| |
35823
+ * 3 | xxx | 3 | |___| |
35824
+ * 4 |_______| 4 |_|___|_|
35825
+ * 5 5
35826
+ *
35827
+ *
35828
+ * The exercise seems simple when we have only 2 zones.
35829
+ * But with n zones and in a performant way, we want to
35830
+ * avoid comparing each zone with all the others.
35831
+ *
35832
+ *
35833
+ * ####################################################
35834
+ * # Methodological approach
35835
+ * ####################################################
35836
+ *
35837
+ * The methodological approach to avoid comparing each
35838
+ * zone with all the others is to use a data structure
35839
+ * that allow to quickly find which zones are
35840
+ * overlapping with any other given zone.
35841
+ *
35842
+ * Here the idea is to profile the zones at the columns level.
35843
+ *
35844
+ * To do that, we propose to use a data structure
35845
+ * composed of 2 parts:
35846
+ * - profilesStartingPosition: a sorted number array
35847
+ * indicating on which columns a new profile begins.
35848
+ * - profiles: a map where the key is a column
35849
+ * position (from profilesStartingPosition) and the
35850
+ * value is a sorted number array representing a
35851
+ * profile.
35852
+ *
35853
+ *
35854
+ * See the following example: here profileStartingPosition
35855
+ * corresponds to [A,C,E,G,K]
35856
+ * A B C D E F G H I J K so with number [0,2,4,6,10]
35857
+ * 1 ' ' ' '
35858
+ * 2 ' ' '_______' here profile correspond
35859
+ * 3 '___' |_______| for A to []
35860
+ * 4 | | for C to [3, 5]
35861
+ * 5 |___| for E to []
35862
+ * 6 for G to [2, 3]
35863
+ * 7 for K to []
35864
+ *
35865
+ *
35866
+ * Now we can easily find which zones are overlapping
35867
+ * with a given zone. Suppose we want to add a new zone
35868
+ * D5:H6 to the ensemble:
35869
+ *
35870
+ * With a binary search of left and right
35871
+ * A B C D E F G H I J K on profilesStartingPosition, we can
35872
+ * 1 ' ' ' ' find the indexes of the profiles on which
35873
+ * 2 ' ' '_______' to apply a modification.
35874
+ * 3 '___' |_______|
35875
+ * 4 | _|_______ Here we will:
35876
+ * 5 |_|_| | - add a new profile in D --> become [3, 6]
35877
+ * 6 |_________| - modify the profile in E --> become [4, 6]
35878
+ * 7 - modify the profile in G --> become [2, 3, 4, 6]
35879
+ * - add a new profile in I --> become [8, 10]
35880
+ *
35881
+ * See below the result:
35882
+ *
35883
+ * Note the particularity of the profile
35884
+ * A B C D E F G H I J K for G: it will correspond to [2, 3, 4, 6]
35885
+ * 1 ' ' ' ' ' '
35886
+ * 2 ' ' ' '___'___' To know how to modify the profile (add a
35887
+ * 3 '_'_' |___|___| zone or remove it) we do a binary
35888
+ * 4 | | |___ ___ search of the top and bottom value on the
35889
+ * 5 |_| | | | profile array. Depending on the result index
35890
+ * 6 |_|___|___| parity (odd or even), because zone boundaries
35891
+ * 7 go by pairs, we know if we are in a zone or
35892
+ * not and how operate.
35893
+ */
35894
+ /**
35895
+ * Recompute the zone without the cells in toRemoveZones and avoid overlapping.
35896
+ * This compute is particularly useful because after this function:
35897
+ * - you will find coordinate of a cell only once among all the zones
35898
+ * - the number of zones will be reduced to the minimum
35899
+ */
35900
+ function futureRecomputeZones(zones, zonesToRemove = []) {
35901
+ const profilesStartingPosition = [0];
35902
+ const profiles = new Map([[0, []]]);
35903
+ modifyProfiles(profilesStartingPosition, profiles, zones, false);
35904
+ modifyProfiles(profilesStartingPosition, profiles, zonesToRemove, true);
35905
+ return constructZonesFromProfiles(profilesStartingPosition, profiles);
35906
+ }
35907
+ function modifyProfiles(// export for testing only
35908
+ profilesStartingPosition, profiles, zones, toRemove = false) {
35909
+ for (const zone of zones) {
35910
+ const leftValue = zone.left;
35911
+ const rightValue = zone.right === undefined ? undefined : zone.right + 1;
35912
+ const leftIndex = findIndexAndCreateProfile(profilesStartingPosition, profiles, leftValue, true, 0);
35913
+ const rightIndex = findIndexAndCreateProfile(profilesStartingPosition, profiles, rightValue, false, leftIndex);
35914
+ for (let i = leftIndex; i <= rightIndex; i++) {
35915
+ const profile = profiles.get(profilesStartingPosition[i]);
35916
+ modifyProfile(profile, zone, toRemove);
35917
+ }
35918
+ // maybe this part cost in performance, and maybe it's not necessary (depending on the use case). To be checked
35919
+ removeContiguousProfiles(profilesStartingPosition, profiles, leftIndex, rightIndex);
35920
+ }
35921
+ }
35922
+ function findIndexAndCreateProfile(profilesStartingPosition, profiles, value, searchLeft, startIndex) {
35923
+ if (value === undefined) {
35924
+ // this is only the case when the value correspond to a bottom value that could be undefined
35925
+ return profilesStartingPosition.length - 1;
35926
+ }
35927
+ const predecessorIndex = binaryPredecessorSearch(profilesStartingPosition, value, startIndex);
35928
+ if (value != profilesStartingPosition[predecessorIndex]) {
35929
+ // mean that the value is not ending/starting at the same position as the previous/next profile
35930
+ // --> it's a new profile
35931
+ // --> we need to add it
35932
+ profilesStartingPosition.splice(predecessorIndex + 1, 0, value);
35933
+ // suppose the we want to add the for the left value
35934
+ // following profile following zone: 'C', the predecessor index
35935
+ // for B: [1, 3] "C3:D4" correspond to 'B'.
35936
+ // The next line code will
35937
+ // A B C D A B C D copy the profile of 'B'
35938
+ // 1 '___' 1 '___' to 'C'. In the rest of the
35939
+ // 2 | | ---> 2 | _|_ process the 'modifyProfile'
35940
+ // 3 |___| 3 |_|_| | function will adapt the waiting
35941
+ // 4 4 |___| 'C' profile [1, 3] to the
35942
+ // correct 'C' profile [1, 4]
35943
+ profiles.set(value, [...profiles.get(profilesStartingPosition[predecessorIndex])]);
35944
+ return searchLeft ? predecessorIndex + 1 : predecessorIndex;
35945
+ }
35946
+ return searchLeft ? predecessorIndex : predecessorIndex - 1;
35947
+ }
35948
+ /**
35949
+ * Suppose the following Suppose we want to add We want to have the
35950
+ * profile: the following zone: following profile:
35951
+ *
35952
+ * A B C D E F A B C D E F A B C D E F
35953
+ * 1 '___' 1 ' ' 1 '___'
35954
+ * 2 |___| 2 '___' 2 | |
35955
+ * 3 ' ' 3 | | 3 | |
35956
+ * 4 '___' --> 4 | | --> 4 | |
35957
+ * 6 | | 6 |___| 6 | |
35958
+ * 7 |___| 7 7 |___|
35959
+ * 8 8 8
35960
+ *
35961
+ * the profile for 'C' the top zone correspond Here [2, 3, 5, 8] with [3, 7]
35962
+ * corresponds to: to 3 and the bottom zone would be merged into [2, 8]
35963
+ * ____ ____ correspond to 6
35964
+ * [2, 3, 5, 8] would be the profile: The difficulty of modify profile
35965
+ * ____ is to know what must be deleted
35966
+ * Note that the 'filled [3, 7] and what must be added to the
35967
+ * zone' are always between existing profile.
35968
+ * an even index and its
35969
+ * next index
35970
+ *
35971
+ */
35972
+ function modifyProfile(profile, zone, toRemove = false) {
35973
+ const topValue = zone.top;
35974
+ const bottomValue = zone.bottom === undefined ? undefined : zone.bottom + 1;
35975
+ const newPoints = [];
35976
+ // Case we want to add a zone to the profile:
35977
+ // - If the top predecessor index `topPredIndex` is even, it means the top of the zone is already positioned on a filled zone
35978
+ // so we don't need to add it to the profile. we can keep in reference the index of the predecessor.
35979
+ // - If it is odd, it means the top of the zone must be the beginning of a filled zone.
35980
+ // so we can keep the index of the top position
35981
+ // Case we want to remove a zone from the profile: it's the opposite of the previous case
35982
+ const topPredIndex = binaryPredecessorSearch(profile, topValue, 0, false);
35983
+ if ((topPredIndex % 2 !== 0 && !toRemove) || (topPredIndex % 2 === 0 && toRemove)) {
35984
+ newPoints.push(topValue);
35985
+ }
35986
+ if (bottomValue === undefined) {
35987
+ // The following two code lines will not impact the final result,
35988
+ // but they will impact the intermediate profile.
35989
+ // We keep them for performance reason
35990
+ profile.splice(topPredIndex + 1);
35991
+ profile.push(...newPoints);
35992
+ return;
35993
+ }
35994
+ // Case we want to add a zone to the profile:
35995
+ // - If the bottom successor index `bottomSuccIndex` is even, it means the bottom of the zone must be the ending of a filled zone
35996
+ // so we can keep the index of the bottom position.
35997
+ // - If it is odd, it means the bottom of the zone is already positioned on a filled zone
35998
+ // so we don't need to add it to the profile. we can keep in reference the index of the successor
35999
+ // Case we want to remove a zone from the profile: it's the opposite of the previous case
36000
+ const bottomSuccIndex = binarySuccessorSearch(profile, bottomValue, 0, false);
36001
+ if ((bottomSuccIndex % 2 === 0 && !toRemove) || (bottomSuccIndex % 2 !== 0 && toRemove)) {
36002
+ newPoints.push(bottomValue);
36003
+ }
36004
+ // add the top and bottom value to the profile and
36005
+ // remove all information between the top and bottom index
36006
+ profile.splice(topPredIndex + 1, bottomSuccIndex - topPredIndex - 1, ...newPoints);
36007
+ }
36008
+ function removeContiguousProfiles(profilesStartingPosition, profiles, leftIndex, rightIndex) {
36009
+ const start = leftIndex - 1 === -1 ? 0 : leftIndex - 1;
36010
+ const end = rightIndex === profilesStartingPosition.length - 1 ? rightIndex : rightIndex + 1;
36011
+ for (let i = end; i > start; i--) {
36012
+ if (deepEqualsArray(profiles.get(profilesStartingPosition[i]), profiles.get(profilesStartingPosition[i - 1]))) {
36013
+ profiles.delete(profilesStartingPosition[i]);
36014
+ profilesStartingPosition.splice(i, 1);
36015
+ }
36016
+ }
36017
+ }
36018
+ function constructZonesFromProfiles(profilesStartingPosition, profiles) {
36019
+ const mergedZone = [];
36020
+ let pendingZones = [];
36021
+ for (let colIndex = 0; colIndex < profilesStartingPosition.length; colIndex++) {
36022
+ const left = profilesStartingPosition[colIndex];
36023
+ const profile = profiles.get(left);
36024
+ if (!profile || profile.length === 0) {
36025
+ mergedZone.push(...pendingZones);
36026
+ pendingZones = [];
36027
+ continue;
36028
+ }
36029
+ let right = profilesStartingPosition[colIndex + 1];
36030
+ if (right !== undefined) {
36031
+ right--;
36032
+ }
36033
+ const nextPendingZones = [];
36034
+ for (let i = 0; i < profile.length; i += 2) {
36035
+ const top = profile[i];
36036
+ let bottom = profile[i + 1];
36037
+ if (bottom !== undefined) {
36038
+ bottom--;
36039
+ }
36040
+ const profileZone = {
36041
+ top,
36042
+ left,
36043
+ bottom,
36044
+ right,
36045
+ hasHeader: (bottom === undefined && top !== 0) || (right === undefined && left !== 0),
36046
+ };
36047
+ let findCorrespondingZone = false;
36048
+ for (let j = pendingZones.length - 1; j >= 0; j--) {
36049
+ const pendingZone = pendingZones[j];
36050
+ if (pendingZone.top === profileZone.top && pendingZone.bottom === profileZone.bottom) {
36051
+ pendingZone.right = profileZone.right;
36052
+ pendingZones.splice(j, 1);
36053
+ nextPendingZones.push(pendingZone);
36054
+ findCorrespondingZone = true;
36055
+ break;
36056
+ }
36057
+ }
36058
+ if (!findCorrespondingZone) {
36059
+ nextPendingZones.push(profileZone);
36060
+ }
36061
+ }
36062
+ mergedZone.push(...pendingZones);
36063
+ pendingZones = nextPendingZones;
36064
+ }
36065
+ mergedZone.push(...pendingZones);
36066
+ return mergedZone;
36067
+ }
36068
+ function binaryPredecessorSearch(arr, val, start = 0, matchEqual = true) {
36069
+ let end = arr.length - 1;
36070
+ let result = -1;
36071
+ while (start <= end) {
36072
+ const mid = Math.floor((start + end) / 2);
36073
+ if (arr[mid] === val && matchEqual) {
36074
+ return mid;
36075
+ }
36076
+ else if (arr[mid] < val) {
36077
+ result = mid;
36078
+ start = mid + 1;
36079
+ }
36080
+ else {
36081
+ end = mid - 1;
36082
+ }
36083
+ }
36084
+ return result;
36085
+ }
36086
+ function binarySuccessorSearch(arr, val, start = 0, matchEqual = true) {
36087
+ let end = arr.length - 1;
36088
+ let result = arr.length;
36089
+ while (start <= end) {
36090
+ const mid = Math.floor((start + end) / 2);
36091
+ if (arr[mid] === val && matchEqual) {
36092
+ return mid;
36093
+ }
36094
+ else if (arr[mid] > val) {
36095
+ result = mid;
36096
+ end = mid - 1;
36097
+ }
36098
+ else {
36099
+ start = mid + 1;
36100
+ }
36101
+ }
36102
+ return result;
36103
+ }
36104
+ /**
36105
+ * Compares two arrays.
36106
+ * For performance reasons, this function is to be preferred
36107
+ * to 'deepEquals' in the case we know that the inputs are arrays.
36108
+ */
36109
+ function deepEqualsArray(arr1, arr2) {
36110
+ if (arr1.length !== arr2.length) {
36111
+ return false;
36112
+ }
36113
+ for (let i = 0; i < arr1.length; i++) {
36114
+ if (!deepEquals(arr1[i], arr2[i])) {
36115
+ return false;
36116
+ }
36117
+ }
36118
+ return true;
36119
+ }
36120
+
35793
36121
  function quickselect(arr, k, left, right, compare) {
35794
36122
  quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
35795
36123
  }
@@ -36553,7 +36881,7 @@
36553
36881
  }
36554
36882
  }
36555
36883
  /**
36556
- * Return the cell and all cells that depend on it,
36884
+ * Return all the cells that depend on the provided ranges,
36557
36885
  * in the correct order they should be evaluated.
36558
36886
  * This is called a topological ordering (excluding cycles)
36559
36887
  */
@@ -36564,11 +36892,20 @@
36564
36892
  const range = queue.pop();
36565
36893
  visited.addMany(this.encoder.encodeBoundingBox(range));
36566
36894
  const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
36895
+ const nextInQueue = {};
36567
36896
  for (const positionId of impactedPositionIds) {
36568
36897
  if (!visited.has(positionId)) {
36569
- queue.push(this.encoder.decodeToBoundingBox(positionId));
36898
+ const { sheetId, zone } = this.encoder.decodeToBoundingBox(positionId);
36899
+ if (!nextInQueue[sheetId]) {
36900
+ nextInQueue[sheetId] = [];
36901
+ }
36902
+ nextInQueue[sheetId].push(zone);
36570
36903
  }
36571
36904
  }
36905
+ for (const sheetId in nextInQueue) {
36906
+ const zones = futureRecomputeZones(nextInQueue[sheetId]);
36907
+ queue.push(...zones.map((zone) => ({ sheetId, zone })));
36908
+ }
36572
36909
  }
36573
36910
  visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
36574
36911
  return visited;
@@ -36717,7 +37054,7 @@
36717
37054
  }
36718
37055
  if (!content) {
36719
37056
  // The previous content could have blocked some array formulas
36720
- impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
37057
+ impactedPositionIds.addMany(this.getArrayFormulasBlockedBy(positionId));
36721
37058
  }
36722
37059
  }
36723
37060
  return impactedPositionIds;
@@ -36761,13 +37098,22 @@
36761
37098
  }
36762
37099
  return positionIds;
36763
37100
  }
36764
- getArrayFormulasBlockedByOrSpreadingOn(positionId) {
37101
+ /**
37102
+ * Return the position of formulas blocked by the given position
37103
+ * as well as all their dependencies.
37104
+ */
37105
+ getArrayFormulasBlockedBy(positionId) {
36765
37106
  if (!this.spreadingRelations.hasArrayFormulaResult(positionId)) {
36766
37107
  return [];
36767
37108
  }
36768
37109
  const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
36769
37110
  const cells = new JetSet(arrayFormulas);
36770
- cells.addMany(this.getCellsDependingOn(arrayFormulas));
37111
+ const arrayFormulaPositionId = this.getArrayFormulaSpreadingOnId(positionId);
37112
+ if (arrayFormulaPositionId) {
37113
+ // ignore the formula spreading on the position. Keep only the blocked ones
37114
+ cells.delete(arrayFormulaPositionId);
37115
+ }
37116
+ cells.addMany(this.getCellsDependingOn(cells));
36771
37117
  return cells;
36772
37118
  }
36773
37119
  nextPositionsToUpdate = new JetSet();
@@ -36934,7 +37280,7 @@
36934
37280
  }
36935
37281
  this.evaluatedCells.delete(child);
36936
37282
  this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
36937
- this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
37283
+ this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(child));
36938
37284
  }
36939
37285
  this.spreadingRelations.removeNode(positionId);
36940
37286
  }
@@ -46753,7 +47099,6 @@
46753
47099
  cursor: pointer;
46754
47100
  }
46755
47101
  `;
46756
- let tKey = 1;
46757
47102
  class SpreadsheetDashboard extends owl.Component {
46758
47103
  static template = "o-spreadsheet-SpreadsheetDashboard";
46759
47104
  static components = {
@@ -46831,13 +47176,9 @@
46831
47176
  coordinates: rect,
46832
47177
  position: { col, row },
46833
47178
  action,
46834
- // we can't rely on position only because a row or a column could
46835
- // be inserted at any time.
46836
- tKey: `${tKey}-${col}-${row}`,
46837
47179
  });
46838
47180
  }
46839
47181
  }
46840
- tKey++;
46841
47182
  return cells;
46842
47183
  }
46843
47184
  getClickableAction(position) {
@@ -51785,9 +52126,9 @@
51785
52126
  Object.defineProperty(exports, '__esModule', { value: true });
51786
52127
 
51787
52128
 
51788
- __info__.version = '16.4.29';
51789
- __info__.date = '2024-04-10T12:19:13.935Z';
51790
- __info__.hash = 'c022445';
52129
+ __info__.version = '16.4.31';
52130
+ __info__.date = '2024-04-26T07:37:06.433Z';
52131
+ __info__.hash = '16d6656';
51791
52132
 
51792
52133
 
51793
52134
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);