@odoo/o-spreadsheet 17.4.0-alpha.0 → 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 +353 -265
- package/dist/o-spreadsheet.d.ts +80 -63
- package/dist/o-spreadsheet.esm.js +353 -265
- package/dist/o-spreadsheet.iife.js +353 -265
- 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-
|
|
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
|
(function (exports, owl) {
|
|
@@ -8960,7 +8960,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
8960
8960
|
"askConfirmation",
|
|
8961
8961
|
"updateNotificationCallbacks",
|
|
8962
8962
|
];
|
|
8963
|
-
notifyUser = (notification) => window.alert(notification);
|
|
8963
|
+
notifyUser = (notification) => window.alert(notification.text);
|
|
8964
8964
|
askConfirmation = (content, confirm, cancel) => {
|
|
8965
8965
|
if (window.confirm(content)) {
|
|
8966
8966
|
confirm();
|
|
@@ -18376,6 +18376,131 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18376
18376
|
const supportedPivotExplodedFormulaRegistry = new Registry();
|
|
18377
18377
|
supportedPivotExplodedFormulaRegistry.add("SPREADSHEET", false);
|
|
18378
18378
|
|
|
18379
|
+
const AGGREGATOR_NAMES = {
|
|
18380
|
+
count: _t("Count"),
|
|
18381
|
+
count_distinct: _t("Count Distinct"),
|
|
18382
|
+
bool_and: _t("Boolean And"),
|
|
18383
|
+
bool_or: _t("Boolean Or"),
|
|
18384
|
+
max: _t("Maximum"),
|
|
18385
|
+
min: _t("Minimum"),
|
|
18386
|
+
avg: _t("Average"),
|
|
18387
|
+
sum: _t("Sum"),
|
|
18388
|
+
};
|
|
18389
|
+
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
18390
|
+
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
18391
|
+
integer: NUMBER_CHAR_AGGREGATORS,
|
|
18392
|
+
char: NUMBER_CHAR_AGGREGATORS,
|
|
18393
|
+
//TODO Support for date and boolean
|
|
18394
|
+
};
|
|
18395
|
+
const AGGREGATORS = {};
|
|
18396
|
+
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
|
|
18397
|
+
AGGREGATORS[type] = {};
|
|
18398
|
+
for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
|
|
18399
|
+
AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
|
|
18400
|
+
}
|
|
18401
|
+
}
|
|
18402
|
+
const AGGREGATORS_FN = {
|
|
18403
|
+
count: {
|
|
18404
|
+
fn: (args) => countAny([args]),
|
|
18405
|
+
format: () => "0",
|
|
18406
|
+
},
|
|
18407
|
+
count_distinct: {
|
|
18408
|
+
fn: (args) => countUnique([args]),
|
|
18409
|
+
format: () => "0",
|
|
18410
|
+
},
|
|
18411
|
+
bool_and: {
|
|
18412
|
+
fn: (args) => boolAnd([args]).result,
|
|
18413
|
+
format: () => undefined,
|
|
18414
|
+
},
|
|
18415
|
+
bool_or: {
|
|
18416
|
+
fn: (args) => boolOr([args]).result,
|
|
18417
|
+
format: () => undefined,
|
|
18418
|
+
},
|
|
18419
|
+
max: {
|
|
18420
|
+
fn: (args, locale) => max([args], locale),
|
|
18421
|
+
format: inferFormat,
|
|
18422
|
+
},
|
|
18423
|
+
min: {
|
|
18424
|
+
fn: (args, locale) => min([args], locale),
|
|
18425
|
+
format: inferFormat,
|
|
18426
|
+
},
|
|
18427
|
+
avg: {
|
|
18428
|
+
fn: (args, locale) => average([args], locale),
|
|
18429
|
+
format: inferFormat,
|
|
18430
|
+
},
|
|
18431
|
+
sum: {
|
|
18432
|
+
fn: (args, locale) => sum([args], locale),
|
|
18433
|
+
format: inferFormat,
|
|
18434
|
+
},
|
|
18435
|
+
};
|
|
18436
|
+
/**
|
|
18437
|
+
* Build a pivot formula expression
|
|
18438
|
+
*/
|
|
18439
|
+
function makePivotFormula(formula, args) {
|
|
18440
|
+
return `=${formula}(${args
|
|
18441
|
+
.map((arg) => {
|
|
18442
|
+
const stringIsNumber = typeof arg == "string" && !isNaN(Number(arg)) && Number(arg).toString() === arg;
|
|
18443
|
+
const convertToNumber = typeof arg == "number" || stringIsNumber;
|
|
18444
|
+
return convertToNumber ? `${arg}` : `"${arg.toString().replace(/"/g, '\\"')}"`;
|
|
18445
|
+
})
|
|
18446
|
+
.join(",")})`;
|
|
18447
|
+
}
|
|
18448
|
+
/**
|
|
18449
|
+
* Given an object of form {"1": {...}, "2": {...}, ...} get the maximum ID used
|
|
18450
|
+
* in this object
|
|
18451
|
+
* If the object has no keys, return 0
|
|
18452
|
+
*
|
|
18453
|
+
*/
|
|
18454
|
+
function getMaxObjectId(o) {
|
|
18455
|
+
const keys = Object.keys(o);
|
|
18456
|
+
if (!keys.length) {
|
|
18457
|
+
return 0;
|
|
18458
|
+
}
|
|
18459
|
+
const nums = keys.map((id) => parseInt(id, 10));
|
|
18460
|
+
const max = Math.max(...nums);
|
|
18461
|
+
return max;
|
|
18462
|
+
}
|
|
18463
|
+
const ALL_PERIODS = {
|
|
18464
|
+
year: _t("Year"),
|
|
18465
|
+
quarter: _t("Quarter"),
|
|
18466
|
+
month: _t("Month"),
|
|
18467
|
+
week: _t("Week"),
|
|
18468
|
+
day: _t("Day"),
|
|
18469
|
+
year_number: _t("Year"),
|
|
18470
|
+
quarter_number: _t("Quarter"),
|
|
18471
|
+
month_number: _t("Month"),
|
|
18472
|
+
iso_week_number: _t("Week"),
|
|
18473
|
+
day_of_month: _t("Day of Month"),
|
|
18474
|
+
};
|
|
18475
|
+
const DATE_FIELDS = ["date", "datetime"];
|
|
18476
|
+
/**
|
|
18477
|
+
* Parse a dimension string into a pivot dimension definition.
|
|
18478
|
+
* e.g "create_date:month" => { name: "create_date", granularity: "month" }
|
|
18479
|
+
*/
|
|
18480
|
+
function parseDimension(dimension) {
|
|
18481
|
+
const [name, granularity] = dimension.split(":");
|
|
18482
|
+
if (granularity) {
|
|
18483
|
+
return { name, granularity };
|
|
18484
|
+
}
|
|
18485
|
+
return { name };
|
|
18486
|
+
}
|
|
18487
|
+
function isDateField(field) {
|
|
18488
|
+
return DATE_FIELDS.includes(field.type);
|
|
18489
|
+
}
|
|
18490
|
+
function toPivotDomain(domainStr) {
|
|
18491
|
+
if (domainStr.length % 2 !== 0) {
|
|
18492
|
+
throw new Error("Invalid domain: odd number of elements");
|
|
18493
|
+
}
|
|
18494
|
+
const domain = [];
|
|
18495
|
+
for (let i = 0; i < domainStr.length - 1; i += 2) {
|
|
18496
|
+
domain.push({ field: domainStr[i], value: domainStr[i + 1] });
|
|
18497
|
+
}
|
|
18498
|
+
return domain;
|
|
18499
|
+
}
|
|
18500
|
+
function flatPivotDomain(domain) {
|
|
18501
|
+
return domain.flatMap((arg) => [arg.field, arg.value]);
|
|
18502
|
+
}
|
|
18503
|
+
|
|
18379
18504
|
/**
|
|
18380
18505
|
* Get the pivot ID from the formula pivot ID.
|
|
18381
18506
|
*/
|
|
@@ -18855,13 +18980,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18855
18980
|
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
|
|
18856
18981
|
arg("domain_value (string,optional,repeating)", _t("Value.")),
|
|
18857
18982
|
],
|
|
18858
|
-
compute: function (formulaId, measureName, ...
|
|
18983
|
+
compute: function (formulaId, measureName, ...domainArgs) {
|
|
18859
18984
|
const _pivotFormulaId = toString(formulaId);
|
|
18860
|
-
const
|
|
18861
|
-
const
|
|
18985
|
+
const _measure = toString(measureName);
|
|
18986
|
+
const _domainArgs = domainArgs.map(toString);
|
|
18862
18987
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18863
|
-
assertMeasureExist(pivotId,
|
|
18864
|
-
assertDomainLength(
|
|
18988
|
+
assertMeasureExist(pivotId, _measure, this.getters);
|
|
18989
|
+
assertDomainLength(_domainArgs);
|
|
18865
18990
|
const pivot = this.getters.getPivot(pivotId);
|
|
18866
18991
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18867
18992
|
if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
|
|
@@ -18875,8 +19000,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18875
19000
|
if (error) {
|
|
18876
19001
|
return error;
|
|
18877
19002
|
}
|
|
18878
|
-
const
|
|
18879
|
-
|
|
19003
|
+
const domain = toPivotDomain(_domainArgs);
|
|
19004
|
+
const { value, format } = pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
19005
|
+
if (!value && !this.getters.areDomainArgsFieldsValid(pivotId, domain)) {
|
|
18880
19006
|
return {
|
|
18881
19007
|
value: CellErrorType.GenericError,
|
|
18882
19008
|
message: _t("Dimensions don't match the pivot definition"),
|
|
@@ -18893,11 +19019,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18893
19019
|
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
|
|
18894
19020
|
arg("domain_value (string,optional,repeating)", _t("Value.")),
|
|
18895
19021
|
],
|
|
18896
|
-
compute: function (pivotId, ...
|
|
19022
|
+
compute: function (pivotId, ...domainArgs) {
|
|
18897
19023
|
const _pivotFormulaId = toString(pivotId);
|
|
18898
|
-
const
|
|
19024
|
+
const _domainArgs = domainArgs.map(toString);
|
|
18899
19025
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18900
|
-
assertDomainLength(
|
|
19026
|
+
assertDomainLength(_domainArgs);
|
|
18901
19027
|
const pivot = this.getters.getPivot(_pivotId);
|
|
18902
19028
|
const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
|
|
18903
19029
|
if (!supportedPivotExplodedFormulaRegistry.get(coreDefinition.type)) {
|
|
@@ -18911,18 +19037,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18911
19037
|
if (error) {
|
|
18912
19038
|
return error;
|
|
18913
19039
|
}
|
|
18914
|
-
const
|
|
18915
|
-
const
|
|
18916
|
-
if (!this.getters.areDomainArgsFieldsValid(_pivotId,
|
|
19040
|
+
const domain = toPivotDomain(_domainArgs);
|
|
19041
|
+
const lastNode = domain.at(-1);
|
|
19042
|
+
if (!this.getters.areDomainArgsFieldsValid(_pivotId, lastNode?.field === "measure" ? domain.slice(0, -1) : domain)) {
|
|
18917
19043
|
return {
|
|
18918
19044
|
value: CellErrorType.GenericError,
|
|
18919
19045
|
message: _t("Dimensions don't match the pivot definition"),
|
|
18920
19046
|
};
|
|
18921
19047
|
}
|
|
18922
|
-
|
|
19048
|
+
if (lastNode?.field === "measure") {
|
|
19049
|
+
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
19050
|
+
}
|
|
19051
|
+
const { value, format } = pivot.getPivotHeaderValueAndFormat(domain);
|
|
18923
19052
|
return {
|
|
18924
19053
|
value,
|
|
18925
|
-
format: !
|
|
19054
|
+
format: !lastNode || lastNode.field === "measure" || lastNode.value === "false"
|
|
19055
|
+
? undefined
|
|
19056
|
+
: format,
|
|
18926
19057
|
};
|
|
18927
19058
|
},
|
|
18928
19059
|
returns: ["NUMBER", "STRING"],
|
|
@@ -18935,11 +19066,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18935
19066
|
arg("include_total (boolean, default=TRUE)", _t("Whether to include total/sub-totals or not.")),
|
|
18936
19067
|
arg("include_column_titles (boolean, default=TRUE)", _t("Whether to include the column titles or not.")),
|
|
18937
19068
|
],
|
|
18938
|
-
compute: function (
|
|
18939
|
-
const _pivotFormulaId = toString(
|
|
18940
|
-
const
|
|
18941
|
-
const
|
|
18942
|
-
const
|
|
19069
|
+
compute: function (pivotFormulaId, rowCount = { value: 10000 }, includeTotal = { value: true }, includeColumnHeaders = { value: true }) {
|
|
19070
|
+
const _pivotFormulaId = toString(pivotFormulaId);
|
|
19071
|
+
const _rowCount = toNumber(rowCount, this.locale);
|
|
19072
|
+
const _includeColumnHeaders = toBoolean(includeColumnHeaders);
|
|
19073
|
+
const _includedTotal = toBoolean(includeTotal);
|
|
19074
|
+
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19075
|
+
const pivot = this.getters.getPivot(pivotId);
|
|
19076
|
+
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18943
19077
|
addPivotDependencies(this, coreDefinition);
|
|
18944
19078
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18945
19079
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
@@ -18947,11 +19081,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18947
19081
|
return error;
|
|
18948
19082
|
}
|
|
18949
19083
|
const table = pivot.getTableStructure();
|
|
18950
|
-
const
|
|
18951
|
-
const cells = table.getPivotCells(toBoolean(includeTotal), _includeColumnHeaders);
|
|
19084
|
+
const cells = table.getPivotCells(_includedTotal, _includeColumnHeaders);
|
|
18952
19085
|
const headerRows = _includeColumnHeaders ? table.columns.length : 0;
|
|
18953
|
-
const pivotTitle = this.getters.getPivotDisplayName(
|
|
18954
|
-
const _rowCount = toNumber(rowCount, this.locale);
|
|
19086
|
+
const pivotTitle = this.getters.getPivotDisplayName(pivotId);
|
|
18955
19087
|
if (_rowCount < 0) {
|
|
18956
19088
|
throw new EvaluationError(_t("The number of rows must be positive."));
|
|
18957
19089
|
}
|
|
@@ -18966,17 +19098,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18966
19098
|
result[col] = [];
|
|
18967
19099
|
for (const row of tableRows) {
|
|
18968
19100
|
const pivotCell = cells[col][row];
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
19101
|
+
switch (pivotCell.type) {
|
|
19102
|
+
case "EMPTY":
|
|
19103
|
+
result[col].push({ value: "" });
|
|
19104
|
+
break;
|
|
19105
|
+
case "HEADER":
|
|
19106
|
+
const domain = pivotCell.domain;
|
|
19107
|
+
const lastNode = domain.at(-1);
|
|
19108
|
+
if (lastNode?.field === "measure") {
|
|
19109
|
+
result[col].push(pivot.getPivotMeasureValue(toString(lastNode.value), domain));
|
|
19110
|
+
}
|
|
19111
|
+
else {
|
|
19112
|
+
result[col].push(pivot.getPivotHeaderValueAndFormat(domain));
|
|
19113
|
+
}
|
|
19114
|
+
break;
|
|
19115
|
+
case "VALUE":
|
|
19116
|
+
result[col].push(pivot.getPivotCellValueAndFormat(pivotCell.measure, pivotCell.domain));
|
|
19117
|
+
break;
|
|
18980
19118
|
}
|
|
18981
19119
|
}
|
|
18982
19120
|
}
|
|
@@ -20901,8 +21039,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20901
21039
|
}
|
|
20902
21040
|
onPaste(ev) {
|
|
20903
21041
|
if (this.composerStore.editionMode !== "inactive") {
|
|
21042
|
+
// let the browser clipboard work
|
|
20904
21043
|
ev.stopPropagation();
|
|
20905
21044
|
}
|
|
21045
|
+
else {
|
|
21046
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
21047
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
21048
|
+
// the native "paste" to occur.
|
|
21049
|
+
ev.preventDefault();
|
|
21050
|
+
}
|
|
20906
21051
|
}
|
|
20907
21052
|
/*
|
|
20908
21053
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -20911,9 +21056,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20911
21056
|
if (!this.shouldProcessInputEvents) {
|
|
20912
21057
|
return;
|
|
20913
21058
|
}
|
|
20914
|
-
if (ev.inputType === "insertFromPaste" && this.composerStore.editionMode === "inactive") {
|
|
20915
|
-
return;
|
|
20916
|
-
}
|
|
20917
21059
|
ev.stopPropagation();
|
|
20918
21060
|
let content;
|
|
20919
21061
|
if (this.composerStore.editionMode === "inactive") {
|
|
@@ -21566,132 +21708,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21566
21708
|
}
|
|
21567
21709
|
|
|
21568
21710
|
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
21711
|
/**
|
|
21694
|
-
* Create a proposal entry for the compose
|
|
21712
|
+
* Create a proposal entry for the compose autowcomplete
|
|
21695
21713
|
* to insert a field name string in a formula.
|
|
21696
21714
|
*/
|
|
21697
21715
|
function makeFieldProposal(field, granularity) {
|
|
@@ -21747,15 +21765,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21747
21765
|
}
|
|
21748
21766
|
return idAst.value;
|
|
21749
21767
|
}
|
|
21750
|
-
|
|
21751
|
-
|
|
21752
|
-
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21768
|
+
/**
|
|
21769
|
+
* Get the first Pivot function description of the given formula.
|
|
21770
|
+
*/
|
|
21771
|
+
function getFirstPivotFunction(tokens) {
|
|
21772
|
+
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
|
|
21773
|
+
}
|
|
21774
|
+
/**
|
|
21775
|
+
* Parse a spreadsheet formula and detect the number of PIVOT functions that are
|
|
21776
|
+
* present in the given formula.
|
|
21777
|
+
*/
|
|
21778
|
+
function getNumberOfPivotFunctions(tokens) {
|
|
21779
|
+
return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS).length;
|
|
21759
21780
|
}
|
|
21760
21781
|
|
|
21761
21782
|
autoCompleteProviders.add("pivot_ids", {
|
|
@@ -32783,7 +32804,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32783
32804
|
vertical-align: middle;
|
|
32784
32805
|
}
|
|
32785
32806
|
.o_cf_radio_item {
|
|
32786
|
-
margin-right:
|
|
32807
|
+
margin-right: 30px;
|
|
32787
32808
|
}
|
|
32788
32809
|
.radio input:checked {
|
|
32789
32810
|
color: #e9ecef;
|
|
@@ -32803,6 +32824,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32803
32824
|
}
|
|
32804
32825
|
margin-top: 10px;
|
|
32805
32826
|
display: flex;
|
|
32827
|
+
.form-check {
|
|
32828
|
+
padding-left: 1rem;
|
|
32829
|
+
}
|
|
32806
32830
|
}
|
|
32807
32831
|
.o-section-subtitle:first-child {
|
|
32808
32832
|
margin-top: 0px;
|
|
@@ -32811,7 +32835,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32811
32835
|
font-size: 12px;
|
|
32812
32836
|
line-height: 1.5;
|
|
32813
32837
|
.o-selection-cf {
|
|
32814
|
-
margin-bottom:
|
|
32838
|
+
margin-bottom: 9px;
|
|
32815
32839
|
}
|
|
32816
32840
|
.o-cell-content {
|
|
32817
32841
|
font-size: 12px;
|
|
@@ -32852,7 +32876,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32852
32876
|
width: 100%;
|
|
32853
32877
|
}
|
|
32854
32878
|
.o-threshold-value {
|
|
32855
|
-
margin-left:
|
|
32879
|
+
margin-left: 6px;
|
|
32856
32880
|
width: 20%;
|
|
32857
32881
|
min-width: 0px; // input overflows in Firefox otherwise
|
|
32858
32882
|
}
|
|
@@ -32881,8 +32905,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32881
32905
|
justify-content: space-between;
|
|
32882
32906
|
.o-cf-icon {
|
|
32883
32907
|
display: inline;
|
|
32884
|
-
margin-left:
|
|
32885
|
-
margin-right:
|
|
32908
|
+
margin-left: 3px;
|
|
32909
|
+
margin-right: 3px;
|
|
32886
32910
|
}
|
|
32887
32911
|
svg {
|
|
32888
32912
|
vertical-align: baseline;
|
|
@@ -32905,7 +32929,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32905
32929
|
}
|
|
32906
32930
|
table {
|
|
32907
32931
|
table-layout: fixed;
|
|
32908
|
-
margin-top:
|
|
32932
|
+
margin-top: 6px;
|
|
32909
32933
|
display: table;
|
|
32910
32934
|
text-align: left;
|
|
32911
32935
|
font-size: 12px;
|
|
@@ -32935,8 +32959,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32935
32959
|
}
|
|
32936
32960
|
}
|
|
32937
32961
|
.o-cf-iconset-reverse {
|
|
32938
|
-
margin-bottom:
|
|
32939
|
-
margin-top:
|
|
32962
|
+
margin-bottom: 6px;
|
|
32963
|
+
margin-top: 6px;
|
|
32940
32964
|
.o-cf-label {
|
|
32941
32965
|
display: inline-block;
|
|
32942
32966
|
vertical-align: bottom;
|
|
@@ -34643,6 +34667,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34643
34667
|
select > option {
|
|
34644
34668
|
background-color: white;
|
|
34645
34669
|
}
|
|
34670
|
+
|
|
34671
|
+
.pivot-dim-operator-label {
|
|
34672
|
+
min-width: 120px;
|
|
34673
|
+
}
|
|
34646
34674
|
}
|
|
34647
34675
|
`;
|
|
34648
34676
|
class PivotDimension extends owl.Component {
|
|
@@ -34883,7 +34911,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34883
34911
|
getMeasure(name) {
|
|
34884
34912
|
const measure = this.measures.find((measure) => measure.name === name);
|
|
34885
34913
|
if (!measure) {
|
|
34886
|
-
throw new EvaluationError(_t("Field %s
|
|
34914
|
+
throw new EvaluationError(_t("Field %s is not a measure", name));
|
|
34887
34915
|
}
|
|
34888
34916
|
return measure;
|
|
34889
34917
|
}
|
|
@@ -35009,10 +35037,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35009
35037
|
columns;
|
|
35010
35038
|
rows;
|
|
35011
35039
|
measures;
|
|
35012
|
-
rowTitle;
|
|
35013
35040
|
maxIndent;
|
|
35014
35041
|
pivotCells = {};
|
|
35015
|
-
constructor(columns, rows, measures
|
|
35042
|
+
constructor(columns, rows, measures) {
|
|
35016
35043
|
this.columns = columns.map((row) => {
|
|
35017
35044
|
// offset in the pivot table
|
|
35018
35045
|
// starts at 1 because the first column is the row title
|
|
@@ -35025,7 +35052,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35025
35052
|
});
|
|
35026
35053
|
this.rows = rows;
|
|
35027
35054
|
this.measures = measures;
|
|
35028
|
-
this.rowTitle = rowTitle;
|
|
35029
35055
|
this.maxIndent = Math.max(...this.rows.map((row) => row.indent));
|
|
35030
35056
|
}
|
|
35031
35057
|
/**
|
|
@@ -35067,26 +35093,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35067
35093
|
}
|
|
35068
35094
|
getPivotCell(col, row, includeTotal = true) {
|
|
35069
35095
|
const colHeadersHeight = this.columns.length;
|
|
35070
|
-
if (
|
|
35071
|
-
return { content: this.rowTitle, isHeader: true };
|
|
35072
|
-
}
|
|
35073
|
-
else if (row <= colHeadersHeight - 1) {
|
|
35096
|
+
if (row <= colHeadersHeight - 1) {
|
|
35074
35097
|
const domain = this.getColHeaderDomain(col, row);
|
|
35075
|
-
return {
|
|
35098
|
+
return domain ? { type: "HEADER", domain } : { type: "EMPTY" };
|
|
35076
35099
|
}
|
|
35077
35100
|
else if (col === 0) {
|
|
35078
35101
|
const rowIndex = row - colHeadersHeight;
|
|
35079
35102
|
const domain = this.getRowDomain(rowIndex);
|
|
35080
|
-
return {
|
|
35103
|
+
return { type: "HEADER", domain };
|
|
35081
35104
|
}
|
|
35082
35105
|
else {
|
|
35083
35106
|
const rowIndex = row - colHeadersHeight;
|
|
35084
35107
|
if (!includeTotal && this.isTotalRow(rowIndex)) {
|
|
35085
|
-
return {
|
|
35108
|
+
return { type: "EMPTY" };
|
|
35086
35109
|
}
|
|
35087
35110
|
const domain = [...this.getRowDomain(rowIndex), ...this.getColDomain(col)];
|
|
35088
35111
|
const measure = this.getColMeasure(col);
|
|
35089
|
-
return {
|
|
35112
|
+
return { type: "VALUE", domain, measure };
|
|
35090
35113
|
}
|
|
35091
35114
|
}
|
|
35092
35115
|
getColHeaderDomain(col, row) {
|
|
@@ -35099,24 +35122,32 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35099
35122
|
return undefined;
|
|
35100
35123
|
}
|
|
35101
35124
|
for (let i = 0; i < pivotCol.fields.length; i++) {
|
|
35102
|
-
domain.push(
|
|
35103
|
-
|
|
35125
|
+
domain.push({
|
|
35126
|
+
field: pivotCol.fields[i],
|
|
35127
|
+
value: pivotCol.values[i],
|
|
35128
|
+
});
|
|
35104
35129
|
}
|
|
35105
35130
|
return domain;
|
|
35106
35131
|
}
|
|
35107
35132
|
getColDomain(col) {
|
|
35108
35133
|
const domain = this.getColHeaderDomain(col, this.columns.length - 1);
|
|
35109
|
-
return domain ? domain.slice(0, -
|
|
35134
|
+
return domain ? domain.slice(0, -1) : []; // slice: remove measure and value
|
|
35110
35135
|
}
|
|
35111
35136
|
getColMeasure(col) {
|
|
35112
35137
|
const domain = this.getColHeaderDomain(col, this.columns.length - 1);
|
|
35113
|
-
|
|
35138
|
+
const measure = domain?.at(-1)?.value;
|
|
35139
|
+
if (measure === undefined) {
|
|
35140
|
+
throw new Error("Measure isd missing");
|
|
35141
|
+
}
|
|
35142
|
+
return measure.toString();
|
|
35114
35143
|
}
|
|
35115
35144
|
getRowDomain(row) {
|
|
35116
35145
|
const domain = [];
|
|
35117
35146
|
for (let i = 0; i < this.rows[row].fields.length; i++) {
|
|
35118
|
-
domain.push(
|
|
35119
|
-
|
|
35147
|
+
domain.push({
|
|
35148
|
+
field: this.rows[row].fields[i],
|
|
35149
|
+
value: this.rows[row].values[i],
|
|
35150
|
+
});
|
|
35120
35151
|
}
|
|
35121
35152
|
return domain;
|
|
35122
35153
|
}
|
|
@@ -35125,7 +35156,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35125
35156
|
cols: this.columns,
|
|
35126
35157
|
rows: this.rows,
|
|
35127
35158
|
measures: this.measures,
|
|
35128
|
-
rowTitle: this.rowTitle,
|
|
35129
35159
|
};
|
|
35130
35160
|
}
|
|
35131
35161
|
}
|
|
@@ -35145,8 +35175,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35145
35175
|
indent: 0,
|
|
35146
35176
|
});
|
|
35147
35177
|
const measureNames = definition.measures.map((m) => m.name);
|
|
35148
|
-
|
|
35149
|
-
return new SpreadsheetPivotTable(cols, rows, measureNames, rowTitle);
|
|
35178
|
+
return new SpreadsheetPivotTable(cols, rows, measureNames);
|
|
35150
35179
|
}
|
|
35151
35180
|
// -----------------------------------------------------------------------------
|
|
35152
35181
|
// ROWS
|
|
@@ -35489,7 +35518,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35489
35518
|
}
|
|
35490
35519
|
get definition() {
|
|
35491
35520
|
if (!this._definition) {
|
|
35492
|
-
|
|
35521
|
+
this.init();
|
|
35522
|
+
}
|
|
35523
|
+
if (!this._definition) {
|
|
35524
|
+
throw new Error("Pivot definition should be defined at this point.");
|
|
35493
35525
|
}
|
|
35494
35526
|
return this._definition;
|
|
35495
35527
|
}
|
|
@@ -35538,15 +35570,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35538
35570
|
getMeasure(name) {
|
|
35539
35571
|
return this.definition.getMeasure(name);
|
|
35540
35572
|
}
|
|
35541
|
-
|
|
35542
|
-
|
|
35573
|
+
getPivotMeasureValue(name) {
|
|
35574
|
+
return {
|
|
35575
|
+
value: this.getMeasure(name).displayName,
|
|
35576
|
+
};
|
|
35577
|
+
}
|
|
35578
|
+
getPivotHeaderValueAndFormat(domain) {
|
|
35543
35579
|
const lastNode = domain.at(-1);
|
|
35544
35580
|
if (!lastNode) {
|
|
35545
35581
|
return { value: _t("Total") };
|
|
35546
35582
|
}
|
|
35547
|
-
if (lastNode.field === "measure") {
|
|
35548
|
-
return { value: this.getMeasure(lastNode.value).displayName };
|
|
35549
|
-
}
|
|
35550
35583
|
const dimension = this.getDimension(lastNode.field);
|
|
35551
35584
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
35552
35585
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
@@ -35574,8 +35607,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35574
35607
|
format: finalCell.format,
|
|
35575
35608
|
};
|
|
35576
35609
|
}
|
|
35577
|
-
getPivotCellValueAndFormat(measure,
|
|
35578
|
-
const domain = toDomainArgs(domainStr);
|
|
35610
|
+
getPivotCellValueAndFormat(measure, domain) {
|
|
35579
35611
|
const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
35580
35612
|
if (dataEntries.length === 0) {
|
|
35581
35613
|
return { value: "" };
|
|
@@ -35752,7 +35784,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35752
35784
|
|
|
35753
35785
|
class PivotSidePanelStore extends SpreadsheetStore {
|
|
35754
35786
|
pivotId;
|
|
35755
|
-
mutators = [
|
|
35787
|
+
mutators = [
|
|
35788
|
+
"reset",
|
|
35789
|
+
"deferUpdates",
|
|
35790
|
+
"applyUpdate",
|
|
35791
|
+
"discardPendingUpdate",
|
|
35792
|
+
"renamePivot",
|
|
35793
|
+
"update",
|
|
35794
|
+
];
|
|
35756
35795
|
updatesAreDeferred = true;
|
|
35757
35796
|
draft = null;
|
|
35758
35797
|
constructor(get, pivotId) {
|
|
@@ -35969,7 +36008,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35969
36008
|
state;
|
|
35970
36009
|
setup() {
|
|
35971
36010
|
this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
|
|
35972
|
-
this.pivot.init();
|
|
35973
36011
|
this.state = owl.useState({
|
|
35974
36012
|
range: undefined,
|
|
35975
36013
|
rangeHasChanged: false,
|
|
@@ -36846,7 +36884,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36846
36884
|
}
|
|
36847
36885
|
|
|
36848
36886
|
.o-table-style-list-item {
|
|
36849
|
-
padding: 3px;
|
|
36887
|
+
padding: 3px 2px;
|
|
36850
36888
|
margin: 2px 1px;
|
|
36851
36889
|
|
|
36852
36890
|
.o-table-style-picker-preview {
|
|
@@ -36867,10 +36905,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36867
36905
|
const styles = Object.keys(allStyles).filter((key) => allStyles[key].category === selectedStyleCategory);
|
|
36868
36906
|
const selectedStyleIndex = styles.indexOf(this.props.table.config.styleId);
|
|
36869
36907
|
if (selectedStyleIndex === -1) {
|
|
36870
|
-
return
|
|
36908
|
+
return selectedStyleIndex;
|
|
36871
36909
|
}
|
|
36872
36910
|
const index = Math.floor(selectedStyleIndex / 4) * 4;
|
|
36873
|
-
return styles.slice(index
|
|
36911
|
+
return styles.slice(index);
|
|
36874
36912
|
}
|
|
36875
36913
|
onStylePicked(styleId) {
|
|
36876
36914
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -37910,10 +37948,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37910
37948
|
}
|
|
37911
37949
|
get containerStyle() {
|
|
37912
37950
|
if (this.composerStore.editionMode === "inactive") {
|
|
37913
|
-
return `
|
|
37914
|
-
position: absolute;
|
|
37915
|
-
z-index: -1000;
|
|
37916
|
-
`;
|
|
37951
|
+
return `z-index: -1000;`;
|
|
37917
37952
|
}
|
|
37918
37953
|
const isFormula = this.composerStore.currentContent.startsWith("=");
|
|
37919
37954
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -38789,6 +38824,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
38789
38824
|
|
|
38790
38825
|
class FilterIconsOverlay extends owl.Component {
|
|
38791
38826
|
static template = "o-spreadsheet-FilterIconsOverlay";
|
|
38827
|
+
static props = {};
|
|
38792
38828
|
static components = {
|
|
38793
38829
|
GridCellIcon,
|
|
38794
38830
|
FilterIcon,
|
|
@@ -40756,10 +40792,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40756
40792
|
}
|
|
40757
40793
|
}
|
|
40758
40794
|
|
|
40795
|
+
const DEFAULT_SIDE_PANEL_SIZE = 350;
|
|
40796
|
+
const MIN_SHEET_VIEW_WIDTH = 150;
|
|
40759
40797
|
class SidePanelStore extends SpreadsheetStore {
|
|
40760
|
-
mutators = ["open", "toggle", "close"];
|
|
40798
|
+
mutators = ["open", "toggle", "close", "changePanelSize", "resetPanelSize"];
|
|
40761
40799
|
initialPanelProps = {};
|
|
40762
40800
|
componentTag = "";
|
|
40801
|
+
panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40763
40802
|
get isOpen() {
|
|
40764
40803
|
if (!this.componentTag) {
|
|
40765
40804
|
return false;
|
|
@@ -40804,6 +40843,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40804
40843
|
this.initialPanelProps = {};
|
|
40805
40844
|
this.componentTag = "";
|
|
40806
40845
|
}
|
|
40846
|
+
changePanelSize(size, spreadsheetElWidth) {
|
|
40847
|
+
if (size < DEFAULT_SIDE_PANEL_SIZE) {
|
|
40848
|
+
this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40849
|
+
}
|
|
40850
|
+
else if (size > spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH) {
|
|
40851
|
+
this.panelSize = Math.max(spreadsheetElWidth - MIN_SHEET_VIEW_WIDTH, DEFAULT_SIDE_PANEL_SIZE);
|
|
40852
|
+
}
|
|
40853
|
+
else {
|
|
40854
|
+
this.panelSize = size;
|
|
40855
|
+
}
|
|
40856
|
+
}
|
|
40857
|
+
resetPanelSize() {
|
|
40858
|
+
this.panelSize = DEFAULT_SIDE_PANEL_SIZE;
|
|
40859
|
+
}
|
|
40807
40860
|
computeState(componentTag, panelProps) {
|
|
40808
40861
|
const customComputeState = sidePanelRegistry.get(componentTag).computeState;
|
|
40809
40862
|
if (!customComputeState) {
|
|
@@ -41924,7 +41977,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41924
41977
|
}
|
|
41925
41978
|
}
|
|
41926
41979
|
|
|
41927
|
-
const SUPPORTED_BORDER_STYLES = ["thin"];
|
|
41980
|
+
const SUPPORTED_BORDER_STYLES = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
41928
41981
|
const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
|
|
41929
41982
|
"general",
|
|
41930
41983
|
"left",
|
|
@@ -51063,8 +51116,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51063
51116
|
case "INSERT_PIVOT": {
|
|
51064
51117
|
const { sheetId, col, row, pivotId, table } = cmd;
|
|
51065
51118
|
const position = { sheetId, col, row };
|
|
51066
|
-
const { cols, rows, measures
|
|
51067
|
-
const spTable = new SpreadsheetPivotTable(cols, rows, measures
|
|
51119
|
+
const { cols, rows, measures } = table;
|
|
51120
|
+
const spTable = new SpreadsheetPivotTable(cols, rows, measures);
|
|
51068
51121
|
const formulaId = this.getPivotFormulaId(pivotId);
|
|
51069
51122
|
this.insertPivot(position, formulaId, spTable);
|
|
51070
51123
|
break;
|
|
@@ -51193,13 +51246,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51193
51246
|
}
|
|
51194
51247
|
}
|
|
51195
51248
|
addPivotFormula(position, formulaId, pivotCell) {
|
|
51196
|
-
|
|
51197
|
-
|
|
51198
|
-
|
|
51199
|
-
|
|
51249
|
+
let content = undefined;
|
|
51250
|
+
switch (pivotCell.type) {
|
|
51251
|
+
case "HEADER":
|
|
51252
|
+
content = makePivotFormula("PIVOT.HEADER", [formulaId, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
|
|
51253
|
+
break;
|
|
51254
|
+
case "VALUE":
|
|
51255
|
+
content = makePivotFormula("PIVOT.VALUE", [formulaId, pivotCell.measure, ...flatPivotDomain(pivotCell.domain)].filter(isDefined));
|
|
51256
|
+
break;
|
|
51257
|
+
}
|
|
51200
51258
|
this.dispatch("UPDATE_CELL", {
|
|
51201
51259
|
...position,
|
|
51202
|
-
content
|
|
51260
|
+
content,
|
|
51203
51261
|
});
|
|
51204
51262
|
}
|
|
51205
51263
|
getPivotCore(pivotId) {
|
|
@@ -51218,7 +51276,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51218
51276
|
import(data) {
|
|
51219
51277
|
if (data.pivots) {
|
|
51220
51278
|
for (const [id, pivot] of Object.entries(data.pivots)) {
|
|
51221
|
-
this.addPivot(id,
|
|
51279
|
+
this.addPivot(id, pivot, pivot.formulaId);
|
|
51222
51280
|
}
|
|
51223
51281
|
}
|
|
51224
51282
|
this.history.update("nextFormulaId", data.pivotNextId || getMaxObjectId(this.pivots) + 1);
|
|
@@ -54559,15 +54617,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54559
54617
|
const pivotCol = position.col - mainPosition.col;
|
|
54560
54618
|
const pivotRow = position.row - mainPosition.row;
|
|
54561
54619
|
const pivotCell = pivotCells[pivotCol][pivotRow];
|
|
54620
|
+
if (pivotCell.type === "EMPTY") {
|
|
54621
|
+
return undefined;
|
|
54622
|
+
}
|
|
54562
54623
|
const domain = pivotCell.domain;
|
|
54563
|
-
if (domain
|
|
54564
|
-
return domain.slice(0, -
|
|
54624
|
+
if (domain.at(-1)?.field === "measure") {
|
|
54625
|
+
return domain.slice(0, -1);
|
|
54565
54626
|
}
|
|
54566
54627
|
return domain;
|
|
54567
54628
|
}
|
|
54568
|
-
const domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
|
|
54569
|
-
if (domain.at(-
|
|
54570
|
-
return domain.slice(0, -
|
|
54629
|
+
const domain = toPivotDomain(args.slice(functionName === "PIVOT.VALUE" ? 2 : 1).map((x) => `${x}`));
|
|
54630
|
+
if (domain.at(-1)?.field === "measure") {
|
|
54631
|
+
return domain.slice(0, -1);
|
|
54571
54632
|
}
|
|
54572
54633
|
return domain;
|
|
54573
54634
|
}
|
|
@@ -54582,9 +54643,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54582
54643
|
* a pivot function are valid according to the pivot definition.
|
|
54583
54644
|
* e.g. =PIVOT.VALUE(1,"revenue","country_id",...,"create_date:month",...,"source_id",...)
|
|
54584
54645
|
*/
|
|
54585
|
-
areDomainArgsFieldsValid(pivotId,
|
|
54586
|
-
const dimensions =
|
|
54587
|
-
.
|
|
54646
|
+
areDomainArgsFieldsValid(pivotId, domain) {
|
|
54647
|
+
const dimensions = domain
|
|
54648
|
+
.map((node) => node.field)
|
|
54588
54649
|
.map((name) => (name.startsWith("#") ? name.slice(1) : name));
|
|
54589
54650
|
let argIndex = 0;
|
|
54590
54651
|
let definitionIndex = 0;
|
|
@@ -61598,6 +61659,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61598
61659
|
}
|
|
61599
61660
|
}
|
|
61600
61661
|
}
|
|
61662
|
+
.o-sidePanelBody-container {
|
|
61663
|
+
/* This overwrites the min-height: auto; of flex. Without this, a flex div cannot be smaller than its children */
|
|
61664
|
+
min-height: 0;
|
|
61665
|
+
}
|
|
61601
61666
|
.o-sidePanelBody {
|
|
61602
61667
|
overflow: auto;
|
|
61603
61668
|
width: 100%;
|
|
@@ -61676,24 +61741,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61676
61741
|
text-align: left;
|
|
61677
61742
|
}
|
|
61678
61743
|
|
|
61679
|
-
.o-inflection {
|
|
61680
|
-
table {
|
|
61681
|
-
table-layout: fixed;
|
|
61682
|
-
margin-top: 2%;
|
|
61683
|
-
display: table;
|
|
61684
|
-
text-align: left;
|
|
61685
|
-
font-size: 12px;
|
|
61686
|
-
line-height: 18px;
|
|
61687
|
-
width: 100%;
|
|
61688
|
-
}
|
|
61689
|
-
input,
|
|
61690
|
-
select {
|
|
61691
|
-
width: 100%;
|
|
61692
|
-
height: 100%;
|
|
61693
|
-
box-sizing: border-box;
|
|
61694
|
-
}
|
|
61695
|
-
}
|
|
61696
|
-
|
|
61697
61744
|
.o-sidePanel-tools {
|
|
61698
61745
|
color: #333;
|
|
61699
61746
|
font-size: 13px;
|
|
@@ -61712,12 +61759,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61712
61759
|
}
|
|
61713
61760
|
}
|
|
61714
61761
|
}
|
|
61762
|
+
|
|
61763
|
+
.o-sidePanel-handle-container {
|
|
61764
|
+
width: 8px;
|
|
61765
|
+
}
|
|
61766
|
+
.o-sidePanel-handle {
|
|
61767
|
+
cursor: col-resize;
|
|
61768
|
+
color: #a9a9a9;
|
|
61769
|
+
.o-icon {
|
|
61770
|
+
height: 25px;
|
|
61771
|
+
margin-left: -5px;
|
|
61772
|
+
}
|
|
61773
|
+
}
|
|
61715
61774
|
}
|
|
61716
61775
|
`;
|
|
61717
61776
|
class SidePanel extends owl.Component {
|
|
61718
61777
|
static template = "o-spreadsheet-SidePanel";
|
|
61719
61778
|
static props = {};
|
|
61720
61779
|
sidePanelStore;
|
|
61780
|
+
spreadsheetRect = useSpreadsheetRect();
|
|
61721
61781
|
setup() {
|
|
61722
61782
|
this.sidePanelStore = useStore(SidePanelStore);
|
|
61723
61783
|
owl.useEffect((isOpen) => {
|
|
@@ -61738,6 +61798,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61738
61798
|
? panel.title(this.env, this.sidePanelStore.panelProps)
|
|
61739
61799
|
: panel.title;
|
|
61740
61800
|
}
|
|
61801
|
+
startHandleDrag(ev) {
|
|
61802
|
+
const startingCursor = document.body.style.cursor;
|
|
61803
|
+
const startSize = this.sidePanelStore.panelSize;
|
|
61804
|
+
const startPosition = ev.clientX;
|
|
61805
|
+
const onMouseMove = (ev) => {
|
|
61806
|
+
document.body.style.cursor = "col-resize";
|
|
61807
|
+
const newSize = startSize + startPosition - ev.clientX;
|
|
61808
|
+
this.sidePanelStore.changePanelSize(newSize, this.spreadsheetRect.width);
|
|
61809
|
+
};
|
|
61810
|
+
const cleanUp = () => {
|
|
61811
|
+
document.body.style.cursor = startingCursor;
|
|
61812
|
+
};
|
|
61813
|
+
startDnd(onMouseMove, cleanUp);
|
|
61814
|
+
}
|
|
61741
61815
|
}
|
|
61742
61816
|
|
|
61743
61817
|
css /* scss */ `
|
|
@@ -62521,7 +62595,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62521
62595
|
.o-spreadsheet {
|
|
62522
62596
|
position: relative;
|
|
62523
62597
|
display: grid;
|
|
62524
|
-
grid-template-columns: auto 350px;
|
|
62525
62598
|
color: #333;
|
|
62526
62599
|
font-size: 14px;
|
|
62527
62600
|
|
|
@@ -62719,6 +62792,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62719
62792
|
};
|
|
62720
62793
|
sidePanel;
|
|
62721
62794
|
spreadsheetRef = owl.useRef("spreadsheet");
|
|
62795
|
+
spreadsheetRect = useSpreadsheetRect();
|
|
62722
62796
|
_focusGrid;
|
|
62723
62797
|
keyDownMapping;
|
|
62724
62798
|
isViewportTooSmall = false;
|
|
@@ -62728,10 +62802,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62728
62802
|
return this.props.model;
|
|
62729
62803
|
}
|
|
62730
62804
|
getStyle() {
|
|
62805
|
+
const properties = {};
|
|
62731
62806
|
if (this.env.isDashboard()) {
|
|
62732
|
-
|
|
62807
|
+
properties["grid-template-rows"] = `auto`;
|
|
62733
62808
|
}
|
|
62734
|
-
|
|
62809
|
+
else {
|
|
62810
|
+
properties["grid-template-rows"] = `${TOPBAR_HEIGHT}px auto ${BOTTOMBAR_HEIGHT + 1}px`;
|
|
62811
|
+
}
|
|
62812
|
+
properties["grid-template-columns"] = `auto ${this.sidePanel.panelSize}px`;
|
|
62813
|
+
return cssPropertiesToCss(properties);
|
|
62735
62814
|
}
|
|
62736
62815
|
setup() {
|
|
62737
62816
|
const stores = useStoreProvider();
|
|
@@ -62781,7 +62860,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62781
62860
|
if (nextProps.model !== this.props.model) {
|
|
62782
62861
|
throw new Error("Changing the props model is not supported at the moment.");
|
|
62783
62862
|
}
|
|
62784
|
-
if (
|
|
62863
|
+
if (nextProps.notifyUser !== this.props.notifyUser ||
|
|
62864
|
+
nextProps.askConfirmation !== this.props.askConfirmation ||
|
|
62865
|
+
nextProps.raiseError !== this.props.raiseError) {
|
|
62785
62866
|
this.notificationStore.updateNotificationCallbacks({ ...nextProps });
|
|
62786
62867
|
}
|
|
62787
62868
|
});
|
|
@@ -62789,14 +62870,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62789
62870
|
owl.onMounted(() => {
|
|
62790
62871
|
this.checkViewportSize();
|
|
62791
62872
|
stores.on("store-updated", this, render);
|
|
62873
|
+
resizeObserver.observe(this.spreadsheetRef.el);
|
|
62792
62874
|
});
|
|
62793
62875
|
owl.onWillUnmount(() => {
|
|
62794
62876
|
this.unbindModelEvents();
|
|
62795
62877
|
stores.off("store-updated", this);
|
|
62878
|
+
resizeObserver.disconnect();
|
|
62796
62879
|
});
|
|
62797
62880
|
owl.onPatched(() => {
|
|
62798
62881
|
this.checkViewportSize();
|
|
62799
62882
|
});
|
|
62883
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
62884
|
+
this.sidePanel.changePanelSize(this.sidePanel.panelSize, this.spreadsheetRect.width);
|
|
62885
|
+
});
|
|
62800
62886
|
}
|
|
62801
62887
|
bindModelEvents() {
|
|
62802
62888
|
this.model.on("update", this, () => this.render(true));
|
|
@@ -66851,6 +66937,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66851
66937
|
insertTokenAfterLeftParenthesis,
|
|
66852
66938
|
mergeContiguousZones,
|
|
66853
66939
|
getPivotHighlights,
|
|
66940
|
+
toPivotDomain,
|
|
66941
|
+
flatPivotDomain,
|
|
66854
66942
|
pivotTimeAdapter,
|
|
66855
66943
|
UNDO_REDO_PIVOT_COMMANDS,
|
|
66856
66944
|
};
|
|
@@ -66978,9 +67066,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66978
67066
|
exports.tokenize = tokenize;
|
|
66979
67067
|
|
|
66980
67068
|
|
|
66981
|
-
__info__.version = "17.4.0-alpha.
|
|
66982
|
-
__info__.date = "2024-
|
|
66983
|
-
__info__.hash = "
|
|
67069
|
+
__info__.version = "17.4.0-alpha.2";
|
|
67070
|
+
__info__.date = "2024-06-06T13:31:21.327Z";
|
|
67071
|
+
__info__.hash = "e07794d";
|
|
66984
67072
|
|
|
66985
67073
|
|
|
66986
67074
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|