@odoo/o-spreadsheet 17.4.0-alpha.1 → 17.4.0-alpha.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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.4.0-alpha.1
7
- * @date 2024-06-03T15:30:28.283Z
8
- * @hash cb56c37
6
+ * @version 17.4.0-alpha.3
7
+ * @date 2024-06-10T09:38:53.982Z
8
+ * @hash a45ed6a
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -310,7 +310,10 @@
310
310
  * Check if the object is a plain old javascript object.
311
311
  */
312
312
  function isPlainObject(obj) {
313
- return typeof obj === "object" && obj?.constructor === Object;
313
+ return (typeof obj === "object" &&
314
+ obj !== null &&
315
+ // obj.constructor can be undefined when there's no prototype (`Object.create(null, {})`)
316
+ (obj?.constructor === Object || obj?.constructor === undefined));
314
317
  }
315
318
  /**
316
319
  * Sanitize the name of a sheet, by eventually removing quotes
@@ -18376,6 +18379,131 @@ stores.inject(MyMetaStore, storeInstance);
18376
18379
  const supportedPivotExplodedFormulaRegistry = new Registry();
18377
18380
  supportedPivotExplodedFormulaRegistry.add("SPREADSHEET", false);
18378
18381
 
18382
+ const AGGREGATOR_NAMES = {
18383
+ count: _t("Count"),
18384
+ count_distinct: _t("Count Distinct"),
18385
+ bool_and: _t("Boolean And"),
18386
+ bool_or: _t("Boolean Or"),
18387
+ max: _t("Maximum"),
18388
+ min: _t("Minimum"),
18389
+ avg: _t("Average"),
18390
+ sum: _t("Sum"),
18391
+ };
18392
+ const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
18393
+ const AGGREGATORS_BY_FIELD_TYPE = {
18394
+ integer: NUMBER_CHAR_AGGREGATORS,
18395
+ char: NUMBER_CHAR_AGGREGATORS,
18396
+ //TODO Support for date and boolean
18397
+ };
18398
+ const AGGREGATORS = {};
18399
+ for (const type in AGGREGATORS_BY_FIELD_TYPE) {
18400
+ AGGREGATORS[type] = {};
18401
+ for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
18402
+ AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
18403
+ }
18404
+ }
18405
+ const AGGREGATORS_FN = {
18406
+ count: {
18407
+ fn: (args) => countAny([args]),
18408
+ format: () => "0",
18409
+ },
18410
+ count_distinct: {
18411
+ fn: (args) => countUnique([args]),
18412
+ format: () => "0",
18413
+ },
18414
+ bool_and: {
18415
+ fn: (args) => boolAnd([args]).result,
18416
+ format: () => undefined,
18417
+ },
18418
+ bool_or: {
18419
+ fn: (args) => boolOr([args]).result,
18420
+ format: () => undefined,
18421
+ },
18422
+ max: {
18423
+ fn: (args, locale) => max([args], locale),
18424
+ format: inferFormat,
18425
+ },
18426
+ min: {
18427
+ fn: (args, locale) => min([args], locale),
18428
+ format: inferFormat,
18429
+ },
18430
+ avg: {
18431
+ fn: (args, locale) => average([args], locale),
18432
+ format: inferFormat,
18433
+ },
18434
+ sum: {
18435
+ fn: (args, locale) => sum([args], locale),
18436
+ format: inferFormat,
18437
+ },
18438
+ };
18439
+ /**
18440
+ * Build a pivot formula expression
18441
+ */
18442
+ function makePivotFormula(formula, args) {
18443
+ return `=${formula}(${args
18444
+ .map((arg) => {
18445
+ const stringIsNumber = typeof arg == "string" && !isNaN(Number(arg)) && Number(arg).toString() === arg;
18446
+ const convertToNumber = typeof arg == "number" || stringIsNumber;
18447
+ return convertToNumber ? `${arg}` : `"${arg.toString().replace(/"/g, '\\"')}"`;
18448
+ })
18449
+ .join(",")})`;
18450
+ }
18451
+ /**
18452
+ * Given an object of form {"1": {...}, "2": {...}, ...} get the maximum ID used
18453
+ * in this object
18454
+ * If the object has no keys, return 0
18455
+ *
18456
+ */
18457
+ function getMaxObjectId(o) {
18458
+ const keys = Object.keys(o);
18459
+ if (!keys.length) {
18460
+ return 0;
18461
+ }
18462
+ const nums = keys.map((id) => parseInt(id, 10));
18463
+ const max = Math.max(...nums);
18464
+ return max;
18465
+ }
18466
+ const ALL_PERIODS = {
18467
+ year: _t("Year"),
18468
+ quarter: _t("Quarter"),
18469
+ month: _t("Month"),
18470
+ week: _t("Week"),
18471
+ day: _t("Day"),
18472
+ year_number: _t("Year"),
18473
+ quarter_number: _t("Quarter"),
18474
+ month_number: _t("Month"),
18475
+ iso_week_number: _t("Week"),
18476
+ day_of_month: _t("Day of Month"),
18477
+ };
18478
+ const DATE_FIELDS = ["date", "datetime"];
18479
+ /**
18480
+ * Parse a dimension string into a pivot dimension definition.
18481
+ * e.g "create_date:month" => { name: "create_date", granularity: "month" }
18482
+ */
18483
+ function parseDimension(dimension) {
18484
+ const [name, granularity] = dimension.split(":");
18485
+ if (granularity) {
18486
+ return { name, granularity };
18487
+ }
18488
+ return { name };
18489
+ }
18490
+ function isDateField(field) {
18491
+ return DATE_FIELDS.includes(field.type);
18492
+ }
18493
+ function toPivotDomain(domainStr) {
18494
+ if (domainStr.length % 2 !== 0) {
18495
+ throw new Error("Invalid domain: odd number of elements");
18496
+ }
18497
+ const domain = [];
18498
+ for (let i = 0; i < domainStr.length - 1; i += 2) {
18499
+ domain.push({ field: domainStr[i], value: domainStr[i + 1] });
18500
+ }
18501
+ return domain;
18502
+ }
18503
+ function flatPivotDomain(domain) {
18504
+ return domain.flatMap((arg) => [arg.field, arg.value]);
18505
+ }
18506
+
18379
18507
  /**
18380
18508
  * Get the pivot ID from the formula pivot ID.
18381
18509
  */
@@ -18855,13 +18983,13 @@ stores.inject(MyMetaStore, storeInstance);
18855
18983
  arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
18856
18984
  arg("domain_value (string,optional,repeating)", _t("Value.")),
18857
18985
  ],
18858
- compute: function (formulaId, measureName, ...domain) {
18986
+ compute: function (formulaId, measureName, ...domainArgs) {
18859
18987
  const _pivotFormulaId = toString(formulaId);
18860
- const measure = toString(measureName);
18861
- const domainArgs = domain.map(toString);
18988
+ const _measure = toString(measureName);
18989
+ const _domainArgs = domainArgs.map(toString);
18862
18990
  const pivotId = getPivotId(_pivotFormulaId, this.getters);
18863
- assertMeasureExist(pivotId, measure, this.getters);
18864
- assertDomainLength(domainArgs);
18991
+ assertMeasureExist(pivotId, _measure, this.getters);
18992
+ assertDomainLength(_domainArgs);
18865
18993
  const pivot = this.getters.getPivot(pivotId);
18866
18994
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
18867
18995
  if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
@@ -18875,8 +19003,9 @@ stores.inject(MyMetaStore, storeInstance);
18875
19003
  if (error) {
18876
19004
  return error;
18877
19005
  }
18878
- const { value, format } = pivot.getPivotCellValueAndFormat(measure, domainArgs);
18879
- if (!value && !this.getters.areDomainArgsFieldsValid(pivotId, domainArgs)) {
19006
+ const domain = toPivotDomain(_domainArgs);
19007
+ const { value, format } = pivot.getPivotCellValueAndFormat(_measure, domain);
19008
+ if (!value && !this.getters.areDomainArgsFieldsValid(pivotId, domain)) {
18880
19009
  return {
18881
19010
  value: CellErrorType.GenericError,
18882
19011
  message: _t("Dimensions don't match the pivot definition"),
@@ -18893,11 +19022,11 @@ stores.inject(MyMetaStore, storeInstance);
18893
19022
  arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
18894
19023
  arg("domain_value (string,optional,repeating)", _t("Value.")),
18895
19024
  ],
18896
- compute: function (pivotId, ...domain) {
19025
+ compute: function (pivotId, ...domainArgs) {
18897
19026
  const _pivotFormulaId = toString(pivotId);
18898
- const domainArgs = domain.map(toString);
19027
+ const _domainArgs = domainArgs.map(toString);
18899
19028
  const _pivotId = getPivotId(_pivotFormulaId, this.getters);
18900
- assertDomainLength(domainArgs);
19029
+ assertDomainLength(_domainArgs);
18901
19030
  const pivot = this.getters.getPivot(_pivotId);
18902
19031
  const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
18903
19032
  if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
@@ -18911,18 +19040,23 @@ stores.inject(MyMetaStore, storeInstance);
18911
19040
  if (error) {
18912
19041
  return error;
18913
19042
  }
18914
- const fieldName = domainArgs.at(-2);
18915
- const valueArg = domainArgs.at(-1);
18916
- if (!this.getters.areDomainArgsFieldsValid(_pivotId, fieldName === "measure" ? domainArgs.slice(0, -2) : domainArgs)) {
19043
+ const domain = toPivotDomain(_domainArgs);
19044
+ const lastNode = domain.at(-1);
19045
+ if (!this.getters.areDomainArgsFieldsValid(_pivotId, lastNode?.field === "measure" ? domain.slice(0, -1) : domain)) {
18917
19046
  return {
18918
19047
  value: CellErrorType.GenericError,
18919
19048
  message: _t("Dimensions don't match the pivot definition"),
18920
19049
  };
18921
19050
  }
18922
- const { value, format } = pivot.getPivotHeaderValueAndFormat(domainArgs);
19051
+ if (lastNode?.field === "measure") {
19052
+ return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
19053
+ }
19054
+ const { value, format } = pivot.getPivotHeaderValueAndFormat(domain);
18923
19055
  return {
18924
19056
  value,
18925
- format: !fieldName || fieldName === "measure" || valueArg === "false" ? undefined : format,
19057
+ format: !lastNode || lastNode.field === "measure" || lastNode.value === "false"
19058
+ ? undefined
19059
+ : format,
18926
19060
  };
18927
19061
  },
18928
19062
  returns: ["NUMBER", "STRING"],
@@ -18935,11 +19069,14 @@ stores.inject(MyMetaStore, storeInstance);
18935
19069
  arg("include_total (boolean, default=TRUE)", _t("Whether to include total/sub-totals or not.")),
18936
19070
  arg("include_column_titles (boolean, default=TRUE)", _t("Whether to include the column titles or not.")),
18937
19071
  ],
18938
- compute: function (pivotId, rowCount = { value: 10000 }, includeTotal = { value: true }, includeColumnHeaders = { value: true }) {
18939
- const _pivotFormulaId = toString(pivotId);
18940
- const _pivotId = getPivotId(_pivotFormulaId, this.getters);
18941
- const pivot = this.getters.getPivot(_pivotId);
18942
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
19072
+ compute: function (pivotFormulaId, rowCount = { value: 10000 }, includeTotal = { value: true }, includeColumnHeaders = { value: true }) {
19073
+ const _pivotFormulaId = toString(pivotFormulaId);
19074
+ const _rowCount = toNumber(rowCount, this.locale);
19075
+ const _includeColumnHeaders = toBoolean(includeColumnHeaders);
19076
+ const _includedTotal = toBoolean(includeTotal);
19077
+ const pivotId = getPivotId(_pivotFormulaId, this.getters);
19078
+ const pivot = this.getters.getPivot(pivotId);
19079
+ const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
18943
19080
  addPivotDependencies(this, coreDefinition);
18944
19081
  pivot.init({ reload: pivot.needsReevaluation });
18945
19082
  const error = pivot.assertIsValid({ throwOnError: false });
@@ -18947,11 +19084,9 @@ stores.inject(MyMetaStore, storeInstance);
18947
19084
  return error;
18948
19085
  }
18949
19086
  const table = pivot.getTableStructure();
18950
- const _includeColumnHeaders = toBoolean(includeColumnHeaders);
18951
- const cells = table.getPivotCells(toBoolean(includeTotal), _includeColumnHeaders);
19087
+ const cells = table.getPivotCells(_includedTotal, _includeColumnHeaders);
18952
19088
  const headerRows = _includeColumnHeaders ? table.columns.length : 0;
18953
- const pivotTitle = this.getters.getPivotDisplayName(_pivotId);
18954
- const _rowCount = toNumber(rowCount, this.locale);
19089
+ const pivotTitle = this.getters.getPivotDisplayName(pivotId);
18955
19090
  if (_rowCount < 0) {
18956
19091
  throw new EvaluationError(_t("The number of rows must be positive."));
18957
19092
  }
@@ -18966,17 +19101,23 @@ stores.inject(MyMetaStore, storeInstance);
18966
19101
  result[col] = [];
18967
19102
  for (const row of tableRows) {
18968
19103
  const pivotCell = cells[col][row];
18969
- if (!pivotCell.domain) {
18970
- result[col].push({ value: "", format: undefined });
18971
- }
18972
- else if (pivotCell.isHeader) {
18973
- result[col].push(pivot.getPivotHeaderValueAndFormat(pivotCell.domain));
18974
- }
18975
- else {
18976
- if (!pivotCell.measure) {
18977
- throw new Error("Measure is missing");
18978
- }
18979
- result[col].push(pivot.getPivotCellValueAndFormat(pivotCell.measure, pivotCell.domain));
19104
+ switch (pivotCell.type) {
19105
+ case "EMPTY":
19106
+ result[col].push({ value: "" });
19107
+ break;
19108
+ case "HEADER":
19109
+ const domain = pivotCell.domain;
19110
+ const lastNode = domain.at(-1);
19111
+ if (lastNode?.field === "measure") {
19112
+ result[col].push(pivot.getPivotMeasureValue(toString(lastNode.value), domain));
19113
+ }
19114
+ else {
19115
+ result[col].push(pivot.getPivotHeaderValueAndFormat(domain));
19116
+ }
19117
+ break;
19118
+ case "VALUE":
19119
+ result[col].push(pivot.getPivotCellValueAndFormat(pivotCell.measure, pivotCell.domain));
19120
+ break;
18980
19121
  }
18981
19122
  }
18982
19123
  }
@@ -20901,8 +21042,15 @@ stores.inject(MyMetaStore, storeInstance);
20901
21042
  }
20902
21043
  onPaste(ev) {
20903
21044
  if (this.composerStore.editionMode !== "inactive") {
21045
+ // let the browser clipboard work
20904
21046
  ev.stopPropagation();
20905
21047
  }
21048
+ else {
21049
+ // the user meant to paste in the sheet, not open the composer with the pasted content
21050
+ // While we're not editing, we still have the focus and should therefore prevent
21051
+ // the native "paste" to occur.
21052
+ ev.preventDefault();
21053
+ }
20906
21054
  }
20907
21055
  /*
20908
21056
  * Triggered automatically by the content-editable between the keydown and key up
@@ -20911,9 +21059,6 @@ stores.inject(MyMetaStore, storeInstance);
20911
21059
  if (!this.shouldProcessInputEvents) {
20912
21060
  return;
20913
21061
  }
20914
- if (ev.inputType === "insertFromPaste" && this.composerStore.editionMode === "inactive") {
20915
- return;
20916
- }
20917
21062
  ev.stopPropagation();
20918
21063
  let content;
20919
21064
  if (this.composerStore.editionMode === "inactive") {
@@ -21566,132 +21711,8 @@ stores.inject(MyMetaStore, storeInstance);
21566
21711
  }
21567
21712
 
21568
21713
  const PIVOT_FUNCTIONS = ["PIVOT.VALUE", "PIVOT.HEADER", "PIVOT"];
21569
- const AGGREGATOR_NAMES = {
21570
- count: _t("Count"),
21571
- count_distinct: _t("Count Distinct"),
21572
- bool_and: _t("Boolean And"),
21573
- bool_or: _t("Boolean Or"),
21574
- max: _t("Maximum"),
21575
- min: _t("Minimum"),
21576
- avg: _t("Average"),
21577
- sum: _t("Sum"),
21578
- };
21579
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
21580
- const AGGREGATORS_BY_FIELD_TYPE = {
21581
- integer: NUMBER_CHAR_AGGREGATORS,
21582
- char: NUMBER_CHAR_AGGREGATORS,
21583
- //TODO Support for date and boolean
21584
- };
21585
- const AGGREGATORS = {};
21586
- for (const type in AGGREGATORS_BY_FIELD_TYPE) {
21587
- AGGREGATORS[type] = {};
21588
- for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
21589
- AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
21590
- }
21591
- }
21592
- const AGGREGATORS_FN = {
21593
- count: {
21594
- fn: (args) => countAny([args]),
21595
- format: () => "0",
21596
- },
21597
- count_distinct: {
21598
- fn: (args) => countUnique([args]),
21599
- format: () => "0",
21600
- },
21601
- bool_and: {
21602
- fn: (args) => boolAnd([args]).result,
21603
- format: () => undefined,
21604
- },
21605
- bool_or: {
21606
- fn: (args) => boolOr([args]).result,
21607
- format: () => undefined,
21608
- },
21609
- max: {
21610
- fn: (args, locale) => max([args], locale),
21611
- format: inferFormat,
21612
- },
21613
- min: {
21614
- fn: (args, locale) => min([args], locale),
21615
- format: inferFormat,
21616
- },
21617
- avg: {
21618
- fn: (args, locale) => average([args], locale),
21619
- format: inferFormat,
21620
- },
21621
- sum: {
21622
- fn: (args, locale) => sum([args], locale),
21623
- format: inferFormat,
21624
- },
21625
- };
21626
- /**
21627
- * Build a pivot formula expression
21628
- */
21629
- function makePivotFormula(formula, args) {
21630
- return `=${formula}(${args
21631
- .map((arg) => {
21632
- const stringIsNumber = typeof arg == "string" && !isNaN(Number(arg)) && Number(arg).toString() === arg;
21633
- const convertToNumber = typeof arg == "number" || stringIsNumber;
21634
- return convertToNumber ? `${arg}` : `"${arg.toString().replace(/"/g, '\\"')}"`;
21635
- })
21636
- .join(",")})`;
21637
- }
21638
- /**
21639
- * Given an object of form {"1": {...}, "2": {...}, ...} get the maximum ID used
21640
- * in this object
21641
- * If the object has no keys, return 0
21642
- *
21643
- */
21644
- function getMaxObjectId(o) {
21645
- const keys = Object.keys(o);
21646
- if (!keys.length) {
21647
- return 0;
21648
- }
21649
- const nums = keys.map((id) => parseInt(id, 10));
21650
- const max = Math.max(...nums);
21651
- return max;
21652
- }
21653
- /**
21654
- * Get the first Pivot function description of the given formula.
21655
- */
21656
- function getFirstPivotFunction(tokens) {
21657
- return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
21658
- }
21659
- /**
21660
- * Parse a spreadsheet formula and detect the number of PIVOT functions that are
21661
- * present in the given formula.
21662
- */
21663
- function getNumberOfPivotFunctions(tokens) {
21664
- return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS).length;
21665
- }
21666
- const ALL_PERIODS = {
21667
- year: _t("Year"),
21668
- quarter: _t("Quarter"),
21669
- month: _t("Month"),
21670
- week: _t("Week"),
21671
- day: _t("Day"),
21672
- year_number: _t("Year"),
21673
- quarter_number: _t("Quarter"),
21674
- month_number: _t("Month"),
21675
- iso_week_number: _t("Week"),
21676
- day_of_month: _t("Day of Month"),
21677
- };
21678
- const DATE_FIELDS = ["date", "datetime"];
21679
- /**
21680
- * Parse a dimension string into a pivot dimension definition.
21681
- * e.g "create_date:month" => { name: "create_date", granularity: "month" }
21682
- */
21683
- function parseDimension(dimension) {
21684
- const [name, granularity] = dimension.split(":");
21685
- if (granularity) {
21686
- return { name, granularity };
21687
- }
21688
- return { name };
21689
- }
21690
- function isDateField(field) {
21691
- return DATE_FIELDS.includes(field.type);
21692
- }
21693
21714
  /**
21694
- * Create a proposal entry for the compose autocomplete
21715
+ * Create a proposal entry for the compose autowcomplete
21695
21716
  * to insert a field name string in a formula.
21696
21717
  */
21697
21718
  function makeFieldProposal(field, granularity) {
@@ -21747,15 +21768,18 @@ stores.inject(MyMetaStore, storeInstance);
21747
21768
  }
21748
21769
  return idAst.value;
21749
21770
  }
21750
- function toDomainArgs(domainStr) {
21751
- if (domainStr.length % 2 !== 0) {
21752
- throw new Error("Invalid domain: odd number of elements");
21753
- }
21754
- const domain = [];
21755
- for (let i = 0; i < domainStr.length - 1; i += 2) {
21756
- domain.push({ field: domainStr[i], value: domainStr[i + 1] });
21757
- }
21758
- return domain;
21771
+ /**
21772
+ * Get the first Pivot function description of the given formula.
21773
+ */
21774
+ function getFirstPivotFunction(tokens) {
21775
+ return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
21776
+ }
21777
+ /**
21778
+ * Parse a spreadsheet formula and detect the number of PIVOT functions that are
21779
+ * present in the given formula.
21780
+ */
21781
+ function getNumberOfPivotFunctions(tokens) {
21782
+ return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS).length;
21759
21783
  }
21760
21784
 
21761
21785
  autoCompleteProviders.add("pivot_ids", {
@@ -25322,8 +25346,7 @@ stores.inject(MyMetaStore, storeInstance);
25322
25346
  */
25323
25347
  function useSpreadsheetRect() {
25324
25348
  const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
25325
- let spreadsheetElement = document.querySelector(".o-spreadsheet");
25326
- updatePosition();
25349
+ let spreadsheetElement = null;
25327
25350
  function updatePosition() {
25328
25351
  if (!spreadsheetElement) {
25329
25352
  spreadsheetElement = document.querySelector(".o-spreadsheet");
@@ -32783,7 +32806,7 @@ stores.inject(MyMetaStore, storeInstance);
32783
32806
  vertical-align: middle;
32784
32807
  }
32785
32808
  .o_cf_radio_item {
32786
- margin-right: 10%;
32809
+ margin-right: 30px;
32787
32810
  }
32788
32811
  .radio input:checked {
32789
32812
  color: #e9ecef;
@@ -32803,6 +32826,9 @@ stores.inject(MyMetaStore, storeInstance);
32803
32826
  }
32804
32827
  margin-top: 10px;
32805
32828
  display: flex;
32829
+ .form-check {
32830
+ padding-left: 1rem;
32831
+ }
32806
32832
  }
32807
32833
  .o-section-subtitle:first-child {
32808
32834
  margin-top: 0px;
@@ -32811,7 +32837,7 @@ stores.inject(MyMetaStore, storeInstance);
32811
32837
  font-size: 12px;
32812
32838
  line-height: 1.5;
32813
32839
  .o-selection-cf {
32814
- margin-bottom: 3%;
32840
+ margin-bottom: 9px;
32815
32841
  }
32816
32842
  .o-cell-content {
32817
32843
  font-size: 12px;
@@ -32852,7 +32878,7 @@ stores.inject(MyMetaStore, storeInstance);
32852
32878
  width: 100%;
32853
32879
  }
32854
32880
  .o-threshold-value {
32855
- margin-left: 2%;
32881
+ margin-left: 6px;
32856
32882
  width: 20%;
32857
32883
  min-width: 0px; // input overflows in Firefox otherwise
32858
32884
  }
@@ -32881,8 +32907,8 @@ stores.inject(MyMetaStore, storeInstance);
32881
32907
  justify-content: space-between;
32882
32908
  .o-cf-icon {
32883
32909
  display: inline;
32884
- margin-left: 1%;
32885
- margin-right: 1%;
32910
+ margin-left: 3px;
32911
+ margin-right: 3px;
32886
32912
  }
32887
32913
  svg {
32888
32914
  vertical-align: baseline;
@@ -32905,7 +32931,7 @@ stores.inject(MyMetaStore, storeInstance);
32905
32931
  }
32906
32932
  table {
32907
32933
  table-layout: fixed;
32908
- margin-top: 2%;
32934
+ margin-top: 6px;
32909
32935
  display: table;
32910
32936
  text-align: left;
32911
32937
  font-size: 12px;
@@ -32935,8 +32961,8 @@ stores.inject(MyMetaStore, storeInstance);
32935
32961
  }
32936
32962
  }
32937
32963
  .o-cf-iconset-reverse {
32938
- margin-bottom: 2%;
32939
- margin-top: 2%;
32964
+ margin-bottom: 6px;
32965
+ margin-top: 6px;
32940
32966
  .o-cf-label {
32941
32967
  display: inline-block;
32942
32968
  vertical-align: bottom;
@@ -34524,6 +34550,33 @@ stores.inject(MyMetaStore, storeInstance);
34524
34550
  }
34525
34551
  }
34526
34552
 
34553
+ css /* scss */ `
34554
+ .pivot-defer-update {
34555
+ min-height: 35px;
34556
+ background-color: #f8f9fa;
34557
+ }
34558
+ `;
34559
+ class PivotDeferUpdate extends owl.Component {
34560
+ static template = "o-spreadsheet-PivotDeferUpdate";
34561
+ static props = {
34562
+ deferUpdate: Boolean,
34563
+ isDirty: Boolean,
34564
+ toggleDeferUpdate: Function,
34565
+ discard: Function,
34566
+ apply: Function,
34567
+ };
34568
+ static components = {
34569
+ Section,
34570
+ Checkbox,
34571
+ };
34572
+ get deferUpdatesLabel() {
34573
+ return _t("Defer updates");
34574
+ }
34575
+ get deferUpdatesTooltip() {
34576
+ return _t("Changing the pivot definition requires to reload the data. It may take some time.");
34577
+ }
34578
+ }
34579
+
34527
34580
  function useAutofocus({ refName }) {
34528
34581
  const ref = owl.useRef(refName);
34529
34582
  owl.useEffect((el) => {
@@ -34643,6 +34696,10 @@ stores.inject(MyMetaStore, storeInstance);
34643
34696
  select > option {
34644
34697
  background-color: white;
34645
34698
  }
34699
+
34700
+ .pivot-dim-operator-label {
34701
+ min-width: 120px;
34702
+ }
34646
34703
  }
34647
34704
  `;
34648
34705
  class PivotDimension extends owl.Component {
@@ -34883,7 +34940,7 @@ stores.inject(MyMetaStore, storeInstance);
34883
34940
  getMeasure(name) {
34884
34941
  const measure = this.measures.find((measure) => measure.name === name);
34885
34942
  if (!measure) {
34886
- throw new EvaluationError(_t("Field %s does not exist", name));
34943
+ throw new EvaluationError(_t("Field %s is not a measure", name));
34887
34944
  }
34888
34945
  return measure;
34889
34946
  }
@@ -35009,10 +35066,9 @@ stores.inject(MyMetaStore, storeInstance);
35009
35066
  columns;
35010
35067
  rows;
35011
35068
  measures;
35012
- rowTitle;
35013
35069
  maxIndent;
35014
35070
  pivotCells = {};
35015
- constructor(columns, rows, measures, rowTitle = "") {
35071
+ constructor(columns, rows, measures) {
35016
35072
  this.columns = columns.map((row) => {
35017
35073
  // offset in the pivot table
35018
35074
  // starts at 1 because the first column is the row title
@@ -35025,7 +35081,6 @@ stores.inject(MyMetaStore, storeInstance);
35025
35081
  });
35026
35082
  this.rows = rows;
35027
35083
  this.measures = measures;
35028
- this.rowTitle = rowTitle;
35029
35084
  this.maxIndent = Math.max(...this.rows.map((row) => row.indent));
35030
35085
  }
35031
35086
  /**
@@ -35067,26 +35122,23 @@ stores.inject(MyMetaStore, storeInstance);
35067
35122
  }
35068
35123
  getPivotCell(col, row, includeTotal = true) {
35069
35124
  const colHeadersHeight = this.columns.length;
35070
- if (col === 0 && row === colHeadersHeight - 1) {
35071
- return { content: this.rowTitle, isHeader: true };
35072
- }
35073
- else if (row <= colHeadersHeight - 1) {
35125
+ if (row <= colHeadersHeight - 1) {
35074
35126
  const domain = this.getColHeaderDomain(col, row);
35075
- return { domain, isHeader: true };
35127
+ return domain ? { type: "HEADER", domain } : { type: "EMPTY" };
35076
35128
  }
35077
35129
  else if (col === 0) {
35078
35130
  const rowIndex = row - colHeadersHeight;
35079
35131
  const domain = this.getRowDomain(rowIndex);
35080
- return { domain, isHeader: true };
35132
+ return { type: "HEADER", domain };
35081
35133
  }
35082
35134
  else {
35083
35135
  const rowIndex = row - colHeadersHeight;
35084
35136
  if (!includeTotal && this.isTotalRow(rowIndex)) {
35085
- return { isHeader: false };
35137
+ return { type: "EMPTY" };
35086
35138
  }
35087
35139
  const domain = [...this.getRowDomain(rowIndex), ...this.getColDomain(col)];
35088
35140
  const measure = this.getColMeasure(col);
35089
- return { domain, isHeader: false, measure };
35141
+ return { type: "VALUE", domain, measure };
35090
35142
  }
35091
35143
  }
35092
35144
  getColHeaderDomain(col, row) {
@@ -35099,24 +35151,32 @@ stores.inject(MyMetaStore, storeInstance);
35099
35151
  return undefined;
35100
35152
  }
35101
35153
  for (let i = 0; i < pivotCol.fields.length; i++) {
35102
- domain.push(pivotCol.fields[i]);
35103
- domain.push(pivotCol.values[i]);
35154
+ domain.push({
35155
+ field: pivotCol.fields[i],
35156
+ value: pivotCol.values[i],
35157
+ });
35104
35158
  }
35105
35159
  return domain;
35106
35160
  }
35107
35161
  getColDomain(col) {
35108
35162
  const domain = this.getColHeaderDomain(col, this.columns.length - 1);
35109
- return domain ? domain.slice(0, -2) : []; // slice: remove measure and value
35163
+ return domain ? domain.slice(0, -1) : []; // slice: remove measure and value
35110
35164
  }
35111
35165
  getColMeasure(col) {
35112
35166
  const domain = this.getColHeaderDomain(col, this.columns.length - 1);
35113
- return domain?.at(-1);
35167
+ const measure = domain?.at(-1)?.value;
35168
+ if (measure === undefined) {
35169
+ throw new Error("Measure isd missing");
35170
+ }
35171
+ return measure.toString();
35114
35172
  }
35115
35173
  getRowDomain(row) {
35116
35174
  const domain = [];
35117
35175
  for (let i = 0; i < this.rows[row].fields.length; i++) {
35118
- domain.push(this.rows[row].fields[i]);
35119
- domain.push(this.rows[row].values[i]);
35176
+ domain.push({
35177
+ field: this.rows[row].fields[i],
35178
+ value: this.rows[row].values[i],
35179
+ });
35120
35180
  }
35121
35181
  return domain;
35122
35182
  }
@@ -35125,7 +35185,6 @@ stores.inject(MyMetaStore, storeInstance);
35125
35185
  cols: this.columns,
35126
35186
  rows: this.rows,
35127
35187
  measures: this.measures,
35128
- rowTitle: this.rowTitle,
35129
35188
  };
35130
35189
  }
35131
35190
  }
@@ -35145,8 +35204,7 @@ stores.inject(MyMetaStore, storeInstance);
35145
35204
  indent: 0,
35146
35205
  });
35147
35206
  const measureNames = definition.measures.map((m) => m.name);
35148
- const rowTitle = rows.length > 0 ? rows[0].values[0] : "";
35149
- return new SpreadsheetPivotTable(cols, rows, measureNames, rowTitle);
35207
+ return new SpreadsheetPivotTable(cols, rows, measureNames);
35150
35208
  }
35151
35209
  // -----------------------------------------------------------------------------
35152
35210
  // ROWS
@@ -35489,7 +35547,10 @@ stores.inject(MyMetaStore, storeInstance);
35489
35547
  }
35490
35548
  get definition() {
35491
35549
  if (!this._definition) {
35492
- throw new Error("Pivot not loaded yet");
35550
+ this.init();
35551
+ }
35552
+ if (!this._definition) {
35553
+ throw new Error("Pivot definition should be defined at this point.");
35493
35554
  }
35494
35555
  return this._definition;
35495
35556
  }
@@ -35538,15 +35599,16 @@ stores.inject(MyMetaStore, storeInstance);
35538
35599
  getMeasure(name) {
35539
35600
  return this.definition.getMeasure(name);
35540
35601
  }
35541
- getPivotHeaderValueAndFormat(domainStr) {
35542
- const domain = toDomainArgs(domainStr);
35602
+ getPivotMeasureValue(name) {
35603
+ return {
35604
+ value: this.getMeasure(name).displayName,
35605
+ };
35606
+ }
35607
+ getPivotHeaderValueAndFormat(domain) {
35543
35608
  const lastNode = domain.at(-1);
35544
35609
  if (!lastNode) {
35545
35610
  return { value: _t("Total") };
35546
35611
  }
35547
- if (lastNode.field === "measure") {
35548
- return { value: this.getMeasure(lastNode.value).displayName };
35549
- }
35550
35612
  const dimension = this.getDimension(lastNode.field);
35551
35613
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
35552
35614
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
@@ -35574,8 +35636,7 @@ stores.inject(MyMetaStore, storeInstance);
35574
35636
  format: finalCell.format,
35575
35637
  };
35576
35638
  }
35577
- getPivotCellValueAndFormat(measure, domainStr) {
35578
- const domain = toDomainArgs(domainStr);
35639
+ getPivotCellValueAndFormat(measure, domain) {
35579
35640
  const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
35580
35641
  if (dataEntries.length === 0) {
35581
35642
  return { value: "" };
@@ -35971,12 +36032,12 @@ stores.inject(MyMetaStore, storeInstance);
35971
36032
  SelectionInput,
35972
36033
  EditableName,
35973
36034
  Checkbox,
36035
+ PivotDeferUpdate,
35974
36036
  };
35975
36037
  store;
35976
36038
  state;
35977
36039
  setup() {
35978
36040
  this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
35979
- this.pivot.init();
35980
36041
  this.state = owl.useState({
35981
36042
  range: undefined,
35982
36043
  rangeHasChanged: false,
@@ -36009,12 +36070,6 @@ stores.inject(MyMetaStore, storeInstance);
36009
36070
  get definition() {
36010
36071
  return this.store.definition;
36011
36072
  }
36012
- get deferUpdatesLabel() {
36013
- return _t("Defer updates");
36014
- }
36015
- get deferUpdatesTooltip() {
36016
- return _t("Changing the pivot definition requires to reload the data. It may take some time.");
36017
- }
36018
36073
  onSelectionChanged(ranges) {
36019
36074
  this.state.rangeHasChanged = true;
36020
36075
  this.state.range = ranges[0];
@@ -36853,7 +36908,7 @@ stores.inject(MyMetaStore, storeInstance);
36853
36908
  }
36854
36909
 
36855
36910
  .o-table-style-list-item {
36856
- padding: 3px;
36911
+ padding: 3px 2px;
36857
36912
  margin: 2px 1px;
36858
36913
 
36859
36914
  .o-table-style-picker-preview {
@@ -36874,10 +36929,10 @@ stores.inject(MyMetaStore, storeInstance);
36874
36929
  const styles = Object.keys(allStyles).filter((key) => allStyles[key].category === selectedStyleCategory);
36875
36930
  const selectedStyleIndex = styles.indexOf(this.props.table.config.styleId);
36876
36931
  if (selectedStyleIndex === -1) {
36877
- return styles.slice(0, 4);
36932
+ return selectedStyleIndex;
36878
36933
  }
36879
36934
  const index = Math.floor(selectedStyleIndex / 4) * 4;
36880
- return styles.slice(index, index + 4);
36935
+ return styles.slice(index);
36881
36936
  }
36882
36937
  onStylePicked(styleId) {
36883
36938
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -37917,10 +37972,7 @@ stores.inject(MyMetaStore, storeInstance);
37917
37972
  }
37918
37973
  get containerStyle() {
37919
37974
  if (this.composerStore.editionMode === "inactive") {
37920
- return `
37921
- position: absolute;
37922
- z-index: -1000;
37923
- `;
37975
+ return `z-index: -1000;`;
37924
37976
  }
37925
37977
  const isFormula = this.composerStore.currentContent.startsWith("=");
37926
37978
  const cell = this.env.model.getters.getActiveCell();
@@ -40764,10 +40816,13 @@ stores.inject(MyMetaStore, storeInstance);
40764
40816
  }
40765
40817
  }
40766
40818
 
40819
+ const DEFAULT_SIDE_PANEL_SIZE = 350;
40820
+ const MIN_SHEET_VIEW_WIDTH = 150;
40767
40821
  class SidePanelStore extends SpreadsheetStore {
40768
- mutators = ["open", "toggle", "close"];
40822
+ mutators = ["open", "toggle", "close", "changePanelSize", "resetPanelSize"];
40769
40823
  initialPanelProps = {};
40770
40824
  componentTag = "";
40825
+ panelSize = DEFAULT_SIDE_PANEL_SIZE;
40771
40826
  get isOpen() {
40772
40827
  if (!this.componentTag) {
40773
40828
  return false;
@@ -40812,6 +40867,20 @@ stores.inject(MyMetaStore, storeInstance);
40812
40867
  this.initialPanelProps = {};
40813
40868
  this.componentTag = "";
40814
40869
  }
40870
+ changePanelSize(size, spreadsheetElWidth) {
40871
+ if (size < DEFAULT_SIDE_PANEL_SIZE) {
40872
+ this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
40873
+ }
40874
+ else if (size > spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH) {
40875
+ this.panelSize = Math.max(spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH, DEFAULT_SIDE_PANEL_SIZE);
40876
+ }
40877
+ else {
40878
+ this.panelSize = size;
40879
+ }
40880
+ }
40881
+ resetPanelSize() {
40882
+ this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
40883
+ }
40815
40884
  computeState(componentTag, panelProps) {
40816
40885
  const customComputeState = sidePanelRegistry.get(componentTag).computeState;
40817
40886
  if (!customComputeState) {
@@ -41932,7 +42001,7 @@ stores.inject(MyMetaStore, storeInstance);
41932
42001
  }
41933
42002
  }
41934
42003
 
41935
- const SUPPORTED_BORDER_STYLES = ["thin"];
42004
+ const SUPPORTED_BORDER_STYLES = ["thin", "medium", "thick", "dashed", "dotted"];
41936
42005
  const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
41937
42006
  "general",
41938
42007
  "left",
@@ -51071,8 +51140,8 @@ stores.inject(MyMetaStore, storeInstance);
51071
51140
  case "INSERT_PIVOT": {
51072
51141
  const { sheetId, col, row, pivotId, table } = cmd;
51073
51142
  const position = { sheetId, col, row };
51074
- const { cols, rows, measures, rowTitle } = table;
51075
- const spTable = new SpreadsheetPivotTable(cols, rows, measures, rowTitle);
51143
+ const { cols, rows, measures } = table;
51144
+ const spTable = new SpreadsheetPivotTable(cols, rows, measures);
51076
51145
  const formulaId = this.getPivotFormulaId(pivotId);
51077
51146
  this.insertPivot(position, formulaId, spTable);
51078
51147
  break;
@@ -51201,13 +51270,18 @@ stores.inject(MyMetaStore, storeInstance);
51201
51270
  }
51202
51271
  }
51203
51272
  addPivotFormula(position, formulaId, pivotCell) {
51204
- const formula = pivotCell.isHeader ? "PIVOT.HEADER" : "PIVOT.VALUE";
51205
- const args = pivotCell.domain
51206
- ? [formulaId, pivotCell.measure, ...pivotCell.domain].filter(isDefined)
51207
- : undefined;
51273
+ let content = undefined;
51274
+ switch (pivotCell.type) {
51275
+ case "HEADER":
51276
+ content = makePivotFormula("PIVOT.HEADER", [formulaId, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
51277
+ break;
51278
+ case "VALUE":
51279
+ content = makePivotFormula("PIVOT.VALUE", [formulaId, pivotCell.measure, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
51280
+ break;
51281
+ }
51208
51282
  this.dispatch("UPDATE_CELL", {
51209
51283
  ...position,
51210
- content: pivotCell.content || (args ? makePivotFormula(formula, args) : undefined),
51284
+ content,
51211
51285
  });
51212
51286
  }
51213
51287
  getPivotCore(pivotId) {
@@ -51226,7 +51300,7 @@ stores.inject(MyMetaStore, storeInstance);
51226
51300
  import(data) {
51227
51301
  if (data.pivots) {
51228
51302
  for (const [id, pivot] of Object.entries(data.pivots)) {
51229
- this.addPivot(id, deepCopy(pivot), pivot.formulaId);
51303
+ this.addPivot(id, pivot, pivot.formulaId);
51230
51304
  }
51231
51305
  }
51232
51306
  this.history.update("nextFormulaId", data.pivotNextId || getMaxObjectId(this.pivots) + 1);
@@ -54567,17 +54641,21 @@ stores.inject(MyMetaStore, storeInstance);
54567
54641
  const pivotCol = position.col - mainPosition.col;
54568
54642
  const pivotRow = position.row - mainPosition.row;
54569
54643
  const pivotCell = pivotCells[pivotCol][pivotRow];
54570
- const domain = pivotCell.domain;
54571
- if (domain?.at(-2) === "measure") {
54572
- return domain.slice(0, -2);
54644
+ if (pivotCell.type === "EMPTY") {
54645
+ return undefined;
54646
+ }
54647
+ let domain = pivotCell.domain;
54648
+ if (domain.at(-1)?.field === "measure") {
54649
+ domain = domain.slice(0, -1);
54573
54650
  }
54574
- return domain;
54651
+ return { domainArgs: domain, isHeader: pivotCell.type === "HEADER" };
54575
54652
  }
54576
- const domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
54577
- if (domain.at(-2) === "measure") {
54578
- return domain.slice(0, -2);
54653
+ let domain = toPivotDomain(args.slice(functionName === "PIVOT.VALUE" ? 2 : 1).map((x) => `${x}`));
54654
+ if (domain.at(-1)?.field === "measure") {
54655
+ domain = domain.slice(0, -1);
54579
54656
  }
54580
- return domain;
54657
+ const isHeader = functionName === "PIVOT.HEADER";
54658
+ return { domainArgs: domain, isHeader };
54581
54659
  }
54582
54660
  getPivot(pivotId) {
54583
54661
  return this.pivots[pivotId];
@@ -54590,9 +54668,9 @@ stores.inject(MyMetaStore, storeInstance);
54590
54668
  * a pivot function are valid according to the pivot definition.
54591
54669
  * e.g. =PIVOT.VALUE(1,"revenue","country_id",...,"create_date:month",...,"source_id",...)
54592
54670
  */
54593
- areDomainArgsFieldsValid(pivotId, domainArgs) {
54594
- const dimensions = domainArgs
54595
- .filter((arg, index) => index % 2 === 0)
54671
+ areDomainArgsFieldsValid(pivotId, domain) {
54672
+ const dimensions = domain
54673
+ .map((node) => node.field)
54596
54674
  .map((name) => (name.startsWith("#") ? name.slice(1) : name));
54597
54675
  let argIndex = 0;
54598
54676
  let definitionIndex = 0;
@@ -61606,6 +61684,10 @@ stores.inject(MyMetaStore, storeInstance);
61606
61684
  }
61607
61685
  }
61608
61686
  }
61687
+ .o-sidePanelBody-container {
61688
+ /* This overwrites the min-height: auto; of flex. Without this, a flex div cannot be smaller than its children */
61689
+ min-height: 0;
61690
+ }
61609
61691
  .o-sidePanelBody {
61610
61692
  overflow: auto;
61611
61693
  width: 100%;
@@ -61684,24 +61766,6 @@ stores.inject(MyMetaStore, storeInstance);
61684
61766
  text-align: left;
61685
61767
  }
61686
61768
 
61687
- .o-inflection {
61688
- table {
61689
- table-layout: fixed;
61690
- margin-top: 2%;
61691
- display: table;
61692
- text-align: left;
61693
- font-size: 12px;
61694
- line-height: 18px;
61695
- width: 100%;
61696
- }
61697
- input,
61698
- select {
61699
- width: 100%;
61700
- height: 100%;
61701
- box-sizing: border-box;
61702
- }
61703
- }
61704
-
61705
61769
  .o-sidePanel-tools {
61706
61770
  color: #333;
61707
61771
  font-size: 13px;
@@ -61720,12 +61784,25 @@ stores.inject(MyMetaStore, storeInstance);
61720
61784
  }
61721
61785
  }
61722
61786
  }
61787
+
61788
+ .o-sidePanel-handle-container {
61789
+ width: 8px;
61790
+ }
61791
+ .o-sidePanel-handle {
61792
+ cursor: col-resize;
61793
+ color: #a9a9a9;
61794
+ .o-icon {
61795
+ height: 25px;
61796
+ margin-left: -5px;
61797
+ }
61798
+ }
61723
61799
  }
61724
61800
  `;
61725
61801
  class SidePanel extends owl.Component {
61726
61802
  static template = "o-spreadsheet-SidePanel";
61727
61803
  static props = {};
61728
61804
  sidePanelStore;
61805
+ spreadsheetRect = useSpreadsheetRect();
61729
61806
  setup() {
61730
61807
  this.sidePanelStore = useStore(SidePanelStore);
61731
61808
  owl.useEffect((isOpen) => {
@@ -61746,6 +61823,20 @@ stores.inject(MyMetaStore, storeInstance);
61746
61823
  ? panel.title(this.env, this.sidePanelStore.panelProps)
61747
61824
  : panel.title;
61748
61825
  }
61826
+ startHandleDrag(ev) {
61827
+ const startingCursor = document.body.style.cursor;
61828
+ const startSize = this.sidePanelStore.panelSize;
61829
+ const startPosition = ev.clientX;
61830
+ const onMouseMove = (ev) => {
61831
+ document.body.style.cursor = "col-resize";
61832
+ const newSize = startSize + startPosition - ev.clientX;
61833
+ this.sidePanelStore.changePanelSize(newSize, this.spreadsheetRect.width);
61834
+ };
61835
+ const cleanUp = () => {
61836
+ document.body.style.cursor = startingCursor;
61837
+ };
61838
+ startDnd(onMouseMove, cleanUp);
61839
+ }
61749
61840
  }
61750
61841
 
61751
61842
  css /* scss */ `
@@ -62529,7 +62620,6 @@ stores.inject(MyMetaStore, storeInstance);
62529
62620
  .o-spreadsheet {
62530
62621
  position: relative;
62531
62622
  display: grid;
62532
- grid-template-columns: auto 350px;
62533
62623
  color: #333;
62534
62624
  font-size: 14px;
62535
62625
 
@@ -62727,6 +62817,7 @@ stores.inject(MyMetaStore, storeInstance);
62727
62817
  };
62728
62818
  sidePanel;
62729
62819
  spreadsheetRef = owl.useRef("spreadsheet");
62820
+ spreadsheetRect = useSpreadsheetRect();
62730
62821
  _focusGrid;
62731
62822
  keyDownMapping;
62732
62823
  isViewportTooSmall = false;
@@ -62736,10 +62827,15 @@ stores.inject(MyMetaStore, storeInstance);
62736
62827
  return this.props.model;
62737
62828
  }
62738
62829
  getStyle() {
62830
+ const properties = {};
62739
62831
  if (this.env.isDashboard()) {
62740
- return `grid-template-rows: auto;`;
62832
+ properties["grid-template-rows"] = `auto`;
62833
+ }
62834
+ else {
62835
+ properties["grid-template-rows"] = `${TOPBAR_HEIGHT}px auto ${BOTTOMBAR_HEIGHT + 1}px`;
62741
62836
  }
62742
- return `grid-template-rows: ${TOPBAR_HEIGHT}px auto ${BOTTOMBAR_HEIGHT + 1}px`;
62837
+ properties["grid-template-columns"] = `auto ${this.sidePanel.panelSize}px`;
62838
+ return cssPropertiesToCss(properties);
62743
62839
  }
62744
62840
  setup() {
62745
62841
  const stores = useStoreProvider();
@@ -62799,14 +62895,19 @@ stores.inject(MyMetaStore, storeInstance);
62799
62895
  owl.onMounted(() => {
62800
62896
  this.checkViewportSize();
62801
62897
  stores.on("store-updated", this, render);
62898
+ resizeObserver.observe(this.spreadsheetRef.el);
62802
62899
  });
62803
62900
  owl.onWillUnmount(() => {
62804
62901
  this.unbindModelEvents();
62805
62902
  stores.off("store-updated", this);
62903
+ resizeObserver.disconnect();
62806
62904
  });
62807
62905
  owl.onPatched(() => {
62808
62906
  this.checkViewportSize();
62809
62907
  });
62908
+ const resizeObserver = new ResizeObserver(() => {
62909
+ this.sidePanel.changePanelSize(this.sidePanel.panelSize, this.spreadsheetRect.width);
62910
+ });
62810
62911
  }
62811
62912
  bindModelEvents() {
62812
62913
  this.model.on("update", this, () => this.render(true));
@@ -66861,6 +66962,8 @@ stores.inject(MyMetaStore, storeInstance);
66861
66962
  insertTokenAfterLeftParenthesis,
66862
66963
  mergeContiguousZones,
66863
66964
  getPivotHighlights,
66965
+ toPivotDomain,
66966
+ flatPivotDomain,
66864
66967
  pivotTimeAdapter,
66865
66968
  UNDO_REDO_PIVOT_COMMANDS,
66866
66969
  };
@@ -66905,6 +67008,7 @@ stores.inject(MyMetaStore, storeInstance);
66905
67008
  PivotDimension,
66906
67009
  PivotLayoutConfigurator,
66907
67010
  EditableName,
67011
+ PivotDeferUpdate,
66908
67012
  };
66909
67013
  const hooks = {
66910
67014
  useDragAndDropListItems,
@@ -66988,9 +67092,9 @@ stores.inject(MyMetaStore, storeInstance);
66988
67092
  exports.tokenize = tokenize;
66989
67093
 
66990
67094
 
66991
- __info__.version = "17.4.0-alpha.1";
66992
- __info__.date = "2024-06-03T15:30:28.283Z";
66993
- __info__.hash = "cb56c37";
67095
+ __info__.version = "17.4.0-alpha.3";
67096
+ __info__.date = "2024-06-10T09:38:53.982Z";
67097
+ __info__.hash = "a45ed6a";
66994
67098
 
66995
67099
 
66996
67100
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);