@odoo/o-spreadsheet 16.2.8 → 16.2.10

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.
@@ -707,12 +707,20 @@ function getDefaultCellHeight(cell) {
707
707
  return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
708
708
  }
709
709
  function computeTextWidth(context, text, style) {
710
- context.save();
711
- context.font = computeTextFont(style);
712
- const textWidth = context.measureText(text).width;
713
- context.restore();
714
- return textWidth;
710
+ const font = computeTextFont(style);
711
+ if (!textWidthCache[font]) {
712
+ textWidthCache[font] = {};
713
+ }
714
+ if (textWidthCache[font][text] === undefined) {
715
+ context.save();
716
+ context.font = font;
717
+ const textWidth = context.measureText(text).width;
718
+ context.restore();
719
+ textWidthCache[font][text] = textWidth;
720
+ }
721
+ return textWidthCache[font][text];
715
722
  }
723
+ const textWidthCache = {};
716
724
  function fontSizeInPixels(fontSize) {
717
725
  return Math.round((fontSize * 96) / 72);
718
726
  }
@@ -1722,27 +1730,36 @@ function removeTrailingZeroes(numberString) {
1722
1730
  }
1723
1731
  return numberString.slice(0, i + 1) || undefined;
1724
1732
  }
1733
+ const leadingZeroesRegexp = /^0+/;
1725
1734
  /**
1726
1735
  * Limit the size of the decimal part of a number to the given number of digits.
1727
1736
  */
1728
1737
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1738
+ var _a;
1729
1739
  let integerDigits = "0";
1730
1740
  let resultDecimalDigits = decimalDigits;
1731
1741
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1732
1742
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1733
1743
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1734
1744
  const i = maxDecimals;
1735
- if (Number(Number(decimalDigits[i]) < 5)) {
1745
+ if (Number(decimalDigits[i]) < 5) {
1736
1746
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1737
1747
  }
1738
1748
  // round up
1749
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1739
1750
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1740
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1741
- integerDigits = (Number(integerDigits) + 1).toString();
1751
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1752
+ // e.g. carry over from 99 to 100
1753
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1754
+ if (carryOver && !leadingZeroes) {
1755
+ integerDigits = "1";
1742
1756
  resultDecimalDigits = undefined;
1743
1757
  }
1758
+ else if (carryOver) {
1759
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1760
+ }
1744
1761
  else {
1745
- resultDecimalDigits = slicedRoundedUp;
1762
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1746
1763
  }
1747
1764
  return { integerDigits, decimalDigits: resultDecimalDigits };
1748
1765
  }
@@ -16949,6 +16966,7 @@ css /* scss */ `
16949
16966
  .o-color-picker-toggler {
16950
16967
  display: flex;
16951
16968
  .o-color-picker-toggler-sign {
16969
+ display: flex;
16952
16970
  margin: auto auto;
16953
16971
  width: 55%;
16954
16972
  height: 55%;
@@ -19843,6 +19861,7 @@ class Composer extends Component {
19843
19861
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
19844
19862
  }
19845
19863
  }
19864
+ this.updateCursorIfNeeded();
19846
19865
  }
19847
19866
  processTabKey(ev) {
19848
19867
  var _a;
@@ -19913,10 +19932,12 @@ class Composer extends Component {
19913
19932
  }
19914
19933
  else {
19915
19934
  ev.stopPropagation();
19935
+ this.updateCursorIfNeeded();
19916
19936
  }
19917
- const { start, end } = this.contentHelper.getCurrentSelection();
19918
- if (!this.env.model.getters.isSelectingForComposer() &&
19919
- !(ev.key === "Enter" && (ev.altKey || ev.ctrlKey))) {
19937
+ }
19938
+ updateCursorIfNeeded() {
19939
+ if (!this.env.model.getters.isSelectingForComposer()) {
19940
+ const { start, end } = this.contentHelper.getCurrentSelection();
19920
19941
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
19921
19942
  this.isKeyStillDown = true;
19922
19943
  }
@@ -19974,7 +19995,12 @@ class Composer extends Component {
19974
19995
  };
19975
19996
  });
19976
19997
  if (searchTerm) {
19977
- values = fuzzyLookup(searchTerm, values, (t) => t.text);
19998
+ if (searchTerm.toLowerCase() === "true" || searchTerm.toLowerCase() === "false") {
19999
+ values = [];
20000
+ }
20001
+ else {
20002
+ values = fuzzyLookup(searchTerm, values, (t) => t.text);
20003
+ }
19978
20004
  }
19979
20005
  else {
19980
20006
  // alphabetical order
@@ -29109,7 +29135,14 @@ class FiltersPlugin extends CorePlugin {
29109
29135
  this.history.update("tables", filterTables);
29110
29136
  break;
29111
29137
  case "DUPLICATE_SHEET":
29112
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
29138
+ const tables = {};
29139
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
29140
+ if (filterTable) {
29141
+ const newFilterTable = deepCopy(filterTable);
29142
+ tables[newFilterTable.id] = newFilterTable;
29143
+ }
29144
+ }
29145
+ this.history.update("tables", cmd.sheetIdTo, tables);
29113
29146
  break;
29114
29147
  case "ADD_COLUMNS_ROWS":
29115
29148
  this.onAddColumnsRows(cmd);
@@ -32686,6 +32719,7 @@ class FilterEvaluationPlugin extends UIPlugin {
32686
32719
  }
32687
32720
  exportForExcel(data) {
32688
32721
  for (const sheetData of data.sheets) {
32722
+ const sheetId = sheetData.id;
32689
32723
  for (const tableData of sheetData.filterTables) {
32690
32724
  const tableZone = toZone(tableData.range);
32691
32725
  const filters = [];
@@ -32701,20 +32735,20 @@ class FilterEvaluationPlugin extends UIPlugin {
32701
32735
  if (!filter)
32702
32736
  continue;
32703
32737
  const valuesInFilterZone = filter.filteredZone
32704
- ? positions(filter.filteredZone)
32705
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
32706
- .filter((cell) => cell.type !== CellValueType.empty)
32707
- .map((cell) => cell.formattedValue)
32738
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
32708
32739
  : [];
32709
- // In xlsx, filtered values = values that are displayed, not values that are hidden
32710
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
32711
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
32712
- // In xlsx, filter header should ALWAYS be a string and should be unique
32713
- const headerPosition = {
32714
- col: filter.col,
32715
- row: filter.zoneWithHeaders.top,
32716
- sheetId: sheetData.id,
32717
- };
32740
+ if (filteredValues.length) {
32741
+ const xlsxDisplayedValues = valuesInFilterZone
32742
+ .filter((val) => val)
32743
+ .filter((val) => !filteredValues.includes(val));
32744
+ filters.push({
32745
+ colId: i,
32746
+ displayedValues: [...new Set(xlsxDisplayedValues)],
32747
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
32748
+ });
32749
+ }
32750
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
32751
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
32718
32752
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
32719
32753
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
32720
32754
  headerNames.push(headerName);
@@ -35743,15 +35777,15 @@ SelectionInputPlugin.getters = [];
35743
35777
  * This plugin handles this internal state.
35744
35778
  */
35745
35779
  class SelectionInputsManagerPlugin extends UIPlugin {
35780
+ get currentInput() {
35781
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35782
+ }
35746
35783
  constructor(config) {
35747
35784
  super(config);
35748
35785
  this.config = config;
35749
35786
  this.inputs = {};
35750
35787
  this.focusedInputId = null;
35751
35788
  }
35752
- get currentInput() {
35753
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35754
- }
35755
35789
  // ---------------------------------------------------------------------------
35756
35790
  // Command Handling
35757
35791
  // ---------------------------------------------------------------------------
@@ -40827,11 +40861,9 @@ TopBarComposer.props = {
40827
40861
  onComposerContentFocused: Function,
40828
40862
  };
40829
40863
 
40830
- // -----------------------------------------------------------------------------
40831
- // TopBar
40832
- // -----------------------------------------------------------------------------
40833
40864
  css /* scss */ `
40834
40865
  .o-font-size-editor {
40866
+ height: calc(100% - 4px);
40835
40867
  input.o-font-size {
40836
40868
  height: 20px;
40837
40869
  width: 23px;
@@ -40909,6 +40941,7 @@ FontSizeEditor.components = {};
40909
40941
  FontSizeEditor.props = {
40910
40942
  onToggle: Function,
40911
40943
  dropdownStyle: String,
40944
+ class: String,
40912
40945
  };
40913
40946
 
40914
40947
  const FORMATS = [
@@ -44352,15 +44385,10 @@ function addAutoFilter(table) {
44352
44385
  `;
44353
44386
  }
44354
44387
  function addFilterColumns(table) {
44355
- const tableZone = toZone(table.range);
44356
44388
  const columns = [];
44357
- for (const i of range(0, zoneToDimension(tableZone).numberOfCols)) {
44358
- const filter = table.filters[i];
44359
- if (!filter || !filter.filteredValues.length) {
44360
- continue;
44361
- }
44389
+ for (const filter of table.filters) {
44362
44390
  const colXml = escapeXml /*xml*/ `
44363
- <filterColumn ${formatAttributes([["colId", i]])}>
44391
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
44364
44392
  ${addFilter(filter)}
44365
44393
  </filterColumn>
44366
44394
  `;
@@ -44369,9 +44397,10 @@ function addFilterColumns(table) {
44369
44397
  return columns;
44370
44398
  }
44371
44399
  function addFilter(filter) {
44372
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
44400
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
44401
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
44373
44402
  return escapeXml /*xml*/ `
44374
- <filters>
44403
+ <filters ${formatAttributes(filterAttributes)}>
44375
44404
  ${joinXmlNodes(filterValues)}
44376
44405
  </filters>
44377
44406
  `;
@@ -45318,6 +45347,6 @@ function addFunction(functionName, functionDescription) {
45318
45347
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
45319
45348
 
45320
45349
 
45321
- __info__.version = '16.2.8';
45322
- __info__.date = '2023-06-02T10:12:43.068Z';
45323
- __info__.hash = 'b474e62';
45350
+ __info__.version = '16.2.10';
45351
+ __info__.date = '2023-06-26T14:33:27.213Z';
45352
+ __info__.hash = '1d3f47c';
@@ -708,12 +708,20 @@
708
708
  return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
709
709
  }
710
710
  function computeTextWidth(context, text, style) {
711
- context.save();
712
- context.font = computeTextFont(style);
713
- const textWidth = context.measureText(text).width;
714
- context.restore();
715
- return textWidth;
711
+ const font = computeTextFont(style);
712
+ if (!textWidthCache[font]) {
713
+ textWidthCache[font] = {};
714
+ }
715
+ if (textWidthCache[font][text] === undefined) {
716
+ context.save();
717
+ context.font = font;
718
+ const textWidth = context.measureText(text).width;
719
+ context.restore();
720
+ textWidthCache[font][text] = textWidth;
721
+ }
722
+ return textWidthCache[font][text];
716
723
  }
724
+ const textWidthCache = {};
717
725
  function fontSizeInPixels(fontSize) {
718
726
  return Math.round((fontSize * 96) / 72);
719
727
  }
@@ -1723,27 +1731,36 @@
1723
1731
  }
1724
1732
  return numberString.slice(0, i + 1) || undefined;
1725
1733
  }
1734
+ const leadingZeroesRegexp = /^0+/;
1726
1735
  /**
1727
1736
  * Limit the size of the decimal part of a number to the given number of digits.
1728
1737
  */
1729
1738
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1739
+ var _a;
1730
1740
  let integerDigits = "0";
1731
1741
  let resultDecimalDigits = decimalDigits;
1732
1742
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1733
1743
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1734
1744
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1735
1745
  const i = maxDecimals;
1736
- if (Number(Number(decimalDigits[i]) < 5)) {
1746
+ if (Number(decimalDigits[i]) < 5) {
1737
1747
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1738
1748
  }
1739
1749
  // round up
1750
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1740
1751
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1741
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1742
- integerDigits = (Number(integerDigits) + 1).toString();
1752
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1753
+ // e.g. carry over from 99 to 100
1754
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1755
+ if (carryOver && !leadingZeroes) {
1756
+ integerDigits = "1";
1743
1757
  resultDecimalDigits = undefined;
1744
1758
  }
1759
+ else if (carryOver) {
1760
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1761
+ }
1745
1762
  else {
1746
- resultDecimalDigits = slicedRoundedUp;
1763
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1747
1764
  }
1748
1765
  return { integerDigits, decimalDigits: resultDecimalDigits };
1749
1766
  }
@@ -16950,6 +16967,7 @@
16950
16967
  .o-color-picker-toggler {
16951
16968
  display: flex;
16952
16969
  .o-color-picker-toggler-sign {
16970
+ display: flex;
16953
16971
  margin: auto auto;
16954
16972
  width: 55%;
16955
16973
  height: 55%;
@@ -19844,6 +19862,7 @@
19844
19862
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
19845
19863
  }
19846
19864
  }
19865
+ this.updateCursorIfNeeded();
19847
19866
  }
19848
19867
  processTabKey(ev) {
19849
19868
  var _a;
@@ -19914,10 +19933,12 @@
19914
19933
  }
19915
19934
  else {
19916
19935
  ev.stopPropagation();
19936
+ this.updateCursorIfNeeded();
19917
19937
  }
19918
- const { start, end } = this.contentHelper.getCurrentSelection();
19919
- if (!this.env.model.getters.isSelectingForComposer() &&
19920
- !(ev.key === "Enter" && (ev.altKey || ev.ctrlKey))) {
19938
+ }
19939
+ updateCursorIfNeeded() {
19940
+ if (!this.env.model.getters.isSelectingForComposer()) {
19941
+ const { start, end } = this.contentHelper.getCurrentSelection();
19921
19942
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
19922
19943
  this.isKeyStillDown = true;
19923
19944
  }
@@ -19975,7 +19996,12 @@
19975
19996
  };
19976
19997
  });
19977
19998
  if (searchTerm) {
19978
- values = fuzzyLookup(searchTerm, values, (t) => t.text);
19999
+ if (searchTerm.toLowerCase() === "true" || searchTerm.toLowerCase() === "false") {
20000
+ values = [];
20001
+ }
20002
+ else {
20003
+ values = fuzzyLookup(searchTerm, values, (t) => t.text);
20004
+ }
19979
20005
  }
19980
20006
  else {
19981
20007
  // alphabetical order
@@ -29110,7 +29136,14 @@
29110
29136
  this.history.update("tables", filterTables);
29111
29137
  break;
29112
29138
  case "DUPLICATE_SHEET":
29113
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
29139
+ const tables = {};
29140
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
29141
+ if (filterTable) {
29142
+ const newFilterTable = deepCopy(filterTable);
29143
+ tables[newFilterTable.id] = newFilterTable;
29144
+ }
29145
+ }
29146
+ this.history.update("tables", cmd.sheetIdTo, tables);
29114
29147
  break;
29115
29148
  case "ADD_COLUMNS_ROWS":
29116
29149
  this.onAddColumnsRows(cmd);
@@ -32687,6 +32720,7 @@
32687
32720
  }
32688
32721
  exportForExcel(data) {
32689
32722
  for (const sheetData of data.sheets) {
32723
+ const sheetId = sheetData.id;
32690
32724
  for (const tableData of sheetData.filterTables) {
32691
32725
  const tableZone = toZone(tableData.range);
32692
32726
  const filters = [];
@@ -32702,20 +32736,20 @@
32702
32736
  if (!filter)
32703
32737
  continue;
32704
32738
  const valuesInFilterZone = filter.filteredZone
32705
- ? positions(filter.filteredZone)
32706
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
32707
- .filter((cell) => cell.type !== CellValueType.empty)
32708
- .map((cell) => cell.formattedValue)
32739
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
32709
32740
  : [];
32710
- // In xlsx, filtered values = values that are displayed, not values that are hidden
32711
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
32712
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
32713
- // In xlsx, filter header should ALWAYS be a string and should be unique
32714
- const headerPosition = {
32715
- col: filter.col,
32716
- row: filter.zoneWithHeaders.top,
32717
- sheetId: sheetData.id,
32718
- };
32741
+ if (filteredValues.length) {
32742
+ const xlsxDisplayedValues = valuesInFilterZone
32743
+ .filter((val) => val)
32744
+ .filter((val) => !filteredValues.includes(val));
32745
+ filters.push({
32746
+ colId: i,
32747
+ displayedValues: [...new Set(xlsxDisplayedValues)],
32748
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
32749
+ });
32750
+ }
32751
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
32752
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
32719
32753
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
32720
32754
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
32721
32755
  headerNames.push(headerName);
@@ -35744,15 +35778,15 @@
35744
35778
  * This plugin handles this internal state.
35745
35779
  */
35746
35780
  class SelectionInputsManagerPlugin extends UIPlugin {
35781
+ get currentInput() {
35782
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35783
+ }
35747
35784
  constructor(config) {
35748
35785
  super(config);
35749
35786
  this.config = config;
35750
35787
  this.inputs = {};
35751
35788
  this.focusedInputId = null;
35752
35789
  }
35753
- get currentInput() {
35754
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35755
- }
35756
35790
  // ---------------------------------------------------------------------------
35757
35791
  // Command Handling
35758
35792
  // ---------------------------------------------------------------------------
@@ -40828,11 +40862,9 @@
40828
40862
  onComposerContentFocused: Function,
40829
40863
  };
40830
40864
 
40831
- // -----------------------------------------------------------------------------
40832
- // TopBar
40833
- // -----------------------------------------------------------------------------
40834
40865
  css /* scss */ `
40835
40866
  .o-font-size-editor {
40867
+ height: calc(100% - 4px);
40836
40868
  input.o-font-size {
40837
40869
  height: 20px;
40838
40870
  width: 23px;
@@ -40910,6 +40942,7 @@
40910
40942
  FontSizeEditor.props = {
40911
40943
  onToggle: Function,
40912
40944
  dropdownStyle: String,
40945
+ class: String,
40913
40946
  };
40914
40947
 
40915
40948
  const FORMATS = [
@@ -44353,15 +44386,10 @@
44353
44386
  `;
44354
44387
  }
44355
44388
  function addFilterColumns(table) {
44356
- const tableZone = toZone(table.range);
44357
44389
  const columns = [];
44358
- for (const i of range(0, zoneToDimension(tableZone).numberOfCols)) {
44359
- const filter = table.filters[i];
44360
- if (!filter || !filter.filteredValues.length) {
44361
- continue;
44362
- }
44390
+ for (const filter of table.filters) {
44363
44391
  const colXml = escapeXml /*xml*/ `
44364
- <filterColumn ${formatAttributes([["colId", i]])}>
44392
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
44365
44393
  ${addFilter(filter)}
44366
44394
  </filterColumn>
44367
44395
  `;
@@ -44370,9 +44398,10 @@
44370
44398
  return columns;
44371
44399
  }
44372
44400
  function addFilter(filter) {
44373
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
44401
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
44402
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
44374
44403
  return escapeXml /*xml*/ `
44375
- <filters>
44404
+ <filters ${formatAttributes(filterAttributes)}>
44376
44405
  ${joinXmlNodes(filterValues)}
44377
44406
  </filters>
44378
44407
  `;
@@ -45349,9 +45378,9 @@
45349
45378
  Object.defineProperty(exports, '__esModule', { value: true });
45350
45379
 
45351
45380
 
45352
- __info__.version = '16.2.8';
45353
- __info__.date = '2023-06-02T10:12:43.068Z';
45354
- __info__.hash = 'b474e62';
45381
+ __info__.version = '16.2.10';
45382
+ __info__.date = '2023-06-26T14:33:27.213Z';
45383
+ __info__.hash = '1d3f47c';
45355
45384
 
45356
45385
 
45357
45386
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);