@odoo/o-spreadsheet 17.4.0-alpha.11 → 17.4.0-alpha.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.4.0-alpha.11
6
- * @date 2024-07-02T10:38:50.116Z
7
- * @hash 9fe9477
5
+ * @version 17.4.0-alpha.12
6
+ * @date 2024-07-08T05:43:07.933Z
7
+ * @hash 7cfe14a
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -1804,7 +1804,7 @@
1804
1804
  });
1805
1805
  const getNumberRegex = memoize(function getNumberRegex(locale) {
1806
1806
  const decimalSeparator = escapeRegExp(locale.decimalSeparator);
1807
- const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
1807
+ const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
1808
1808
  const pIntegerAndDecimals = `(?:\\d+(?:${thousandsSeparator}\\d{3,})*(?:${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
1809
1809
  const pOnlyDecimals = `(?:${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
1810
1810
  const pScientificFormat = "(?:e(?:\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -1837,7 +1837,7 @@
1837
1837
  return getNumberRegex(locale).test(value.trim());
1838
1838
  }
1839
1839
  const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
1840
- return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
1840
+ return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
1841
1841
  });
1842
1842
  /**
1843
1843
  * Convert a string into a number. It assumes that the string actually represents
@@ -5861,19 +5861,22 @@
5861
5861
  }
5862
5862
 
5863
5863
  function isValidLocale(locale) {
5864
- if (!(locale &&
5865
- typeof locale === "object" &&
5866
- typeof locale.name === "string" &&
5867
- typeof locale.code === "string" &&
5868
- typeof locale.thousandsSeparator === "string" &&
5869
- typeof locale.decimalSeparator === "string" &&
5870
- typeof locale.dateFormat === "string" &&
5871
- typeof locale.timeFormat === "string" &&
5872
- typeof locale.formulaArgSeparator === "string")) {
5864
+ if (!locale ||
5865
+ typeof locale !== "object" ||
5866
+ !(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
5873
5867
  return false;
5874
5868
  }
5875
- if (!Object.values(locale).every((v) => v)) {
5876
- return false;
5869
+ for (const property of [
5870
+ "code",
5871
+ "name",
5872
+ "decimalSeparator",
5873
+ "dateFormat",
5874
+ "timeFormat",
5875
+ "formulaArgSeparator",
5876
+ ]) {
5877
+ if (!locale[property] || typeof locale[property] !== "string") {
5878
+ return false;
5879
+ }
5877
5880
  }
5878
5881
  if (locale.formulaArgSeparator === locale.decimalSeparator) {
5879
5882
  return false;
@@ -5971,7 +5974,10 @@
5971
5974
  if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
5972
5975
  return content;
5973
5976
  }
5974
- return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
5977
+ if (locale.thousandsSeparator) {
5978
+ content = content.replaceAll(locale.thousandsSeparator, "");
5979
+ }
5980
+ return content.replace(locale.decimalSeparator, ".");
5975
5981
  }
5976
5982
  /**
5977
5983
  * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
@@ -6323,7 +6329,7 @@
6323
6329
  },
6324
6330
  toValueAndFormat(normalizedValue) {
6325
6331
  return {
6326
- value: toNumber(normalizedValue, DEFAULT_LOCALE),
6332
+ value: _t("Q%(quarter_number)s", { quarter_number: normalizedValue }),
6327
6333
  format: "0",
6328
6334
  };
6329
6335
  },
@@ -6453,9 +6459,9 @@
6453
6459
  }
6454
6460
  const ALL_PERIODS = {
6455
6461
  year: _t("Year"),
6456
- quarter: _t("Quarter"),
6457
- month: _t("Month"),
6458
- week: _t("Week"),
6462
+ quarter: _t("Quarter & Year"),
6463
+ month: _t("Month & Year"),
6464
+ week: _t("Week & Year"),
6459
6465
  day: _t("Day"),
6460
6466
  quarter_number: _t("Quarter"),
6461
6467
  month_number: _t("Month"),
@@ -6607,7 +6613,7 @@
6607
6613
  const pivotId = this.getters.getPivotIdFromPosition(position);
6608
6614
  const spreader = this.getters.getArrayFormulaSpreadingOn(position);
6609
6615
  if (pivotId) {
6610
- if (!deepEquals(spreader, position) || !isCopyingOneCell) {
6616
+ if (spreader && (!deepEquals(spreader, position) || !isCopyingOneCell)) {
6611
6617
  const pivotCell = this.getters.getPivotCellFromPosition(position);
6612
6618
  const formulaPivotId = this.getters.getPivotFormulaId(pivotId);
6613
6619
  const pivotFormula = createPivotFormula(formulaPivotId, pivotCell);
@@ -7412,6 +7418,146 @@
7412
7418
  return undefined;
7413
7419
  }
7414
7420
 
7421
+ var State;
7422
+ (function (State) {
7423
+ /**
7424
+ * Initial state.
7425
+ * Expecting any reference for the left part of a range
7426
+ * e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
7427
+ */
7428
+ State[State["LeftRef"] = 0] = "LeftRef";
7429
+ /**
7430
+ * Expecting any reference for the right part of a range
7431
+ * e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
7432
+ */
7433
+ State[State["RightRef"] = 1] = "RightRef";
7434
+ /**
7435
+ * Expecting the separator without any constraint on the right part
7436
+ */
7437
+ State[State["Separator"] = 2] = "Separator";
7438
+ /**
7439
+ * Expecting the separator for a full column range
7440
+ */
7441
+ State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
7442
+ /**
7443
+ * Expecting the separator for a full row range
7444
+ */
7445
+ State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
7446
+ /**
7447
+ * Expecting the right part of a full column range
7448
+ * e.g. "1", "A1"
7449
+ */
7450
+ State[State["RightColumnRef"] = 5] = "RightColumnRef";
7451
+ /**
7452
+ * Expecting the right part of a full row range
7453
+ * e.g. "A", "A1"
7454
+ */
7455
+ State[State["RightRowRef"] = 6] = "RightRowRef";
7456
+ /**
7457
+ * Final state. A range has been matched
7458
+ */
7459
+ State[State["Found"] = 7] = "Found";
7460
+ })(State || (State = {}));
7461
+ const goTo = (state, guard = () => true) => [
7462
+ {
7463
+ goTo: state,
7464
+ guard,
7465
+ },
7466
+ ];
7467
+ const goToMulti = (state, guard = () => true) => ({
7468
+ goTo: state,
7469
+ guard,
7470
+ });
7471
+ const machine = {
7472
+ [State.LeftRef]: {
7473
+ REFERENCE: goTo(State.Separator),
7474
+ NUMBER: goTo(State.FullRowSeparator),
7475
+ SYMBOL: [
7476
+ goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
7477
+ goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
7478
+ ],
7479
+ },
7480
+ [State.FullColumnSeparator]: {
7481
+ SPACE: goTo(State.FullColumnSeparator),
7482
+ OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
7483
+ },
7484
+ [State.FullRowSeparator]: {
7485
+ SPACE: goTo(State.FullRowSeparator),
7486
+ OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
7487
+ },
7488
+ [State.Separator]: {
7489
+ SPACE: goTo(State.Separator),
7490
+ OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
7491
+ },
7492
+ [State.RightRef]: {
7493
+ SPACE: goTo(State.RightRef),
7494
+ NUMBER: goTo(State.Found),
7495
+ REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7496
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
7497
+ },
7498
+ [State.RightColumnRef]: {
7499
+ SPACE: goTo(State.RightColumnRef),
7500
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
7501
+ REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7502
+ },
7503
+ [State.RightRowRef]: {
7504
+ SPACE: goTo(State.RightRowRef),
7505
+ NUMBER: goTo(State.Found),
7506
+ REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7507
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
7508
+ },
7509
+ [State.Found]: {},
7510
+ };
7511
+ /**
7512
+ * Check if the list of tokens starts with a sequence of tokens representing
7513
+ * a range.
7514
+ * If a range is found, the sequence is removed from the list and is returned
7515
+ * as a single token.
7516
+ */
7517
+ function matchReference(tokens) {
7518
+ let head = 0;
7519
+ let transitions = machine[State.LeftRef];
7520
+ let matchedTokens = "";
7521
+ while (transitions !== undefined) {
7522
+ const token = tokens[head++];
7523
+ if (!token) {
7524
+ return null;
7525
+ }
7526
+ const transition = transitions[token.type]?.find((transition) => transition.guard(token));
7527
+ const nextState = transition ? transition.goTo : undefined;
7528
+ switch (nextState) {
7529
+ case undefined:
7530
+ return null;
7531
+ case State.Found:
7532
+ matchedTokens += token.value;
7533
+ tokens.splice(0, head);
7534
+ return {
7535
+ type: "REFERENCE",
7536
+ value: matchedTokens,
7537
+ };
7538
+ default:
7539
+ transitions = machine[nextState];
7540
+ matchedTokens += token.value;
7541
+ break;
7542
+ }
7543
+ }
7544
+ return null;
7545
+ }
7546
+ /**
7547
+ * Take the result of the tokenizer and transform it to be usable in the
7548
+ * manipulations of range
7549
+ *
7550
+ * @param formula
7551
+ */
7552
+ function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
7553
+ const tokens = tokenize(formula, locale);
7554
+ const result = [];
7555
+ while (tokens.length) {
7556
+ result.push(matchReference(tokens) || tokens.shift());
7557
+ }
7558
+ return result;
7559
+ }
7560
+
7415
7561
  const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
7416
7562
  const UNARY_OPERATORS_PREFIX = ["-", "+"];
7417
7563
  const UNARY_OPERATORS_POSTFIX = ["%"];
@@ -7560,7 +7706,7 @@
7560
7706
  * Parse an expression (as a string) into an AST.
7561
7707
  */
7562
7708
  function parse(str) {
7563
- return parseTokens(tokenize(str));
7709
+ return parseTokens(rangeTokenize(str));
7564
7710
  }
7565
7711
  function parseTokens(tokens) {
7566
7712
  tokens = tokens.filter((x) => x.type !== "SPACE");
@@ -7696,146 +7842,6 @@
7696
7842
  return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
7697
7843
  }
7698
7844
 
7699
- var State;
7700
- (function (State) {
7701
- /**
7702
- * Initial state.
7703
- * Expecting any reference for the left part of a range
7704
- * e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
7705
- */
7706
- State[State["LeftRef"] = 0] = "LeftRef";
7707
- /**
7708
- * Expecting any reference for the right part of a range
7709
- * e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
7710
- */
7711
- State[State["RightRef"] = 1] = "RightRef";
7712
- /**
7713
- * Expecting the separator without any constraint on the right part
7714
- */
7715
- State[State["Separator"] = 2] = "Separator";
7716
- /**
7717
- * Expecting the separator for a full column range
7718
- */
7719
- State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
7720
- /**
7721
- * Expecting the separator for a full row range
7722
- */
7723
- State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
7724
- /**
7725
- * Expecting the right part of a full column range
7726
- * e.g. "1", "A1"
7727
- */
7728
- State[State["RightColumnRef"] = 5] = "RightColumnRef";
7729
- /**
7730
- * Expecting the right part of a full row range
7731
- * e.g. "A", "A1"
7732
- */
7733
- State[State["RightRowRef"] = 6] = "RightRowRef";
7734
- /**
7735
- * Final state. A range has been matched
7736
- */
7737
- State[State["Found"] = 7] = "Found";
7738
- })(State || (State = {}));
7739
- const goTo = (state, guard = () => true) => [
7740
- {
7741
- goTo: state,
7742
- guard,
7743
- },
7744
- ];
7745
- const goToMulti = (state, guard = () => true) => ({
7746
- goTo: state,
7747
- guard,
7748
- });
7749
- const machine = {
7750
- [State.LeftRef]: {
7751
- REFERENCE: goTo(State.Separator),
7752
- NUMBER: goTo(State.FullRowSeparator),
7753
- SYMBOL: [
7754
- goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
7755
- goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
7756
- ],
7757
- },
7758
- [State.FullColumnSeparator]: {
7759
- SPACE: goTo(State.FullColumnSeparator),
7760
- OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
7761
- },
7762
- [State.FullRowSeparator]: {
7763
- SPACE: goTo(State.FullRowSeparator),
7764
- OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
7765
- },
7766
- [State.Separator]: {
7767
- SPACE: goTo(State.Separator),
7768
- OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
7769
- },
7770
- [State.RightRef]: {
7771
- SPACE: goTo(State.RightRef),
7772
- NUMBER: goTo(State.Found),
7773
- REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7774
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
7775
- },
7776
- [State.RightColumnRef]: {
7777
- SPACE: goTo(State.RightColumnRef),
7778
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
7779
- REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7780
- },
7781
- [State.RightRowRef]: {
7782
- SPACE: goTo(State.RightRowRef),
7783
- NUMBER: goTo(State.Found),
7784
- REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
7785
- SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
7786
- },
7787
- [State.Found]: {},
7788
- };
7789
- /**
7790
- * Check if the list of tokens starts with a sequence of tokens representing
7791
- * a range.
7792
- * If a range is found, the sequence is removed from the list and is returned
7793
- * as a single token.
7794
- */
7795
- function matchReference(tokens) {
7796
- let head = 0;
7797
- let transitions = machine[State.LeftRef];
7798
- let matchedTokens = "";
7799
- while (transitions !== undefined) {
7800
- const token = tokens[head++];
7801
- if (!token) {
7802
- return null;
7803
- }
7804
- const transition = transitions[token.type]?.find((transition) => transition.guard(token));
7805
- const nextState = transition ? transition.goTo : undefined;
7806
- switch (nextState) {
7807
- case undefined:
7808
- return null;
7809
- case State.Found:
7810
- matchedTokens += token.value;
7811
- tokens.splice(0, head);
7812
- return {
7813
- type: "REFERENCE",
7814
- value: matchedTokens,
7815
- };
7816
- default:
7817
- transitions = machine[nextState];
7818
- matchedTokens += token.value;
7819
- break;
7820
- }
7821
- }
7822
- return null;
7823
- }
7824
- /**
7825
- * Take the result of the tokenizer and transform it to be usable in the
7826
- * manipulations of range
7827
- *
7828
- * @param formula
7829
- */
7830
- function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
7831
- const tokens = tokenize(formula, locale);
7832
- const result = [];
7833
- while (tokens.length) {
7834
- result.push(matchReference(tokens) || tokens.shift());
7835
- }
7836
- return result;
7837
- }
7838
-
7839
7845
  /**
7840
7846
  * Add the following information on tokens:
7841
7847
  * - length
@@ -24026,10 +24032,6 @@ stores.inject(MyMetaStore, storeInstance);
24026
24032
  const colors = new ColorGenerator();
24027
24033
  const definition = chart.getDefinition();
24028
24034
  for (let [index, { label, data }] of dataSetsValues.entries()) {
24029
- if (["linear", "time"].includes(axisType)) {
24030
- // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
24031
- data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
24032
- }
24033
24035
  const color = colors.next();
24034
24036
  let backgroundRGBA = colorToRGBA(color);
24035
24037
  if (areaChart) {
@@ -24045,6 +24047,10 @@ stores.inject(MyMetaStore, storeInstance);
24045
24047
  return value;
24046
24048
  });
24047
24049
  }
24050
+ if (["linear", "time"].includes(axisType)) {
24051
+ // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
24052
+ data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
24053
+ }
24048
24054
  const backgroundColor = rgbaToHex(backgroundRGBA);
24049
24055
  const dataset = {
24050
24056
  label,
@@ -34637,6 +34643,8 @@ stores.inject(MyMetaStore, storeInstance);
34637
34643
  isSearchDirty = false;
34638
34644
  initialShowFormulaState;
34639
34645
  preserveSelectedMatchIndex = false;
34646
+ irreplaceableMatchCount = 0;
34647
+ notificationStore = this.get(NotificationStore);
34640
34648
  // fixme: why do we make selectedMatchIndex on top of a selected
34641
34649
  // property in the matches?
34642
34650
  selectedMatchIndex = null;
@@ -34713,6 +34721,11 @@ stores.inject(MyMetaStore, storeInstance);
34713
34721
  for (const match of cmd.matches) {
34714
34722
  this.replaceMatch(match, cmd.searchString, cmd.replaceWith, cmd.searchOptions);
34715
34723
  }
34724
+ if (this.irreplaceableMatchCount > 0) {
34725
+ this.showReplaceWarningMessage(cmd.matches.length, this.irreplaceableMatchCount);
34726
+ }
34727
+ this.irreplaceableMatchCount = 0;
34728
+ break;
34716
34729
  }
34717
34730
  }
34718
34731
  finalize() {
@@ -34894,12 +34907,36 @@ stores.inject(MyMetaStore, storeInstance);
34894
34907
  searchOptions: this.searchOptions,
34895
34908
  });
34896
34909
  }
34910
+ /**
34911
+ * Show a warning message based on the number of matches replaced and irreplaceable.
34912
+ */
34913
+ showReplaceWarningMessage(totalMatches, irreplaceableMatches) {
34914
+ const replaceableMatches = totalMatches - irreplaceableMatches;
34915
+ if (replaceableMatches === 0) {
34916
+ this.notificationStore.notifyUser({
34917
+ type: "warning",
34918
+ sticky: false,
34919
+ text: _t("Match(es) cannot be replaced as they are part of a formula."),
34920
+ });
34921
+ }
34922
+ else {
34923
+ this.notificationStore.notifyUser({
34924
+ type: "warning",
34925
+ sticky: false,
34926
+ text: _t("%(replaceable_count)s match(es) replaced. %(irreplaceable_count)s match(es) cannot be replaced as they are part of a formula.", {
34927
+ replaceable_count: replaceableMatches,
34928
+ irreplaceable_count: irreplaceableMatches,
34929
+ }),
34930
+ });
34931
+ }
34932
+ }
34897
34933
  replaceMatch(selectedMatch, searchString, replaceWith, searchOptions) {
34898
34934
  const cell = this.getters.getCell(selectedMatch);
34899
34935
  if (!cell?.content) {
34900
34936
  return;
34901
34937
  }
34902
34938
  if (cell?.isFormula && !searchOptions.searchFormulas) {
34939
+ this.irreplaceableMatchCount++;
34903
34940
  return;
34904
34941
  }
34905
34942
  const searchRegex = getSearchRegex(searchString, searchOptions);
@@ -36965,7 +37002,13 @@ stores.inject(MyMetaStore, storeInstance);
36965
37002
  }
36966
37003
  async loadLocales() {
36967
37004
  this.loadedLocales = (await this.env.loadLocales())
36968
- .filter(isValidLocale)
37005
+ .filter((locale) => {
37006
+ const isValid = isValidLocale(locale);
37007
+ if (!isValid) {
37008
+ console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
37009
+ }
37010
+ return isValid;
37011
+ })
36969
37012
  .sort((a, b) => a.name.localeCompare(b.name));
36970
37013
  }
36971
37014
  get numberFormatPreview() {
@@ -38024,6 +38067,9 @@ stores.inject(MyMetaStore, storeInstance);
38024
38067
  const component = { ...value, id: this.uuidGenerator.uuidv4() };
38025
38068
  return super.add(name, component);
38026
38069
  }
38070
+ getAllOrdered() {
38071
+ return this.getAll().sort((a, b) => a.sequence - b.sequence);
38072
+ }
38027
38073
  }
38028
38074
  const topbarComponentRegistry = new TopBarComponentRegistry();
38029
38075
 
@@ -42134,6 +42180,7 @@ stores.inject(MyMetaStore, storeInstance);
42134
42180
  return;
42135
42181
  }
42136
42182
  if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
42183
+ ev.preventDefault();
42137
42184
  const content = clipboardData.getData(ClipboardMIMEType.PlainText);
42138
42185
  const target = this.env.model.getters.getSelectedZones();
42139
42186
  const clipboardString = this.env.model.getters.getClipboardTextContent();
@@ -46797,6 +46844,21 @@ stores.inject(MyMetaStore, storeInstance);
46797
46844
  return [];
46798
46845
  return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
46799
46846
  }
46847
+ /**
46848
+ * Get all the rows which contains at least a border
46849
+ */
46850
+ getRowsWithBorders(sheetId) {
46851
+ const sheetBorders = this.borders[sheetId]?.filter(isDefined);
46852
+ if (!sheetBorders)
46853
+ return [];
46854
+ const rowsWithBorders = new Set();
46855
+ for (const rowBorders of sheetBorders) {
46856
+ for (const rowBorder in rowBorders) {
46857
+ rowsWithBorders.add(parseInt(rowBorder, 10));
46858
+ }
46859
+ }
46860
+ return Array.from(rowsWithBorders);
46861
+ }
46800
46862
  /**
46801
46863
  * Get the range of all the rows in the sheet
46802
46864
  */
@@ -46846,7 +46908,7 @@ stores.inject(MyMetaStore, storeInstance);
46846
46908
  destructive: false,
46847
46909
  });
46848
46910
  }
46849
- this.getRowsRange(sheetId)
46911
+ this.getRowsWithBorders(sheetId)
46850
46912
  .filter((row) => row >= start)
46851
46913
  .sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
46852
46914
  .forEach((row) => {
@@ -63139,7 +63201,7 @@ stores.inject(MyMetaStore, storeInstance);
63139
63201
  }
63140
63202
  get topbarComponents() {
63141
63203
  return topbarComponentRegistry
63142
- .getAll()
63204
+ .getAllOrdered()
63143
63205
  .filter((item) => !item.isVisible || item.isVisible(this.env));
63144
63206
  }
63145
63207
  onExternalClick(ev) {
@@ -67770,9 +67832,9 @@ stores.inject(MyMetaStore, storeInstance);
67770
67832
  exports.tokenize = tokenize;
67771
67833
 
67772
67834
 
67773
- __info__.version = "17.4.0-alpha.11";
67774
- __info__.date = "2024-07-02T10:38:50.116Z";
67775
- __info__.hash = "9fe9477";
67835
+ __info__.version = "17.4.0-alpha.12";
67836
+ __info__.date = "2024-07-08T05:43:07.933Z";
67837
+ __info__.hash = "7cfe14a";
67776
67838
 
67777
67839
 
67778
67840
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);