@odoo/o-spreadsheet 16.3.1 → 16.3.3

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.
@@ -1773,6 +1773,7 @@ function removeTrailingZeroes(numberString) {
1773
1773
  }
1774
1774
  return numberString.slice(0, i + 1) || undefined;
1775
1775
  }
1776
+ const leadingZeroesRegexp = /^0+/;
1776
1777
  /**
1777
1778
  * Limit the size of the decimal part of a number to the given number of digits.
1778
1779
  */
@@ -1783,17 +1784,24 @@ function limitDecimalDigits(decimalDigits, maxDecimals) {
1783
1784
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1784
1785
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1785
1786
  const i = maxDecimals;
1786
- if (Number(Number(decimalDigits[i]) < 5)) {
1787
+ if (Number(decimalDigits[i]) < 5) {
1787
1788
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1788
1789
  }
1789
1790
  // round up
1791
+ const leadingZeroes = slicedDecimalDigits.match(leadingZeroesRegexp)?.[0] || "";
1790
1792
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1791
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1792
- integerDigits = (Number(integerDigits) + 1).toString();
1793
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1794
+ // e.g. carry over from 99 to 100
1795
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1796
+ if (carryOver && !leadingZeroes) {
1797
+ integerDigits = "1";
1793
1798
  resultDecimalDigits = undefined;
1794
1799
  }
1800
+ else if (carryOver) {
1801
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1802
+ }
1795
1803
  else {
1796
- resultDecimalDigits = slicedRoundedUp;
1804
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1797
1805
  }
1798
1806
  return { integerDigits, decimalDigits: resultDecimalDigits };
1799
1807
  }
@@ -17840,7 +17848,7 @@ class LineBarPieConfigPanel extends Component {
17840
17848
  return !!this.state.labelsDispatchResult?.isCancelledBecause(33 /* CommandResult.InvalidLabelRange */);
17841
17849
  }
17842
17850
  onUpdateDataSetsHaveTitle(ev) {
17843
- this.props.updateChart({
17851
+ this.props.updateChart(this.props.figureId, {
17844
17852
  dataSetsHaveTitle: ev.target.checked,
17845
17853
  });
17846
17854
  }
@@ -17852,7 +17860,7 @@ class LineBarPieConfigPanel extends Component {
17852
17860
  this.dataSeriesRanges = ranges;
17853
17861
  }
17854
17862
  onDataSeriesConfirmed() {
17855
- this.state.datasetDispatchResult = this.props.updateChart({
17863
+ this.state.datasetDispatchResult = this.props.updateChart(this.props.figureId, {
17856
17864
  dataSets: this.dataSeriesRanges,
17857
17865
  });
17858
17866
  }
@@ -17864,12 +17872,12 @@ class LineBarPieConfigPanel extends Component {
17864
17872
  this.labelRange = ranges[0];
17865
17873
  }
17866
17874
  onLabelRangeConfirmed() {
17867
- this.state.labelsDispatchResult = this.props.updateChart({
17875
+ this.state.labelsDispatchResult = this.props.updateChart(this.props.figureId, {
17868
17876
  labelRange: this.labelRange,
17869
17877
  });
17870
17878
  }
17871
17879
  onUpdateAggregated(ev) {
17872
- this.props.updateChart({
17880
+ this.props.updateChart(this.props.figureId, {
17873
17881
  aggregated: ev.target.checked,
17874
17882
  });
17875
17883
  }
@@ -17899,12 +17907,12 @@ LineBarPieConfigPanel.props = {
17899
17907
  class BarConfigPanel extends LineBarPieConfigPanel {
17900
17908
  static template = "o-spreadsheet-BarConfigPanel";
17901
17909
  onUpdateStacked(ev) {
17902
- this.props.updateChart({
17910
+ this.props.updateChart(this.props.figureId, {
17903
17911
  stacked: ev.target.checked,
17904
17912
  });
17905
17913
  }
17906
17914
  onUpdateAggregated(ev) {
17907
- this.props.updateChart({
17915
+ this.props.updateChart(this.props.figureId, {
17908
17916
  aggregated: ev.target.checked,
17909
17917
  });
17910
17918
  }
@@ -17944,6 +17952,7 @@ css /* scss */ `
17944
17952
  .o-color-picker-toggler-button {
17945
17953
  display: flex;
17946
17954
  .o-color-picker-toggler-sign {
17955
+ display: flex;
17947
17956
  margin: auto auto;
17948
17957
  width: 55%;
17949
17958
  height: 55%;
@@ -18241,17 +18250,17 @@ class LineBarPieDesignPanel extends Component {
18241
18250
  this.state.fillColorTool = !this.state.fillColorTool;
18242
18251
  }
18243
18252
  updateBackgroundColor(color) {
18244
- this.props.updateChart({
18253
+ this.props.updateChart(this.props.figureId, {
18245
18254
  background: color,
18246
18255
  });
18247
18256
  }
18248
18257
  updateTitle(ev) {
18249
- this.props.updateChart({
18258
+ this.props.updateChart(this.props.figureId, {
18250
18259
  title: ev.target.value,
18251
18260
  });
18252
18261
  }
18253
18262
  updateSelect(attr, ev) {
18254
- this.props.updateChart({
18263
+ this.props.updateChart(this.props.figureId, {
18255
18264
  [attr]: ev.target.value,
18256
18265
  });
18257
18266
  }
@@ -18284,7 +18293,7 @@ class GaugeChartConfigPanel extends Component {
18284
18293
  this.dataRange = ranges[0];
18285
18294
  }
18286
18295
  updateDataRange() {
18287
- this.state.dataRangeDispatchResult = this.props.updateChart({
18296
+ this.state.dataRangeDispatchResult = this.props.updateChart(this.props.figureId, {
18288
18297
  dataRange: this.dataRange,
18289
18298
  });
18290
18299
  }
@@ -18342,12 +18351,12 @@ class GaugeChartDesignPanel extends Component {
18342
18351
  }
18343
18352
  updateBackgroundColor(color) {
18344
18353
  this.state.openedMenu = undefined;
18345
- this.props.updateChart({
18354
+ this.props.updateChart(this.props.figureId, {
18346
18355
  background: color,
18347
18356
  });
18348
18357
  }
18349
18358
  updateTitle(ev) {
18350
- this.props.updateChart({
18359
+ this.props.updateChart(this.props.figureId, {
18351
18360
  title: ev.target.value,
18352
18361
  });
18353
18362
  }
@@ -18412,7 +18421,7 @@ class GaugeChartDesignPanel extends Component {
18412
18421
  }
18413
18422
  }
18414
18423
  updateSectionRule(sectionRule) {
18415
- this.state.sectionRuleDispatchResult = this.props.updateChart({
18424
+ this.state.sectionRuleDispatchResult = this.props.updateChart(this.props.figureId, {
18416
18425
  sectionRule,
18417
18426
  });
18418
18427
  }
@@ -18436,17 +18445,17 @@ class LineConfigPanel extends LineBarPieConfigPanel {
18436
18445
  return false;
18437
18446
  }
18438
18447
  onUpdateLabelsAsText(ev) {
18439
- this.props.updateChart({
18448
+ this.props.updateChart(this.props.figureId, {
18440
18449
  labelsAsText: ev.target.checked,
18441
18450
  });
18442
18451
  }
18443
18452
  onUpdateStacked(ev) {
18444
- this.props.updateChart({
18453
+ this.props.updateChart(this.props.figureId, {
18445
18454
  stacked: ev.target.checked,
18446
18455
  });
18447
18456
  }
18448
18457
  onUpdateAggregated(ev) {
18449
- this.props.updateChart({
18458
+ this.props.updateChart(this.props.figureId, {
18450
18459
  aggregated: ev.target.checked,
18451
18460
  });
18452
18461
  }
@@ -18482,7 +18491,7 @@ class ScorecardChartConfigPanel extends Component {
18482
18491
  this.keyValue = ranges[0];
18483
18492
  }
18484
18493
  updateKeyValueRange() {
18485
- this.state.keyValueDispatchResult = this.props.updateChart({
18494
+ this.state.keyValueDispatchResult = this.props.updateChart(this.props.figureId, {
18486
18495
  keyValue: this.keyValue,
18487
18496
  });
18488
18497
  }
@@ -18490,12 +18499,12 @@ class ScorecardChartConfigPanel extends Component {
18490
18499
  this.baseline = ranges[0];
18491
18500
  }
18492
18501
  updateBaselineRange() {
18493
- this.state.baselineDispatchResult = this.props.updateChart({
18502
+ this.state.baselineDispatchResult = this.props.updateChart(this.props.figureId, {
18494
18503
  baseline: this.baseline,
18495
18504
  });
18496
18505
  }
18497
18506
  updateBaselineMode(ev) {
18498
- this.props.updateChart({ baselineMode: ev.target.value });
18507
+ this.props.updateChart(this.props.figureId, { baselineMode: ev.target.value });
18499
18508
  }
18500
18509
  }
18501
18510
  ScorecardChartConfigPanel.props = {
@@ -18514,12 +18523,12 @@ class ScorecardChartDesignPanel extends Component {
18514
18523
  useExternalListener(window, "click", this.closeMenus);
18515
18524
  }
18516
18525
  updateTitle(ev) {
18517
- this.props.updateChart({
18526
+ this.props.updateChart(this.props.figureId, {
18518
18527
  title: ev.target.value,
18519
18528
  });
18520
18529
  }
18521
18530
  updateBaselineDescr(ev) {
18522
- this.props.updateChart({ baselineDescr: ev.target.value });
18531
+ this.props.updateChart(this.props.figureId, { baselineDescr: ev.target.value });
18523
18532
  }
18524
18533
  toggleColorPicker(colorPickerId) {
18525
18534
  if (this.state.openedColorPicker === colorPickerId) {
@@ -18532,13 +18541,13 @@ class ScorecardChartDesignPanel extends Component {
18532
18541
  setColor(color, colorPickerId) {
18533
18542
  switch (colorPickerId) {
18534
18543
  case "backgroundColor":
18535
- this.props.updateChart({ background: color });
18544
+ this.props.updateChart(this.props.figureId, { background: color });
18536
18545
  break;
18537
18546
  case "baselineColorDown":
18538
- this.props.updateChart({ baselineColorDown: color });
18547
+ this.props.updateChart(this.props.figureId, { baselineColorDown: color });
18539
18548
  break;
18540
18549
  case "baselineColorUp":
18541
- this.props.updateChart({ baselineColorUp: color });
18550
+ this.props.updateChart(this.props.figureId, { baselineColorUp: color });
18542
18551
  break;
18543
18552
  }
18544
18553
  this.closeMenus();
@@ -18603,13 +18612,9 @@ css /* scss */ `
18603
18612
  class ChartPanel extends Component {
18604
18613
  static template = "o-spreadsheet-ChartPanel";
18605
18614
  state;
18606
- shouldUpdateChart = true;
18607
18615
  get figureId() {
18608
18616
  return this.state.figureId;
18609
18617
  }
18610
- get sheetId() {
18611
- return this.state.sheetId;
18612
- }
18613
18618
  setup() {
18614
18619
  const selectedFigureId = this.env.model.getters.getSelectedFigureId();
18615
18620
  if (!selectedFigureId) {
@@ -18619,17 +18624,11 @@ class ChartPanel extends Component {
18619
18624
  this.state = useState({
18620
18625
  panel: "configuration",
18621
18626
  figureId: selectedFigureId,
18622
- sheetId: this.env.model.getters.getActiveSheetId(),
18623
18627
  });
18624
18628
  onWillUpdateProps(() => {
18625
18629
  const selectedFigureId = this.env.model.getters.getSelectedFigureId();
18626
18630
  if (selectedFigureId && selectedFigureId !== this.state.figureId) {
18627
18631
  this.state.figureId = selectedFigureId;
18628
- this.state.sheetId = this.env.model.getters.getActiveSheetId();
18629
- this.shouldUpdateChart = false;
18630
- }
18631
- else {
18632
- this.shouldUpdateChart = true;
18633
18632
  }
18634
18633
  if (!this.env.model.getters.isChartDefined(this.figureId)) {
18635
18634
  this.props.onCloseSidePanel();
@@ -18637,8 +18636,8 @@ class ChartPanel extends Component {
18637
18636
  }
18638
18637
  });
18639
18638
  }
18640
- updateChart(updateDefinition) {
18641
- if (!this.shouldUpdateChart) {
18639
+ updateChart(figureId, updateDefinition) {
18640
+ if (figureId !== this.figureId) {
18642
18641
  return;
18643
18642
  }
18644
18643
  const definition = {
@@ -18647,8 +18646,8 @@ class ChartPanel extends Component {
18647
18646
  };
18648
18647
  return this.env.model.dispatch("UPDATE_CHART", {
18649
18648
  definition,
18650
- id: this.figureId,
18651
- sheetId: this.sheetId,
18649
+ id: figureId,
18650
+ sheetId: this.env.model.getters.getFigureSheetId(figureId),
18652
18651
  });
18653
18652
  }
18654
18653
  onTypeChange(type) {
@@ -18660,7 +18659,7 @@ class ChartPanel extends Component {
18660
18659
  this.env.model.dispatch("UPDATE_CHART", {
18661
18660
  definition,
18662
18661
  id: this.figureId,
18663
- sheetId: this.sheetId,
18662
+ sheetId: this.env.model.getters.getFigureSheetId(this.figureId),
18664
18663
  });
18665
18664
  }
18666
18665
  get chartPanel() {
@@ -24481,6 +24480,16 @@ const XLSX_INDEXED_COLORS = {
24481
24480
  63: "333333",
24482
24481
  64: "000000",
24483
24482
  65: "FFFFFF", // system background
24483
+ };
24484
+ const IMAGE_MIMETYPE_EXTENSION_MAPPING = {
24485
+ "image/avif": "avif",
24486
+ "image/bmp": "bmp",
24487
+ "image/gif": "gif",
24488
+ "image/vnd.microsoft.icon": "ico",
24489
+ "image/jpeg": "jpeg",
24490
+ "image/png": "png",
24491
+ "image/tiff": "tiff",
24492
+ "image/webp": "webp",
24484
24493
  };
24485
24494
 
24486
24495
  /**
@@ -26962,6 +26971,11 @@ function createOverride(partName, contentType) {
26962
26971
  <Override ContentType="${contentType}" PartName="${partName}" />
26963
26972
  `;
26964
26973
  }
26974
+ function createDefaultXMLElement(extension, contentType) {
26975
+ return escapeXml /*xml*/ `
26976
+ <Default Extension="${extension}" ContentType="${contentType}" />
26977
+ `;
26978
+ }
26965
26979
  function joinXmlNodes(xmlNodes) {
26966
26980
  return new XMLString(xmlNodes.join("\n"));
26967
26981
  }
@@ -41729,7 +41743,7 @@ class ImageProvider {
41729
41743
  const file = await this.getImageFromUser();
41730
41744
  const path = await this.fileStore.upload(file);
41731
41745
  const size = await this.getImageSize(path);
41732
- return { path, size };
41746
+ return { path, size, mimetype: file.type };
41733
41747
  }
41734
41748
  getImageFromUser() {
41735
41749
  return new Promise((resolve, reject) => {
@@ -46810,8 +46824,7 @@ function createWorksheets(data, construct) {
46810
46824
  // Figures and Charts
46811
46825
  let drawingNode = escapeXml ``;
46812
46826
  const drawingRelIds = [];
46813
- const charts = sheet.charts;
46814
- for (const chart of charts) {
46827
+ for (const chart of sheet.charts) {
46815
46828
  const xlsxChartId = convertChartId(chart.id);
46816
46829
  const chartRelId = addRelsToFile(construct.relsFiles, `xl/drawings/_rels/drawing${sheetIndex}.xml.rels`, {
46817
46830
  target: `../charts/chart${xlsxChartId}.xml`,
@@ -46820,20 +46833,27 @@ function createWorksheets(data, construct) {
46820
46833
  drawingRelIds.push(chartRelId);
46821
46834
  files.push(createXMLFile(createChart(chart, sheetIndex, data), `xl/charts/chart${xlsxChartId}.xml`, "chart"));
46822
46835
  }
46823
- const images = sheet.images;
46824
- for (const image of images) {
46836
+ for (const image of sheet.images) {
46837
+ const mimeType = image.data.mimetype;
46838
+ if (mimeType === undefined)
46839
+ continue;
46840
+ const extension = IMAGE_MIMETYPE_EXTENSION_MAPPING[mimeType];
46841
+ // only support exporting images with mimetypes specified in the mapping
46842
+ if (extension === undefined)
46843
+ continue;
46825
46844
  const xlsxImageId = convertImageId(image.id);
46845
+ let imageFileName = `image${xlsxImageId}.${extension}`;
46826
46846
  const imageRelId = addRelsToFile(construct.relsFiles, `xl/drawings/_rels/drawing${sheetIndex}.xml.rels`, {
46827
- target: `../media/image${xlsxImageId}`,
46847
+ target: `../media/${imageFileName}`,
46828
46848
  type: XLSX_RELATION_TYPE.image,
46829
46849
  });
46830
46850
  drawingRelIds.push(imageRelId);
46831
46851
  files.push({
46832
- path: `xl/media/image${xlsxImageId}`,
46833
- imagePath: image.data.path,
46852
+ path: `xl/media/${imageFileName}`,
46853
+ imageSrc: image.data.path,
46834
46854
  });
46835
46855
  }
46836
- const drawings = [...charts, ...images];
46856
+ const drawings = [...sheet.charts, ...sheet.images];
46837
46857
  if (drawings.length) {
46838
46858
  const drawingRelId = addRelsToFile(construct.relsFiles, `xl/worksheets/_rels/sheet${sheetIndex}.xml.rels`, {
46839
46859
  target: `../drawings/drawing${sheetIndex}.xml`,
@@ -46952,6 +46972,8 @@ function createRelsFiles(relsFiles) {
46952
46972
  }
46953
46973
  function createContentTypes(files) {
46954
46974
  const overrideNodes = [];
46975
+ // hard-code supported image mimetypes
46976
+ const imageDefaultNodes = Object.entries(IMAGE_MIMETYPE_EXTENSION_MAPPING).map(([mimetype, extension]) => createDefaultXMLElement(extension, mimetype));
46955
46977
  for (const file of files) {
46956
46978
  if ("contentType" in file && file.contentType) {
46957
46979
  overrideNodes.push(createOverride("/" + file.path, CONTENT_TYPES[file.contentType]));
@@ -46967,6 +46989,7 @@ function createContentTypes(files) {
46967
46989
  ];
46968
46990
  const xml = escapeXml /*xml*/ `
46969
46991
  <Types xmlns="${NAMESPACE["Types"]}">
46992
+ ${joinXmlNodes(Object.values(imageDefaultNodes))}
46970
46993
  <Default ${formatAttributes(relsAttributes)} />
46971
46994
  <Default ${formatAttributes(xmlAttributes)} />
46972
46995
  ${joinXmlNodes(overrideNodes)}
@@ -47551,6 +47574,6 @@ function addFunction(functionName, functionDescription) {
47551
47574
  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 };
47552
47575
 
47553
47576
 
47554
- __info__.version = '16.3.1';
47555
- __info__.date = '2023-05-25T13:00:27.320Z';
47556
- __info__.hash = 'b3cfd2c';
47577
+ __info__.version = '16.3.3';
47578
+ __info__.date = '2023-06-12T13:50:01.114Z';
47579
+ __info__.hash = 'd3ab96f';