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