@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.
@@ -112,8 +112,8 @@ const SELECTION_BORDER_COLOR = "#3266ca";
112
112
  const HEADER_BORDER_COLOR = "#C0C0C0";
113
113
  const CELL_BORDER_COLOR = "#E2E3E3";
114
114
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
115
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
116
115
  const BG_HOVER_COLOR = "#EBEBEB";
116
+ const DISABLED_TEXT_COLOR = "#CACACA";
117
117
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
118
118
  const LINK_COLOR = "#01666b";
119
119
  const FILTERS_COLOR = "#188038";
@@ -754,12 +754,20 @@ function getDefaultCellHeight(cell) {
754
754
  return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
755
755
  }
756
756
  function computeTextWidth(context, text, style) {
757
- context.save();
758
- context.font = computeTextFont(style);
759
- const textWidth = context.measureText(text).width;
760
- context.restore();
761
- return textWidth;
757
+ const font = computeTextFont(style);
758
+ if (!textWidthCache[font]) {
759
+ textWidthCache[font] = {};
760
+ }
761
+ if (textWidthCache[font][text] === undefined) {
762
+ context.save();
763
+ context.font = font;
764
+ const textWidth = context.measureText(text).width;
765
+ context.restore();
766
+ textWidthCache[font][text] = textWidth;
767
+ }
768
+ return textWidthCache[font][text];
762
769
  }
770
+ const textWidthCache = {};
763
771
  function fontSizeInPixels(fontSize) {
764
772
  return Math.round((fontSize * 96) / 72);
765
773
  }
@@ -4214,7 +4222,6 @@ const readonlyAllowedCommands = new Set([
4214
4222
  "SET_VIEWPORT_OFFSET",
4215
4223
  "SELECT_SEARCH_NEXT_MATCH",
4216
4224
  "SELECT_SEARCH_PREVIOUS_MATCH",
4217
- "REFRESH_SEARCH",
4218
4225
  "UPDATE_SEARCH",
4219
4226
  "CLEAR_SEARCH",
4220
4227
  "EVALUATE_CELLS",
@@ -5535,7 +5542,7 @@ css /* scss */ `
5535
5542
  }
5536
5543
  }
5537
5544
  &.disabled {
5538
- color: ${MENU_ITEM_DISABLED_COLOR};
5545
+ color: ${DISABLED_TEXT_COLOR};
5539
5546
  cursor: not-allowed;
5540
5547
  }
5541
5548
  }
@@ -9519,9 +9526,9 @@ const ARG_TYPES = [
9519
9526
  "META",
9520
9527
  ];
9521
9528
  function arg(definition, description = "") {
9522
- return makeArg(`${definition} ${description}`);
9529
+ return makeArg(definition, description);
9523
9530
  }
9524
- function makeArg(str) {
9531
+ function makeArg(str, description) {
9525
9532
  let parts = str.match(ARG_REGEXP);
9526
9533
  let name = parts[1].trim();
9527
9534
  let types = [];
@@ -9551,7 +9558,6 @@ function makeArg(str) {
9551
9558
  defaultValue = param.trim().slice(8);
9552
9559
  }
9553
9560
  }
9554
- let description = parts[3].trim();
9555
9561
  const result = {
9556
9562
  name,
9557
9563
  description,
@@ -16373,7 +16379,7 @@ const insertFunctionMin = {
16373
16379
  };
16374
16380
  const categorieFunctionAll = {
16375
16381
  name: _lt("All"),
16376
- children: allFunctionListMenuBuilder(),
16382
+ children: [allFunctionListMenuBuilder],
16377
16383
  };
16378
16384
  function allFunctionListMenuBuilder() {
16379
16385
  const fnNames = functionRegistry.getKeys();
@@ -19640,6 +19646,7 @@ class FindAndReplacePanel extends owl.Component {
19640
19646
  state = owl.useState(this.initialState());
19641
19647
  debounceTimeoutId;
19642
19648
  showFormulaState = false;
19649
+ debouncedUpdateSearch;
19643
19650
  findAndReplaceRef = owl.useRef("findAndReplace");
19644
19651
  get hasSearchResult() {
19645
19652
  return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
@@ -19649,11 +19656,16 @@ class FindAndReplacePanel extends owl.Component {
19649
19656
  }
19650
19657
  setup() {
19651
19658
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
19659
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
19652
19660
  owl.onMounted(() => this.focusInput());
19653
19661
  owl.onWillUnmount(() => {
19654
19662
  this.env.model.dispatch("CLEAR_SEARCH");
19655
19663
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
19656
19664
  });
19665
+ owl.useEffect(() => {
19666
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
19667
+ this.searchFormulas();
19668
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
19657
19669
  }
19658
19670
  onInput(ev) {
19659
19671
  this.state.toSearch = ev.target.value;
@@ -19673,10 +19685,6 @@ class FindAndReplacePanel extends owl.Component {
19673
19685
  this.replace();
19674
19686
  }
19675
19687
  }
19676
- onFocusSidePanel() {
19677
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
19678
- this.env.model.dispatch("REFRESH_SEARCH");
19679
- }
19680
19688
  searchFormulas() {
19681
19689
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
19682
19690
  show: this.state.searchOptions.searchFormulas,
@@ -19695,13 +19703,6 @@ class FindAndReplacePanel extends owl.Component {
19695
19703
  searchOptions: this.state.searchOptions,
19696
19704
  });
19697
19705
  }
19698
- debouncedUpdateSearch() {
19699
- clearTimeout(this.debounceTimeoutId);
19700
- this.debounceTimeoutId = setTimeout(() => {
19701
- this.updateSearch();
19702
- this.debounceTimeoutId = undefined;
19703
- }, 400);
19704
- }
19705
19706
  replace() {
19706
19707
  this.env.model.dispatch("REPLACE_SEARCH", {
19707
19708
  replaceWith: this.state.replaceWith,
@@ -20932,6 +20933,7 @@ class Composer extends owl.Component {
20932
20933
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
20933
20934
  }
20934
20935
  }
20936
+ this.updateCursorIfNeeded();
20935
20937
  }
20936
20938
  processTabKey(ev) {
20937
20939
  ev.preventDefault();
@@ -21000,10 +21002,12 @@ class Composer extends owl.Component {
21000
21002
  }
21001
21003
  else {
21002
21004
  ev.stopPropagation();
21005
+ this.updateCursorIfNeeded();
21003
21006
  }
21004
- const { start, end } = this.contentHelper.getCurrentSelection();
21005
- if (!this.env.model.getters.isSelectingForComposer() &&
21006
- !(ev.key === "Enter" && (ev.altKey || ev.ctrlKey))) {
21007
+ }
21008
+ updateCursorIfNeeded() {
21009
+ if (!this.env.model.getters.isSelectingForComposer()) {
21010
+ const { start, end } = this.contentHelper.getCurrentSelection();
21007
21011
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
21008
21012
  this.isKeyStillDown = true;
21009
21013
  }
@@ -21061,7 +21065,12 @@ class Composer extends owl.Component {
21061
21065
  };
21062
21066
  });
21063
21067
  if (searchTerm) {
21064
- values = fuzzyLookup(searchTerm, values, (t) => t.text);
21068
+ if (searchTerm.toLowerCase() === "true" || searchTerm.toLowerCase() === "false") {
21069
+ values = [];
21070
+ }
21071
+ else {
21072
+ values = fuzzyLookup(searchTerm, values, (t) => t.text);
21073
+ }
21065
21074
  }
21066
21075
  else {
21067
21076
  // alphabetical order
@@ -30644,7 +30653,14 @@ class FiltersPlugin extends CorePlugin {
30644
30653
  this.history.update("tables", filterTables);
30645
30654
  break;
30646
30655
  case "DUPLICATE_SHEET":
30647
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
30656
+ const tables = {};
30657
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
30658
+ if (filterTable) {
30659
+ const newFilterTable = deepCopy(filterTable);
30660
+ tables[newFilterTable.id] = newFilterTable;
30661
+ }
30662
+ }
30663
+ this.history.update("tables", cmd.sheetIdTo, tables);
30648
30664
  break;
30649
30665
  case "ADD_COLUMNS_ROWS":
30650
30666
  this.onAddColumnsRows(cmd);
@@ -34193,6 +34209,7 @@ class FilterEvaluationPlugin extends UIPlugin {
34193
34209
  }
34194
34210
  exportForExcel(data) {
34195
34211
  for (const sheetData of data.sheets) {
34212
+ const sheetId = sheetData.id;
34196
34213
  for (const tableData of sheetData.filterTables) {
34197
34214
  const tableZone = toZone(tableData.range);
34198
34215
  const filters = [];
@@ -34208,20 +34225,20 @@ class FilterEvaluationPlugin extends UIPlugin {
34208
34225
  if (!filter)
34209
34226
  continue;
34210
34227
  const valuesInFilterZone = filter.filteredZone
34211
- ? positions(filter.filteredZone)
34212
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
34213
- .filter((cell) => cell.type !== CellValueType.empty)
34214
- .map((cell) => cell.formattedValue)
34228
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
34215
34229
  : [];
34216
- // In xlsx, filtered values = values that are displayed, not values that are hidden
34217
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
34218
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
34219
- // In xlsx, filter header should ALWAYS be a string and should be unique
34220
- const headerPosition = {
34221
- col: filter.col,
34222
- row: filter.zoneWithHeaders.top,
34223
- sheetId: sheetData.id,
34224
- };
34230
+ if (filteredValues.length) {
34231
+ const xlsxDisplayedValues = valuesInFilterZone
34232
+ .filter((val) => val)
34233
+ .filter((val) => !filteredValues.includes(val));
34234
+ filters.push({
34235
+ colId: i,
34236
+ displayedValues: [...new Set(xlsxDisplayedValues)],
34237
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
34238
+ });
34239
+ }
34240
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
34241
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
34225
34242
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
34226
34243
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
34227
34244
  headerNames.push(headerName);
@@ -36869,6 +36886,7 @@ class FindAndReplacePlugin extends UIPlugin {
36869
36886
  searchFormulas: false,
36870
36887
  };
36871
36888
  toSearch = "";
36889
+ isSearchDirty = false;
36872
36890
  // ---------------------------------------------------------------------------
36873
36891
  // Command Handling
36874
36892
  // ---------------------------------------------------------------------------
@@ -36896,14 +36914,21 @@ class FindAndReplacePlugin extends UIPlugin {
36896
36914
  case "REDO":
36897
36915
  case "REMOVE_COLUMNS_ROWS":
36898
36916
  case "ADD_COLUMNS_ROWS":
36899
- this.clearSearch();
36917
+ case "EVALUATE_CELLS":
36918
+ case "UPDATE_CELL":
36919
+ this.isSearchDirty = true;
36900
36920
  break;
36901
36921
  case "ACTIVATE_SHEET":
36902
- case "REFRESH_SEARCH":
36903
36922
  this.refreshSearch();
36904
36923
  break;
36905
36924
  }
36906
36925
  }
36926
+ finalize() {
36927
+ if (this.isSearchDirty) {
36928
+ this.refreshSearch();
36929
+ this.isSearchDirty = false;
36930
+ }
36931
+ }
36907
36932
  // ---------------------------------------------------------------------------
36908
36933
  // Getters
36909
36934
  // ---------------------------------------------------------------------------
@@ -36959,6 +36984,11 @@ class FindAndReplacePlugin extends UIPlugin {
36959
36984
  if (this.toSearch) {
36960
36985
  for (const cell of Object.values(cells)) {
36961
36986
  const { col, row } = this.getters.getCellPosition(cell.id);
36987
+ const isColHidden = this.getters.isColHidden(sheetId, col);
36988
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
36989
+ if (isColHidden || isRowHidden) {
36990
+ continue;
36991
+ }
36962
36992
  if (cell &&
36963
36993
  this.currentSearchRegex &&
36964
36994
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -38596,10 +38626,8 @@ class SortPlugin extends UIPlugin {
38596
38626
  }
38597
38627
  updateCellCommands.push(newCellValues);
38598
38628
  }
38599
- for (const cmd of updateCellCommands) {
38600
- this.dispatch("UPDATE_CELL", cmd);
38601
- }
38602
38629
  }
38630
+ updateCellCommands.forEach((cmdPayload) => this.dispatch("UPDATE_CELL", cmdPayload));
38603
38631
  }
38604
38632
  /**
38605
38633
  * Return the distances between main merge cells in the zone.
@@ -42864,6 +42892,11 @@ css /* scss */ `
42864
42892
  .o-sidePanelButton:enabled {
42865
42893
  cursor: pointer;
42866
42894
  }
42895
+
42896
+ .o-sidePanelButton:disabled {
42897
+ color: ${DISABLED_TEXT_COLOR};
42898
+ }
42899
+
42867
42900
  .o-sidePanelButton:last-child {
42868
42901
  margin-right: 0px;
42869
42902
  }
@@ -43293,11 +43326,9 @@ TopBarComposer.props = {
43293
43326
  onComposerContentFocused: Function,
43294
43327
  };
43295
43328
 
43296
- // -----------------------------------------------------------------------------
43297
- // TopBar
43298
- // -----------------------------------------------------------------------------
43299
43329
  css /* scss */ `
43300
43330
  .o-font-size-editor {
43331
+ height: calc(100% - 4px);
43301
43332
  input.o-font-size {
43302
43333
  outline-color: ${SELECTION_BORDER_COLOR};
43303
43334
  height: 20px;
@@ -43310,13 +43341,13 @@ css /* scss */ `
43310
43341
  input::-webkit-inner-spin-button {
43311
43342
  -webkit-appearance: none;
43312
43343
  }
43313
-
43314
- .o-text-options > div {
43315
- line-height: 26px;
43316
- padding: 3px 12px;
43317
- &:hover {
43318
- background-color: rgba(0, 0, 0, 0.08);
43319
- }
43344
+ }
43345
+ .o-text-options > div {
43346
+ cursor: pointer;
43347
+ line-height: 26px;
43348
+ padding: 3px 12px;
43349
+ &:hover {
43350
+ background-color: rgba(0, 0, 0, 0.08);
43320
43351
  }
43321
43352
  }
43322
43353
  `;
@@ -43381,6 +43412,7 @@ class FontSizeEditor extends owl.Component {
43381
43412
  FontSizeEditor.props = {
43382
43413
  onToggle: Function,
43383
43414
  dropdownStyle: String,
43415
+ class: String,
43384
43416
  };
43385
43417
 
43386
43418
  // -----------------------------------------------------------------------------
@@ -46549,15 +46581,10 @@ function addAutoFilter(table) {
46549
46581
  `;
46550
46582
  }
46551
46583
  function addFilterColumns(table) {
46552
- const tableZone = toZone(table.range);
46553
46584
  const columns = [];
46554
- for (const i of range(0, zoneToDimension(tableZone).numberOfCols)) {
46555
- const filter = table.filters[i];
46556
- if (!filter || !filter.filteredValues.length) {
46557
- continue;
46558
- }
46585
+ for (const filter of table.filters) {
46559
46586
  const colXml = escapeXml /*xml*/ `
46560
- <filterColumn ${formatAttributes([["colId", i]])}>
46587
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
46561
46588
  ${addFilter(filter)}
46562
46589
  </filterColumn>
46563
46590
  `;
@@ -46566,9 +46593,10 @@ function addFilterColumns(table) {
46566
46593
  return columns;
46567
46594
  }
46568
46595
  function addFilter(filter) {
46569
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46596
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46597
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
46570
46598
  return escapeXml /*xml*/ `
46571
- <filters>
46599
+ <filters ${formatAttributes(filterAttributes)}>
46572
46600
  ${joinXmlNodes(filterValues)}
46573
46601
  </filters>
46574
46602
  `;
@@ -46687,8 +46715,13 @@ function addHyperlinks(construct, data, sheetIndex) {
46687
46715
  const sheetId = parseSheetUrl(url);
46688
46716
  const sheet = data.sheets.find((sheet) => sheet.id === sheetId);
46689
46717
  const location = sheet ? `${sheet.name}!A1` : INCORRECT_RANGE_STRING;
46718
+ const hyperlinkAttributes = [
46719
+ ["display", label],
46720
+ ["location", location],
46721
+ ["ref", xc],
46722
+ ];
46690
46723
  linkNodes.push(escapeXml /*xml*/ `
46691
- <hyperlink display="${label}" location="${location}" ref="${xc}"/>
46724
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46692
46725
  `);
46693
46726
  }
46694
46727
  else {
@@ -46697,8 +46730,12 @@ function addHyperlinks(construct, data, sheetIndex) {
46697
46730
  type: XLSX_RELATION_TYPE.hyperlink,
46698
46731
  targetMode: "External",
46699
46732
  });
46733
+ const hyperlinkAttributes = [
46734
+ ["r:id", linkRelId],
46735
+ ["ref", xc],
46736
+ ];
46700
46737
  linkNodes.push(escapeXml /*xml*/ `
46701
- <hyperlink r:id="${linkRelId}" ref="${xc}"/>
46738
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46702
46739
  `);
46703
46740
  }
46704
46741
  }
@@ -47606,6 +47643,6 @@ exports.setTranslationMethod = setTranslationMethod;
47606
47643
  exports.tokenize = tokenize;
47607
47644
 
47608
47645
 
47609
- __info__.version = '16.3.3';
47610
- __info__.date = '2023-06-12T13:50:01.114Z';
47611
- __info__.hash = 'd3ab96f';
47646
+ __info__.version = '16.3.5';
47647
+ __info__.date = '2023-07-26T12:10:02.115Z';
47648
+ __info__.hash = '328bce4';