@odoo/o-spreadsheet 17.1.10 → 17.1.12

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 17.1.10
6
- * @date 2024-04-05T14:00:03.890Z
7
- * @hash edc821c
5
+ * @version 17.1.12
6
+ * @date 2024-04-18T16:45:30.109Z
7
+ * @hash 3e90776
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -549,7 +549,7 @@ function deepEquals(o1, o2) {
549
549
  if (typeof o1 !== typeof o2)
550
550
  return false;
551
551
  if (typeof o1 !== "object")
552
- return o1 === o2;
552
+ return false;
553
553
  // Objects can have different keys if the values are undefined
554
554
  for (const key in o2) {
555
555
  if (!(key in o1) && o2[key] !== undefined) {
@@ -2475,6 +2475,15 @@ function matrixMap(matrix, fn) {
2475
2475
  }
2476
2476
  return generateMatrix(matrix.length, matrix[0].length, (col, row) => fn(matrix[col][row]));
2477
2477
  }
2478
+ function matrixForEach(matrix, fn) {
2479
+ const numberOfCols = matrix.length;
2480
+ const numberOfRows = matrix[0]?.length ?? 0;
2481
+ for (let col = 0; col < numberOfCols; col++) {
2482
+ for (let row = 0; row < numberOfRows; row++) {
2483
+ fn(matrix[col][row]);
2484
+ }
2485
+ }
2486
+ }
2478
2487
  function transposeMatrix(matrix) {
2479
2488
  if (!matrix.length) {
2480
2489
  return [];
@@ -8178,6 +8187,7 @@ class LinkEditor extends Component {
8178
8187
  this.save();
8179
8188
  }
8180
8189
  ev.stopPropagation();
8190
+ ev.preventDefault();
8181
8191
  break;
8182
8192
  case "Escape":
8183
8193
  this.cancel();
@@ -8463,7 +8473,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
8463
8473
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
8464
8474
  // tooltipItem.parsed.y can be an object or a number for pie charts
8465
8475
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
8466
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
8476
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
8467
8477
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
8468
8478
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
8469
8479
  },
@@ -8750,7 +8760,10 @@ function getBarConfiguration(chart, labels, localeFormat) {
8750
8760
  if (isNaN(value))
8751
8761
  return value;
8752
8762
  const { locale, format } = localeFormat;
8753
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
8763
+ return formatValue(value, {
8764
+ locale,
8765
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
8766
+ });
8754
8767
  },
8755
8768
  },
8756
8769
  },
@@ -9401,7 +9414,10 @@ function getLineConfiguration(chart, labels, localeFormat) {
9401
9414
  if (isNaN(value))
9402
9415
  return value;
9403
9416
  const { locale, format } = localeFormat;
9404
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
9417
+ return formatValue(value, {
9418
+ locale,
9419
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
9420
+ });
9405
9421
  },
9406
9422
  },
9407
9423
  },
@@ -9628,7 +9644,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
9628
9644
  const percentage = calculatePercentage(data, dataIndex);
9629
9645
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
9630
9646
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
9631
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
9647
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
9632
9648
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
9633
9649
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
9634
9650
  };
@@ -19754,7 +19770,7 @@ class FunctionRegistry extends Registry {
19754
19770
  }
19755
19771
  const descr = addMetaInfoFromArg(addDescr);
19756
19772
  validateArguments(descr.args);
19757
- this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
19773
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr), name), name);
19758
19774
  super.add(name, descr);
19759
19775
  return this;
19760
19776
  }
@@ -19793,9 +19809,7 @@ function handleError(e, functionName) {
19793
19809
  // so we fallback to a generic error
19794
19810
  if (hasStringValue(e) && isEvaluationError(e.value)) {
19795
19811
  if (hasStringMessage(e)) {
19796
- if (e.message?.includes("[[FUNCTION_NAME]]")) {
19797
- e.message = e.message.replace("[[FUNCTION_NAME]]", functionName);
19798
- }
19812
+ replaceFunctionNamePlaceholder(e, functionName);
19799
19813
  }
19800
19814
  return e;
19801
19815
  }
@@ -19810,21 +19824,29 @@ function hasStringMessage(obj) {
19810
19824
  return (obj?.message !== undefined &&
19811
19825
  typeof obj.message === "string");
19812
19826
  }
19813
- function addResultHandling(compute) {
19814
- return function (...args) {
19827
+ function addResultHandling(compute, functionName) {
19828
+ return function computeWithResultHandling(...args) {
19815
19829
  const result = compute.apply(this, args);
19816
19830
  if (!isMatrix(result)) {
19817
19831
  if (typeof result === "object" && result !== null && "value" in result) {
19832
+ replaceFunctionNamePlaceholder(result, functionName);
19818
19833
  return result;
19819
19834
  }
19820
19835
  return { value: result };
19821
19836
  }
19822
19837
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
19838
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
19823
19839
  return result;
19824
19840
  }
19825
19841
  return matrixMap(result, (row) => ({ value: row }));
19826
19842
  };
19827
19843
  }
19844
+ function replaceFunctionNamePlaceholder(fPayload, functionName) {
19845
+ // for performance reasons: change in place and only if needed
19846
+ if (fPayload.message?.includes("[[FUNCTION_NAME]]")) {
19847
+ fPayload.message = fPayload.message.replace("[[FUNCTION_NAME]]", functionName);
19848
+ }
19849
+ }
19828
19850
  const functionRegistry = new FunctionRegistry();
19829
19851
  for (let category of categories) {
19830
19852
  const fns = category.functions;
@@ -20196,6 +20218,332 @@ function interactiveAddFilter(env, sheetId, target) {
20196
20218
  }
20197
20219
  }
20198
20220
 
20221
+ function interactiveFreezeColumnsRows(env, dimension, base) {
20222
+ const sheetId = env.model.getters.getActiveSheetId();
20223
+ const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
20224
+ const result = env.model.dispatch(cmd, { sheetId, quantity: base });
20225
+ if (result.isCancelledBecause("MergeOverlap" /* CommandResult.MergeOverlap */)) {
20226
+ env.raiseError(MergeErrorMessage);
20227
+ }
20228
+ }
20229
+
20230
+ const hideCols = {
20231
+ name: HIDE_COLUMNS_NAME,
20232
+ execute: (env) => {
20233
+ const columns = env.model.getters.getElementsFromSelection("COL");
20234
+ env.model.dispatch("HIDE_COLUMNS_ROWS", {
20235
+ sheetId: env.model.getters.getActiveSheetId(),
20236
+ dimension: "COL",
20237
+ elements: columns,
20238
+ });
20239
+ },
20240
+ isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
20241
+ icon: "o-spreadsheet-Icon.HIDE_COL",
20242
+ };
20243
+ const unhideCols = {
20244
+ name: _t("Unhide columns"),
20245
+ execute: (env) => {
20246
+ const columns = env.model.getters.getElementsFromSelection("COL");
20247
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20248
+ sheetId: env.model.getters.getActiveSheetId(),
20249
+ dimension: "COL",
20250
+ elements: columns,
20251
+ });
20252
+ },
20253
+ isVisible: (env) => {
20254
+ const hiddenCols = env.model.getters
20255
+ .getHiddenColsGroups(env.model.getters.getActiveSheetId())
20256
+ .flat();
20257
+ const currentCols = env.model.getters.getElementsFromSelection("COL");
20258
+ return currentCols.some((col) => hiddenCols.includes(col));
20259
+ },
20260
+ };
20261
+ const unhideAllCols = {
20262
+ name: _t("Unhide all columns"),
20263
+ execute: (env) => {
20264
+ const sheetId = env.model.getters.getActiveSheetId();
20265
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20266
+ sheetId,
20267
+ dimension: "COL",
20268
+ elements: Array.from(Array(env.model.getters.getNumberCols(sheetId)).keys()),
20269
+ });
20270
+ },
20271
+ isVisible: (env) => env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId()).length > 0,
20272
+ };
20273
+ const hideRows = {
20274
+ name: HIDE_ROWS_NAME,
20275
+ execute: (env) => {
20276
+ const rows = env.model.getters.getElementsFromSelection("ROW");
20277
+ env.model.dispatch("HIDE_COLUMNS_ROWS", {
20278
+ sheetId: env.model.getters.getActiveSheetId(),
20279
+ dimension: "ROW",
20280
+ elements: rows,
20281
+ });
20282
+ },
20283
+ isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
20284
+ icon: "o-spreadsheet-Icon.HIDE_ROW",
20285
+ };
20286
+ const unhideRows = {
20287
+ name: _t("Unhide rows"),
20288
+ execute: (env) => {
20289
+ const columns = env.model.getters.getElementsFromSelection("ROW");
20290
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20291
+ sheetId: env.model.getters.getActiveSheetId(),
20292
+ dimension: "ROW",
20293
+ elements: columns,
20294
+ });
20295
+ },
20296
+ isVisible: (env) => {
20297
+ const hiddenRows = env.model.getters
20298
+ .getHiddenRowsGroups(env.model.getters.getActiveSheetId())
20299
+ .flat();
20300
+ const currentRows = env.model.getters.getElementsFromSelection("ROW");
20301
+ return currentRows.some((col) => hiddenRows.includes(col));
20302
+ },
20303
+ };
20304
+ const unhideAllRows = {
20305
+ name: _t("Unhide all rows"),
20306
+ execute: (env) => {
20307
+ const sheetId = env.model.getters.getActiveSheetId();
20308
+ env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20309
+ sheetId,
20310
+ dimension: "ROW",
20311
+ elements: Array.from(Array(env.model.getters.getNumberRows(sheetId)).keys()),
20312
+ });
20313
+ },
20314
+ isVisible: (env) => env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId()).length > 0,
20315
+ };
20316
+ const unFreezePane = {
20317
+ name: _t("Unfreeze"),
20318
+ isVisible: (env) => {
20319
+ const { xSplit, ySplit } = env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId());
20320
+ return xSplit + ySplit > 0;
20321
+ },
20322
+ execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS_ROWS", {
20323
+ sheetId: env.model.getters.getActiveSheetId(),
20324
+ }),
20325
+ icon: "o-spreadsheet-Icon.UNFREEZE",
20326
+ };
20327
+ const freezePane = {
20328
+ name: _t("Freeze"),
20329
+ icon: "o-spreadsheet-Icon.FREEZE",
20330
+ };
20331
+ const unFreezeRows = {
20332
+ name: _t("No rows"),
20333
+ execute: (env) => env.model.dispatch("UNFREEZE_ROWS", {
20334
+ sheetId: env.model.getters.getActiveSheetId(),
20335
+ }),
20336
+ isReadonlyAllowed: true,
20337
+ isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).ySplit,
20338
+ };
20339
+ const freezeFirstRow = {
20340
+ name: _t("1 row"),
20341
+ execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 1),
20342
+ isReadonlyAllowed: true,
20343
+ };
20344
+ const freezeSecondRow = {
20345
+ name: _t("2 rows"),
20346
+ execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 2),
20347
+ isReadonlyAllowed: true,
20348
+ };
20349
+ const freezeCurrentRow = {
20350
+ name: _t("Up to current row"),
20351
+ execute: (env) => {
20352
+ const { bottom } = env.model.getters.getSelectedZone();
20353
+ interactiveFreezeColumnsRows(env, "ROW", bottom + 1);
20354
+ },
20355
+ isReadonlyAllowed: true,
20356
+ };
20357
+ const unFreezeCols = {
20358
+ name: _t("No columns"),
20359
+ execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS", {
20360
+ sheetId: env.model.getters.getActiveSheetId(),
20361
+ }),
20362
+ isReadonlyAllowed: true,
20363
+ isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).xSplit,
20364
+ };
20365
+ const freezeFirstCol = {
20366
+ name: _t("1 column"),
20367
+ execute: (env) => interactiveFreezeColumnsRows(env, "COL", 1),
20368
+ isReadonlyAllowed: true,
20369
+ };
20370
+ const freezeSecondCol = {
20371
+ name: _t("2 columns"),
20372
+ execute: (env) => interactiveFreezeColumnsRows(env, "COL", 2),
20373
+ isReadonlyAllowed: true,
20374
+ };
20375
+ const freezeCurrentCol = {
20376
+ name: _t("Up to current column"),
20377
+ execute: (env) => {
20378
+ const { right } = env.model.getters.getSelectedZone();
20379
+ interactiveFreezeColumnsRows(env, "COL", right + 1);
20380
+ },
20381
+ isReadonlyAllowed: true,
20382
+ };
20383
+ const viewGridlines = {
20384
+ name: (env) => env.model.getters.getGridLinesVisibility(env.model.getters.getActiveSheetId())
20385
+ ? _t("Hide gridlines")
20386
+ : _t("Show gridlines"),
20387
+ execute: (env) => {
20388
+ const sheetId = env.model.getters.getActiveSheetId();
20389
+ env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
20390
+ sheetId,
20391
+ areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
20392
+ });
20393
+ },
20394
+ icon: "o-spreadsheet-Icon.SHOW_HIDE_GRID",
20395
+ };
20396
+ const viewFormulas = {
20397
+ name: (env) => env.model.getters.shouldShowFormulas() ? "Hide formulas" : _t("Show formulas"),
20398
+ execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
20399
+ isReadonlyAllowed: true,
20400
+ icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
20401
+ };
20402
+ const createRemoveFilter = {
20403
+ name: (env) => selectionContainsFilter(env) ? _t("Remove selected filters") : _t("Create filter"),
20404
+ isActive: (env) => selectionContainsFilter(env),
20405
+ isEnabled: (env) => !cannotCreateFilter(env),
20406
+ execute: (env) => createRemoveFilterAction(env),
20407
+ icon: "o-spreadsheet-Icon.FILTER_ICON_INACTIVE",
20408
+ };
20409
+ const groupColumns = {
20410
+ name: (env) => {
20411
+ const selection = env.model.getters.getSelectedZone();
20412
+ if (selection.left === selection.right) {
20413
+ return _t("Group column %s", numberToLetters(selection.left));
20414
+ }
20415
+ return _t("Group columns %s - %s", numberToLetters(selection.left), numberToLetters(selection.right));
20416
+ },
20417
+ execute: (env) => groupHeadersAction(env, "COL"),
20418
+ isVisible: (env) => {
20419
+ const sheetId = env.model.getters.getActiveSheetId();
20420
+ const selection = env.model.getters.getSelectedZone();
20421
+ const groups = env.model.getters.getHeaderGroupsInZone(sheetId, "COL", selection);
20422
+ return (IS_ONLY_ONE_RANGE(env) &&
20423
+ !groups.some((group) => group.start === selection.left && group.end === selection.right));
20424
+ },
20425
+ icon: "o-spreadsheet-Icon.GROUP_COLUMNS",
20426
+ };
20427
+ const groupRows = {
20428
+ name: (env) => {
20429
+ const selection = env.model.getters.getSelectedZone();
20430
+ if (selection.top === selection.bottom) {
20431
+ return _t("Group row %s", String(selection.top + 1));
20432
+ }
20433
+ return _t("Group rows %s - %s", String(selection.top + 1), String(selection.bottom + 1));
20434
+ },
20435
+ execute: (env) => groupHeadersAction(env, "ROW"),
20436
+ isVisible: (env) => {
20437
+ const sheetId = env.model.getters.getActiveSheetId();
20438
+ const selection = env.model.getters.getSelectedZone();
20439
+ const groups = env.model.getters.getHeaderGroupsInZone(sheetId, "ROW", selection);
20440
+ return (IS_ONLY_ONE_RANGE(env) &&
20441
+ !groups.some((group) => group.start === selection.top && group.end === selection.bottom));
20442
+ },
20443
+ icon: "o-spreadsheet-Icon.GROUP_ROWS",
20444
+ };
20445
+ const ungroupColumns = {
20446
+ name: (env) => {
20447
+ const selection = env.model.getters.getSelectedZone();
20448
+ if (selection.left === selection.right) {
20449
+ return _t("Ungroup column %s", numberToLetters(selection.left));
20450
+ }
20451
+ return _t("Ungroup columns %s - %s", numberToLetters(selection.left), numberToLetters(selection.right));
20452
+ },
20453
+ execute: (env) => ungroupHeaders(env, "COL"),
20454
+ icon: "o-spreadsheet-Icon.UNGROUP_COLUMNS",
20455
+ };
20456
+ const ungroupRows = {
20457
+ name: (env) => {
20458
+ const selection = env.model.getters.getSelectedZone();
20459
+ if (selection.top === selection.bottom) {
20460
+ return _t("Ungroup row %s", String(selection.top + 1));
20461
+ }
20462
+ return _t("Ungroup rows %s - %s", String(selection.top + 1), String(selection.bottom + 1));
20463
+ },
20464
+ execute: (env) => ungroupHeaders(env, "ROW"),
20465
+ icon: "o-spreadsheet-Icon.UNGROUP_ROWS",
20466
+ };
20467
+ function selectionContainsFilter(env) {
20468
+ const sheetId = env.model.getters.getActiveSheetId();
20469
+ const selectedZones = env.model.getters.getSelectedZones();
20470
+ return env.model.getters.doesZonesContainFilter(sheetId, selectedZones);
20471
+ }
20472
+ function cannotCreateFilter(env) {
20473
+ return !areZonesContinuous(...env.model.getters.getSelectedZones());
20474
+ }
20475
+ function createRemoveFilterAction(env) {
20476
+ if (selectionContainsFilter(env)) {
20477
+ env.model.dispatch("REMOVE_FILTER_TABLE", {
20478
+ sheetId: env.model.getters.getActiveSheetId(),
20479
+ target: env.model.getters.getSelectedZones(),
20480
+ });
20481
+ return;
20482
+ }
20483
+ if (cannotCreateFilter(env)) {
20484
+ return;
20485
+ }
20486
+ env.model.selection.selectTableAroundSelection();
20487
+ const sheetId = env.model.getters.getActiveSheetId();
20488
+ const selection = env.model.getters.getSelectedZones();
20489
+ interactiveAddFilter(env, sheetId, selection);
20490
+ }
20491
+ function groupHeadersAction(env, dim) {
20492
+ const selection = env.model.getters.getSelectedZone();
20493
+ const sheetId = env.model.getters.getActiveSheetId();
20494
+ env.model.dispatch("GROUP_HEADERS", {
20495
+ sheetId,
20496
+ dimension: dim,
20497
+ start: dim === "COL" ? selection.left : selection.top,
20498
+ end: dim === "COL" ? selection.right : selection.bottom,
20499
+ });
20500
+ }
20501
+ function ungroupHeaders(env, dim) {
20502
+ const selection = env.model.getters.getSelectedZone();
20503
+ const sheetId = env.model.getters.getActiveSheetId();
20504
+ env.model.dispatch("UNGROUP_HEADERS", {
20505
+ sheetId,
20506
+ dimension: dim,
20507
+ start: dim === "COL" ? selection.left : selection.top,
20508
+ end: dim === "COL" ? selection.right : selection.bottom,
20509
+ });
20510
+ }
20511
+ function canUngroupHeaders(env, dimension) {
20512
+ const sheetId = env.model.getters.getActiveSheetId();
20513
+ const selection = env.model.getters.getSelectedZones();
20514
+ return (selection.length === 1 &&
20515
+ env.model.getters.getHeaderGroupsInZone(sheetId, dimension, selection[0]).length > 0);
20516
+ }
20517
+
20518
+ var ACTION_VIEW = /*#__PURE__*/Object.freeze({
20519
+ __proto__: null,
20520
+ canUngroupHeaders: canUngroupHeaders,
20521
+ createRemoveFilter: createRemoveFilter,
20522
+ createRemoveFilterAction: createRemoveFilterAction,
20523
+ freezeCurrentCol: freezeCurrentCol,
20524
+ freezeCurrentRow: freezeCurrentRow,
20525
+ freezeFirstCol: freezeFirstCol,
20526
+ freezeFirstRow: freezeFirstRow,
20527
+ freezePane: freezePane,
20528
+ freezeSecondCol: freezeSecondCol,
20529
+ freezeSecondRow: freezeSecondRow,
20530
+ groupColumns: groupColumns,
20531
+ groupRows: groupRows,
20532
+ hideCols: hideCols,
20533
+ hideRows: hideRows,
20534
+ unFreezeCols: unFreezeCols,
20535
+ unFreezePane: unFreezePane,
20536
+ unFreezeRows: unFreezeRows,
20537
+ ungroupColumns: ungroupColumns,
20538
+ ungroupRows: ungroupRows,
20539
+ unhideAllCols: unhideAllCols,
20540
+ unhideAllRows: unhideAllRows,
20541
+ unhideCols: unhideCols,
20542
+ unhideRows: unhideRows,
20543
+ viewFormulas: viewFormulas,
20544
+ viewGridlines: viewGridlines
20545
+ });
20546
+
20199
20547
  const sortRange = {
20200
20548
  name: _t("Sort range"),
20201
20549
  isVisible: IS_ONLY_ONE_RANGE,
@@ -20238,32 +20586,15 @@ const sortDescending = {
20238
20586
  },
20239
20587
  icon: "o-spreadsheet-Icon.SORT_DESCENDING",
20240
20588
  };
20241
- const addDataFilter = {
20242
- name: _t("Create filter"),
20243
- execute: (env) => {
20244
- const sheetId = env.model.getters.getActiveSheetId();
20245
- const selection = env.model.getters.getSelection().zones;
20246
- interactiveAddFilter(env, sheetId, selection);
20247
- },
20248
- isVisible: (env) => !SELECTION_CONTAINS_FILTER(env),
20589
+ const addRemoveDataFilter = {
20590
+ name: (env) => SELECTION_CONTAINS_FILTER(env) ? _t("Remove filter") : _t("Create filter"),
20591
+ execute: (env) => createRemoveFilterAction(env),
20249
20592
  isEnabled: (env) => {
20250
20593
  const selectedZones = env.model.getters.getSelectedZones();
20251
20594
  return areZonesContinuous(...selectedZones);
20252
20595
  },
20253
20596
  icon: "o-spreadsheet-Icon.MENU_FILTER_ICON",
20254
20597
  };
20255
- const removeDataFilter = {
20256
- name: _t("Remove filter"),
20257
- execute: (env) => {
20258
- const sheetId = env.model.getters.getActiveSheetId();
20259
- env.model.dispatch("REMOVE_FILTER_TABLE", {
20260
- sheetId,
20261
- target: env.model.getters.getSelectedZones(),
20262
- });
20263
- },
20264
- isVisible: SELECTION_CONTAINS_FILTER,
20265
- icon: "o-spreadsheet-Icon.MENU_FILTER_ICON",
20266
- };
20267
20598
  const splitToColumns = {
20268
20599
  name: _t("Split text to columns"),
20269
20600
  sequence: 1,
@@ -20675,331 +21006,6 @@ var ACTION_FORMAT = /*#__PURE__*/Object.freeze({
20675
21006
  textColor: textColor
20676
21007
  });
20677
21008
 
20678
- function interactiveFreezeColumnsRows(env, dimension, base) {
20679
- const sheetId = env.model.getters.getActiveSheetId();
20680
- const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
20681
- const result = env.model.dispatch(cmd, { sheetId, quantity: base });
20682
- if (result.isCancelledBecause("MergeOverlap" /* CommandResult.MergeOverlap */)) {
20683
- env.raiseError(MergeErrorMessage);
20684
- }
20685
- }
20686
-
20687
- const hideCols = {
20688
- name: HIDE_COLUMNS_NAME,
20689
- execute: (env) => {
20690
- const columns = env.model.getters.getElementsFromSelection("COL");
20691
- env.model.dispatch("HIDE_COLUMNS_ROWS", {
20692
- sheetId: env.model.getters.getActiveSheetId(),
20693
- dimension: "COL",
20694
- elements: columns,
20695
- });
20696
- },
20697
- isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
20698
- icon: "o-spreadsheet-Icon.HIDE_COL",
20699
- };
20700
- const unhideCols = {
20701
- name: _t("Unhide columns"),
20702
- execute: (env) => {
20703
- const columns = env.model.getters.getElementsFromSelection("COL");
20704
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20705
- sheetId: env.model.getters.getActiveSheetId(),
20706
- dimension: "COL",
20707
- elements: columns,
20708
- });
20709
- },
20710
- isVisible: (env) => {
20711
- const hiddenCols = env.model.getters
20712
- .getHiddenColsGroups(env.model.getters.getActiveSheetId())
20713
- .flat();
20714
- const currentCols = env.model.getters.getElementsFromSelection("COL");
20715
- return currentCols.some((col) => hiddenCols.includes(col));
20716
- },
20717
- };
20718
- const unhideAllCols = {
20719
- name: _t("Unhide all columns"),
20720
- execute: (env) => {
20721
- const sheetId = env.model.getters.getActiveSheetId();
20722
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20723
- sheetId,
20724
- dimension: "COL",
20725
- elements: Array.from(Array(env.model.getters.getNumberCols(sheetId)).keys()),
20726
- });
20727
- },
20728
- isVisible: (env) => env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId()).length > 0,
20729
- };
20730
- const hideRows = {
20731
- name: HIDE_ROWS_NAME,
20732
- execute: (env) => {
20733
- const rows = env.model.getters.getElementsFromSelection("ROW");
20734
- env.model.dispatch("HIDE_COLUMNS_ROWS", {
20735
- sheetId: env.model.getters.getActiveSheetId(),
20736
- dimension: "ROW",
20737
- elements: rows,
20738
- });
20739
- },
20740
- isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
20741
- icon: "o-spreadsheet-Icon.HIDE_ROW",
20742
- };
20743
- const unhideRows = {
20744
- name: _t("Unhide rows"),
20745
- execute: (env) => {
20746
- const columns = env.model.getters.getElementsFromSelection("ROW");
20747
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20748
- sheetId: env.model.getters.getActiveSheetId(),
20749
- dimension: "ROW",
20750
- elements: columns,
20751
- });
20752
- },
20753
- isVisible: (env) => {
20754
- const hiddenRows = env.model.getters
20755
- .getHiddenRowsGroups(env.model.getters.getActiveSheetId())
20756
- .flat();
20757
- const currentRows = env.model.getters.getElementsFromSelection("ROW");
20758
- return currentRows.some((col) => hiddenRows.includes(col));
20759
- },
20760
- };
20761
- const unhideAllRows = {
20762
- name: _t("Unhide all rows"),
20763
- execute: (env) => {
20764
- const sheetId = env.model.getters.getActiveSheetId();
20765
- env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
20766
- sheetId,
20767
- dimension: "ROW",
20768
- elements: Array.from(Array(env.model.getters.getNumberRows(sheetId)).keys()),
20769
- });
20770
- },
20771
- isVisible: (env) => env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId()).length > 0,
20772
- };
20773
- const unFreezePane = {
20774
- name: _t("Unfreeze"),
20775
- isVisible: (env) => {
20776
- const { xSplit, ySplit } = env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId());
20777
- return xSplit + ySplit > 0;
20778
- },
20779
- execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS_ROWS", {
20780
- sheetId: env.model.getters.getActiveSheetId(),
20781
- }),
20782
- icon: "o-spreadsheet-Icon.UNFREEZE",
20783
- };
20784
- const freezePane = {
20785
- name: _t("Freeze"),
20786
- icon: "o-spreadsheet-Icon.FREEZE",
20787
- };
20788
- const unFreezeRows = {
20789
- name: _t("No rows"),
20790
- execute: (env) => env.model.dispatch("UNFREEZE_ROWS", {
20791
- sheetId: env.model.getters.getActiveSheetId(),
20792
- }),
20793
- isReadonlyAllowed: true,
20794
- isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).ySplit,
20795
- };
20796
- const freezeFirstRow = {
20797
- name: _t("1 row"),
20798
- execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 1),
20799
- isReadonlyAllowed: true,
20800
- };
20801
- const freezeSecondRow = {
20802
- name: _t("2 rows"),
20803
- execute: (env) => interactiveFreezeColumnsRows(env, "ROW", 2),
20804
- isReadonlyAllowed: true,
20805
- };
20806
- const freezeCurrentRow = {
20807
- name: _t("Up to current row"),
20808
- execute: (env) => {
20809
- const { bottom } = env.model.getters.getSelectedZone();
20810
- interactiveFreezeColumnsRows(env, "ROW", bottom + 1);
20811
- },
20812
- isReadonlyAllowed: true,
20813
- };
20814
- const unFreezeCols = {
20815
- name: _t("No columns"),
20816
- execute: (env) => env.model.dispatch("UNFREEZE_COLUMNS", {
20817
- sheetId: env.model.getters.getActiveSheetId(),
20818
- }),
20819
- isReadonlyAllowed: true,
20820
- isVisible: (env) => !!env.model.getters.getPaneDivisions(env.model.getters.getActiveSheetId()).xSplit,
20821
- };
20822
- const freezeFirstCol = {
20823
- name: _t("1 column"),
20824
- execute: (env) => interactiveFreezeColumnsRows(env, "COL", 1),
20825
- isReadonlyAllowed: true,
20826
- };
20827
- const freezeSecondCol = {
20828
- name: _t("2 columns"),
20829
- execute: (env) => interactiveFreezeColumnsRows(env, "COL", 2),
20830
- isReadonlyAllowed: true,
20831
- };
20832
- const freezeCurrentCol = {
20833
- name: _t("Up to current column"),
20834
- execute: (env) => {
20835
- const { right } = env.model.getters.getSelectedZone();
20836
- interactiveFreezeColumnsRows(env, "COL", right + 1);
20837
- },
20838
- isReadonlyAllowed: true,
20839
- };
20840
- const viewGridlines = {
20841
- name: (env) => env.model.getters.getGridLinesVisibility(env.model.getters.getActiveSheetId())
20842
- ? _t("Hide gridlines")
20843
- : _t("Show gridlines"),
20844
- execute: (env) => {
20845
- const sheetId = env.model.getters.getActiveSheetId();
20846
- env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
20847
- sheetId,
20848
- areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
20849
- });
20850
- },
20851
- icon: "o-spreadsheet-Icon.SHOW_HIDE_GRID",
20852
- };
20853
- const viewFormulas = {
20854
- name: (env) => env.model.getters.shouldShowFormulas() ? "Hide formulas" : _t("Show formulas"),
20855
- execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
20856
- isReadonlyAllowed: true,
20857
- icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
20858
- };
20859
- const createRemoveFilter = {
20860
- name: (env) => selectionContainsFilter(env) ? _t("Remove selected filters") : _t("Create filter"),
20861
- isActive: (env) => selectionContainsFilter(env),
20862
- isEnabled: (env) => !cannotCreateFilter(env),
20863
- execute: (env) => createRemoveFilterAction(env),
20864
- icon: "o-spreadsheet-Icon.FILTER_ICON_INACTIVE",
20865
- };
20866
- const groupColumns = {
20867
- name: (env) => {
20868
- const selection = env.model.getters.getSelectedZone();
20869
- if (selection.left === selection.right) {
20870
- return _t("Group column %s", numberToLetters(selection.left));
20871
- }
20872
- return _t("Group columns %s - %s", numberToLetters(selection.left), numberToLetters(selection.right));
20873
- },
20874
- execute: (env) => groupHeadersAction(env, "COL"),
20875
- isVisible: (env) => {
20876
- const sheetId = env.model.getters.getActiveSheetId();
20877
- const selection = env.model.getters.getSelectedZone();
20878
- const groups = env.model.getters.getHeaderGroupsInZone(sheetId, "COL", selection);
20879
- return (IS_ONLY_ONE_RANGE(env) &&
20880
- !groups.some((group) => group.start === selection.left && group.end === selection.right));
20881
- },
20882
- icon: "o-spreadsheet-Icon.GROUP_COLUMNS",
20883
- };
20884
- const groupRows = {
20885
- name: (env) => {
20886
- const selection = env.model.getters.getSelectedZone();
20887
- if (selection.top === selection.bottom) {
20888
- return _t("Group row %s", String(selection.top + 1));
20889
- }
20890
- return _t("Group rows %s - %s", String(selection.top + 1), String(selection.bottom + 1));
20891
- },
20892
- execute: (env) => groupHeadersAction(env, "ROW"),
20893
- isVisible: (env) => {
20894
- const sheetId = env.model.getters.getActiveSheetId();
20895
- const selection = env.model.getters.getSelectedZone();
20896
- const groups = env.model.getters.getHeaderGroupsInZone(sheetId, "ROW", selection);
20897
- return (IS_ONLY_ONE_RANGE(env) &&
20898
- !groups.some((group) => group.start === selection.top && group.end === selection.bottom));
20899
- },
20900
- icon: "o-spreadsheet-Icon.GROUP_ROWS",
20901
- };
20902
- const ungroupColumns = {
20903
- name: (env) => {
20904
- const selection = env.model.getters.getSelectedZone();
20905
- if (selection.left === selection.right) {
20906
- return _t("Ungroup column %s", numberToLetters(selection.left));
20907
- }
20908
- return _t("Ungroup columns %s - %s", numberToLetters(selection.left), numberToLetters(selection.right));
20909
- },
20910
- execute: (env) => ungroupHeaders(env, "COL"),
20911
- icon: "o-spreadsheet-Icon.UNGROUP_COLUMNS",
20912
- };
20913
- const ungroupRows = {
20914
- name: (env) => {
20915
- const selection = env.model.getters.getSelectedZone();
20916
- if (selection.top === selection.bottom) {
20917
- return _t("Ungroup row %s", String(selection.top + 1));
20918
- }
20919
- return _t("Ungroup rows %s - %s", String(selection.top + 1), String(selection.bottom + 1));
20920
- },
20921
- execute: (env) => ungroupHeaders(env, "ROW"),
20922
- icon: "o-spreadsheet-Icon.UNGROUP_ROWS",
20923
- };
20924
- function selectionContainsFilter(env) {
20925
- const sheetId = env.model.getters.getActiveSheetId();
20926
- const selectedZones = env.model.getters.getSelectedZones();
20927
- return env.model.getters.doesZonesContainFilter(sheetId, selectedZones);
20928
- }
20929
- function cannotCreateFilter(env) {
20930
- return !areZonesContinuous(...env.model.getters.getSelectedZones());
20931
- }
20932
- function createRemoveFilterAction(env) {
20933
- if (selectionContainsFilter(env)) {
20934
- env.model.dispatch("REMOVE_FILTER_TABLE", {
20935
- sheetId: env.model.getters.getActiveSheetId(),
20936
- target: env.model.getters.getSelectedZones(),
20937
- });
20938
- return;
20939
- }
20940
- if (cannotCreateFilter(env)) {
20941
- return;
20942
- }
20943
- env.model.selection.selectTableAroundSelection();
20944
- const sheetId = env.model.getters.getActiveSheetId();
20945
- const selection = env.model.getters.getSelectedZones();
20946
- interactiveAddFilter(env, sheetId, selection);
20947
- }
20948
- function groupHeadersAction(env, dim) {
20949
- const selection = env.model.getters.getSelectedZone();
20950
- const sheetId = env.model.getters.getActiveSheetId();
20951
- env.model.dispatch("GROUP_HEADERS", {
20952
- sheetId,
20953
- dimension: dim,
20954
- start: dim === "COL" ? selection.left : selection.top,
20955
- end: dim === "COL" ? selection.right : selection.bottom,
20956
- });
20957
- }
20958
- function ungroupHeaders(env, dim) {
20959
- const selection = env.model.getters.getSelectedZone();
20960
- const sheetId = env.model.getters.getActiveSheetId();
20961
- env.model.dispatch("UNGROUP_HEADERS", {
20962
- sheetId,
20963
- dimension: dim,
20964
- start: dim === "COL" ? selection.left : selection.top,
20965
- end: dim === "COL" ? selection.right : selection.bottom,
20966
- });
20967
- }
20968
- function canUngroupHeaders(env, dimension) {
20969
- const sheetId = env.model.getters.getActiveSheetId();
20970
- const selection = env.model.getters.getSelectedZones();
20971
- return (selection.length === 1 &&
20972
- env.model.getters.getHeaderGroupsInZone(sheetId, dimension, selection[0]).length > 0);
20973
- }
20974
-
20975
- var ACTION_VIEW = /*#__PURE__*/Object.freeze({
20976
- __proto__: null,
20977
- canUngroupHeaders: canUngroupHeaders,
20978
- createRemoveFilter: createRemoveFilter,
20979
- freezeCurrentCol: freezeCurrentCol,
20980
- freezeCurrentRow: freezeCurrentRow,
20981
- freezeFirstCol: freezeFirstCol,
20982
- freezeFirstRow: freezeFirstRow,
20983
- freezePane: freezePane,
20984
- freezeSecondCol: freezeSecondCol,
20985
- freezeSecondRow: freezeSecondRow,
20986
- groupColumns: groupColumns,
20987
- groupRows: groupRows,
20988
- hideCols: hideCols,
20989
- hideRows: hideRows,
20990
- unFreezeCols: unFreezeCols,
20991
- unFreezePane: unFreezePane,
20992
- unFreezeRows: unFreezeRows,
20993
- ungroupColumns: ungroupColumns,
20994
- ungroupRows: ungroupRows,
20995
- unhideAllCols: unhideAllCols,
20996
- unhideAllRows: unhideAllRows,
20997
- unhideCols: unhideCols,
20998
- unhideRows: unhideRows,
20999
- viewFormulas: viewFormulas,
21000
- viewGridlines: viewGridlines
21001
- });
21002
-
21003
21009
  const colMenuRegistry = new MenuItemRegistry();
21004
21010
  colMenuRegistry
21005
21011
  .add("cut", {
@@ -21646,13 +21652,8 @@ topbarMenuRegistry
21646
21652
  sequence: 30,
21647
21653
  separator: true,
21648
21654
  })
21649
- .addChild("add_data_filter", ["data"], {
21650
- ...addDataFilter,
21651
- sequence: 40,
21652
- separator: true,
21653
- })
21654
- .addChild("remove_data_filter", ["data"], {
21655
- ...removeDataFilter,
21655
+ .addChild("add_remove_data_filter", ["data"], {
21656
+ ...addRemoveDataFilter,
21656
21657
  sequence: 40,
21657
21658
  separator: true,
21658
21659
  });
@@ -27101,6 +27102,7 @@ class Composer extends Component {
27101
27102
  onComposerCellFocused: { type: Function, optional: true },
27102
27103
  onComposerContentFocused: Function,
27103
27104
  isDefaultFocus: { type: Boolean, optional: true },
27105
+ onInputContextMenu: { type: Function, optional: true },
27104
27106
  };
27105
27107
  static components = { TextValueProvider, FunctionDescriptionProvider };
27106
27108
  static defaultProps = {
@@ -27459,6 +27461,11 @@ class Composer extends Component {
27459
27461
  }
27460
27462
  }
27461
27463
  }
27464
+ onContextMenu(ev) {
27465
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27466
+ this.props.onInputContextMenu?.(ev);
27467
+ }
27468
+ }
27462
27469
  // ---------------------------------------------------------------------------
27463
27470
  // Private
27464
27471
  // ---------------------------------------------------------------------------
@@ -27726,6 +27733,7 @@ class GridComposer extends Component {
27726
27733
  onComposerCellFocused: Function,
27727
27734
  onComposerContentFocused: Function,
27728
27735
  gridDims: Object,
27736
+ onInputContextMenu: Function,
27729
27737
  };
27730
27738
  static components = { Composer };
27731
27739
  rect = this.defaultRect;
@@ -27770,6 +27778,7 @@ class GridComposer extends Component {
27770
27778
  isDefaultFocus: true,
27771
27779
  onComposerContentFocused: this.props.onComposerContentFocused,
27772
27780
  onComposerCellFocused: this.props.onComposerCellFocused,
27781
+ onInputContextMenu: this.props.onInputContextMenu,
27773
27782
  };
27774
27783
  }
27775
27784
  get containerStyle() {
@@ -28329,6 +28338,10 @@ css /*SCSS*/ `
28329
28338
  height: 0px;
28330
28339
  }
28331
28340
  }
28341
+ .o-figure-container {
28342
+ -webkit-user-select: none; // safari
28343
+ user-select: none;
28344
+ }
28332
28345
  `;
28333
28346
  /**
28334
28347
  * Each figure ⭐ is positioned inside a container `div` placed and sized
@@ -31767,29 +31780,12 @@ function convertWidthFromExcel(width) {
31767
31780
  return width;
31768
31781
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
31769
31782
  }
31770
- function convertBorderDescr(descr) {
31771
- if (!descr) {
31772
- return undefined;
31773
- }
31774
- return {
31775
- style: descr.style,
31776
- color: { rgb: descr.color },
31777
- };
31778
- }
31779
31783
  function extractStyle(cell, data) {
31780
31784
  let style = {};
31781
31785
  if (cell.style) {
31782
31786
  style = data.styles[cell.style];
31783
31787
  }
31784
31788
  const format = extractFormat(cell, data);
31785
- const exportedBorder = {};
31786
- if (cell.border) {
31787
- const border = data.borders[cell.border];
31788
- exportedBorder.left = convertBorderDescr(border.left);
31789
- exportedBorder.right = convertBorderDescr(border.right);
31790
- exportedBorder.bottom = convertBorderDescr(border.bottom);
31791
- exportedBorder.top = convertBorderDescr(border.top);
31792
- }
31793
31789
  const styles = {
31794
31790
  font: {
31795
31791
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -31803,7 +31799,7 @@ function extractStyle(cell, data) {
31803
31799
  }
31804
31800
  : { reservedAttribute: "none" },
31805
31801
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
31806
- border: exportedBorder || {},
31802
+ border: cell.border || 0,
31807
31803
  alignment: {
31808
31804
  horizontal: style.align,
31809
31805
  vertical: style.verticalAlign
@@ -31825,15 +31821,12 @@ function extractFormat(cell, data) {
31825
31821
  return undefined;
31826
31822
  }
31827
31823
  function normalizeStyle(construct, styles) {
31828
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
31829
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
31830
- const { id: borderId } = pushElement(styles["border"], construct.borders);
31831
31824
  // Normalize this
31832
31825
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
31833
31826
  const style = {
31834
- fontId,
31835
- fillId,
31836
- borderId,
31827
+ fontId: pushElement(styles.font, construct.fonts),
31828
+ fillId: pushElement(styles.fill, construct.fills),
31829
+ borderId: styles.border,
31837
31830
  numFmtId,
31838
31831
  alignment: {
31839
31832
  vertical: styles.alignment.vertical,
@@ -31841,8 +31834,7 @@ function normalizeStyle(construct, styles) {
31841
31834
  wrapText: styles.alignment.wrapText,
31842
31835
  },
31843
31836
  };
31844
- const { id } = pushElement(style, construct.styles);
31845
- return id;
31837
+ return pushElement(style, construct.styles);
31846
31838
  }
31847
31839
  function convertFormat(format, numFmtStructure) {
31848
31840
  if (!format) {
@@ -31850,8 +31842,7 @@ function convertFormat(format, numFmtStructure) {
31850
31842
  }
31851
31843
  let formatId = XLSX_FORMAT_MAP[format.format];
31852
31844
  if (!formatId) {
31853
- const { id } = pushElement(format, numFmtStructure);
31854
- formatId = id + FIRST_NUMFMT_ID;
31845
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
31855
31846
  }
31856
31847
  return formatId;
31857
31848
  }
@@ -31876,20 +31867,15 @@ function addRelsToFile(relsFiles, path, rel) {
31876
31867
  return id;
31877
31868
  }
31878
31869
  function pushElement(property, propertyList) {
31879
- for (let [key, value] of Object.entries(propertyList)) {
31880
- if (JSON.stringify(value) === JSON.stringify(property)) {
31881
- return { id: parseInt(key, 10), list: propertyList };
31870
+ let len = propertyList.length;
31871
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
31872
+ for (let i = 0; i < len; i++) {
31873
+ if (operator(property, propertyList[i])) {
31874
+ return i;
31882
31875
  }
31883
31876
  }
31884
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
31885
- if (elemId === -1) {
31886
- propertyList.push(property);
31887
- elemId = propertyList.length - 1;
31888
- }
31889
- return {
31890
- id: elemId,
31891
- list: propertyList,
31892
- };
31877
+ propertyList[propertyList.length] = property;
31878
+ return propertyList.length - 1;
31893
31879
  }
31894
31880
  const chartIds = [];
31895
31881
  /**
@@ -32616,7 +32602,25 @@ function parseXML(xmlString, mimeType = "text/xml") {
32616
32602
  }
32617
32603
  return document;
32618
32604
  }
32619
- function getDefaultXLSXStructure() {
32605
+ function convertBorderDescr(descr) {
32606
+ if (!descr) {
32607
+ return undefined;
32608
+ }
32609
+ return {
32610
+ style: descr.style,
32611
+ color: { rgb: descr.color },
32612
+ };
32613
+ }
32614
+ function getDefaultXLSXStructure(data) {
32615
+ const xlsxBorders = Object.values(data.borders).map((border) => {
32616
+ return {
32617
+ left: convertBorderDescr(border.left),
32618
+ right: convertBorderDescr(border.right),
32619
+ bottom: convertBorderDescr(border.bottom),
32620
+ top: convertBorderDescr(border.top),
32621
+ };
32622
+ });
32623
+ const borders = [{}, ...xlsxBorders];
32620
32624
  return {
32621
32625
  relsFiles: [],
32622
32626
  sharedStrings: [],
@@ -32639,7 +32643,7 @@ function getDefaultXLSXStructure() {
32639
32643
  },
32640
32644
  ],
32641
32645
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
32642
- borders: [{}],
32646
+ borders,
32643
32647
  numFmts: [],
32644
32648
  dxfs: [],
32645
32649
  };
@@ -37835,7 +37839,17 @@ class FiltersPlugin extends CorePlugin {
37835
37839
  }
37836
37840
  }
37837
37841
  exportForExcel(data) {
37838
- this.export(data);
37842
+ for (const sheet of data.sheets) {
37843
+ for (const filterTable of this.getFilterTables(sheet.id)) {
37844
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
37845
+ continue;
37846
+ }
37847
+ sheet.filterTables.push({
37848
+ range: zoneToXc(filterTable.zone),
37849
+ filters: [],
37850
+ });
37851
+ }
37852
+ }
37839
37853
  }
37840
37854
  }
37841
37855
 
@@ -41555,7 +41569,9 @@ class Evaluator {
41555
41569
  this.blockedArrayFormulas = new Set();
41556
41570
  this.spreadingRelations = new SpreadingRelation();
41557
41571
  this.formulaDependencies = lazy(() => {
41558
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
41572
+ const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
41573
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
41574
+ .map((range) => ({
41559
41575
  data: positionId,
41560
41576
  boundingBox: {
41561
41577
  zone: range.zone,
@@ -49288,7 +49304,7 @@ class FilterEvaluationPlugin extends UIPlugin {
49288
49304
  "isFilterActive",
49289
49305
  ];
49290
49306
  filterValues = {};
49291
- hiddenRows = new Set();
49307
+ hiddenRows = {};
49292
49308
  isEvaluationDirty = false;
49293
49309
  allowDispatch(cmd) {
49294
49310
  switch (cmd.type) {
@@ -49331,11 +49347,11 @@ class FilterEvaluationPlugin extends UIPlugin {
49331
49347
  case "UNFOLD_HEADER_GROUP":
49332
49348
  case "FOLD_ALL_HEADER_GROUPS":
49333
49349
  case "UNFOLD_ALL_HEADER_GROUPS":
49334
- this.updateHiddenRows();
49350
+ this.updateHiddenRows(cmd.sheetId);
49335
49351
  break;
49336
49352
  case "UPDATE_FILTER":
49337
49353
  this.updateFilter(cmd);
49338
- this.updateHiddenRows();
49354
+ this.updateHiddenRows(cmd.sheetId);
49339
49355
  break;
49340
49356
  case "DUPLICATE_SHEET":
49341
49357
  const filterValues = {};
@@ -49355,15 +49371,14 @@ class FilterEvaluationPlugin extends UIPlugin {
49355
49371
  }
49356
49372
  finalize() {
49357
49373
  if (this.isEvaluationDirty) {
49358
- this.updateHiddenRows();
49374
+ for (const sheetId of this.getters.getSheetIds()) {
49375
+ this.updateHiddenRows(sheetId);
49376
+ }
49359
49377
  this.isEvaluationDirty = false;
49360
49378
  }
49361
49379
  }
49362
49380
  isRowFiltered(sheetId, row) {
49363
- if (sheetId !== this.getters.getActiveSheetId()) {
49364
- return false;
49365
- }
49366
- return this.hiddenRows.has(row);
49381
+ return !!this.hiddenRows[sheetId]?.has(row);
49367
49382
  }
49368
49383
  getCellBorderWithFilterBorder(position) {
49369
49384
  const { sheetId, col, row } = position;
@@ -49414,8 +49429,7 @@ class FilterEvaluationPlugin extends UIPlugin {
49414
49429
  this.filterValues[sheetId] = {};
49415
49430
  this.filterValues[sheetId][id] = hiddenValues;
49416
49431
  }
49417
- updateHiddenRows() {
49418
- const sheetId = this.getters.getActiveSheetId();
49432
+ updateHiddenRows(sheetId) {
49419
49433
  const filters = this.getters
49420
49434
  .getFilters(sheetId)
49421
49435
  .sort((filter1, filter2) => filter1.zoneWithHeaders.top - filter2.zoneWithHeaders.top);
@@ -49436,7 +49450,7 @@ class FilterEvaluationPlugin extends UIPlugin {
49436
49450
  }
49437
49451
  }
49438
49452
  }
49439
- this.hiddenRows = hiddenRows;
49453
+ this.hiddenRows[sheetId] = hiddenRows;
49440
49454
  }
49441
49455
  getCellValueAsString(sheetId, col, row) {
49442
49456
  const value = this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue;
@@ -50546,13 +50560,14 @@ class SheetViewPlugin extends UIPlugin {
50546
50560
  }
50547
50561
  }
50548
50562
  handleEvent(event) {
50563
+ const sheetId = this.getters.getActiveSheetId();
50549
50564
  if (event.options.scrollIntoView) {
50550
50565
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
50551
50566
  if (event.mode === "updateAnchor") {
50552
50567
  const oldZone = event.previousAnchor.zone;
50553
50568
  const newZone = event.anchor.zone;
50554
50569
  // altering a zone should not move the viewport in a dimension that wasn't changed
50555
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
50570
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
50556
50571
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
50557
50572
  col = left > col || col > right ? left : col;
50558
50573
  }
@@ -50560,7 +50575,6 @@ class SheetViewPlugin extends UIPlugin {
50560
50575
  row = top > row || row > bottom ? top : row;
50561
50576
  }
50562
50577
  }
50563
- const sheetId = this.getters.getActiveSheetId();
50564
50578
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
50565
50579
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
50566
50580
  if (!this.sheetsWithDirtyViewports.has(sheetId)) {
@@ -50597,16 +50611,16 @@ class SheetViewPlugin extends UIPlugin {
50597
50611
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
50598
50612
  break;
50599
50613
  case "SHIFT_VIEWPORT_DOWN":
50600
- const { top } = this.getActiveMainViewport();
50601
50614
  const sheetId = this.getters.getActiveSheetId();
50602
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
50603
- this.shiftVertically(shiftedOffsetY);
50615
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
50616
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
50617
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
50604
50618
  break;
50605
50619
  case "SHIFT_VIEWPORT_UP": {
50606
- const { top } = this.getActiveMainViewport();
50607
50620
  const sheetId = this.getters.getActiveSheetId();
50608
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
50609
- this.shiftVertically(shiftedOffsetY);
50621
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
50622
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
50623
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
50610
50624
  break;
50611
50625
  }
50612
50626
  case "REMOVE_FILTER_TABLE":
@@ -50999,17 +51013,6 @@ class SheetViewPlugin extends UIPlugin {
50999
51013
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
51000
51014
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
51001
51015
  }
51002
- /**
51003
- * Clip the vertical offset within the allowed range.
51004
- * Not above the sheet, nor below the sheet.
51005
- */
51006
- clipOffsetY(offsetY) {
51007
- const { height } = this.getMainViewportRect();
51008
- const maxOffset = height - this.sheetViewHeight;
51009
- offsetY = Math.min(offsetY, maxOffset);
51010
- offsetY = Math.max(offsetY, 0);
51011
- return offsetY;
51012
- }
51013
51016
  getViewportOffset(sheetId) {
51014
51017
  return {
51015
51018
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -51065,12 +51068,15 @@ class SheetViewPlugin extends UIPlugin {
51065
51068
  * viewport top.
51066
51069
  */
51067
51070
  shiftVertically(offset) {
51068
- const { top } = this.getActiveMainViewport();
51071
+ const sheetId = this.getters.getActiveSheetId();
51072
+ const { top } = this.getMainInternalViewport(sheetId);
51069
51073
  const { scrollX } = this.getActiveSheetScrollInfo();
51070
51074
  this.setSheetViewOffset(scrollX, offset);
51071
51075
  const { anchor } = this.getters.getSelection();
51072
- const deltaRow = this.getActiveMainViewport().top - top;
51073
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
51076
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
51077
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
51078
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
51079
+ }
51074
51080
  }
51075
51081
  getVisibleFigures() {
51076
51082
  const sheetId = this.getters.getActiveSheetId();
@@ -52001,7 +52007,6 @@ css /* scss */ `
52001
52007
  cursor: pointer;
52002
52008
  }
52003
52009
  `;
52004
- let tKey = 1;
52005
52010
  class SpreadsheetDashboard extends Component {
52006
52011
  static template = "o-spreadsheet-SpreadsheetDashboard";
52007
52012
  static props = {};
@@ -52080,13 +52085,9 @@ class SpreadsheetDashboard extends Component {
52080
52085
  coordinates: rect,
52081
52086
  position: { col, row },
52082
52087
  action,
52083
- // we can't rely on position only because a row or a column could
52084
- // be inserted at any time.
52085
- tKey: `${tKey}-${col}-${row}`,
52086
52088
  });
52087
52089
  }
52088
52090
  }
52089
- tKey++;
52090
52091
  return cells;
52091
52092
  }
52092
52093
  getClickableAction(position) {
@@ -55529,8 +55530,7 @@ function addContent(content, sharedStrings, forceString = false) {
55529
55530
  attrs.push(["t", "b"]);
55530
55531
  }
55531
55532
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
55532
- const { id } = pushElement(content, sharedStrings);
55533
- value = id.toString();
55533
+ value = pushElement(content, sharedStrings);
55534
55534
  attrs.push(["t", "s"]);
55535
55535
  }
55536
55536
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -55655,8 +55655,7 @@ function addCellIsRule(cf, rule, dxfs) {
55655
55655
  if (rule.style.fillColor) {
55656
55656
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
55657
55657
  }
55658
- const { id } = pushElement(dxf, dxfs);
55659
- ruleAttributes.push(["dxfId", id]);
55658
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
55660
55659
  return escapeXml /*xml*/ `
55661
55660
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
55662
55661
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -56466,7 +56465,7 @@ function addSheetViews(sheet) {
56466
56465
  */
56467
56466
  function getXLSX(data) {
56468
56467
  const files = [];
56469
- const construct = getDefaultXLSXStructure();
56468
+ const construct = getDefaultXLSXStructure(data);
56470
56469
  files.push(createWorkbook(data, construct));
56471
56470
  files.push(...createWorksheets(data, construct));
56472
56471
  files.push(createStylesSheet(construct));
@@ -57319,6 +57318,6 @@ const constants = {
57319
57318
  export { AbstractChart, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57320
57319
 
57321
57320
 
57322
- __info__.version = "17.1.10";
57323
- __info__.date = "2024-04-05T14:00:03.890Z";
57324
- __info__.hash = "edc821c";
57321
+ __info__.version = "17.1.12";
57322
+ __info__.date = "2024-04-18T16:45:30.109Z";
57323
+ __info__.hash = "3e90776";