@odoo/o-spreadsheet 16.1.14 → 16.1.16

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.
@@ -105,7 +105,7 @@ const SELECTION_BORDER_COLOR = "#3266ca";
105
105
  const HEADER_BORDER_COLOR = "#C0C0C0";
106
106
  const CELL_BORDER_COLOR = "#E2E3E3";
107
107
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
108
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
108
+ const DISABLED_TEXT_COLOR = "#CACACA";
109
109
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
110
110
  const LINK_COLOR = "#01666b";
111
111
  const FILTERS_COLOR = "#188038";
@@ -722,12 +722,20 @@ function getDefaultCellHeight(style) {
722
722
  return computeTextLinesHeight(fontSize) + 2 * PADDING_AUTORESIZE_VERTICAL;
723
723
  }
724
724
  function computeTextWidth(context, text, style) {
725
- context.save();
726
- context.font = computeTextFont(style);
727
- const textWidth = context.measureText(text).width;
728
- context.restore();
729
- return textWidth;
725
+ const font = computeTextFont(style);
726
+ if (!textWidthCache[font]) {
727
+ textWidthCache[font] = {};
728
+ }
729
+ if (textWidthCache[font][text] === undefined) {
730
+ context.save();
731
+ context.font = font;
732
+ const textWidth = context.measureText(text).width;
733
+ context.restore();
734
+ textWidthCache[font][text] = textWidth;
735
+ }
736
+ return textWidthCache[font][text];
730
737
  }
738
+ const textWidthCache = {};
731
739
  function computeTextFont(style) {
732
740
  const italic = style.italic ? "italic " : "";
733
741
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -3447,7 +3455,6 @@ const readonlyAllowedCommands = new Set([
3447
3455
  "SET_VIEWPORT_OFFSET",
3448
3456
  "SELECT_SEARCH_NEXT_MATCH",
3449
3457
  "SELECT_SEARCH_PREVIOUS_MATCH",
3450
- "REFRESH_SEARCH",
3451
3458
  "UPDATE_SEARCH",
3452
3459
  "CLEAR_SEARCH",
3453
3460
  "EVALUATE_CELLS",
@@ -5955,7 +5962,7 @@ css /* scss */ `
5955
5962
  }
5956
5963
  }
5957
5964
  &.disabled {
5958
- color: ${MENU_ITEM_DISABLED_COLOR};
5965
+ color: ${DISABLED_TEXT_COLOR};
5959
5966
  cursor: not-allowed;
5960
5967
  }
5961
5968
  }
@@ -21707,11 +21714,16 @@ class FindAndReplacePanel extends Component {
21707
21714
  }
21708
21715
  setup() {
21709
21716
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
21717
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
21710
21718
  onMounted(() => this.focusInput());
21711
21719
  onWillUnmount(() => {
21712
21720
  this.env.model.dispatch("CLEAR_SEARCH");
21713
21721
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
21714
21722
  });
21723
+ useEffect(() => {
21724
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
21725
+ this.searchFormulas();
21726
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
21715
21727
  }
21716
21728
  onInput(ev) {
21717
21729
  this.state.toSearch = ev.target.value;
@@ -21731,10 +21743,6 @@ class FindAndReplacePanel extends Component {
21731
21743
  this.replace();
21732
21744
  }
21733
21745
  }
21734
- onFocusSidePanel() {
21735
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
21736
- this.env.model.dispatch("REFRESH_SEARCH");
21737
- }
21738
21746
  searchFormulas() {
21739
21747
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
21740
21748
  show: this.state.searchOptions.searchFormulas,
@@ -21753,13 +21761,6 @@ class FindAndReplacePanel extends Component {
21753
21761
  searchOptions: this.state.searchOptions,
21754
21762
  });
21755
21763
  }
21756
- debouncedUpdateSearch() {
21757
- clearTimeout(this.debounceTimeoutId);
21758
- this.debounceTimeoutId = setTimeout(() => {
21759
- this.updateSearch();
21760
- this.debounceTimeoutId = undefined;
21761
- }, 400);
21762
- }
21763
21764
  replace() {
21764
21765
  this.env.model.dispatch("REPLACE_SEARCH", {
21765
21766
  replaceWith: this.state.replaceWith,
@@ -22263,6 +22264,14 @@ class FiguresContainer extends Component {
22263
22264
  if (dirY < 0) {
22264
22265
  this.dnd.y = dndInitialY + figure.height * fraction;
22265
22266
  }
22267
+ if (this.dnd.x < 0) {
22268
+ this.dnd.width += this.dnd.x;
22269
+ this.dnd.x = 0;
22270
+ }
22271
+ if (this.dnd.y < 0) {
22272
+ this.dnd.height += this.dnd.y;
22273
+ this.dnd.y = 0;
22274
+ }
22266
22275
  };
22267
22276
  }
22268
22277
  else {
@@ -22278,6 +22287,14 @@ class FiguresContainer extends Component {
22278
22287
  if (dirY < 0) {
22279
22288
  this.dnd.y = dndInitialY - deltaY;
22280
22289
  }
22290
+ if (this.dnd.x < 0) {
22291
+ this.dnd.width += this.dnd.x;
22292
+ this.dnd.x = 0;
22293
+ }
22294
+ if (this.dnd.y < 0) {
22295
+ this.dnd.height += this.dnd.y;
22296
+ this.dnd.y = 0;
22297
+ }
22281
22298
  };
22282
22299
  }
22283
22300
  const onMouseUp = (ev) => {
@@ -29556,7 +29573,14 @@ class FiltersPlugin extends CorePlugin {
29556
29573
  this.history.update("tables", filterTables);
29557
29574
  break;
29558
29575
  case "DUPLICATE_SHEET":
29559
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
29576
+ const tables = {};
29577
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
29578
+ if (filterTable) {
29579
+ const newFilterTable = deepCopy(filterTable);
29580
+ tables[newFilterTable.id] = newFilterTable;
29581
+ }
29582
+ }
29583
+ this.history.update("tables", cmd.sheetIdTo, tables);
29560
29584
  break;
29561
29585
  case "ADD_COLUMNS_ROWS":
29562
29586
  this.onAddColumnsRows(cmd);
@@ -33100,6 +33124,7 @@ class FilterEvaluationPlugin extends UIPlugin {
33100
33124
  }
33101
33125
  exportForExcel(data) {
33102
33126
  for (const sheetData of data.sheets) {
33127
+ const sheetId = sheetData.id;
33103
33128
  for (const tableData of sheetData.filterTables) {
33104
33129
  const tableZone = toZone(tableData.range);
33105
33130
  const filters = [];
@@ -33115,20 +33140,20 @@ class FilterEvaluationPlugin extends UIPlugin {
33115
33140
  if (!filter)
33116
33141
  continue;
33117
33142
  const valuesInFilterZone = filter.filteredZone
33118
- ? positions(filter.filteredZone)
33119
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
33120
- .filter((cell) => cell.type !== CellValueType.empty)
33121
- .map((cell) => cell.formattedValue)
33143
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
33122
33144
  : [];
33123
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33124
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33125
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33126
- // In xlsx, filter header should ALWAYS be a string and should be unique
33127
- const headerPosition = {
33128
- col: filter.col,
33129
- row: filter.zoneWithHeaders.top,
33130
- sheetId: sheetData.id,
33131
- };
33145
+ if (filteredValues.length) {
33146
+ const xlsxDisplayedValues = valuesInFilterZone
33147
+ .filter((val) => val)
33148
+ .filter((val) => !filteredValues.includes(val));
33149
+ filters.push({
33150
+ colId: i,
33151
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33152
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33153
+ });
33154
+ }
33155
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33156
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
33132
33157
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
33133
33158
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
33134
33159
  headerNames.push(headerName);
@@ -34864,6 +34889,7 @@ class FindAndReplacePlugin extends UIPlugin {
34864
34889
  searchFormulas: false,
34865
34890
  };
34866
34891
  this.toSearch = "";
34892
+ this.isSearchDirty = false;
34867
34893
  }
34868
34894
  // ---------------------------------------------------------------------------
34869
34895
  // Command Handling
@@ -34892,14 +34918,21 @@ class FindAndReplacePlugin extends UIPlugin {
34892
34918
  case "REDO":
34893
34919
  case "REMOVE_COLUMNS_ROWS":
34894
34920
  case "ADD_COLUMNS_ROWS":
34895
- this.clearSearch();
34921
+ case "EVALUATE_CELLS":
34922
+ case "UPDATE_CELL":
34923
+ this.isSearchDirty = true;
34896
34924
  break;
34897
34925
  case "ACTIVATE_SHEET":
34898
- case "REFRESH_SEARCH":
34899
34926
  this.refreshSearch();
34900
34927
  break;
34901
34928
  }
34902
34929
  }
34930
+ finalize() {
34931
+ if (this.isSearchDirty) {
34932
+ this.refreshSearch();
34933
+ this.isSearchDirty = false;
34934
+ }
34935
+ }
34903
34936
  // ---------------------------------------------------------------------------
34904
34937
  // Getters
34905
34938
  // ---------------------------------------------------------------------------
@@ -34955,6 +34988,11 @@ class FindAndReplacePlugin extends UIPlugin {
34955
34988
  if (this.toSearch) {
34956
34989
  for (const cell of Object.values(cells)) {
34957
34990
  const { col, row } = this.getters.getCellPosition(cell.id);
34991
+ const isColHidden = this.getters.isColHidden(sheetId, col);
34992
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
34993
+ if (isColHidden || isRowHidden) {
34994
+ continue;
34995
+ }
34958
34996
  if (cell &&
34959
34997
  this.currentSearchRegex &&
34960
34998
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -36157,15 +36195,15 @@ SelectionInputPlugin.getters = [];
36157
36195
  * This plugin handles this internal state.
36158
36196
  */
36159
36197
  class SelectionInputsManagerPlugin extends UIPlugin {
36198
+ get currentInput() {
36199
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36200
+ }
36160
36201
  constructor(config) {
36161
36202
  super(config);
36162
36203
  this.config = config;
36163
36204
  this.inputs = {};
36164
36205
  this.focusedInputId = null;
36165
36206
  }
36166
- get currentInput() {
36167
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36168
- }
36169
36207
  // ---------------------------------------------------------------------------
36170
36208
  // Command Handling
36171
36209
  // ---------------------------------------------------------------------------
@@ -37397,10 +37435,8 @@ class SortPlugin extends UIPlugin {
37397
37435
  }
37398
37436
  updateCellCommands.push(newCellValues);
37399
37437
  }
37400
- for (const cmd of updateCellCommands) {
37401
- this.dispatch("UPDATE_CELL", cmd);
37402
- }
37403
37438
  }
37439
+ updateCellCommands.forEach((cmdPayload) => this.dispatch("UPDATE_CELL", cmdPayload));
37404
37440
  }
37405
37441
  /**
37406
37442
  * Return the distances between main merge cells in the zone.
@@ -39727,6 +39763,11 @@ css /* scss */ `
39727
39763
  .o-sidePanelButton:enabled {
39728
39764
  cursor: pointer;
39729
39765
  }
39766
+
39767
+ .o-sidePanelButton:disabled {
39768
+ color: ${DISABLED_TEXT_COLOR};
39769
+ }
39770
+
39730
39771
  .o-sidePanelButton:last-child {
39731
39772
  margin-right: 0px;
39732
39773
  }
@@ -43296,15 +43337,10 @@ function addAutoFilter(table) {
43296
43337
  `;
43297
43338
  }
43298
43339
  function addFilterColumns(table) {
43299
- const tableZone = toZone(table.range);
43300
43340
  const columns = [];
43301
- for (const i of range(0, zoneToDimension(tableZone).width)) {
43302
- const filter = table.filters[i];
43303
- if (!filter || !filter.filteredValues.length) {
43304
- continue;
43305
- }
43341
+ for (const filter of table.filters) {
43306
43342
  const colXml = escapeXml /*xml*/ `
43307
- <filterColumn ${formatAttributes([["colId", i]])}>
43343
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
43308
43344
  ${addFilter(filter)}
43309
43345
  </filterColumn>
43310
43346
  `;
@@ -43313,9 +43349,10 @@ function addFilterColumns(table) {
43313
43349
  return columns;
43314
43350
  }
43315
43351
  function addFilter(filter) {
43316
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43352
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43353
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
43317
43354
  return escapeXml /*xml*/ `
43318
- <filters>
43355
+ <filters ${formatAttributes(filterAttributes)}>
43319
43356
  ${joinXmlNodes(filterValues)}
43320
43357
  </filters>
43321
43358
  `;
@@ -44240,6 +44277,6 @@ function addFunction(functionName, functionDescription) {
44240
44277
  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 };
44241
44278
 
44242
44279
 
44243
- __info__.version = '16.1.14';
44244
- __info__.date = '2023-06-12T13:50:13.693Z';
44245
- __info__.hash = 'a51d9fa';
44280
+ __info__.version = '16.1.16';
44281
+ __info__.date = '2023-07-26T12:09:57.059Z';
44282
+ __info__.hash = '96f5f09';
@@ -106,7 +106,7 @@
106
106
  const HEADER_BORDER_COLOR = "#C0C0C0";
107
107
  const CELL_BORDER_COLOR = "#E2E3E3";
108
108
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
109
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
109
+ const DISABLED_TEXT_COLOR = "#CACACA";
110
110
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
111
111
  const LINK_COLOR = "#01666b";
112
112
  const FILTERS_COLOR = "#188038";
@@ -723,12 +723,20 @@
723
723
  return computeTextLinesHeight(fontSize) + 2 * PADDING_AUTORESIZE_VERTICAL;
724
724
  }
725
725
  function computeTextWidth(context, text, style) {
726
- context.save();
727
- context.font = computeTextFont(style);
728
- const textWidth = context.measureText(text).width;
729
- context.restore();
730
- return textWidth;
726
+ const font = computeTextFont(style);
727
+ if (!textWidthCache[font]) {
728
+ textWidthCache[font] = {};
729
+ }
730
+ if (textWidthCache[font][text] === undefined) {
731
+ context.save();
732
+ context.font = font;
733
+ const textWidth = context.measureText(text).width;
734
+ context.restore();
735
+ textWidthCache[font][text] = textWidth;
736
+ }
737
+ return textWidthCache[font][text];
731
738
  }
739
+ const textWidthCache = {};
732
740
  function computeTextFont(style) {
733
741
  const italic = style.italic ? "italic " : "";
734
742
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -3448,7 +3456,6 @@
3448
3456
  "SET_VIEWPORT_OFFSET",
3449
3457
  "SELECT_SEARCH_NEXT_MATCH",
3450
3458
  "SELECT_SEARCH_PREVIOUS_MATCH",
3451
- "REFRESH_SEARCH",
3452
3459
  "UPDATE_SEARCH",
3453
3460
  "CLEAR_SEARCH",
3454
3461
  "EVALUATE_CELLS",
@@ -5956,7 +5963,7 @@
5956
5963
  }
5957
5964
  }
5958
5965
  &.disabled {
5959
- color: ${MENU_ITEM_DISABLED_COLOR};
5966
+ color: ${DISABLED_TEXT_COLOR};
5960
5967
  cursor: not-allowed;
5961
5968
  }
5962
5969
  }
@@ -21708,11 +21715,16 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
21708
21715
  }
21709
21716
  setup() {
21710
21717
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
21718
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
21711
21719
  owl.onMounted(() => this.focusInput());
21712
21720
  owl.onWillUnmount(() => {
21713
21721
  this.env.model.dispatch("CLEAR_SEARCH");
21714
21722
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
21715
21723
  });
21724
+ owl.useEffect(() => {
21725
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
21726
+ this.searchFormulas();
21727
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
21716
21728
  }
21717
21729
  onInput(ev) {
21718
21730
  this.state.toSearch = ev.target.value;
@@ -21732,10 +21744,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
21732
21744
  this.replace();
21733
21745
  }
21734
21746
  }
21735
- onFocusSidePanel() {
21736
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
21737
- this.env.model.dispatch("REFRESH_SEARCH");
21738
- }
21739
21747
  searchFormulas() {
21740
21748
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
21741
21749
  show: this.state.searchOptions.searchFormulas,
@@ -21754,13 +21762,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
21754
21762
  searchOptions: this.state.searchOptions,
21755
21763
  });
21756
21764
  }
21757
- debouncedUpdateSearch() {
21758
- clearTimeout(this.debounceTimeoutId);
21759
- this.debounceTimeoutId = setTimeout(() => {
21760
- this.updateSearch();
21761
- this.debounceTimeoutId = undefined;
21762
- }, 400);
21763
- }
21764
21765
  replace() {
21765
21766
  this.env.model.dispatch("REPLACE_SEARCH", {
21766
21767
  replaceWith: this.state.replaceWith,
@@ -22264,6 +22265,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22264
22265
  if (dirY < 0) {
22265
22266
  this.dnd.y = dndInitialY + figure.height * fraction;
22266
22267
  }
22268
+ if (this.dnd.x < 0) {
22269
+ this.dnd.width += this.dnd.x;
22270
+ this.dnd.x = 0;
22271
+ }
22272
+ if (this.dnd.y < 0) {
22273
+ this.dnd.height += this.dnd.y;
22274
+ this.dnd.y = 0;
22275
+ }
22267
22276
  };
22268
22277
  }
22269
22278
  else {
@@ -22279,6 +22288,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22279
22288
  if (dirY < 0) {
22280
22289
  this.dnd.y = dndInitialY - deltaY;
22281
22290
  }
22291
+ if (this.dnd.x < 0) {
22292
+ this.dnd.width += this.dnd.x;
22293
+ this.dnd.x = 0;
22294
+ }
22295
+ if (this.dnd.y < 0) {
22296
+ this.dnd.height += this.dnd.y;
22297
+ this.dnd.y = 0;
22298
+ }
22282
22299
  };
22283
22300
  }
22284
22301
  const onMouseUp = (ev) => {
@@ -29557,7 +29574,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29557
29574
  this.history.update("tables", filterTables);
29558
29575
  break;
29559
29576
  case "DUPLICATE_SHEET":
29560
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
29577
+ const tables = {};
29578
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
29579
+ if (filterTable) {
29580
+ const newFilterTable = deepCopy(filterTable);
29581
+ tables[newFilterTable.id] = newFilterTable;
29582
+ }
29583
+ }
29584
+ this.history.update("tables", cmd.sheetIdTo, tables);
29561
29585
  break;
29562
29586
  case "ADD_COLUMNS_ROWS":
29563
29587
  this.onAddColumnsRows(cmd);
@@ -33101,6 +33125,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33101
33125
  }
33102
33126
  exportForExcel(data) {
33103
33127
  for (const sheetData of data.sheets) {
33128
+ const sheetId = sheetData.id;
33104
33129
  for (const tableData of sheetData.filterTables) {
33105
33130
  const tableZone = toZone(tableData.range);
33106
33131
  const filters = [];
@@ -33116,20 +33141,20 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33116
33141
  if (!filter)
33117
33142
  continue;
33118
33143
  const valuesInFilterZone = filter.filteredZone
33119
- ? positions(filter.filteredZone)
33120
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
33121
- .filter((cell) => cell.type !== CellValueType.empty)
33122
- .map((cell) => cell.formattedValue)
33144
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
33123
33145
  : [];
33124
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33125
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33126
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33127
- // In xlsx, filter header should ALWAYS be a string and should be unique
33128
- const headerPosition = {
33129
- col: filter.col,
33130
- row: filter.zoneWithHeaders.top,
33131
- sheetId: sheetData.id,
33132
- };
33146
+ if (filteredValues.length) {
33147
+ const xlsxDisplayedValues = valuesInFilterZone
33148
+ .filter((val) => val)
33149
+ .filter((val) => !filteredValues.includes(val));
33150
+ filters.push({
33151
+ colId: i,
33152
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33153
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33154
+ });
33155
+ }
33156
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33157
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
33133
33158
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
33134
33159
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
33135
33160
  headerNames.push(headerName);
@@ -34865,6 +34890,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34865
34890
  searchFormulas: false,
34866
34891
  };
34867
34892
  this.toSearch = "";
34893
+ this.isSearchDirty = false;
34868
34894
  }
34869
34895
  // ---------------------------------------------------------------------------
34870
34896
  // Command Handling
@@ -34893,14 +34919,21 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34893
34919
  case "REDO":
34894
34920
  case "REMOVE_COLUMNS_ROWS":
34895
34921
  case "ADD_COLUMNS_ROWS":
34896
- this.clearSearch();
34922
+ case "EVALUATE_CELLS":
34923
+ case "UPDATE_CELL":
34924
+ this.isSearchDirty = true;
34897
34925
  break;
34898
34926
  case "ACTIVATE_SHEET":
34899
- case "REFRESH_SEARCH":
34900
34927
  this.refreshSearch();
34901
34928
  break;
34902
34929
  }
34903
34930
  }
34931
+ finalize() {
34932
+ if (this.isSearchDirty) {
34933
+ this.refreshSearch();
34934
+ this.isSearchDirty = false;
34935
+ }
34936
+ }
34904
34937
  // ---------------------------------------------------------------------------
34905
34938
  // Getters
34906
34939
  // ---------------------------------------------------------------------------
@@ -34956,6 +34989,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34956
34989
  if (this.toSearch) {
34957
34990
  for (const cell of Object.values(cells)) {
34958
34991
  const { col, row } = this.getters.getCellPosition(cell.id);
34992
+ const isColHidden = this.getters.isColHidden(sheetId, col);
34993
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
34994
+ if (isColHidden || isRowHidden) {
34995
+ continue;
34996
+ }
34959
34997
  if (cell &&
34960
34998
  this.currentSearchRegex &&
34961
34999
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -36158,15 +36196,15 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36158
36196
  * This plugin handles this internal state.
36159
36197
  */
36160
36198
  class SelectionInputsManagerPlugin extends UIPlugin {
36199
+ get currentInput() {
36200
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36201
+ }
36161
36202
  constructor(config) {
36162
36203
  super(config);
36163
36204
  this.config = config;
36164
36205
  this.inputs = {};
36165
36206
  this.focusedInputId = null;
36166
36207
  }
36167
- get currentInput() {
36168
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36169
- }
36170
36208
  // ---------------------------------------------------------------------------
36171
36209
  // Command Handling
36172
36210
  // ---------------------------------------------------------------------------
@@ -37398,10 +37436,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
37398
37436
  }
37399
37437
  updateCellCommands.push(newCellValues);
37400
37438
  }
37401
- for (const cmd of updateCellCommands) {
37402
- this.dispatch("UPDATE_CELL", cmd);
37403
- }
37404
37439
  }
37440
+ updateCellCommands.forEach((cmdPayload) => this.dispatch("UPDATE_CELL", cmdPayload));
37405
37441
  }
37406
37442
  /**
37407
37443
  * Return the distances between main merge cells in the zone.
@@ -39728,6 +39764,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39728
39764
  .o-sidePanelButton:enabled {
39729
39765
  cursor: pointer;
39730
39766
  }
39767
+
39768
+ .o-sidePanelButton:disabled {
39769
+ color: ${DISABLED_TEXT_COLOR};
39770
+ }
39771
+
39731
39772
  .o-sidePanelButton:last-child {
39732
39773
  margin-right: 0px;
39733
39774
  }
@@ -43297,15 +43338,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43297
43338
  `;
43298
43339
  }
43299
43340
  function addFilterColumns(table) {
43300
- const tableZone = toZone(table.range);
43301
43341
  const columns = [];
43302
- for (const i of range(0, zoneToDimension(tableZone).width)) {
43303
- const filter = table.filters[i];
43304
- if (!filter || !filter.filteredValues.length) {
43305
- continue;
43306
- }
43342
+ for (const filter of table.filters) {
43307
43343
  const colXml = escapeXml /*xml*/ `
43308
- <filterColumn ${formatAttributes([["colId", i]])}>
43344
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
43309
43345
  ${addFilter(filter)}
43310
43346
  </filterColumn>
43311
43347
  `;
@@ -43314,9 +43350,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43314
43350
  return columns;
43315
43351
  }
43316
43352
  function addFilter(filter) {
43317
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43353
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43354
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
43318
43355
  return escapeXml /*xml*/ `
43319
- <filters>
43356
+ <filters ${formatAttributes(filterAttributes)}>
43320
43357
  ${joinXmlNodes(filterValues)}
43321
43358
  </filters>
43322
43359
  `;
@@ -44271,9 +44308,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
44271
44308
  Object.defineProperty(exports, '__esModule', { value: true });
44272
44309
 
44273
44310
 
44274
- __info__.version = '16.1.14';
44275
- __info__.date = '2023-06-12T13:50:13.693Z';
44276
- __info__.hash = 'a51d9fa';
44311
+ __info__.version = '16.1.16';
44312
+ __info__.date = '2023-07-26T12:09:57.059Z';
44313
+ __info__.hash = '96f5f09';
44277
44314
 
44278
44315
 
44279
44316
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);