@odoo/o-spreadsheet 17.1.13 → 17.1.14

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.1.13
6
- * @date 2024-04-26T07:39:54.100Z
7
- * @hash f2ea8c7
5
+ * @version 17.1.14
6
+ * @date 2024-05-07T10:41:25.690Z
7
+ * @hash 622c47c
8
8
  */
9
9
 
10
10
  'use strict';
@@ -543,7 +543,7 @@ function getAddHeaderStartIndex(position, base) {
543
543
  /**
544
544
  * Compares two objects.
545
545
  */
546
- function deepEquals(o1, o2) {
546
+ function deepEquals(o1, o2, ignoreFunctions) {
547
547
  if (o1 === o2)
548
548
  return true;
549
549
  if ((o1 && !o2) || (o2 && !o1))
@@ -559,13 +559,16 @@ function deepEquals(o1, o2) {
559
559
  }
560
560
  }
561
561
  for (const key in o1) {
562
- if (typeof o1[key] !== typeof o2[key])
562
+ const typeOfO1Key = typeof o1[key];
563
+ if (typeOfO1Key !== typeof o2[key])
563
564
  return false;
564
- if (typeof o1[key] === "object") {
565
- if (!deepEquals(o1[key], o2[key]))
565
+ if (typeOfO1Key === "object") {
566
+ if (!deepEquals(o1[key], o2[key], ignoreFunctions))
566
567
  return false;
567
568
  }
568
569
  else {
570
+ if (ignoreFunctions && typeOfO1Key === "function")
571
+ return true;
569
572
  if (o1[key] !== o2[key])
570
573
  return false;
571
574
  }
@@ -3625,21 +3628,22 @@ function toZoneWithoutBoundaryChanges(xc) {
3625
3628
  xc = xc.split("!").at(-1);
3626
3629
  }
3627
3630
  if (xc.includes("$")) {
3628
- xc = xc.replace(/\$/g, "");
3631
+ xc = xc.replaceAll("$", "");
3629
3632
  }
3630
- let ranges;
3633
+ let firstRangePart = "";
3634
+ let secondRangePart;
3631
3635
  if (xc.includes(":")) {
3632
- ranges = xc.split(":").map((x) => x.trim());
3636
+ [firstRangePart, secondRangePart] = xc.split(":");
3637
+ firstRangePart = firstRangePart.trim();
3638
+ secondRangePart = secondRangePart.trim();
3633
3639
  }
3634
3640
  else {
3635
- ranges = [xc.trim()];
3641
+ firstRangePart = xc.trim();
3636
3642
  }
3637
3643
  let top, bottom, left, right;
3638
3644
  let fullCol = false;
3639
3645
  let fullRow = false;
3640
3646
  let hasHeader = false;
3641
- const firstRangePart = ranges[0];
3642
- const secondRangePart = ranges[1] && ranges[1];
3643
3647
  if (isColReference(firstRangePart)) {
3644
3648
  left = right = lettersToNumber(firstRangePart);
3645
3649
  top = bottom = 0;
@@ -3656,7 +3660,7 @@ function toZoneWithoutBoundaryChanges(xc) {
3656
3660
  top = bottom = c.row;
3657
3661
  hasHeader = true;
3658
3662
  }
3659
- if (ranges.length === 2) {
3663
+ if (secondRangePart) {
3660
3664
  if (isColReference(secondRangePart)) {
3661
3665
  right = lettersToNumber(secondRangePart);
3662
3666
  fullCol = true;
@@ -4830,6 +4834,7 @@ class ChartJsComponent extends owl.Component {
4830
4834
  };
4831
4835
  canvas = owl.useRef("graphContainer");
4832
4836
  chart;
4837
+ currentRuntime;
4833
4838
  get background() {
4834
4839
  return this.chartRuntime.background;
4835
4840
  }
@@ -4846,9 +4851,18 @@ class ChartJsComponent extends owl.Component {
4846
4851
  setup() {
4847
4852
  owl.onMounted(() => {
4848
4853
  const runtime = this.chartRuntime;
4849
- this.createChart(runtime.chartJsConfig);
4854
+ this.currentRuntime = runtime;
4855
+ // Note: chartJS modify the runtime in place, so it's important to give it a copy
4856
+ this.createChart(deepCopy(runtime.chartJsConfig));
4857
+ });
4858
+ owl.onWillUnmount(() => this.chart?.destroy());
4859
+ owl.useEffect(() => {
4860
+ const runtime = this.chartRuntime;
4861
+ if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
4862
+ this.currentRuntime = runtime;
4863
+ this.updateChartJs(deepCopy(runtime));
4864
+ }
4850
4865
  });
4851
- owl.useEffect(() => this.updateChartJs(this.chartRuntime), () => [this.chartRuntime]);
4852
4866
  }
4853
4867
  createChart(chartData) {
4854
4868
  const canvas = this.canvas.el;
@@ -4876,8 +4890,7 @@ class ChartJsComponent extends owl.Component {
4876
4890
  this.chart.config.options.plugins.tooltip = chartData.options.plugins.tooltip;
4877
4891
  this.chart.config.options.plugins.legend = chartData.options.plugins.legend;
4878
4892
  this.chart.config.options.scales = chartData.options?.scales;
4879
- // ?
4880
- this.chart.update("active");
4893
+ this.chart.update();
4881
4894
  }
4882
4895
  }
4883
4896
 
@@ -8440,7 +8453,7 @@ function truncateLabel(label) {
8440
8453
  /**
8441
8454
  * Get a default chart js configuration
8442
8455
  */
8443
- function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }) {
8456
+ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
8444
8457
  const options = {
8445
8458
  // https://www.chartjs.org/docs/latest/general/responsive.html
8446
8459
  responsive: true,
@@ -8487,7 +8500,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
8487
8500
  type: chart.type,
8488
8501
  options,
8489
8502
  data: {
8490
- labels: labels.map(truncateLabel),
8503
+ labels: truncateLabels ? labels.map(truncateLabel) : labels,
8491
8504
  datasets: [],
8492
8505
  },
8493
8506
  platform: undefined,
@@ -9370,9 +9383,9 @@ function canBeLinearChart(labelRange, getters) {
9370
9383
  }
9371
9384
  return true;
9372
9385
  }
9373
- function getLineConfiguration(chart, labels, localeFormat) {
9386
+ function getLineConfiguration(chart, labels, options) {
9374
9387
  const fontColor = chartFontColor(chart.background);
9375
- const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
9388
+ const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
9376
9389
  const legend = {
9377
9390
  labels: {
9378
9391
  color: fontColor,
@@ -9415,7 +9428,7 @@ function getLineConfiguration(chart, labels, localeFormat) {
9415
9428
  value = Number(value);
9416
9429
  if (isNaN(value))
9417
9430
  return value;
9418
- const { locale, format } = localeFormat;
9431
+ const { locale, format } = options;
9419
9432
  return formatValue(value, {
9420
9433
  locale,
9421
9434
  format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
@@ -9448,9 +9461,10 @@ function createLineChartRuntime(chart, getters) {
9448
9461
  ({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
9449
9462
  }
9450
9463
  const locale = getters.getLocale();
9464
+ const truncateLabels = axisType === "category";
9451
9465
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
9452
- const localeFormat = { format: dataSetFormat, locale };
9453
- const config = getLineConfiguration(chart, labels, localeFormat);
9466
+ const options = { format: dataSetFormat, locale, truncateLabels };
9467
+ const config = getLineConfiguration(chart, labels, options);
9454
9468
  const labelFormat = getChartLabelFormat(getters, chart.labelRange);
9455
9469
  if (axisType === "time") {
9456
9470
  const axis = {
@@ -28054,7 +28068,8 @@ class DataValidationOverlay extends owl.Component {
28054
28068
  get checkBoxCellPositions() {
28055
28069
  return this.env.model.getters
28056
28070
  .getVisibleCellPositions()
28057
- .filter(this.env.model.getters.isCellValidCheckbox);
28071
+ .filter((position) => this.env.model.getters.isCellValidCheckbox(position) &&
28072
+ !this.env.model.getters.isFilterHeader(position));
28058
28073
  }
28059
28074
  get listIconsCellPositions() {
28060
28075
  if (this.env.model.getters.isReadonly()) {
@@ -28062,7 +28077,8 @@ class DataValidationOverlay extends owl.Component {
28062
28077
  }
28063
28078
  return this.env.model.getters
28064
28079
  .getVisibleCellPositions()
28065
- .filter(this.env.model.getters.cellHasListDataValidationIcon);
28080
+ .filter((position) => this.env.model.getters.cellHasListDataValidationIcon(position) &&
28081
+ !this.env.model.getters.isFilterHeader(position));
28066
28082
  }
28067
28083
  }
28068
28084
 
@@ -42504,7 +42520,7 @@ class EvaluationPlugin extends UIPlugin {
42504
42520
  ? getItemId(newFormat, data.formats)
42505
42521
  : exportedCellData.format;
42506
42522
  let content;
42507
- if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42523
+ if (isExported && isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42508
42524
  content = formulaCell.contentWithFixedReferences;
42509
42525
  }
42510
42526
  else {
@@ -57718,6 +57734,6 @@ exports.setTranslationMethod = setTranslationMethod;
57718
57734
  exports.tokenize = tokenize;
57719
57735
 
57720
57736
 
57721
- __info__.version = "17.1.13";
57722
- __info__.date = "2024-04-26T07:39:54.100Z";
57723
- __info__.hash = "f2ea8c7";
57737
+ __info__.version = "17.1.14";
57738
+ __info__.date = "2024-05-07T10:41:25.690Z";
57739
+ __info__.hash = "622c47c";
@@ -6248,6 +6248,7 @@ declare class ChartJsComponent extends Component<Props$B, SpreadsheetChildEnv> {
6248
6248
  };
6249
6249
  private canvas;
6250
6250
  private chart?;
6251
+ private currentRuntime;
6251
6252
  get background(): string;
6252
6253
  get canvasStyle(): string;
6253
6254
  get chartRuntime(): ChartJSRuntime;
@@ -8536,7 +8537,9 @@ declare function chartFontColor(backgroundColor: Color | undefined): Color;
8536
8537
  /**
8537
8538
  * Get a default chart js configuration
8538
8539
  */
8539
- declare function getDefaultChartJsRuntime(chart: AbstractChart, labels: string[], fontColor: Color, { format, locale }: LocaleFormat): Required<ChartConfiguration>;
8540
+ declare function getDefaultChartJsRuntime(chart: AbstractChart, labels: string[], fontColor: Color, { format, locale, truncateLabels }: LocaleFormat & {
8541
+ truncateLabels?: boolean;
8542
+ }): Required<ChartConfiguration>;
8540
8543
  /** See https://www.chartjs.org/docs/latest/charts/area.html#filling-modes */
8541
8544
  declare function getFillingMode(index: number): "origin" | number;
8542
8545
 
@@ -2,12 +2,12 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.1.13
6
- * @date 2024-04-26T07:39:54.100Z
7
- * @hash f2ea8c7
5
+ * @version 17.1.14
6
+ * @date 2024-05-07T10:41:25.690Z
7
+ * @hash 622c47c
8
8
  */
9
9
 
10
- import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
10
+ import { Component, useRef, onMounted, onWillUnmount, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
11
11
 
12
12
  const CANVAS_SHIFT = 0.5;
13
13
  // Colors
@@ -541,7 +541,7 @@ function getAddHeaderStartIndex(position, base) {
541
541
  /**
542
542
  * Compares two objects.
543
543
  */
544
- function deepEquals(o1, o2) {
544
+ function deepEquals(o1, o2, ignoreFunctions) {
545
545
  if (o1 === o2)
546
546
  return true;
547
547
  if ((o1 && !o2) || (o2 && !o1))
@@ -557,13 +557,16 @@ function deepEquals(o1, o2) {
557
557
  }
558
558
  }
559
559
  for (const key in o1) {
560
- if (typeof o1[key] !== typeof o2[key])
560
+ const typeOfO1Key = typeof o1[key];
561
+ if (typeOfO1Key !== typeof o2[key])
561
562
  return false;
562
- if (typeof o1[key] === "object") {
563
- if (!deepEquals(o1[key], o2[key]))
563
+ if (typeOfO1Key === "object") {
564
+ if (!deepEquals(o1[key], o2[key], ignoreFunctions))
564
565
  return false;
565
566
  }
566
567
  else {
568
+ if (ignoreFunctions && typeOfO1Key === "function")
569
+ return true;
567
570
  if (o1[key] !== o2[key])
568
571
  return false;
569
572
  }
@@ -3623,21 +3626,22 @@ function toZoneWithoutBoundaryChanges(xc) {
3623
3626
  xc = xc.split("!").at(-1);
3624
3627
  }
3625
3628
  if (xc.includes("$")) {
3626
- xc = xc.replace(/\$/g, "");
3629
+ xc = xc.replaceAll("$", "");
3627
3630
  }
3628
- let ranges;
3631
+ let firstRangePart = "";
3632
+ let secondRangePart;
3629
3633
  if (xc.includes(":")) {
3630
- ranges = xc.split(":").map((x) => x.trim());
3634
+ [firstRangePart, secondRangePart] = xc.split(":");
3635
+ firstRangePart = firstRangePart.trim();
3636
+ secondRangePart = secondRangePart.trim();
3631
3637
  }
3632
3638
  else {
3633
- ranges = [xc.trim()];
3639
+ firstRangePart = xc.trim();
3634
3640
  }
3635
3641
  let top, bottom, left, right;
3636
3642
  let fullCol = false;
3637
3643
  let fullRow = false;
3638
3644
  let hasHeader = false;
3639
- const firstRangePart = ranges[0];
3640
- const secondRangePart = ranges[1] && ranges[1];
3641
3645
  if (isColReference(firstRangePart)) {
3642
3646
  left = right = lettersToNumber(firstRangePart);
3643
3647
  top = bottom = 0;
@@ -3654,7 +3658,7 @@ function toZoneWithoutBoundaryChanges(xc) {
3654
3658
  top = bottom = c.row;
3655
3659
  hasHeader = true;
3656
3660
  }
3657
- if (ranges.length === 2) {
3661
+ if (secondRangePart) {
3658
3662
  if (isColReference(secondRangePart)) {
3659
3663
  right = lettersToNumber(secondRangePart);
3660
3664
  fullCol = true;
@@ -4828,6 +4832,7 @@ class ChartJsComponent extends Component {
4828
4832
  };
4829
4833
  canvas = useRef("graphContainer");
4830
4834
  chart;
4835
+ currentRuntime;
4831
4836
  get background() {
4832
4837
  return this.chartRuntime.background;
4833
4838
  }
@@ -4844,9 +4849,18 @@ class ChartJsComponent extends Component {
4844
4849
  setup() {
4845
4850
  onMounted(() => {
4846
4851
  const runtime = this.chartRuntime;
4847
- this.createChart(runtime.chartJsConfig);
4852
+ this.currentRuntime = runtime;
4853
+ // Note: chartJS modify the runtime in place, so it's important to give it a copy
4854
+ this.createChart(deepCopy(runtime.chartJsConfig));
4855
+ });
4856
+ onWillUnmount(() => this.chart?.destroy());
4857
+ useEffect(() => {
4858
+ const runtime = this.chartRuntime;
4859
+ if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
4860
+ this.currentRuntime = runtime;
4861
+ this.updateChartJs(deepCopy(runtime));
4862
+ }
4848
4863
  });
4849
- useEffect(() => this.updateChartJs(this.chartRuntime), () => [this.chartRuntime]);
4850
4864
  }
4851
4865
  createChart(chartData) {
4852
4866
  const canvas = this.canvas.el;
@@ -4874,8 +4888,7 @@ class ChartJsComponent extends Component {
4874
4888
  this.chart.config.options.plugins.tooltip = chartData.options.plugins.tooltip;
4875
4889
  this.chart.config.options.plugins.legend = chartData.options.plugins.legend;
4876
4890
  this.chart.config.options.scales = chartData.options?.scales;
4877
- // ?
4878
- this.chart.update("active");
4891
+ this.chart.update();
4879
4892
  }
4880
4893
  }
4881
4894
 
@@ -8438,7 +8451,7 @@ function truncateLabel(label) {
8438
8451
  /**
8439
8452
  * Get a default chart js configuration
8440
8453
  */
8441
- function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }) {
8454
+ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
8442
8455
  const options = {
8443
8456
  // https://www.chartjs.org/docs/latest/general/responsive.html
8444
8457
  responsive: true,
@@ -8485,7 +8498,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
8485
8498
  type: chart.type,
8486
8499
  options,
8487
8500
  data: {
8488
- labels: labels.map(truncateLabel),
8501
+ labels: truncateLabels ? labels.map(truncateLabel) : labels,
8489
8502
  datasets: [],
8490
8503
  },
8491
8504
  platform: undefined,
@@ -9368,9 +9381,9 @@ function canBeLinearChart(labelRange, getters) {
9368
9381
  }
9369
9382
  return true;
9370
9383
  }
9371
- function getLineConfiguration(chart, labels, localeFormat) {
9384
+ function getLineConfiguration(chart, labels, options) {
9372
9385
  const fontColor = chartFontColor(chart.background);
9373
- const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
9386
+ const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
9374
9387
  const legend = {
9375
9388
  labels: {
9376
9389
  color: fontColor,
@@ -9413,7 +9426,7 @@ function getLineConfiguration(chart, labels, localeFormat) {
9413
9426
  value = Number(value);
9414
9427
  if (isNaN(value))
9415
9428
  return value;
9416
- const { locale, format } = localeFormat;
9429
+ const { locale, format } = options;
9417
9430
  return formatValue(value, {
9418
9431
  locale,
9419
9432
  format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
@@ -9446,9 +9459,10 @@ function createLineChartRuntime(chart, getters) {
9446
9459
  ({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
9447
9460
  }
9448
9461
  const locale = getters.getLocale();
9462
+ const truncateLabels = axisType === "category";
9449
9463
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
9450
- const localeFormat = { format: dataSetFormat, locale };
9451
- const config = getLineConfiguration(chart, labels, localeFormat);
9464
+ const options = { format: dataSetFormat, locale, truncateLabels };
9465
+ const config = getLineConfiguration(chart, labels, options);
9452
9466
  const labelFormat = getChartLabelFormat(getters, chart.labelRange);
9453
9467
  if (axisType === "time") {
9454
9468
  const axis = {
@@ -28052,7 +28066,8 @@ class DataValidationOverlay extends Component {
28052
28066
  get checkBoxCellPositions() {
28053
28067
  return this.env.model.getters
28054
28068
  .getVisibleCellPositions()
28055
- .filter(this.env.model.getters.isCellValidCheckbox);
28069
+ .filter((position) => this.env.model.getters.isCellValidCheckbox(position) &&
28070
+ !this.env.model.getters.isFilterHeader(position));
28056
28071
  }
28057
28072
  get listIconsCellPositions() {
28058
28073
  if (this.env.model.getters.isReadonly()) {
@@ -28060,7 +28075,8 @@ class DataValidationOverlay extends Component {
28060
28075
  }
28061
28076
  return this.env.model.getters
28062
28077
  .getVisibleCellPositions()
28063
- .filter(this.env.model.getters.cellHasListDataValidationIcon);
28078
+ .filter((position) => this.env.model.getters.cellHasListDataValidationIcon(position) &&
28079
+ !this.env.model.getters.isFilterHeader(position));
28064
28080
  }
28065
28081
  }
28066
28082
 
@@ -42502,7 +42518,7 @@ class EvaluationPlugin extends UIPlugin {
42502
42518
  ? getItemId(newFormat, data.formats)
42503
42519
  : exportedCellData.format;
42504
42520
  let content;
42505
- if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42521
+ if (isExported && isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42506
42522
  content = formulaCell.contentWithFixedReferences;
42507
42523
  }
42508
42524
  else {
@@ -57680,6 +57696,6 @@ const constants = {
57680
57696
  export { AbstractChart, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57681
57697
 
57682
57698
 
57683
- __info__.version = "17.1.13";
57684
- __info__.date = "2024-04-26T07:39:54.100Z";
57685
- __info__.hash = "f2ea8c7";
57699
+ __info__.version = "17.1.14";
57700
+ __info__.date = "2024-05-07T10:41:25.690Z";
57701
+ __info__.hash = "622c47c";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.1.13
6
- * @date 2024-04-26T07:39:54.100Z
7
- * @hash f2ea8c7
5
+ * @version 17.1.14
6
+ * @date 2024-05-07T10:41:25.690Z
7
+ * @hash 622c47c
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -542,7 +542,7 @@
542
542
  /**
543
543
  * Compares two objects.
544
544
  */
545
- function deepEquals(o1, o2) {
545
+ function deepEquals(o1, o2, ignoreFunctions) {
546
546
  if (o1 === o2)
547
547
  return true;
548
548
  if ((o1 && !o2) || (o2 && !o1))
@@ -558,13 +558,16 @@
558
558
  }
559
559
  }
560
560
  for (const key in o1) {
561
- if (typeof o1[key] !== typeof o2[key])
561
+ const typeOfO1Key = typeof o1[key];
562
+ if (typeOfO1Key !== typeof o2[key])
562
563
  return false;
563
- if (typeof o1[key] === "object") {
564
- if (!deepEquals(o1[key], o2[key]))
564
+ if (typeOfO1Key === "object") {
565
+ if (!deepEquals(o1[key], o2[key], ignoreFunctions))
565
566
  return false;
566
567
  }
567
568
  else {
569
+ if (ignoreFunctions && typeOfO1Key === "function")
570
+ return true;
568
571
  if (o1[key] !== o2[key])
569
572
  return false;
570
573
  }
@@ -3624,21 +3627,22 @@
3624
3627
  xc = xc.split("!").at(-1);
3625
3628
  }
3626
3629
  if (xc.includes("$")) {
3627
- xc = xc.replace(/\$/g, "");
3630
+ xc = xc.replaceAll("$", "");
3628
3631
  }
3629
- let ranges;
3632
+ let firstRangePart = "";
3633
+ let secondRangePart;
3630
3634
  if (xc.includes(":")) {
3631
- ranges = xc.split(":").map((x) => x.trim());
3635
+ [firstRangePart, secondRangePart] = xc.split(":");
3636
+ firstRangePart = firstRangePart.trim();
3637
+ secondRangePart = secondRangePart.trim();
3632
3638
  }
3633
3639
  else {
3634
- ranges = [xc.trim()];
3640
+ firstRangePart = xc.trim();
3635
3641
  }
3636
3642
  let top, bottom, left, right;
3637
3643
  let fullCol = false;
3638
3644
  let fullRow = false;
3639
3645
  let hasHeader = false;
3640
- const firstRangePart = ranges[0];
3641
- const secondRangePart = ranges[1] && ranges[1];
3642
3646
  if (isColReference(firstRangePart)) {
3643
3647
  left = right = lettersToNumber(firstRangePart);
3644
3648
  top = bottom = 0;
@@ -3655,7 +3659,7 @@
3655
3659
  top = bottom = c.row;
3656
3660
  hasHeader = true;
3657
3661
  }
3658
- if (ranges.length === 2) {
3662
+ if (secondRangePart) {
3659
3663
  if (isColReference(secondRangePart)) {
3660
3664
  right = lettersToNumber(secondRangePart);
3661
3665
  fullCol = true;
@@ -4829,6 +4833,7 @@
4829
4833
  };
4830
4834
  canvas = owl.useRef("graphContainer");
4831
4835
  chart;
4836
+ currentRuntime;
4832
4837
  get background() {
4833
4838
  return this.chartRuntime.background;
4834
4839
  }
@@ -4845,9 +4850,18 @@
4845
4850
  setup() {
4846
4851
  owl.onMounted(() => {
4847
4852
  const runtime = this.chartRuntime;
4848
- this.createChart(runtime.chartJsConfig);
4853
+ this.currentRuntime = runtime;
4854
+ // Note: chartJS modify the runtime in place, so it's important to give it a copy
4855
+ this.createChart(deepCopy(runtime.chartJsConfig));
4856
+ });
4857
+ owl.onWillUnmount(() => this.chart?.destroy());
4858
+ owl.useEffect(() => {
4859
+ const runtime = this.chartRuntime;
4860
+ if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
4861
+ this.currentRuntime = runtime;
4862
+ this.updateChartJs(deepCopy(runtime));
4863
+ }
4849
4864
  });
4850
- owl.useEffect(() => this.updateChartJs(this.chartRuntime), () => [this.chartRuntime]);
4851
4865
  }
4852
4866
  createChart(chartData) {
4853
4867
  const canvas = this.canvas.el;
@@ -4875,8 +4889,7 @@
4875
4889
  this.chart.config.options.plugins.tooltip = chartData.options.plugins.tooltip;
4876
4890
  this.chart.config.options.plugins.legend = chartData.options.plugins.legend;
4877
4891
  this.chart.config.options.scales = chartData.options?.scales;
4878
- // ?
4879
- this.chart.update("active");
4892
+ this.chart.update();
4880
4893
  }
4881
4894
  }
4882
4895
 
@@ -8439,7 +8452,7 @@
8439
8452
  /**
8440
8453
  * Get a default chart js configuration
8441
8454
  */
8442
- function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }) {
8455
+ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
8443
8456
  const options = {
8444
8457
  // https://www.chartjs.org/docs/latest/general/responsive.html
8445
8458
  responsive: true,
@@ -8486,7 +8499,7 @@
8486
8499
  type: chart.type,
8487
8500
  options,
8488
8501
  data: {
8489
- labels: labels.map(truncateLabel),
8502
+ labels: truncateLabels ? labels.map(truncateLabel) : labels,
8490
8503
  datasets: [],
8491
8504
  },
8492
8505
  platform: undefined,
@@ -9369,9 +9382,9 @@
9369
9382
  }
9370
9383
  return true;
9371
9384
  }
9372
- function getLineConfiguration(chart, labels, localeFormat) {
9385
+ function getLineConfiguration(chart, labels, options) {
9373
9386
  const fontColor = chartFontColor(chart.background);
9374
- const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
9387
+ const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
9375
9388
  const legend = {
9376
9389
  labels: {
9377
9390
  color: fontColor,
@@ -9414,7 +9427,7 @@
9414
9427
  value = Number(value);
9415
9428
  if (isNaN(value))
9416
9429
  return value;
9417
- const { locale, format } = localeFormat;
9430
+ const { locale, format } = options;
9418
9431
  return formatValue(value, {
9419
9432
  locale,
9420
9433
  format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
@@ -9447,9 +9460,10 @@
9447
9460
  ({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
9448
9461
  }
9449
9462
  const locale = getters.getLocale();
9463
+ const truncateLabels = axisType === "category";
9450
9464
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
9451
- const localeFormat = { format: dataSetFormat, locale };
9452
- const config = getLineConfiguration(chart, labels, localeFormat);
9465
+ const options = { format: dataSetFormat, locale, truncateLabels };
9466
+ const config = getLineConfiguration(chart, labels, options);
9453
9467
  const labelFormat = getChartLabelFormat(getters, chart.labelRange);
9454
9468
  if (axisType === "time") {
9455
9469
  const axis = {
@@ -28053,7 +28067,8 @@
28053
28067
  get checkBoxCellPositions() {
28054
28068
  return this.env.model.getters
28055
28069
  .getVisibleCellPositions()
28056
- .filter(this.env.model.getters.isCellValidCheckbox);
28070
+ .filter((position) => this.env.model.getters.isCellValidCheckbox(position) &&
28071
+ !this.env.model.getters.isFilterHeader(position));
28057
28072
  }
28058
28073
  get listIconsCellPositions() {
28059
28074
  if (this.env.model.getters.isReadonly()) {
@@ -28061,7 +28076,8 @@
28061
28076
  }
28062
28077
  return this.env.model.getters
28063
28078
  .getVisibleCellPositions()
28064
- .filter(this.env.model.getters.cellHasListDataValidationIcon);
28079
+ .filter((position) => this.env.model.getters.cellHasListDataValidationIcon(position) &&
28080
+ !this.env.model.getters.isFilterHeader(position));
28065
28081
  }
28066
28082
  }
28067
28083
 
@@ -42503,7 +42519,7 @@
42503
42519
  ? getItemId(newFormat, data.formats)
42504
42520
  : exportedCellData.format;
42505
42521
  let content;
42506
- if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42522
+ if (isExported && isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42507
42523
  content = formulaCell.contentWithFixedReferences;
42508
42524
  }
42509
42525
  else {
@@ -57717,9 +57733,9 @@
57717
57733
  exports.tokenize = tokenize;
57718
57734
 
57719
57735
 
57720
- __info__.version = "17.1.13";
57721
- __info__.date = "2024-04-26T07:39:54.100Z";
57722
- __info__.hash = "f2ea8c7";
57736
+ __info__.version = "17.1.14";
57737
+ __info__.date = "2024-05-07T10:41:25.690Z";
57738
+ __info__.hash = "622c47c";
57723
57739
 
57724
57740
 
57725
57741
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);