@odoo/o-spreadsheet 17.4.0-alpha.1 → 17.4.0-alpha.2
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.
- package/dist/o-spreadsheet.cjs.js +340 -262
- package/dist/o-spreadsheet.d.ts +78 -62
- package/dist/o-spreadsheet.esm.js +340 -262
- package/dist/o-spreadsheet.iife.js +340 -262
- package/dist/o-spreadsheet.iife.min.js +375 -371
- package/dist/o_spreadsheet.xml +33 -23
- package/package.json +1 -1
|
@@ -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.
|
|
7
|
-
* @date 2024-06-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.4.0-alpha.2
|
|
7
|
+
* @date 2024-06-06T13:31:21.327Z
|
|
8
|
+
* @hash e07794d
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
@@ -18377,6 +18377,131 @@ var logical = /*#__PURE__*/Object.freeze({
|
|
|
18377
18377
|
const supportedPivotExplodedFormulaRegistry = new Registry();
|
|
18378
18378
|
supportedPivotExplodedFormulaRegistry.add("SPREADSHEET", false);
|
|
18379
18379
|
|
|
18380
|
+
const AGGREGATOR_NAMES = {
|
|
18381
|
+
count: _t("Count"),
|
|
18382
|
+
count_distinct: _t("Count Distinct"),
|
|
18383
|
+
bool_and: _t("Boolean And"),
|
|
18384
|
+
bool_or: _t("Boolean Or"),
|
|
18385
|
+
max: _t("Maximum"),
|
|
18386
|
+
min: _t("Minimum"),
|
|
18387
|
+
avg: _t("Average"),
|
|
18388
|
+
sum: _t("Sum"),
|
|
18389
|
+
};
|
|
18390
|
+
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
18391
|
+
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
18392
|
+
integer: NUMBER_CHAR_AGGREGATORS,
|
|
18393
|
+
char: NUMBER_CHAR_AGGREGATORS,
|
|
18394
|
+
//TODO Support for date and boolean
|
|
18395
|
+
};
|
|
18396
|
+
const AGGREGATORS = {};
|
|
18397
|
+
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
|
|
18398
|
+
AGGREGATORS[type] = {};
|
|
18399
|
+
for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
|
|
18400
|
+
AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
|
|
18401
|
+
}
|
|
18402
|
+
}
|
|
18403
|
+
const AGGREGATORS_FN = {
|
|
18404
|
+
count: {
|
|
18405
|
+
fn: (args) => countAny([args]),
|
|
18406
|
+
format: () => "0",
|
|
18407
|
+
},
|
|
18408
|
+
count_distinct: {
|
|
18409
|
+
fn: (args) => countUnique([args]),
|
|
18410
|
+
format: () => "0",
|
|
18411
|
+
},
|
|
18412
|
+
bool_and: {
|
|
18413
|
+
fn: (args) => boolAnd([args]).result,
|
|
18414
|
+
format: () => undefined,
|
|
18415
|
+
},
|
|
18416
|
+
bool_or: {
|
|
18417
|
+
fn: (args) => boolOr([args]).result,
|
|
18418
|
+
format: () => undefined,
|
|
18419
|
+
},
|
|
18420
|
+
max: {
|
|
18421
|
+
fn: (args, locale) => max([args], locale),
|
|
18422
|
+
format: inferFormat,
|
|
18423
|
+
},
|
|
18424
|
+
min: {
|
|
18425
|
+
fn: (args, locale) => min([args], locale),
|
|
18426
|
+
format: inferFormat,
|
|
18427
|
+
},
|
|
18428
|
+
avg: {
|
|
18429
|
+
fn: (args, locale) => average([args], locale),
|
|
18430
|
+
format: inferFormat,
|
|
18431
|
+
},
|
|
18432
|
+
sum: {
|
|
18433
|
+
fn: (args, locale) => sum([args], locale),
|
|
18434
|
+
format: inferFormat,
|
|
18435
|
+
},
|
|
18436
|
+
};
|
|
18437
|
+
/**
|
|
18438
|
+
* Build a pivot formula expression
|
|
18439
|
+
*/
|
|
18440
|
+
function makePivotFormula(formula, args) {
|
|
18441
|
+
return `=${formula}(${args
|
|
18442
|
+
.map((arg) => {
|
|
18443
|
+
const stringIsNumber = typeof arg == "string" && !isNaN(Number(arg)) && Number(arg).toString() === arg;
|
|
18444
|
+
const convertToNumber = typeof arg == "number" || stringIsNumber;
|
|
18445
|
+
return convertToNumber ? `${arg}` : `"${arg.toString().replace(/"/g, '\\"')}"`;
|
|
18446
|
+
})
|
|
18447
|
+
.join(",")})`;
|
|
18448
|
+
}
|
|
18449
|
+
/**
|
|
18450
|
+
* Given an object of form {"1": {...}, "2": {...}, ...} get the maximum ID used
|
|
18451
|
+
* in this object
|
|
18452
|
+
* If the object has no keys, return 0
|
|
18453
|
+
*
|
|
18454
|
+
*/
|
|
18455
|
+
function getMaxObjectId(o) {
|
|
18456
|
+
const keys = Object.keys(o);
|
|
18457
|
+
if (!keys.length) {
|
|
18458
|
+
return 0;
|
|
18459
|
+
}
|
|
18460
|
+
const nums = keys.map((id) => parseInt(id, 10));
|
|
18461
|
+
const max = Math.max(...nums);
|
|
18462
|
+
return max;
|
|
18463
|
+
}
|
|
18464
|
+
const ALL_PERIODS = {
|
|
18465
|
+
year: _t("Year"),
|
|
18466
|
+
quarter: _t("Quarter"),
|
|
18467
|
+
month: _t("Month"),
|
|
18468
|
+
week: _t("Week"),
|
|
18469
|
+
day: _t("Day"),
|
|
18470
|
+
year_number: _t("Year"),
|
|
18471
|
+
quarter_number: _t("Quarter"),
|
|
18472
|
+
month_number: _t("Month"),
|
|
18473
|
+
iso_week_number: _t("Week"),
|
|
18474
|
+
day_of_month: _t("Day of Month"),
|
|
18475
|
+
};
|
|
18476
|
+
const DATE_FIELDS = ["date", "datetime"];
|
|
18477
|
+
/**
|
|
18478
|
+
* Parse a dimension string into a pivot dimension definition.
|
|
18479
|
+
* e.g "create_date:month" => { name: "create_date", granularity: "month" }
|
|
18480
|
+
*/
|
|
18481
|
+
function parseDimension(dimension) {
|
|
18482
|
+
const [name, granularity] = dimension.split(":");
|
|
18483
|
+
if (granularity) {
|
|
18484
|
+
return { name, granularity };
|
|
18485
|
+
}
|
|
18486
|
+
return { name };
|
|
18487
|
+
}
|
|
18488
|
+
function isDateField(field) {
|
|
18489
|
+
return DATE_FIELDS.includes(field.type);
|
|
18490
|
+
}
|
|
18491
|
+
function toPivotDomain(domainStr) {
|
|
18492
|
+
if (domainStr.length % 2 !== 0) {
|
|
18493
|
+
throw new Error("Invalid domain: odd number of elements");
|
|
18494
|
+
}
|
|
18495
|
+
const domain = [];
|
|
18496
|
+
for (let i = 0; i < domainStr.length - 1; i += 2) {
|
|
18497
|
+
domain.push({ field: domainStr[i], value: domainStr[i + 1] });
|
|
18498
|
+
}
|
|
18499
|
+
return domain;
|
|
18500
|
+
}
|
|
18501
|
+
function flatPivotDomain(domain) {
|
|
18502
|
+
return domain.flatMap((arg) => [arg.field, arg.value]);
|
|
18503
|
+
}
|
|
18504
|
+
|
|
18380
18505
|
/**
|
|
18381
18506
|
* Get the pivot ID from the formula pivot ID.
|
|
18382
18507
|
*/
|
|
@@ -18856,13 +18981,13 @@ const PIVOT_VALUE = {
|
|
|
18856
18981
|
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
|
|
18857
18982
|
arg("domain_value (string,optional,repeating)", _t("Value.")),
|
|
18858
18983
|
],
|
|
18859
|
-
compute: function (formulaId, measureName, ...
|
|
18984
|
+
compute: function (formulaId, measureName, ...domainArgs) {
|
|
18860
18985
|
const _pivotFormulaId = toString(formulaId);
|
|
18861
|
-
const
|
|
18862
|
-
const
|
|
18986
|
+
const _measure = toString(measureName);
|
|
18987
|
+
const _domainArgs = domainArgs.map(toString);
|
|
18863
18988
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18864
|
-
assertMeasureExist(pivotId,
|
|
18865
|
-
assertDomainLength(
|
|
18989
|
+
assertMeasureExist(pivotId, _measure, this.getters);
|
|
18990
|
+
assertDomainLength(_domainArgs);
|
|
18866
18991
|
const pivot = this.getters.getPivot(pivotId);
|
|
18867
18992
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18868
18993
|
if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
|
|
@@ -18876,8 +19001,9 @@ const PIVOT_VALUE = {
|
|
|
18876
19001
|
if (error) {
|
|
18877
19002
|
return error;
|
|
18878
19003
|
}
|
|
18879
|
-
const
|
|
18880
|
-
|
|
19004
|
+
const domain = toPivotDomain(_domainArgs);
|
|
19005
|
+
const { value, format } = pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
19006
|
+
if (!value && !this.getters.areDomainArgsFieldsValid(pivotId, domain)) {
|
|
18881
19007
|
return {
|
|
18882
19008
|
value: CellErrorType.GenericError,
|
|
18883
19009
|
message: _t("Dimensions don't match the pivot definition"),
|
|
@@ -18894,11 +19020,11 @@ const PIVOT_HEADER = {
|
|
|
18894
19020
|
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
|
|
18895
19021
|
arg("domain_value (string,optional,repeating)", _t("Value.")),
|
|
18896
19022
|
],
|
|
18897
|
-
compute: function (pivotId, ...
|
|
19023
|
+
compute: function (pivotId, ...domainArgs) {
|
|
18898
19024
|
const _pivotFormulaId = toString(pivotId);
|
|
18899
|
-
const
|
|
19025
|
+
const _domainArgs = domainArgs.map(toString);
|
|
18900
19026
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18901
|
-
assertDomainLength(
|
|
19027
|
+
assertDomainLength(_domainArgs);
|
|
18902
19028
|
const pivot = this.getters.getPivot(_pivotId);
|
|
18903
19029
|
const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
|
|
18904
19030
|
if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
|
|
@@ -18912,18 +19038,23 @@ const PIVOT_HEADER = {
|
|
|
18912
19038
|
if (error) {
|
|
18913
19039
|
return error;
|
|
18914
19040
|
}
|
|
18915
|
-
const
|
|
18916
|
-
const
|
|
18917
|
-
if (!this.getters.areDomainArgsFieldsValid(_pivotId,
|
|
19041
|
+
const domain = toPivotDomain(_domainArgs);
|
|
19042
|
+
const lastNode = domain.at(-1);
|
|
19043
|
+
if (!this.getters.areDomainArgsFieldsValid(_pivotId, lastNode?.field === "measure" ? domain.slice(0, -1) : domain)) {
|
|
18918
19044
|
return {
|
|
18919
19045
|
value: CellErrorType.GenericError,
|
|
18920
19046
|
message: _t("Dimensions don't match the pivot definition"),
|
|
18921
19047
|
};
|
|
18922
19048
|
}
|
|
18923
|
-
|
|
19049
|
+
if (lastNode?.field === "measure") {
|
|
19050
|
+
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
19051
|
+
}
|
|
19052
|
+
const { value, format } = pivot.getPivotHeaderValueAndFormat(domain);
|
|
18924
19053
|
return {
|
|
18925
19054
|
value,
|
|
18926
|
-
format: !
|
|
19055
|
+
format: !lastNode || lastNode.field === "measure" || lastNode.value === "false"
|
|
19056
|
+
? undefined
|
|
19057
|
+
: format,
|
|
18927
19058
|
};
|
|
18928
19059
|
},
|
|
18929
19060
|
returns: ["NUMBER", "STRING"],
|
|
@@ -18936,11 +19067,14 @@ const PIVOT = {
|
|
|
18936
19067
|
arg("include_total (boolean, default=TRUE)", _t("Whether to include total/sub-totals or not.")),
|
|
18937
19068
|
arg("include_column_titles (boolean, default=TRUE)", _t("Whether to include the column titles or not.")),
|
|
18938
19069
|
],
|
|
18939
|
-
compute: function (
|
|
18940
|
-
const _pivotFormulaId = toString(
|
|
18941
|
-
const
|
|
18942
|
-
const
|
|
18943
|
-
const
|
|
19070
|
+
compute: function (pivotFormulaId, rowCount = { value: 10000 }, includeTotal = { value: true }, includeColumnHeaders = { value: true }) {
|
|
19071
|
+
const _pivotFormulaId = toString(pivotFormulaId);
|
|
19072
|
+
const _rowCount = toNumber(rowCount, this.locale);
|
|
19073
|
+
const _includeColumnHeaders = toBoolean(includeColumnHeaders);
|
|
19074
|
+
const _includedTotal = toBoolean(includeTotal);
|
|
19075
|
+
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19076
|
+
const pivot = this.getters.getPivot(pivotId);
|
|
19077
|
+
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18944
19078
|
addPivotDependencies(this, coreDefinition);
|
|
18945
19079
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18946
19080
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
@@ -18948,11 +19082,9 @@ const PIVOT = {
|
|
|
18948
19082
|
return error;
|
|
18949
19083
|
}
|
|
18950
19084
|
const table = pivot.getTableStructure();
|
|
18951
|
-
const
|
|
18952
|
-
const cells = table.getPivotCells(toBoolean(includeTotal), _includeColumnHeaders);
|
|
19085
|
+
const cells = table.getPivotCells(_includedTotal, _includeColumnHeaders);
|
|
18953
19086
|
const headerRows = _includeColumnHeaders ? table.columns.length : 0;
|
|
18954
|
-
const pivotTitle = this.getters.getPivotDisplayName(
|
|
18955
|
-
const _rowCount = toNumber(rowCount, this.locale);
|
|
19087
|
+
const pivotTitle = this.getters.getPivotDisplayName(pivotId);
|
|
18956
19088
|
if (_rowCount < 0) {
|
|
18957
19089
|
throw new EvaluationError(_t("The number of rows must be positive."));
|
|
18958
19090
|
}
|
|
@@ -18967,17 +19099,23 @@ const PIVOT = {
|
|
|
18967
19099
|
result[col] = [];
|
|
18968
19100
|
for (const row of tableRows) {
|
|
18969
19101
|
const pivotCell = cells[col][row];
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
19102
|
+
switch (pivotCell.type) {
|
|
19103
|
+
case "EMPTY":
|
|
19104
|
+
result[col].push({ value: "" });
|
|
19105
|
+
break;
|
|
19106
|
+
case "HEADER":
|
|
19107
|
+
const domain = pivotCell.domain;
|
|
19108
|
+
const lastNode = domain.at(-1);
|
|
19109
|
+
if (lastNode?.field === "measure") {
|
|
19110
|
+
result[col].push(pivot.getPivotMeasureValue(toString(lastNode.value), domain));
|
|
19111
|
+
}
|
|
19112
|
+
else {
|
|
19113
|
+
result[col].push(pivot.getPivotHeaderValueAndFormat(domain));
|
|
19114
|
+
}
|
|
19115
|
+
break;
|
|
19116
|
+
case "VALUE":
|
|
19117
|
+
result[col].push(pivot.getPivotCellValueAndFormat(pivotCell.measure, pivotCell.domain));
|
|
19118
|
+
break;
|
|
18981
19119
|
}
|
|
18982
19120
|
}
|
|
18983
19121
|
}
|
|
@@ -20902,8 +21040,15 @@ class Composer extends owl.Component {
|
|
|
20902
21040
|
}
|
|
20903
21041
|
onPaste(ev) {
|
|
20904
21042
|
if (this.composerStore.editionMode !== "inactive") {
|
|
21043
|
+
// let the browser clipboard work
|
|
20905
21044
|
ev.stopPropagation();
|
|
20906
21045
|
}
|
|
21046
|
+
else {
|
|
21047
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
21048
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
21049
|
+
// the native "paste" to occur.
|
|
21050
|
+
ev.preventDefault();
|
|
21051
|
+
}
|
|
20907
21052
|
}
|
|
20908
21053
|
/*
|
|
20909
21054
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -20912,9 +21057,6 @@ class Composer extends owl.Component {
|
|
|
20912
21057
|
if (!this.shouldProcessInputEvents) {
|
|
20913
21058
|
return;
|
|
20914
21059
|
}
|
|
20915
|
-
if (ev.inputType === "insertFromPaste" && this.composerStore.editionMode === "inactive") {
|
|
20916
|
-
return;
|
|
20917
|
-
}
|
|
20918
21060
|
ev.stopPropagation();
|
|
20919
21061
|
let content;
|
|
20920
21062
|
if (this.composerStore.editionMode === "inactive") {
|
|
@@ -21567,132 +21709,8 @@ function getFunctionsFromAST(ast, functionNames) {
|
|
|
21567
21709
|
}
|
|
21568
21710
|
|
|
21569
21711
|
const PIVOT_FUNCTIONS = ["PIVOT.VALUE", "PIVOT.HEADER", "PIVOT"];
|
|
21570
|
-
const AGGREGATOR_NAMES = {
|
|
21571
|
-
count: _t("Count"),
|
|
21572
|
-
count_distinct: _t("Count Distinct"),
|
|
21573
|
-
bool_and: _t("Boolean And"),
|
|
21574
|
-
bool_or: _t("Boolean Or"),
|
|
21575
|
-
max: _t("Maximum"),
|
|
21576
|
-
min: _t("Minimum"),
|
|
21577
|
-
avg: _t("Average"),
|
|
21578
|
-
sum: _t("Sum"),
|
|
21579
|
-
};
|
|
21580
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
21581
|
-
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
21582
|
-
integer: NUMBER_CHAR_AGGREGATORS,
|
|
21583
|
-
char: NUMBER_CHAR_AGGREGATORS,
|
|
21584
|
-
//TODO Support for date and boolean
|
|
21585
|
-
};
|
|
21586
|
-
const AGGREGATORS = {};
|
|
21587
|
-
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
|
|
21588
|
-
AGGREGATORS[type] = {};
|
|
21589
|
-
for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
|
|
21590
|
-
AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
|
|
21591
|
-
}
|
|
21592
|
-
}
|
|
21593
|
-
const AGGREGATORS_FN = {
|
|
21594
|
-
count: {
|
|
21595
|
-
fn: (args) => countAny([args]),
|
|
21596
|
-
format: () => "0",
|
|
21597
|
-
},
|
|
21598
|
-
count_distinct: {
|
|
21599
|
-
fn: (args) => countUnique([args]),
|
|
21600
|
-
format: () => "0",
|
|
21601
|
-
},
|
|
21602
|
-
bool_and: {
|
|
21603
|
-
fn: (args) => boolAnd([args]).result,
|
|
21604
|
-
format: () => undefined,
|
|
21605
|
-
},
|
|
21606
|
-
bool_or: {
|
|
21607
|
-
fn: (args) => boolOr([args]).result,
|
|
21608
|
-
format: () => undefined,
|
|
21609
|
-
},
|
|
21610
|
-
max: {
|
|
21611
|
-
fn: (args, locale) => max([args], locale),
|
|
21612
|
-
format: inferFormat,
|
|
21613
|
-
},
|
|
21614
|
-
min: {
|
|
21615
|
-
fn: (args, locale) => min([args], locale),
|
|
21616
|
-
format: inferFormat,
|
|
21617
|
-
},
|
|
21618
|
-
avg: {
|
|
21619
|
-
fn: (args, locale) => average([args], locale),
|
|
21620
|
-
format: inferFormat,
|
|
21621
|
-
},
|
|
21622
|
-
sum: {
|
|
21623
|
-
fn: (args, locale) => sum([args], locale),
|
|
21624
|
-
format: inferFormat,
|
|
21625
|
-
},
|
|
21626
|
-
};
|
|
21627
|
-
/**
|
|
21628
|
-
* Build a pivot formula expression
|
|
21629
|
-
*/
|
|
21630
|
-
function makePivotFormula(formula, args) {
|
|
21631
|
-
return `=${formula}(${args
|
|
21632
|
-
.map((arg) => {
|
|
21633
|
-
const stringIsNumber = typeof arg == "string" && !isNaN(Number(arg)) && Number(arg).toString() === arg;
|
|
21634
|
-
const convertToNumber = typeof arg == "number" || stringIsNumber;
|
|
21635
|
-
return convertToNumber ? `${arg}` : `"${arg.toString().replace(/"/g, '\\"')}"`;
|
|
21636
|
-
})
|
|
21637
|
-
.join(",")})`;
|
|
21638
|
-
}
|
|
21639
|
-
/**
|
|
21640
|
-
* Given an object of form {"1": {...}, "2": {...}, ...} get the maximum ID used
|
|
21641
|
-
* in this object
|
|
21642
|
-
* If the object has no keys, return 0
|
|
21643
|
-
*
|
|
21644
|
-
*/
|
|
21645
|
-
function getMaxObjectId(o) {
|
|
21646
|
-
const keys = Object.keys(o);
|
|
21647
|
-
if (!keys.length) {
|
|
21648
|
-
return 0;
|
|
21649
|
-
}
|
|
21650
|
-
const nums = keys.map((id) => parseInt(id, 10));
|
|
21651
|
-
const max = Math.max(...nums);
|
|
21652
|
-
return max;
|
|
21653
|
-
}
|
|
21654
|
-
/**
|
|
21655
|
-
* Get the first Pivot function description of the given formula.
|
|
21656
|
-
*/
|
|
21657
|
-
function getFirstPivotFunction(tokens) {
|
|
21658
|
-
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
|
|
21659
|
-
}
|
|
21660
|
-
/**
|
|
21661
|
-
* Parse a spreadsheet formula and detect the number of PIVOT functions that are
|
|
21662
|
-
* present in the given formula.
|
|
21663
|
-
*/
|
|
21664
|
-
function getNumberOfPivotFunctions(tokens) {
|
|
21665
|
-
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS).length;
|
|
21666
|
-
}
|
|
21667
|
-
const ALL_PERIODS = {
|
|
21668
|
-
year: _t("Year"),
|
|
21669
|
-
quarter: _t("Quarter"),
|
|
21670
|
-
month: _t("Month"),
|
|
21671
|
-
week: _t("Week"),
|
|
21672
|
-
day: _t("Day"),
|
|
21673
|
-
year_number: _t("Year"),
|
|
21674
|
-
quarter_number: _t("Quarter"),
|
|
21675
|
-
month_number: _t("Month"),
|
|
21676
|
-
iso_week_number: _t("Week"),
|
|
21677
|
-
day_of_month: _t("Day of Month"),
|
|
21678
|
-
};
|
|
21679
|
-
const DATE_FIELDS = ["date", "datetime"];
|
|
21680
|
-
/**
|
|
21681
|
-
* Parse a dimension string into a pivot dimension definition.
|
|
21682
|
-
* e.g "create_date:month" => { name: "create_date", granularity: "month" }
|
|
21683
|
-
*/
|
|
21684
|
-
function parseDimension(dimension) {
|
|
21685
|
-
const [name, granularity] = dimension.split(":");
|
|
21686
|
-
if (granularity) {
|
|
21687
|
-
return { name, granularity };
|
|
21688
|
-
}
|
|
21689
|
-
return { name };
|
|
21690
|
-
}
|
|
21691
|
-
function isDateField(field) {
|
|
21692
|
-
return DATE_FIELDS.includes(field.type);
|
|
21693
|
-
}
|
|
21694
21712
|
/**
|
|
21695
|
-
* Create a proposal entry for the compose
|
|
21713
|
+
* Create a proposal entry for the compose autowcomplete
|
|
21696
21714
|
* to insert a field name string in a formula.
|
|
21697
21715
|
*/
|
|
21698
21716
|
function makeFieldProposal(field, granularity) {
|
|
@@ -21748,15 +21766,18 @@ function extractFormulaIdFromToken(tokenAtCursor) {
|
|
|
21748
21766
|
}
|
|
21749
21767
|
return idAst.value;
|
|
21750
21768
|
}
|
|
21751
|
-
|
|
21752
|
-
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21759
|
-
|
|
21769
|
+
/**
|
|
21770
|
+
* Get the first Pivot function description of the given formula.
|
|
21771
|
+
*/
|
|
21772
|
+
function getFirstPivotFunction(tokens) {
|
|
21773
|
+
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
|
|
21774
|
+
}
|
|
21775
|
+
/**
|
|
21776
|
+
* Parse a spreadsheet formula and detect the number of PIVOT functions that are
|
|
21777
|
+
* present in the given formula.
|
|
21778
|
+
*/
|
|
21779
|
+
function getNumberOfPivotFunctions(tokens) {
|
|
21780
|
+
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS).length;
|
|
21760
21781
|
}
|
|
21761
21782
|
|
|
21762
21783
|
autoCompleteProviders.add("pivot_ids", {
|
|
@@ -32784,7 +32805,7 @@ css /* scss */ `
|
|
|
32784
32805
|
vertical-align: middle;
|
|
32785
32806
|
}
|
|
32786
32807
|
.o_cf_radio_item {
|
|
32787
|
-
margin-right:
|
|
32808
|
+
margin-right: 30px;
|
|
32788
32809
|
}
|
|
32789
32810
|
.radio input:checked {
|
|
32790
32811
|
color: #e9ecef;
|
|
@@ -32804,6 +32825,9 @@ css /* scss */ `
|
|
|
32804
32825
|
}
|
|
32805
32826
|
margin-top: 10px;
|
|
32806
32827
|
display: flex;
|
|
32828
|
+
.form-check {
|
|
32829
|
+
padding-left: 1rem;
|
|
32830
|
+
}
|
|
32807
32831
|
}
|
|
32808
32832
|
.o-section-subtitle:first-child {
|
|
32809
32833
|
margin-top: 0px;
|
|
@@ -32812,7 +32836,7 @@ css /* scss */ `
|
|
|
32812
32836
|
font-size: 12px;
|
|
32813
32837
|
line-height: 1.5;
|
|
32814
32838
|
.o-selection-cf {
|
|
32815
|
-
margin-bottom:
|
|
32839
|
+
margin-bottom: 9px;
|
|
32816
32840
|
}
|
|
32817
32841
|
.o-cell-content {
|
|
32818
32842
|
font-size: 12px;
|
|
@@ -32853,7 +32877,7 @@ css /* scss */ `
|
|
|
32853
32877
|
width: 100%;
|
|
32854
32878
|
}
|
|
32855
32879
|
.o-threshold-value {
|
|
32856
|
-
margin-left:
|
|
32880
|
+
margin-left: 6px;
|
|
32857
32881
|
width: 20%;
|
|
32858
32882
|
min-width: 0px; // input overflows in Firefox otherwise
|
|
32859
32883
|
}
|
|
@@ -32882,8 +32906,8 @@ css /* scss */ `
|
|
|
32882
32906
|
justify-content: space-between;
|
|
32883
32907
|
.o-cf-icon {
|
|
32884
32908
|
display: inline;
|
|
32885
|
-
margin-left:
|
|
32886
|
-
margin-right:
|
|
32909
|
+
margin-left: 3px;
|
|
32910
|
+
margin-right: 3px;
|
|
32887
32911
|
}
|
|
32888
32912
|
svg {
|
|
32889
32913
|
vertical-align: baseline;
|
|
@@ -32906,7 +32930,7 @@ css /* scss */ `
|
|
|
32906
32930
|
}
|
|
32907
32931
|
table {
|
|
32908
32932
|
table-layout: fixed;
|
|
32909
|
-
margin-top:
|
|
32933
|
+
margin-top: 6px;
|
|
32910
32934
|
display: table;
|
|
32911
32935
|
text-align: left;
|
|
32912
32936
|
font-size: 12px;
|
|
@@ -32936,8 +32960,8 @@ css /* scss */ `
|
|
|
32936
32960
|
}
|
|
32937
32961
|
}
|
|
32938
32962
|
.o-cf-iconset-reverse {
|
|
32939
|
-
margin-bottom:
|
|
32940
|
-
margin-top:
|
|
32963
|
+
margin-bottom: 6px;
|
|
32964
|
+
margin-top: 6px;
|
|
32941
32965
|
.o-cf-label {
|
|
32942
32966
|
display: inline-block;
|
|
32943
32967
|
vertical-align: bottom;
|
|
@@ -34644,6 +34668,10 @@ css /* scss */ `
|
|
|
34644
34668
|
select > option {
|
|
34645
34669
|
background-color: white;
|
|
34646
34670
|
}
|
|
34671
|
+
|
|
34672
|
+
.pivot-dim-operator-label {
|
|
34673
|
+
min-width: 120px;
|
|
34674
|
+
}
|
|
34647
34675
|
}
|
|
34648
34676
|
`;
|
|
34649
34677
|
class PivotDimension extends owl.Component {
|
|
@@ -34884,7 +34912,7 @@ class PivotRuntimeDefinition {
|
|
|
34884
34912
|
getMeasure(name) {
|
|
34885
34913
|
const measure = this.measures.find((measure) => measure.name === name);
|
|
34886
34914
|
if (!measure) {
|
|
34887
|
-
throw new EvaluationError(_t("Field %s
|
|
34915
|
+
throw new EvaluationError(_t("Field %s is not a measure", name));
|
|
34888
34916
|
}
|
|
34889
34917
|
return measure;
|
|
34890
34918
|
}
|
|
@@ -35010,10 +35038,9 @@ class SpreadsheetPivotTable {
|
|
|
35010
35038
|
columns;
|
|
35011
35039
|
rows;
|
|
35012
35040
|
measures;
|
|
35013
|
-
rowTitle;
|
|
35014
35041
|
maxIndent;
|
|
35015
35042
|
pivotCells = {};
|
|
35016
|
-
constructor(columns, rows, measures
|
|
35043
|
+
constructor(columns, rows, measures) {
|
|
35017
35044
|
this.columns = columns.map((row) => {
|
|
35018
35045
|
// offset in the pivot table
|
|
35019
35046
|
// starts at 1 because the first column is the row title
|
|
@@ -35026,7 +35053,6 @@ class SpreadsheetPivotTable {
|
|
|
35026
35053
|
});
|
|
35027
35054
|
this.rows = rows;
|
|
35028
35055
|
this.measures = measures;
|
|
35029
|
-
this.rowTitle = rowTitle;
|
|
35030
35056
|
this.maxIndent = Math.max(...this.rows.map((row) => row.indent));
|
|
35031
35057
|
}
|
|
35032
35058
|
/**
|
|
@@ -35068,26 +35094,23 @@ class SpreadsheetPivotTable {
|
|
|
35068
35094
|
}
|
|
35069
35095
|
getPivotCell(col, row, includeTotal = true) {
|
|
35070
35096
|
const colHeadersHeight = this.columns.length;
|
|
35071
|
-
if (
|
|
35072
|
-
return { content: this.rowTitle, isHeader: true };
|
|
35073
|
-
}
|
|
35074
|
-
else if (row <= colHeadersHeight - 1) {
|
|
35097
|
+
if (row <= colHeadersHeight - 1) {
|
|
35075
35098
|
const domain = this.getColHeaderDomain(col, row);
|
|
35076
|
-
return {
|
|
35099
|
+
return domain ? { type: "HEADER", domain } : { type: "EMPTY" };
|
|
35077
35100
|
}
|
|
35078
35101
|
else if (col === 0) {
|
|
35079
35102
|
const rowIndex = row - colHeadersHeight;
|
|
35080
35103
|
const domain = this.getRowDomain(rowIndex);
|
|
35081
|
-
return {
|
|
35104
|
+
return { type: "HEADER", domain };
|
|
35082
35105
|
}
|
|
35083
35106
|
else {
|
|
35084
35107
|
const rowIndex = row - colHeadersHeight;
|
|
35085
35108
|
if (!includeTotal && this.isTotalRow(rowIndex)) {
|
|
35086
|
-
return {
|
|
35109
|
+
return { type: "EMPTY" };
|
|
35087
35110
|
}
|
|
35088
35111
|
const domain = [...this.getRowDomain(rowIndex), ...this.getColDomain(col)];
|
|
35089
35112
|
const measure = this.getColMeasure(col);
|
|
35090
|
-
return {
|
|
35113
|
+
return { type: "VALUE", domain, measure };
|
|
35091
35114
|
}
|
|
35092
35115
|
}
|
|
35093
35116
|
getColHeaderDomain(col, row) {
|
|
@@ -35100,24 +35123,32 @@ class SpreadsheetPivotTable {
|
|
|
35100
35123
|
return undefined;
|
|
35101
35124
|
}
|
|
35102
35125
|
for (let i = 0; i < pivotCol.fields.length; i++) {
|
|
35103
|
-
domain.push(
|
|
35104
|
-
|
|
35126
|
+
domain.push({
|
|
35127
|
+
field: pivotCol.fields[i],
|
|
35128
|
+
value: pivotCol.values[i],
|
|
35129
|
+
});
|
|
35105
35130
|
}
|
|
35106
35131
|
return domain;
|
|
35107
35132
|
}
|
|
35108
35133
|
getColDomain(col) {
|
|
35109
35134
|
const domain = this.getColHeaderDomain(col, this.columns.length - 1);
|
|
35110
|
-
return domain ? domain.slice(0, -
|
|
35135
|
+
return domain ? domain.slice(0, -1) : []; // slice: remove measure and value
|
|
35111
35136
|
}
|
|
35112
35137
|
getColMeasure(col) {
|
|
35113
35138
|
const domain = this.getColHeaderDomain(col, this.columns.length - 1);
|
|
35114
|
-
|
|
35139
|
+
const measure = domain?.at(-1)?.value;
|
|
35140
|
+
if (measure === undefined) {
|
|
35141
|
+
throw new Error("Measure isd missing");
|
|
35142
|
+
}
|
|
35143
|
+
return measure.toString();
|
|
35115
35144
|
}
|
|
35116
35145
|
getRowDomain(row) {
|
|
35117
35146
|
const domain = [];
|
|
35118
35147
|
for (let i = 0; i < this.rows[row].fields.length; i++) {
|
|
35119
|
-
domain.push(
|
|
35120
|
-
|
|
35148
|
+
domain.push({
|
|
35149
|
+
field: this.rows[row].fields[i],
|
|
35150
|
+
value: this.rows[row].values[i],
|
|
35151
|
+
});
|
|
35121
35152
|
}
|
|
35122
35153
|
return domain;
|
|
35123
35154
|
}
|
|
@@ -35126,7 +35157,6 @@ class SpreadsheetPivotTable {
|
|
|
35126
35157
|
cols: this.columns,
|
|
35127
35158
|
rows: this.rows,
|
|
35128
35159
|
measures: this.measures,
|
|
35129
|
-
rowTitle: this.rowTitle,
|
|
35130
35160
|
};
|
|
35131
35161
|
}
|
|
35132
35162
|
}
|
|
@@ -35146,8 +35176,7 @@ function dataEntriesToSpreadsheetPivotTable(dataEntries, definition) {
|
|
|
35146
35176
|
indent: 0,
|
|
35147
35177
|
});
|
|
35148
35178
|
const measureNames = definition.measures.map((m) => m.name);
|
|
35149
|
-
|
|
35150
|
-
return new SpreadsheetPivotTable(cols, rows, measureNames, rowTitle);
|
|
35179
|
+
return new SpreadsheetPivotTable(cols, rows, measureNames);
|
|
35151
35180
|
}
|
|
35152
35181
|
// -----------------------------------------------------------------------------
|
|
35153
35182
|
// ROWS
|
|
@@ -35490,7 +35519,10 @@ class SpreadsheetPivot {
|
|
|
35490
35519
|
}
|
|
35491
35520
|
get definition() {
|
|
35492
35521
|
if (!this._definition) {
|
|
35493
|
-
|
|
35522
|
+
this.init();
|
|
35523
|
+
}
|
|
35524
|
+
if (!this._definition) {
|
|
35525
|
+
throw new Error("Pivot definition should be defined at this point.");
|
|
35494
35526
|
}
|
|
35495
35527
|
return this._definition;
|
|
35496
35528
|
}
|
|
@@ -35539,15 +35571,16 @@ class SpreadsheetPivot {
|
|
|
35539
35571
|
getMeasure(name) {
|
|
35540
35572
|
return this.definition.getMeasure(name);
|
|
35541
35573
|
}
|
|
35542
|
-
|
|
35543
|
-
|
|
35574
|
+
getPivotMeasureValue(name) {
|
|
35575
|
+
return {
|
|
35576
|
+
value: this.getMeasure(name).displayName,
|
|
35577
|
+
};
|
|
35578
|
+
}
|
|
35579
|
+
getPivotHeaderValueAndFormat(domain) {
|
|
35544
35580
|
const lastNode = domain.at(-1);
|
|
35545
35581
|
if (!lastNode) {
|
|
35546
35582
|
return { value: _t("Total") };
|
|
35547
35583
|
}
|
|
35548
|
-
if (lastNode.field === "measure") {
|
|
35549
|
-
return { value: this.getMeasure(lastNode.value).displayName };
|
|
35550
|
-
}
|
|
35551
35584
|
const dimension = this.getDimension(lastNode.field);
|
|
35552
35585
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
35553
35586
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
@@ -35575,8 +35608,7 @@ class SpreadsheetPivot {
|
|
|
35575
35608
|
format: finalCell.format,
|
|
35576
35609
|
};
|
|
35577
35610
|
}
|
|
35578
|
-
getPivotCellValueAndFormat(measure,
|
|
35579
|
-
const domain = toDomainArgs(domainStr);
|
|
35611
|
+
getPivotCellValueAndFormat(measure, domain) {
|
|
35580
35612
|
const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
35581
35613
|
if (dataEntries.length === 0) {
|
|
35582
35614
|
return { value: "" };
|
|
@@ -35977,7 +36009,6 @@ class PivotSpreadsheetSidePanel extends owl.Component {
|
|
|
35977
36009
|
state;
|
|
35978
36010
|
setup() {
|
|
35979
36011
|
this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
|
|
35980
|
-
this.pivot.init();
|
|
35981
36012
|
this.state = owl.useState({
|
|
35982
36013
|
range: undefined,
|
|
35983
36014
|
rangeHasChanged: false,
|
|
@@ -36854,7 +36885,7 @@ css /* scss */ `
|
|
|
36854
36885
|
}
|
|
36855
36886
|
|
|
36856
36887
|
.o-table-style-list-item {
|
|
36857
|
-
padding: 3px;
|
|
36888
|
+
padding: 3px 2px;
|
|
36858
36889
|
margin: 2px 1px;
|
|
36859
36890
|
|
|
36860
36891
|
.o-table-style-picker-preview {
|
|
@@ -36875,10 +36906,10 @@ class TableStylePicker extends owl.Component {
|
|
|
36875
36906
|
const styles = Object.keys(allStyles).filter((key) => allStyles[key].category === selectedStyleCategory);
|
|
36876
36907
|
const selectedStyleIndex = styles.indexOf(this.props.table.config.styleId);
|
|
36877
36908
|
if (selectedStyleIndex === -1) {
|
|
36878
|
-
return
|
|
36909
|
+
return selectedStyleIndex;
|
|
36879
36910
|
}
|
|
36880
36911
|
const index = Math.floor(selectedStyleIndex / 4) * 4;
|
|
36881
|
-
return styles.slice(index
|
|
36912
|
+
return styles.slice(index);
|
|
36882
36913
|
}
|
|
36883
36914
|
onStylePicked(styleId) {
|
|
36884
36915
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -37918,10 +37949,7 @@ class GridComposer extends owl.Component {
|
|
|
37918
37949
|
}
|
|
37919
37950
|
get containerStyle() {
|
|
37920
37951
|
if (this.composerStore.editionMode === "inactive") {
|
|
37921
|
-
return `
|
|
37922
|
-
position: absolute;
|
|
37923
|
-
z-index: -1000;
|
|
37924
|
-
`;
|
|
37952
|
+
return `z-index: -1000;`;
|
|
37925
37953
|
}
|
|
37926
37954
|
const isFormula = this.composerStore.currentContent.startsWith("=");
|
|
37927
37955
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -40765,10 +40793,13 @@ class VerticalScrollBar extends owl.Component {
|
|
|
40765
40793
|
}
|
|
40766
40794
|
}
|
|
40767
40795
|
|
|
40796
|
+
const DEFAULT_SIDE_PANEL_SIZE = 350;
|
|
40797
|
+
const MIN_SHEET_VIEW_WIDTH = 150;
|
|
40768
40798
|
class SidePanelStore extends SpreadsheetStore {
|
|
40769
|
-
mutators = ["open", "toggle", "close"];
|
|
40799
|
+
mutators = ["open", "toggle", "close", "changePanelSize", "resetPanelSize"];
|
|
40770
40800
|
initialPanelProps = {};
|
|
40771
40801
|
componentTag = "";
|
|
40802
|
+
panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40772
40803
|
get isOpen() {
|
|
40773
40804
|
if (!this.componentTag) {
|
|
40774
40805
|
return false;
|
|
@@ -40813,6 +40844,20 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
40813
40844
|
this.initialPanelProps = {};
|
|
40814
40845
|
this.componentTag = "";
|
|
40815
40846
|
}
|
|
40847
|
+
changePanelSize(size, spreadsheetElWidth) {
|
|
40848
|
+
if (size < DEFAULT_SIDE_PANEL_SIZE) {
|
|
40849
|
+
this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40850
|
+
}
|
|
40851
|
+
else if (size > spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH) {
|
|
40852
|
+
this.panelSize = Math.max(spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH, DEFAULT_SIDE_PANEL_SIZE);
|
|
40853
|
+
}
|
|
40854
|
+
else {
|
|
40855
|
+
this.panelSize = size;
|
|
40856
|
+
}
|
|
40857
|
+
}
|
|
40858
|
+
resetPanelSize() {
|
|
40859
|
+
this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40860
|
+
}
|
|
40816
40861
|
computeState(componentTag, panelProps) {
|
|
40817
40862
|
const customComputeState = sidePanelRegistry.get(componentTag).computeState;
|
|
40818
40863
|
if (!customComputeState) {
|
|
@@ -41933,7 +41978,7 @@ class XLSXImportWarningManager {
|
|
|
41933
41978
|
}
|
|
41934
41979
|
}
|
|
41935
41980
|
|
|
41936
|
-
const SUPPORTED_BORDER_STYLES = ["thin"];
|
|
41981
|
+
const SUPPORTED_BORDER_STYLES = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
41937
41982
|
const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
|
|
41938
41983
|
"general",
|
|
41939
41984
|
"left",
|
|
@@ -51072,8 +51117,8 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
51072
51117
|
case "INSERT_PIVOT": {
|
|
51073
51118
|
const { sheetId, col, row, pivotId, table } = cmd;
|
|
51074
51119
|
const position = { sheetId, col, row };
|
|
51075
|
-
const { cols, rows, measures
|
|
51076
|
-
const spTable = new SpreadsheetPivotTable(cols, rows, measures
|
|
51120
|
+
const { cols, rows, measures } = table;
|
|
51121
|
+
const spTable = new SpreadsheetPivotTable(cols, rows, measures);
|
|
51077
51122
|
const formulaId = this.getPivotFormulaId(pivotId);
|
|
51078
51123
|
this.insertPivot(position, formulaId, spTable);
|
|
51079
51124
|
break;
|
|
@@ -51202,13 +51247,18 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
51202
51247
|
}
|
|
51203
51248
|
}
|
|
51204
51249
|
addPivotFormula(position, formulaId, pivotCell) {
|
|
51205
|
-
|
|
51206
|
-
|
|
51207
|
-
|
|
51208
|
-
|
|
51250
|
+
let content = undefined;
|
|
51251
|
+
switch (pivotCell.type) {
|
|
51252
|
+
case "HEADER":
|
|
51253
|
+
content = makePivotFormula("PIVOT.HEADER", [formulaId, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
|
|
51254
|
+
break;
|
|
51255
|
+
case "VALUE":
|
|
51256
|
+
content = makePivotFormula("PIVOT.VALUE", [formulaId, pivotCell.measure, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
|
|
51257
|
+
break;
|
|
51258
|
+
}
|
|
51209
51259
|
this.dispatch("UPDATE_CELL", {
|
|
51210
51260
|
...position,
|
|
51211
|
-
content
|
|
51261
|
+
content,
|
|
51212
51262
|
});
|
|
51213
51263
|
}
|
|
51214
51264
|
getPivotCore(pivotId) {
|
|
@@ -51227,7 +51277,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
51227
51277
|
import(data) {
|
|
51228
51278
|
if (data.pivots) {
|
|
51229
51279
|
for (const [id, pivot] of Object.entries(data.pivots)) {
|
|
51230
|
-
this.addPivot(id,
|
|
51280
|
+
this.addPivot(id, pivot, pivot.formulaId);
|
|
51231
51281
|
}
|
|
51232
51282
|
}
|
|
51233
51283
|
this.history.update("nextFormulaId", data.pivotNextId || getMaxObjectId(this.pivots) + 1);
|
|
@@ -54568,15 +54618,18 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
54568
54618
|
const pivotCol = position.col - mainPosition.col;
|
|
54569
54619
|
const pivotRow = position.row - mainPosition.row;
|
|
54570
54620
|
const pivotCell = pivotCells[pivotCol][pivotRow];
|
|
54621
|
+
if (pivotCell.type === "EMPTY") {
|
|
54622
|
+
return undefined;
|
|
54623
|
+
}
|
|
54571
54624
|
const domain = pivotCell.domain;
|
|
54572
|
-
if (domain
|
|
54573
|
-
return domain.slice(0, -
|
|
54625
|
+
if (domain.at(-1)?.field === "measure") {
|
|
54626
|
+
return domain.slice(0, -1);
|
|
54574
54627
|
}
|
|
54575
54628
|
return domain;
|
|
54576
54629
|
}
|
|
54577
|
-
const domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
|
|
54578
|
-
if (domain.at(-
|
|
54579
|
-
return domain.slice(0, -
|
|
54630
|
+
const domain = toPivotDomain(args.slice(functionName === "PIVOT.VALUE" ? 2 : 1).map((x) => `${x}`));
|
|
54631
|
+
if (domain.at(-1)?.field === "measure") {
|
|
54632
|
+
return domain.slice(0, -1);
|
|
54580
54633
|
}
|
|
54581
54634
|
return domain;
|
|
54582
54635
|
}
|
|
@@ -54591,9 +54644,9 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
54591
54644
|
* a pivot function are valid according to the pivot definition.
|
|
54592
54645
|
* e.g. =PIVOT.VALUE(1,"revenue","country_id",...,"create_date:month",...,"source_id",...)
|
|
54593
54646
|
*/
|
|
54594
|
-
areDomainArgsFieldsValid(pivotId,
|
|
54595
|
-
const dimensions =
|
|
54596
|
-
.
|
|
54647
|
+
areDomainArgsFieldsValid(pivotId, domain) {
|
|
54648
|
+
const dimensions = domain
|
|
54649
|
+
.map((node) => node.field)
|
|
54597
54650
|
.map((name) => (name.startsWith("#") ? name.slice(1) : name));
|
|
54598
54651
|
let argIndex = 0;
|
|
54599
54652
|
let definitionIndex = 0;
|
|
@@ -61607,6 +61660,10 @@ css /* scss */ `
|
|
|
61607
61660
|
}
|
|
61608
61661
|
}
|
|
61609
61662
|
}
|
|
61663
|
+
.o-sidePanelBody-container {
|
|
61664
|
+
/* This overwrites the min-height: auto; of flex. Without this, a flex div cannot be smaller than its children */
|
|
61665
|
+
min-height: 0;
|
|
61666
|
+
}
|
|
61610
61667
|
.o-sidePanelBody {
|
|
61611
61668
|
overflow: auto;
|
|
61612
61669
|
width: 100%;
|
|
@@ -61685,24 +61742,6 @@ css /* scss */ `
|
|
|
61685
61742
|
text-align: left;
|
|
61686
61743
|
}
|
|
61687
61744
|
|
|
61688
|
-
.o-inflection {
|
|
61689
|
-
table {
|
|
61690
|
-
table-layout: fixed;
|
|
61691
|
-
margin-top: 2%;
|
|
61692
|
-
display: table;
|
|
61693
|
-
text-align: left;
|
|
61694
|
-
font-size: 12px;
|
|
61695
|
-
line-height: 18px;
|
|
61696
|
-
width: 100%;
|
|
61697
|
-
}
|
|
61698
|
-
input,
|
|
61699
|
-
select {
|
|
61700
|
-
width: 100%;
|
|
61701
|
-
height: 100%;
|
|
61702
|
-
box-sizing: border-box;
|
|
61703
|
-
}
|
|
61704
|
-
}
|
|
61705
|
-
|
|
61706
61745
|
.o-sidePanel-tools {
|
|
61707
61746
|
color: #333;
|
|
61708
61747
|
font-size: 13px;
|
|
@@ -61721,12 +61760,25 @@ css /* scss */ `
|
|
|
61721
61760
|
}
|
|
61722
61761
|
}
|
|
61723
61762
|
}
|
|
61763
|
+
|
|
61764
|
+
.o-sidePanel-handle-container {
|
|
61765
|
+
width: 8px;
|
|
61766
|
+
}
|
|
61767
|
+
.o-sidePanel-handle {
|
|
61768
|
+
cursor: col-resize;
|
|
61769
|
+
color: #a9a9a9;
|
|
61770
|
+
.o-icon {
|
|
61771
|
+
height: 25px;
|
|
61772
|
+
margin-left: -5px;
|
|
61773
|
+
}
|
|
61774
|
+
}
|
|
61724
61775
|
}
|
|
61725
61776
|
`;
|
|
61726
61777
|
class SidePanel extends owl.Component {
|
|
61727
61778
|
static template = "o-spreadsheet-SidePanel";
|
|
61728
61779
|
static props = {};
|
|
61729
61780
|
sidePanelStore;
|
|
61781
|
+
spreadsheetRect = useSpreadsheetRect();
|
|
61730
61782
|
setup() {
|
|
61731
61783
|
this.sidePanelStore = useStore(SidePanelStore);
|
|
61732
61784
|
owl.useEffect((isOpen) => {
|
|
@@ -61747,6 +61799,20 @@ class SidePanel extends owl.Component {
|
|
|
61747
61799
|
? panel.title(this.env, this.sidePanelStore.panelProps)
|
|
61748
61800
|
: panel.title;
|
|
61749
61801
|
}
|
|
61802
|
+
startHandleDrag(ev) {
|
|
61803
|
+
const startingCursor = document.body.style.cursor;
|
|
61804
|
+
const startSize = this.sidePanelStore.panelSize;
|
|
61805
|
+
const startPosition = ev.clientX;
|
|
61806
|
+
const onMouseMove = (ev) => {
|
|
61807
|
+
document.body.style.cursor = "col-resize";
|
|
61808
|
+
const newSize = startSize + startPosition - ev.clientX;
|
|
61809
|
+
this.sidePanelStore.changePanelSize(newSize, this.spreadsheetRect.width);
|
|
61810
|
+
};
|
|
61811
|
+
const cleanUp = () => {
|
|
61812
|
+
document.body.style.cursor = startingCursor;
|
|
61813
|
+
};
|
|
61814
|
+
startDnd(onMouseMove, cleanUp);
|
|
61815
|
+
}
|
|
61750
61816
|
}
|
|
61751
61817
|
|
|
61752
61818
|
css /* scss */ `
|
|
@@ -62530,7 +62596,6 @@ css /* scss */ `
|
|
|
62530
62596
|
.o-spreadsheet {
|
|
62531
62597
|
position: relative;
|
|
62532
62598
|
display: grid;
|
|
62533
|
-
grid-template-columns: auto 350px;
|
|
62534
62599
|
color: #333;
|
|
62535
62600
|
font-size: 14px;
|
|
62536
62601
|
|
|
@@ -62728,6 +62793,7 @@ class Spreadsheet extends owl.Component {
|
|
|
62728
62793
|
};
|
|
62729
62794
|
sidePanel;
|
|
62730
62795
|
spreadsheetRef = owl.useRef("spreadsheet");
|
|
62796
|
+
spreadsheetRect = useSpreadsheetRect();
|
|
62731
62797
|
_focusGrid;
|
|
62732
62798
|
keyDownMapping;
|
|
62733
62799
|
isViewportTooSmall = false;
|
|
@@ -62737,10 +62803,15 @@ class Spreadsheet extends owl.Component {
|
|
|
62737
62803
|
return this.props.model;
|
|
62738
62804
|
}
|
|
62739
62805
|
getStyle() {
|
|
62806
|
+
const properties = {};
|
|
62740
62807
|
if (this.env.isDashboard()) {
|
|
62741
|
-
|
|
62808
|
+
properties["grid-template-rows"] = `auto`;
|
|
62742
62809
|
}
|
|
62743
|
-
|
|
62810
|
+
else {
|
|
62811
|
+
properties["grid-template-rows"] = `${TOPBAR_HEIGHT}px auto ${BOTTOMBAR_HEIGHT + 1}px`;
|
|
62812
|
+
}
|
|
62813
|
+
properties["grid-template-columns"] = `auto ${this.sidePanel.panelSize}px`;
|
|
62814
|
+
return cssPropertiesToCss(properties);
|
|
62744
62815
|
}
|
|
62745
62816
|
setup() {
|
|
62746
62817
|
const stores = useStoreProvider();
|
|
@@ -62800,14 +62871,19 @@ class Spreadsheet extends owl.Component {
|
|
|
62800
62871
|
owl.onMounted(() => {
|
|
62801
62872
|
this.checkViewportSize();
|
|
62802
62873
|
stores.on("store-updated", this, render);
|
|
62874
|
+
resizeObserver.observe(this.spreadsheetRef.el);
|
|
62803
62875
|
});
|
|
62804
62876
|
owl.onWillUnmount(() => {
|
|
62805
62877
|
this.unbindModelEvents();
|
|
62806
62878
|
stores.off("store-updated", this);
|
|
62879
|
+
resizeObserver.disconnect();
|
|
62807
62880
|
});
|
|
62808
62881
|
owl.onPatched(() => {
|
|
62809
62882
|
this.checkViewportSize();
|
|
62810
62883
|
});
|
|
62884
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
62885
|
+
this.sidePanel.changePanelSize(this.sidePanel.panelSize, this.spreadsheetRect.width);
|
|
62886
|
+
});
|
|
62811
62887
|
}
|
|
62812
62888
|
bindModelEvents() {
|
|
62813
62889
|
this.model.on("update", this, () => this.render(true));
|
|
@@ -66862,6 +66938,8 @@ const helpers = {
|
|
|
66862
66938
|
insertTokenAfterLeftParenthesis,
|
|
66863
66939
|
mergeContiguousZones,
|
|
66864
66940
|
getPivotHighlights,
|
|
66941
|
+
toPivotDomain,
|
|
66942
|
+
flatPivotDomain,
|
|
66865
66943
|
pivotTimeAdapter,
|
|
66866
66944
|
UNDO_REDO_PIVOT_COMMANDS,
|
|
66867
66945
|
};
|
|
@@ -66989,6 +67067,6 @@ exports.tokenColors = tokenColors;
|
|
|
66989
67067
|
exports.tokenize = tokenize;
|
|
66990
67068
|
|
|
66991
67069
|
|
|
66992
|
-
__info__.version = "17.4.0-alpha.
|
|
66993
|
-
__info__.date = "2024-06-
|
|
66994
|
-
__info__.hash = "
|
|
67070
|
+
__info__.version = "17.4.0-alpha.2";
|
|
67071
|
+
__info__.date = "2024-06-06T13:31:21.327Z";
|
|
67072
|
+
__info__.hash = "e07794d";
|