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