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