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