@odoo/o-spreadsheet 16.3.3 → 16.3.5

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.
@@ -109,8 +109,8 @@
109
109
  const HEADER_BORDER_COLOR = "#C0C0C0";
110
110
  const CELL_BORDER_COLOR = "#E2E3E3";
111
111
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
112
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
113
112
  const BG_HOVER_COLOR = "#EBEBEB";
113
+ const DISABLED_TEXT_COLOR = "#CACACA";
114
114
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
115
115
  const LINK_COLOR = "#01666b";
116
116
  const FILTERS_COLOR = "#188038";
@@ -751,12 +751,20 @@
751
751
  return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
752
752
  }
753
753
  function computeTextWidth(context, text, style) {
754
- context.save();
755
- context.font = computeTextFont(style);
756
- const textWidth = context.measureText(text).width;
757
- context.restore();
758
- return textWidth;
754
+ const font = computeTextFont(style);
755
+ if (!textWidthCache[font]) {
756
+ textWidthCache[font] = {};
757
+ }
758
+ if (textWidthCache[font][text] === undefined) {
759
+ context.save();
760
+ context.font = font;
761
+ const textWidth = context.measureText(text).width;
762
+ context.restore();
763
+ textWidthCache[font][text] = textWidth;
764
+ }
765
+ return textWidthCache[font][text];
759
766
  }
767
+ const textWidthCache = {};
760
768
  function fontSizeInPixels(fontSize) {
761
769
  return Math.round((fontSize * 96) / 72);
762
770
  }
@@ -4211,7 +4219,6 @@
4211
4219
  "SET_VIEWPORT_OFFSET",
4212
4220
  "SELECT_SEARCH_NEXT_MATCH",
4213
4221
  "SELECT_SEARCH_PREVIOUS_MATCH",
4214
- "REFRESH_SEARCH",
4215
4222
  "UPDATE_SEARCH",
4216
4223
  "CLEAR_SEARCH",
4217
4224
  "EVALUATE_CELLS",
@@ -5532,7 +5539,7 @@
5532
5539
  }
5533
5540
  }
5534
5541
  &.disabled {
5535
- color: ${MENU_ITEM_DISABLED_COLOR};
5542
+ color: ${DISABLED_TEXT_COLOR};
5536
5543
  cursor: not-allowed;
5537
5544
  }
5538
5545
  }
@@ -9516,9 +9523,9 @@
9516
9523
  "META",
9517
9524
  ];
9518
9525
  function arg(definition, description = "") {
9519
- return makeArg(`${definition} ${description}`);
9526
+ return makeArg(definition, description);
9520
9527
  }
9521
- function makeArg(str) {
9528
+ function makeArg(str, description) {
9522
9529
  let parts = str.match(ARG_REGEXP);
9523
9530
  let name = parts[1].trim();
9524
9531
  let types = [];
@@ -9548,7 +9555,6 @@
9548
9555
  defaultValue = param.trim().slice(8);
9549
9556
  }
9550
9557
  }
9551
- let description = parts[3].trim();
9552
9558
  const result = {
9553
9559
  name,
9554
9560
  description,
@@ -16370,7 +16376,7 @@
16370
16376
  };
16371
16377
  const categorieFunctionAll = {
16372
16378
  name: _lt("All"),
16373
- children: allFunctionListMenuBuilder(),
16379
+ children: [allFunctionListMenuBuilder],
16374
16380
  };
16375
16381
  function allFunctionListMenuBuilder() {
16376
16382
  const fnNames = functionRegistry.getKeys();
@@ -19637,6 +19643,7 @@
19637
19643
  state = owl.useState(this.initialState());
19638
19644
  debounceTimeoutId;
19639
19645
  showFormulaState = false;
19646
+ debouncedUpdateSearch;
19640
19647
  findAndReplaceRef = owl.useRef("findAndReplace");
19641
19648
  get hasSearchResult() {
19642
19649
  return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
@@ -19646,11 +19653,16 @@
19646
19653
  }
19647
19654
  setup() {
19648
19655
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
19656
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
19649
19657
  owl.onMounted(() => this.focusInput());
19650
19658
  owl.onWillUnmount(() => {
19651
19659
  this.env.model.dispatch("CLEAR_SEARCH");
19652
19660
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
19653
19661
  });
19662
+ owl.useEffect(() => {
19663
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
19664
+ this.searchFormulas();
19665
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
19654
19666
  }
19655
19667
  onInput(ev) {
19656
19668
  this.state.toSearch = ev.target.value;
@@ -19670,10 +19682,6 @@
19670
19682
  this.replace();
19671
19683
  }
19672
19684
  }
19673
- onFocusSidePanel() {
19674
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
19675
- this.env.model.dispatch("REFRESH_SEARCH");
19676
- }
19677
19685
  searchFormulas() {
19678
19686
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
19679
19687
  show: this.state.searchOptions.searchFormulas,
@@ -19692,13 +19700,6 @@
19692
19700
  searchOptions: this.state.searchOptions,
19693
19701
  });
19694
19702
  }
19695
- debouncedUpdateSearch() {
19696
- clearTimeout(this.debounceTimeoutId);
19697
- this.debounceTimeoutId = setTimeout(() => {
19698
- this.updateSearch();
19699
- this.debounceTimeoutId = undefined;
19700
- }, 400);
19701
- }
19702
19703
  replace() {
19703
19704
  this.env.model.dispatch("REPLACE_SEARCH", {
19704
19705
  replaceWith: this.state.replaceWith,
@@ -20929,6 +20930,7 @@
20929
20930
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
20930
20931
  }
20931
20932
  }
20933
+ this.updateCursorIfNeeded();
20932
20934
  }
20933
20935
  processTabKey(ev) {
20934
20936
  ev.preventDefault();
@@ -20997,10 +20999,12 @@
20997
20999
  }
20998
21000
  else {
20999
21001
  ev.stopPropagation();
21002
+ this.updateCursorIfNeeded();
21000
21003
  }
21001
- const { start, end } = this.contentHelper.getCurrentSelection();
21002
- if (!this.env.model.getters.isSelectingForComposer() &&
21003
- !(ev.key === "Enter" && (ev.altKey || ev.ctrlKey))) {
21004
+ }
21005
+ updateCursorIfNeeded() {
21006
+ if (!this.env.model.getters.isSelectingForComposer()) {
21007
+ const { start, end } = this.contentHelper.getCurrentSelection();
21004
21008
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
21005
21009
  this.isKeyStillDown = true;
21006
21010
  }
@@ -21058,7 +21062,12 @@
21058
21062
  };
21059
21063
  });
21060
21064
  if (searchTerm) {
21061
- values = fuzzyLookup(searchTerm, values, (t) => t.text);
21065
+ if (searchTerm.toLowerCase() === "true" || searchTerm.toLowerCase() === "false") {
21066
+ values = [];
21067
+ }
21068
+ else {
21069
+ values = fuzzyLookup(searchTerm, values, (t) => t.text);
21070
+ }
21062
21071
  }
21063
21072
  else {
21064
21073
  // alphabetical order
@@ -30641,7 +30650,14 @@
30641
30650
  this.history.update("tables", filterTables);
30642
30651
  break;
30643
30652
  case "DUPLICATE_SHEET":
30644
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
30653
+ const tables = {};
30654
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
30655
+ if (filterTable) {
30656
+ const newFilterTable = deepCopy(filterTable);
30657
+ tables[newFilterTable.id] = newFilterTable;
30658
+ }
30659
+ }
30660
+ this.history.update("tables", cmd.sheetIdTo, tables);
30645
30661
  break;
30646
30662
  case "ADD_COLUMNS_ROWS":
30647
30663
  this.onAddColumnsRows(cmd);
@@ -34190,6 +34206,7 @@
34190
34206
  }
34191
34207
  exportForExcel(data) {
34192
34208
  for (const sheetData of data.sheets) {
34209
+ const sheetId = sheetData.id;
34193
34210
  for (const tableData of sheetData.filterTables) {
34194
34211
  const tableZone = toZone(tableData.range);
34195
34212
  const filters = [];
@@ -34205,20 +34222,20 @@
34205
34222
  if (!filter)
34206
34223
  continue;
34207
34224
  const valuesInFilterZone = filter.filteredZone
34208
- ? positions(filter.filteredZone)
34209
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
34210
- .filter((cell) => cell.type !== CellValueType.empty)
34211
- .map((cell) => cell.formattedValue)
34225
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
34212
34226
  : [];
34213
- // In xlsx, filtered values = values that are displayed, not values that are hidden
34214
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
34215
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
34216
- // In xlsx, filter header should ALWAYS be a string and should be unique
34217
- const headerPosition = {
34218
- col: filter.col,
34219
- row: filter.zoneWithHeaders.top,
34220
- sheetId: sheetData.id,
34221
- };
34227
+ if (filteredValues.length) {
34228
+ const xlsxDisplayedValues = valuesInFilterZone
34229
+ .filter((val) => val)
34230
+ .filter((val) => !filteredValues.includes(val));
34231
+ filters.push({
34232
+ colId: i,
34233
+ displayedValues: [...new Set(xlsxDisplayedValues)],
34234
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
34235
+ });
34236
+ }
34237
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
34238
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
34222
34239
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
34223
34240
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
34224
34241
  headerNames.push(headerName);
@@ -36866,6 +36883,7 @@
36866
36883
  searchFormulas: false,
36867
36884
  };
36868
36885
  toSearch = "";
36886
+ isSearchDirty = false;
36869
36887
  // ---------------------------------------------------------------------------
36870
36888
  // Command Handling
36871
36889
  // ---------------------------------------------------------------------------
@@ -36893,14 +36911,21 @@
36893
36911
  case "REDO":
36894
36912
  case "REMOVE_COLUMNS_ROWS":
36895
36913
  case "ADD_COLUMNS_ROWS":
36896
- this.clearSearch();
36914
+ case "EVALUATE_CELLS":
36915
+ case "UPDATE_CELL":
36916
+ this.isSearchDirty = true;
36897
36917
  break;
36898
36918
  case "ACTIVATE_SHEET":
36899
- case "REFRESH_SEARCH":
36900
36919
  this.refreshSearch();
36901
36920
  break;
36902
36921
  }
36903
36922
  }
36923
+ finalize() {
36924
+ if (this.isSearchDirty) {
36925
+ this.refreshSearch();
36926
+ this.isSearchDirty = false;
36927
+ }
36928
+ }
36904
36929
  // ---------------------------------------------------------------------------
36905
36930
  // Getters
36906
36931
  // ---------------------------------------------------------------------------
@@ -36956,6 +36981,11 @@
36956
36981
  if (this.toSearch) {
36957
36982
  for (const cell of Object.values(cells)) {
36958
36983
  const { col, row } = this.getters.getCellPosition(cell.id);
36984
+ const isColHidden = this.getters.isColHidden(sheetId, col);
36985
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
36986
+ if (isColHidden || isRowHidden) {
36987
+ continue;
36988
+ }
36959
36989
  if (cell &&
36960
36990
  this.currentSearchRegex &&
36961
36991
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -38593,10 +38623,8 @@
38593
38623
  }
38594
38624
  updateCellCommands.push(newCellValues);
38595
38625
  }
38596
- for (const cmd of updateCellCommands) {
38597
- this.dispatch("UPDATE_CELL", cmd);
38598
- }
38599
38626
  }
38627
+ updateCellCommands.forEach((cmdPayload) => this.dispatch("UPDATE_CELL", cmdPayload));
38600
38628
  }
38601
38629
  /**
38602
38630
  * Return the distances between main merge cells in the zone.
@@ -42861,6 +42889,11 @@
42861
42889
  .o-sidePanelButton:enabled {
42862
42890
  cursor: pointer;
42863
42891
  }
42892
+
42893
+ .o-sidePanelButton:disabled {
42894
+ color: ${DISABLED_TEXT_COLOR};
42895
+ }
42896
+
42864
42897
  .o-sidePanelButton:last-child {
42865
42898
  margin-right: 0px;
42866
42899
  }
@@ -43290,11 +43323,9 @@
43290
43323
  onComposerContentFocused: Function,
43291
43324
  };
43292
43325
 
43293
- // -----------------------------------------------------------------------------
43294
- // TopBar
43295
- // -----------------------------------------------------------------------------
43296
43326
  css /* scss */ `
43297
43327
  .o-font-size-editor {
43328
+ height: calc(100% - 4px);
43298
43329
  input.o-font-size {
43299
43330
  outline-color: ${SELECTION_BORDER_COLOR};
43300
43331
  height: 20px;
@@ -43307,13 +43338,13 @@
43307
43338
  input::-webkit-inner-spin-button {
43308
43339
  -webkit-appearance: none;
43309
43340
  }
43310
-
43311
- .o-text-options > div {
43312
- line-height: 26px;
43313
- padding: 3px 12px;
43314
- &:hover {
43315
- background-color: rgba(0, 0, 0, 0.08);
43316
- }
43341
+ }
43342
+ .o-text-options > div {
43343
+ cursor: pointer;
43344
+ line-height: 26px;
43345
+ padding: 3px 12px;
43346
+ &:hover {
43347
+ background-color: rgba(0, 0, 0, 0.08);
43317
43348
  }
43318
43349
  }
43319
43350
  `;
@@ -43378,6 +43409,7 @@
43378
43409
  FontSizeEditor.props = {
43379
43410
  onToggle: Function,
43380
43411
  dropdownStyle: String,
43412
+ class: String,
43381
43413
  };
43382
43414
 
43383
43415
  // -----------------------------------------------------------------------------
@@ -46546,15 +46578,10 @@
46546
46578
  `;
46547
46579
  }
46548
46580
  function addFilterColumns(table) {
46549
- const tableZone = toZone(table.range);
46550
46581
  const columns = [];
46551
- for (const i of range(0, zoneToDimension(tableZone).numberOfCols)) {
46552
- const filter = table.filters[i];
46553
- if (!filter || !filter.filteredValues.length) {
46554
- continue;
46555
- }
46582
+ for (const filter of table.filters) {
46556
46583
  const colXml = escapeXml /*xml*/ `
46557
- <filterColumn ${formatAttributes([["colId", i]])}>
46584
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
46558
46585
  ${addFilter(filter)}
46559
46586
  </filterColumn>
46560
46587
  `;
@@ -46563,9 +46590,10 @@
46563
46590
  return columns;
46564
46591
  }
46565
46592
  function addFilter(filter) {
46566
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46593
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46594
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
46567
46595
  return escapeXml /*xml*/ `
46568
- <filters>
46596
+ <filters ${formatAttributes(filterAttributes)}>
46569
46597
  ${joinXmlNodes(filterValues)}
46570
46598
  </filters>
46571
46599
  `;
@@ -46684,8 +46712,13 @@
46684
46712
  const sheetId = parseSheetUrl(url);
46685
46713
  const sheet = data.sheets.find((sheet) => sheet.id === sheetId);
46686
46714
  const location = sheet ? `${sheet.name}!A1` : INCORRECT_RANGE_STRING;
46715
+ const hyperlinkAttributes = [
46716
+ ["display", label],
46717
+ ["location", location],
46718
+ ["ref", xc],
46719
+ ];
46687
46720
  linkNodes.push(escapeXml /*xml*/ `
46688
- <hyperlink display="${label}" location="${location}" ref="${xc}"/>
46721
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46689
46722
  `);
46690
46723
  }
46691
46724
  else {
@@ -46694,8 +46727,12 @@
46694
46727
  type: XLSX_RELATION_TYPE.hyperlink,
46695
46728
  targetMode: "External",
46696
46729
  });
46730
+ const hyperlinkAttributes = [
46731
+ ["r:id", linkRelId],
46732
+ ["ref", xc],
46733
+ ];
46697
46734
  linkNodes.push(escapeXml /*xml*/ `
46698
- <hyperlink r:id="${linkRelId}" ref="${xc}"/>
46735
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46699
46736
  `);
46700
46737
  }
46701
46738
  }
@@ -47605,9 +47642,9 @@
47605
47642
  Object.defineProperty(exports, '__esModule', { value: true });
47606
47643
 
47607
47644
 
47608
- __info__.version = '16.3.3';
47609
- __info__.date = '2023-06-12T13:50:01.114Z';
47610
- __info__.hash = 'd3ab96f';
47645
+ __info__.version = '16.3.5';
47646
+ __info__.date = '2023-07-26T12:10:02.115Z';
47647
+ __info__.hash = '328bce4';
47611
47648
 
47612
47649
 
47613
47650
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);