@odoo/o-spreadsheet 17.4.2 → 17.4.4
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 +217 -195
- package/dist/o-spreadsheet.d.ts +3 -1
- package/dist/o-spreadsheet.esm.js +217 -195
- package/dist/o-spreadsheet.iife.js +217 -195
- package/dist/o-spreadsheet.iife.min.js +361 -351
- package/dist/o_spreadsheet.xml +10 -7
- package/package.json +2 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.4.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.4
|
|
6
|
+
* @date 2024-08-09T12:24:07.798Z
|
|
7
|
+
* @hash a43e855
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -2765,13 +2765,16 @@ const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
|
|
|
2765
2765
|
}
|
|
2766
2766
|
return new RegExp("^" + exp + "$", "i");
|
|
2767
2767
|
});
|
|
2768
|
-
function evaluatePredicate(value = "", criterion) {
|
|
2768
|
+
function evaluatePredicate(value = "", criterion, locale) {
|
|
2769
2769
|
const { operator, operand } = criterion;
|
|
2770
2770
|
if (operand === undefined || value === null || operand === null) {
|
|
2771
2771
|
return false;
|
|
2772
2772
|
}
|
|
2773
2773
|
if (typeof operand === "number" && operator === "=") {
|
|
2774
|
-
|
|
2774
|
+
if (typeof value === "string" && (isNumber(value, locale) || isDateTime(value, locale))) {
|
|
2775
|
+
return toNumber(value, locale) === operand;
|
|
2776
|
+
}
|
|
2777
|
+
return value === operand;
|
|
2775
2778
|
}
|
|
2776
2779
|
if (operator === "<>" || operator === "=") {
|
|
2777
2780
|
let result;
|
|
@@ -2853,7 +2856,7 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
|
|
|
2853
2856
|
for (let k = 0; k < countArg - 1; k += 2) {
|
|
2854
2857
|
const criteriaValue = toMatrix(args[k])[i][j].value;
|
|
2855
2858
|
const criterion = predicates[k / 2];
|
|
2856
|
-
validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
|
|
2859
|
+
validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion, locale);
|
|
2857
2860
|
if (!validatedPredicates) {
|
|
2858
2861
|
break;
|
|
2859
2862
|
}
|
|
@@ -6544,6 +6547,9 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
6544
6547
|
const groupValueString = typeof groupValue === "boolean"
|
|
6545
6548
|
? toString(groupValue).toLocaleLowerCase()
|
|
6546
6549
|
: toString(groupValue);
|
|
6550
|
+
if (groupValueString === "null") {
|
|
6551
|
+
return null;
|
|
6552
|
+
}
|
|
6547
6553
|
if (!pivotNormalizationValueRegistry.contains(dimension.type)) {
|
|
6548
6554
|
throw new EvaluationError(_t("Field %(field)s is not supported because of its type (%(type)s)", {
|
|
6549
6555
|
field: dimension.displayName,
|
|
@@ -6564,6 +6570,9 @@ function normalizeDateTime(value, granularity) {
|
|
|
6564
6570
|
return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
|
|
6565
6571
|
}
|
|
6566
6572
|
function toFunctionPivotValue(value, dimension) {
|
|
6573
|
+
if (value === null) {
|
|
6574
|
+
return `"null"`;
|
|
6575
|
+
}
|
|
6567
6576
|
if (!pivotToFunctionValueRegistry.contains(dimension.type)) {
|
|
6568
6577
|
return `"${value}"`;
|
|
6569
6578
|
}
|
|
@@ -10567,6 +10576,18 @@ function getDefinedAxis(definition) {
|
|
|
10567
10576
|
useLeftAxis ||= !useRightAxis;
|
|
10568
10577
|
return { useLeftAxis, useRightAxis };
|
|
10569
10578
|
}
|
|
10579
|
+
function formatTickValue(localeFormat) {
|
|
10580
|
+
return (value) => {
|
|
10581
|
+
value = Number(value);
|
|
10582
|
+
if (isNaN(value))
|
|
10583
|
+
return value;
|
|
10584
|
+
const { locale, format } = localeFormat;
|
|
10585
|
+
return formatValue(value, {
|
|
10586
|
+
locale,
|
|
10587
|
+
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
10588
|
+
});
|
|
10589
|
+
};
|
|
10590
|
+
}
|
|
10570
10591
|
|
|
10571
10592
|
/** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
|
|
10572
10593
|
const chartShowValuesPlugin = {
|
|
@@ -19115,6 +19136,7 @@ const PIVOT_VALUE = {
|
|
|
19115
19136
|
const pivot = this.getters.getPivot(pivotId);
|
|
19116
19137
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19117
19138
|
addPivotDependencies(this, coreDefinition);
|
|
19139
|
+
pivot.init({ reload: pivot.needsReevaluation });
|
|
19118
19140
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19119
19141
|
if (error) {
|
|
19120
19142
|
return error;
|
|
@@ -19143,6 +19165,7 @@ const PIVOT_HEADER = {
|
|
|
19143
19165
|
const pivot = this.getters.getPivot(_pivotId);
|
|
19144
19166
|
const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
|
|
19145
19167
|
addPivotDependencies(this, coreDefinition);
|
|
19168
|
+
pivot.init({ reload: pivot.needsReevaluation });
|
|
19146
19169
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19147
19170
|
if (error) {
|
|
19148
19171
|
return error;
|
|
@@ -20360,14 +20383,6 @@ for (let category of categories) {
|
|
|
20360
20383
|
}
|
|
20361
20384
|
const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
20362
20385
|
function createComputeFunction(descr, functionName) {
|
|
20363
|
-
function runtimeCompute(...args) {
|
|
20364
|
-
try {
|
|
20365
|
-
return vectorizedCompute.apply(this, args);
|
|
20366
|
-
}
|
|
20367
|
-
catch (e) {
|
|
20368
|
-
return handleError(e, functionName);
|
|
20369
|
-
}
|
|
20370
|
-
}
|
|
20371
20386
|
function vectorizedCompute(...args) {
|
|
20372
20387
|
let countVectorizableCol = 1;
|
|
20373
20388
|
let countVectorizableRow = 1;
|
|
@@ -20408,13 +20423,13 @@ function createComputeFunction(descr, functionName) {
|
|
|
20408
20423
|
}
|
|
20409
20424
|
}
|
|
20410
20425
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
20411
|
-
throw new BadExpressionError(_t("Function
|
|
20426
|
+
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
20412
20427
|
}
|
|
20413
20428
|
}
|
|
20414
20429
|
//#endregion
|
|
20415
20430
|
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
20416
20431
|
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
20417
|
-
return
|
|
20432
|
+
return errorHandlingCompute.apply(this, args);
|
|
20418
20433
|
}
|
|
20419
20434
|
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
20420
20435
|
switch (vectorArgsType?.[index]) {
|
|
@@ -20432,7 +20447,7 @@ function createComputeFunction(descr, functionName) {
|
|
|
20432
20447
|
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
20433
20448
|
return notAvailableError;
|
|
20434
20449
|
}
|
|
20435
|
-
const singleCellComputeResult =
|
|
20450
|
+
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
20436
20451
|
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
20437
20452
|
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
20438
20453
|
// we won't be able to return the values.
|
|
@@ -20447,6 +20462,14 @@ function createComputeFunction(descr, functionName) {
|
|
|
20447
20462
|
: singleCellComputeResult;
|
|
20448
20463
|
});
|
|
20449
20464
|
}
|
|
20465
|
+
function errorHandlingCompute(...args) {
|
|
20466
|
+
try {
|
|
20467
|
+
return computeFunctionToObject.apply(this, args);
|
|
20468
|
+
}
|
|
20469
|
+
catch (e) {
|
|
20470
|
+
return handleError(e, functionName);
|
|
20471
|
+
}
|
|
20472
|
+
}
|
|
20450
20473
|
function computeFunctionToObject(...args) {
|
|
20451
20474
|
const result = descr.compute.apply(this, args);
|
|
20452
20475
|
if (!isMatrix(result)) {
|
|
@@ -20462,7 +20485,7 @@ function createComputeFunction(descr, functionName) {
|
|
|
20462
20485
|
}
|
|
20463
20486
|
return matrixMap(result, (row) => ({ value: row }));
|
|
20464
20487
|
}
|
|
20465
|
-
return
|
|
20488
|
+
return vectorizedCompute;
|
|
20466
20489
|
}
|
|
20467
20490
|
function handleError(e, functionName) {
|
|
20468
20491
|
// the error could be an user error (instance of EvaluationError)
|
|
@@ -20779,6 +20802,78 @@ function isCtrlKey(ev) {
|
|
|
20779
20802
|
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
20780
20803
|
}
|
|
20781
20804
|
|
|
20805
|
+
/**
|
|
20806
|
+
* Return the o-spreadsheet element position relative
|
|
20807
|
+
* to the browser viewport.
|
|
20808
|
+
*/
|
|
20809
|
+
function useSpreadsheetRect() {
|
|
20810
|
+
const position = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
20811
|
+
let spreadsheetElement = null;
|
|
20812
|
+
function updatePosition() {
|
|
20813
|
+
if (!spreadsheetElement) {
|
|
20814
|
+
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
|
20815
|
+
}
|
|
20816
|
+
if (spreadsheetElement) {
|
|
20817
|
+
const { top, left, width, height } = spreadsheetElement.getBoundingClientRect();
|
|
20818
|
+
position.x = left;
|
|
20819
|
+
position.y = top;
|
|
20820
|
+
position.width = width;
|
|
20821
|
+
position.height = height;
|
|
20822
|
+
}
|
|
20823
|
+
}
|
|
20824
|
+
onMounted(updatePosition);
|
|
20825
|
+
onPatched(updatePosition);
|
|
20826
|
+
return position;
|
|
20827
|
+
}
|
|
20828
|
+
/**
|
|
20829
|
+
* Return the component (or ref's component) BoundingRect, relative
|
|
20830
|
+
* to the upper left corner of the screen (<body> element).
|
|
20831
|
+
*
|
|
20832
|
+
* Note: when used with a <Portal/> component, it will
|
|
20833
|
+
* return the portal position, not the teleported position.
|
|
20834
|
+
*/
|
|
20835
|
+
function useAbsoluteBoundingRect(ref) {
|
|
20836
|
+
const rect = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
20837
|
+
function updateElRect() {
|
|
20838
|
+
const el = ref.el;
|
|
20839
|
+
if (el === null) {
|
|
20840
|
+
return;
|
|
20841
|
+
}
|
|
20842
|
+
const { top, left, width, height } = el.getBoundingClientRect();
|
|
20843
|
+
rect.x = left;
|
|
20844
|
+
rect.y = top;
|
|
20845
|
+
rect.width = width;
|
|
20846
|
+
rect.height = height;
|
|
20847
|
+
}
|
|
20848
|
+
onMounted(updateElRect);
|
|
20849
|
+
onPatched(updateElRect);
|
|
20850
|
+
return rect;
|
|
20851
|
+
}
|
|
20852
|
+
/**
|
|
20853
|
+
* Get the rectangle inside which a popover should stay when being displayed.
|
|
20854
|
+
* It's the value defined in `env.getPopoverContainerRect`, or the Rect of the "o-spreadsheet"
|
|
20855
|
+
* element by default.
|
|
20856
|
+
*
|
|
20857
|
+
* Coordinates are expressed expressed as absolute DOM position.
|
|
20858
|
+
*/
|
|
20859
|
+
function usePopoverContainer() {
|
|
20860
|
+
const container = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
20861
|
+
const component = useComponent();
|
|
20862
|
+
const spreadsheetRect = useSpreadsheetRect();
|
|
20863
|
+
function updateRect() {
|
|
20864
|
+
const env = component.env;
|
|
20865
|
+
const newRect = "getPopoverContainerRect" in env ? env.getPopoverContainerRect() : spreadsheetRect;
|
|
20866
|
+
container.x = newRect.x;
|
|
20867
|
+
container.y = newRect.y;
|
|
20868
|
+
container.width = newRect.width;
|
|
20869
|
+
container.height = newRect.height;
|
|
20870
|
+
}
|
|
20871
|
+
updateRect();
|
|
20872
|
+
onMounted(updateRect);
|
|
20873
|
+
onPatched(updateRect);
|
|
20874
|
+
return container;
|
|
20875
|
+
}
|
|
20876
|
+
|
|
20782
20877
|
const arrowMap = {
|
|
20783
20878
|
ArrowDown: "down",
|
|
20784
20879
|
ArrowLeft: "left",
|
|
@@ -21368,7 +21463,9 @@ class Composer extends Component {
|
|
|
21368
21463
|
argToFocus: 0,
|
|
21369
21464
|
});
|
|
21370
21465
|
compositionActive = false;
|
|
21466
|
+
spreadsheetRect = useSpreadsheetRect();
|
|
21371
21467
|
get assistantStyle() {
|
|
21468
|
+
const composerRect = this.composerRef.el.getBoundingClientRect();
|
|
21372
21469
|
const assistantStyle = {};
|
|
21373
21470
|
assistantStyle["min-width"] = `${this.props.rect?.width || ASSISTANT_WIDTH}px`;
|
|
21374
21471
|
const proposals = this.autoCompleteState.provider?.proposals;
|
|
@@ -21395,6 +21492,9 @@ class Composer extends Component {
|
|
|
21395
21492
|
}
|
|
21396
21493
|
else if (this.props.delimitation) {
|
|
21397
21494
|
assistantStyle["max-height"] = `${this.props.delimitation.height}px`;
|
|
21495
|
+
if (composerRect.left + ASSISTANT_WIDTH > this.spreadsheetRect.width) {
|
|
21496
|
+
assistantStyle.right = `0px`;
|
|
21497
|
+
}
|
|
21398
21498
|
}
|
|
21399
21499
|
return cssPropertiesToCss(assistantStyle);
|
|
21400
21500
|
}
|
|
@@ -23606,23 +23706,13 @@ function getBarConfiguration(chart, labels, localeFormat) {
|
|
|
23606
23706
|
padding: { left: 20, right: 20, top: chart.title ? 10 : 25, bottom: 10 },
|
|
23607
23707
|
};
|
|
23608
23708
|
config.options.indexAxis = chart.horizontal ? "y" : "x";
|
|
23609
|
-
const formatCallback = (value) => {
|
|
23610
|
-
value = Number(value);
|
|
23611
|
-
if (isNaN(value))
|
|
23612
|
-
return value;
|
|
23613
|
-
const { locale, format } = localeFormat;
|
|
23614
|
-
return formatValue(value, {
|
|
23615
|
-
locale,
|
|
23616
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
23617
|
-
});
|
|
23618
|
-
};
|
|
23619
23709
|
config.options.scales = {};
|
|
23620
23710
|
const labelsAxis = { ticks: { padding: 5, color: fontColor } };
|
|
23621
23711
|
const valuesAxis = {
|
|
23622
23712
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
23623
23713
|
ticks: {
|
|
23624
23714
|
color: fontColor,
|
|
23625
|
-
callback:
|
|
23715
|
+
callback: formatTickValue(localeFormat),
|
|
23626
23716
|
},
|
|
23627
23717
|
};
|
|
23628
23718
|
const xAxis = chart.horizontal ? valuesAxis : labelsAxis;
|
|
@@ -23659,7 +23749,7 @@ function getBarConfiguration(chart, labels, localeFormat) {
|
|
|
23659
23749
|
showValues: chart.showValues,
|
|
23660
23750
|
background: chart.background,
|
|
23661
23751
|
horizontal: chart.horizontal,
|
|
23662
|
-
callback:
|
|
23752
|
+
callback: formatTickValue(localeFormat),
|
|
23663
23753
|
};
|
|
23664
23754
|
return config;
|
|
23665
23755
|
}
|
|
@@ -23938,21 +24028,11 @@ function getLineOrScatterConfiguration(chart, labels, options) {
|
|
|
23938
24028
|
title: getChartAxisTitleRuntime(chart.axesDesign?.x),
|
|
23939
24029
|
},
|
|
23940
24030
|
};
|
|
23941
|
-
const formatCallback = (value) => {
|
|
23942
|
-
value = Number(value);
|
|
23943
|
-
if (isNaN(value))
|
|
23944
|
-
return value;
|
|
23945
|
-
const { locale, format } = options;
|
|
23946
|
-
return formatValue(value, {
|
|
23947
|
-
locale,
|
|
23948
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
23949
|
-
});
|
|
23950
|
-
};
|
|
23951
24031
|
const yAxis = {
|
|
23952
24032
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
23953
24033
|
ticks: {
|
|
23954
24034
|
color: fontColor,
|
|
23955
|
-
callback:
|
|
24035
|
+
callback: formatTickValue(options),
|
|
23956
24036
|
},
|
|
23957
24037
|
};
|
|
23958
24038
|
const { useLeftAxis, useRightAxis } = getDefinedAxis(chart.getDefinition());
|
|
@@ -23983,7 +24063,7 @@ function getLineOrScatterConfiguration(chart, labels, options) {
|
|
|
23983
24063
|
config.options.plugins.chartShowValuesPlugin = {
|
|
23984
24064
|
showValues: chart.showValues,
|
|
23985
24065
|
background: chart.background,
|
|
23986
|
-
callback:
|
|
24066
|
+
callback: formatTickValue(options),
|
|
23987
24067
|
};
|
|
23988
24068
|
return config;
|
|
23989
24069
|
}
|
|
@@ -24258,30 +24338,18 @@ function createComboChartRuntime(chart, getters) {
|
|
|
24258
24338
|
title: getChartAxisTitleRuntime(chart.axesDesign?.x),
|
|
24259
24339
|
},
|
|
24260
24340
|
};
|
|
24261
|
-
const formatCallback = (format) => {
|
|
24262
|
-
return (value) => {
|
|
24263
|
-
value = Number(value);
|
|
24264
|
-
if (isNaN(value))
|
|
24265
|
-
return value;
|
|
24266
|
-
const { locale } = localeFormat;
|
|
24267
|
-
return formatValue(value, {
|
|
24268
|
-
locale,
|
|
24269
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
24270
|
-
});
|
|
24271
|
-
};
|
|
24272
|
-
};
|
|
24273
24341
|
const leftVerticalAxis = {
|
|
24274
24342
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
24275
24343
|
ticks: {
|
|
24276
24344
|
color: fontColor,
|
|
24277
|
-
callback:
|
|
24345
|
+
callback: formatTickValue({ format: mainDataSetFormat, locale }),
|
|
24278
24346
|
},
|
|
24279
24347
|
};
|
|
24280
24348
|
const rightVerticalAxis = {
|
|
24281
24349
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
24282
24350
|
ticks: {
|
|
24283
24351
|
color: fontColor,
|
|
24284
|
-
callback:
|
|
24352
|
+
callback: formatTickValue({ format: lineDataSetsFormat, locale }),
|
|
24285
24353
|
},
|
|
24286
24354
|
};
|
|
24287
24355
|
const definition = chart.getDefinition();
|
|
@@ -24306,7 +24374,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
24306
24374
|
config.options.plugins.chartShowValuesPlugin = {
|
|
24307
24375
|
showValues: chart.showValues,
|
|
24308
24376
|
background: chart.background,
|
|
24309
|
-
callback:
|
|
24377
|
+
callback: formatTickValue({ format: mainDataSetFormat, locale }),
|
|
24310
24378
|
};
|
|
24311
24379
|
const colors = new ColorGenerator();
|
|
24312
24380
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
@@ -24838,7 +24906,10 @@ function getPieConfiguration(chart, labels, localeFormat) {
|
|
|
24838
24906
|
const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
|
|
24839
24907
|
return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
|
|
24840
24908
|
};
|
|
24841
|
-
config.options.plugins.chartShowValuesPlugin = {
|
|
24909
|
+
config.options.plugins.chartShowValuesPlugin = {
|
|
24910
|
+
showValues: chart.showValues,
|
|
24911
|
+
callback: formatTickValue(localeFormat),
|
|
24912
|
+
};
|
|
24842
24913
|
return config;
|
|
24843
24914
|
}
|
|
24844
24915
|
function getPieColors(colors, dataSetsValues) {
|
|
@@ -25422,6 +25493,7 @@ function getWaterfallConfiguration(chart, labels, dataSeriesLabels, localeFormat
|
|
|
25422
25493
|
config.options.plugins.chartShowValuesPlugin = {
|
|
25423
25494
|
showValues: chart.showValues,
|
|
25424
25495
|
background: chart.background,
|
|
25496
|
+
callback: formatTickValue(localeFormat),
|
|
25425
25497
|
};
|
|
25426
25498
|
return config;
|
|
25427
25499
|
}
|
|
@@ -26237,78 +26309,6 @@ function zoneToRect(zone) {
|
|
|
26237
26309
|
};
|
|
26238
26310
|
}
|
|
26239
26311
|
|
|
26240
|
-
/**
|
|
26241
|
-
* Return the o-spreadsheet element position relative
|
|
26242
|
-
* to the browser viewport.
|
|
26243
|
-
*/
|
|
26244
|
-
function useSpreadsheetRect() {
|
|
26245
|
-
const position = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
26246
|
-
let spreadsheetElement = null;
|
|
26247
|
-
function updatePosition() {
|
|
26248
|
-
if (!spreadsheetElement) {
|
|
26249
|
-
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
|
26250
|
-
}
|
|
26251
|
-
if (spreadsheetElement) {
|
|
26252
|
-
const { top, left, width, height } = spreadsheetElement.getBoundingClientRect();
|
|
26253
|
-
position.x = left;
|
|
26254
|
-
position.y = top;
|
|
26255
|
-
position.width = width;
|
|
26256
|
-
position.height = height;
|
|
26257
|
-
}
|
|
26258
|
-
}
|
|
26259
|
-
onMounted(updatePosition);
|
|
26260
|
-
onPatched(updatePosition);
|
|
26261
|
-
return position;
|
|
26262
|
-
}
|
|
26263
|
-
/**
|
|
26264
|
-
* Return the component (or ref's component) BoundingRect, relative
|
|
26265
|
-
* to the upper left corner of the screen (<body> element).
|
|
26266
|
-
*
|
|
26267
|
-
* Note: when used with a <Portal/> component, it will
|
|
26268
|
-
* return the portal position, not the teleported position.
|
|
26269
|
-
*/
|
|
26270
|
-
function useAbsoluteBoundingRect(ref) {
|
|
26271
|
-
const rect = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
26272
|
-
function updateElRect() {
|
|
26273
|
-
const el = ref.el;
|
|
26274
|
-
if (el === null) {
|
|
26275
|
-
return;
|
|
26276
|
-
}
|
|
26277
|
-
const { top, left, width, height } = el.getBoundingClientRect();
|
|
26278
|
-
rect.x = left;
|
|
26279
|
-
rect.y = top;
|
|
26280
|
-
rect.width = width;
|
|
26281
|
-
rect.height = height;
|
|
26282
|
-
}
|
|
26283
|
-
onMounted(updateElRect);
|
|
26284
|
-
onPatched(updateElRect);
|
|
26285
|
-
return rect;
|
|
26286
|
-
}
|
|
26287
|
-
/**
|
|
26288
|
-
* Get the rectangle inside which a popover should stay when being displayed.
|
|
26289
|
-
* It's the value defined in `env.getPopoverContainerRect`, or the Rect of the "o-spreadsheet"
|
|
26290
|
-
* element by default.
|
|
26291
|
-
*
|
|
26292
|
-
* Coordinates are expressed expressed as absolute DOM position.
|
|
26293
|
-
*/
|
|
26294
|
-
function usePopoverContainer() {
|
|
26295
|
-
const container = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
26296
|
-
const component = useComponent();
|
|
26297
|
-
const spreadsheetRect = useSpreadsheetRect();
|
|
26298
|
-
function updateRect() {
|
|
26299
|
-
const env = component.env;
|
|
26300
|
-
const newRect = "getPopoverContainerRect" in env ? env.getPopoverContainerRect() : spreadsheetRect;
|
|
26301
|
-
container.x = newRect.x;
|
|
26302
|
-
container.y = newRect.y;
|
|
26303
|
-
container.width = newRect.width;
|
|
26304
|
-
container.height = newRect.height;
|
|
26305
|
-
}
|
|
26306
|
-
updateRect();
|
|
26307
|
-
onMounted(updateRect);
|
|
26308
|
-
onPatched(updateRect);
|
|
26309
|
-
return container;
|
|
26310
|
-
}
|
|
26311
|
-
|
|
26312
26312
|
css /* scss */ `
|
|
26313
26313
|
.o-popover {
|
|
26314
26314
|
position: absolute;
|
|
@@ -35807,6 +35807,14 @@ css /* scss */ `
|
|
|
35807
35807
|
.pivot-dim-operator-label {
|
|
35808
35808
|
min-width: 120px;
|
|
35809
35809
|
}
|
|
35810
|
+
|
|
35811
|
+
&.pivot-dimension-invalid {
|
|
35812
|
+
background-color: #ffdddd;
|
|
35813
|
+
border-color: red !important;
|
|
35814
|
+
select {
|
|
35815
|
+
background-color: #ffdddd;
|
|
35816
|
+
}
|
|
35817
|
+
}
|
|
35810
35818
|
}
|
|
35811
35819
|
`;
|
|
35812
35820
|
class PivotDimension extends Component {
|
|
@@ -47214,12 +47222,13 @@ class BordersPlugin extends CorePlugin {
|
|
|
47214
47222
|
this.clearBorders(cmd.sheetId, cmd.target);
|
|
47215
47223
|
break;
|
|
47216
47224
|
case "REMOVE_COLUMNS_ROWS":
|
|
47217
|
-
|
|
47225
|
+
const elements = [...cmd.elements].sort((a, b) => b - a);
|
|
47226
|
+
for (const group of groupConsecutive(elements)) {
|
|
47218
47227
|
if (cmd.dimension === "COL") {
|
|
47219
|
-
this.shiftBordersHorizontally(cmd.sheetId,
|
|
47228
|
+
this.shiftBordersHorizontally(cmd.sheetId, group[group.length - 1] + 1, -group.length);
|
|
47220
47229
|
}
|
|
47221
47230
|
else {
|
|
47222
|
-
this.shiftBordersVertically(cmd.sheetId,
|
|
47231
|
+
this.shiftBordersVertically(cmd.sheetId, group[group.length - 1] + 1, -group.length);
|
|
47223
47232
|
}
|
|
47224
47233
|
}
|
|
47225
47234
|
break;
|
|
@@ -50389,7 +50398,7 @@ class RangeAdapter {
|
|
|
50389
50398
|
* @param sheetXC the string description of a range, in the form SheetName!XC:XC
|
|
50390
50399
|
*/
|
|
50391
50400
|
getRangeFromSheetXC(defaultSheetId, sheetXC) {
|
|
50392
|
-
if (!rangeReference.test(sheetXC)) {
|
|
50401
|
+
if (!rangeReference.test(sheetXC) || !this.getters.tryGetSheet(defaultSheetId)) {
|
|
50393
50402
|
return new RangeImpl({
|
|
50394
50403
|
sheetId: "",
|
|
50395
50404
|
zone: { left: -1, top: -1, right: -1, bottom: -1 },
|
|
@@ -51280,12 +51289,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
51280
51289
|
});
|
|
51281
51290
|
}
|
|
51282
51291
|
if (colIndex > deletedColumn) {
|
|
51283
|
-
this.
|
|
51284
|
-
sheetId: sheet.id,
|
|
51285
|
-
cellId: cellId,
|
|
51286
|
-
col: colIndex - 1,
|
|
51287
|
-
row: rowIndex,
|
|
51288
|
-
});
|
|
51292
|
+
this.setNewPosition(cellId, sheet.id, colIndex - 1, rowIndex);
|
|
51289
51293
|
}
|
|
51290
51294
|
}
|
|
51291
51295
|
}
|
|
@@ -51295,7 +51299,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
51295
51299
|
* Move the cells after a column or rows insertion
|
|
51296
51300
|
*/
|
|
51297
51301
|
moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
|
|
51298
|
-
const
|
|
51302
|
+
const updates = [];
|
|
51299
51303
|
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
51300
51304
|
const row = sheet.rows[rowIndex];
|
|
51301
51305
|
if (dimension !== "rows" || rowIndex >= addedElement) {
|
|
@@ -51304,20 +51308,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
51304
51308
|
const cellId = row.cells[i];
|
|
51305
51309
|
if (cellId) {
|
|
51306
51310
|
if (dimension === "rows" || colIndex >= addedElement) {
|
|
51307
|
-
|
|
51308
|
-
type: "UPDATE_CELL_POSITION",
|
|
51311
|
+
updates.push({
|
|
51309
51312
|
sheetId: sheet.id,
|
|
51310
51313
|
cellId: cellId,
|
|
51311
51314
|
col: colIndex + (dimension === "columns" ? quantity : 0),
|
|
51312
51315
|
row: rowIndex + (dimension === "rows" ? quantity : 0),
|
|
51316
|
+
type: "UPDATE_CELL_POSITION",
|
|
51313
51317
|
});
|
|
51314
51318
|
}
|
|
51315
51319
|
}
|
|
51316
51320
|
}
|
|
51317
51321
|
}
|
|
51318
51322
|
}
|
|
51319
|
-
for (let
|
|
51320
|
-
this.
|
|
51323
|
+
for (let update of updates.reverse()) {
|
|
51324
|
+
this.updateCellPosition(update);
|
|
51321
51325
|
}
|
|
51322
51326
|
}
|
|
51323
51327
|
/**
|
|
@@ -51350,12 +51354,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
51350
51354
|
const colIndex = Number(i);
|
|
51351
51355
|
const cellId = row.cells[i];
|
|
51352
51356
|
if (cellId) {
|
|
51353
|
-
this.
|
|
51354
|
-
sheetId: sheet.id,
|
|
51355
|
-
cellId: cellId,
|
|
51356
|
-
col: colIndex,
|
|
51357
|
-
row: rowIndex - numberRows,
|
|
51358
|
-
});
|
|
51357
|
+
this.setNewPosition(cellId, sheet.id, colIndex, rowIndex - numberRows);
|
|
51359
51358
|
}
|
|
51360
51359
|
}
|
|
51361
51360
|
}
|
|
@@ -54052,18 +54051,23 @@ class Evaluator {
|
|
|
54052
54051
|
this.evaluate(this.getAllCells());
|
|
54053
54052
|
console.info("evaluate all cells", performance.now() - start, "ms");
|
|
54054
54053
|
}
|
|
54055
|
-
|
|
54056
|
-
|
|
54057
|
-
|
|
54058
|
-
|
|
54059
|
-
|
|
54060
|
-
|
|
54061
|
-
|
|
54054
|
+
evaluateFormulaResult(sheetId, formulaString) {
|
|
54055
|
+
try {
|
|
54056
|
+
const compiledFormula = compile(formulaString);
|
|
54057
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
54058
|
+
this.updateCompilationParameters();
|
|
54059
|
+
const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
|
|
54060
|
+
if (isMatrix(result)) {
|
|
54061
|
+
return result;
|
|
54062
|
+
}
|
|
54063
|
+
if (result.value === null) {
|
|
54064
|
+
return { value: 0, format: result.format };
|
|
54065
|
+
}
|
|
54066
|
+
return result;
|
|
54062
54067
|
}
|
|
54063
|
-
|
|
54064
|
-
return
|
|
54068
|
+
catch (error) {
|
|
54069
|
+
return handleError(error, "");
|
|
54065
54070
|
}
|
|
54066
|
-
return result.value;
|
|
54067
54071
|
}
|
|
54068
54072
|
getAllCells() {
|
|
54069
54073
|
const positions = this.createEmptyPositionSet();
|
|
@@ -54121,6 +54125,9 @@ class Evaluator {
|
|
|
54121
54125
|
if (!this.blockedArrayFormulas.has(position)) {
|
|
54122
54126
|
this.invalidateSpreading(position);
|
|
54123
54127
|
}
|
|
54128
|
+
if (this.spreadingRelations.isArrayFormula(position)) {
|
|
54129
|
+
this.spreadingRelations.removeNode(position);
|
|
54130
|
+
}
|
|
54124
54131
|
const cell = this.getters.getCell(position);
|
|
54125
54132
|
if (cell === undefined) {
|
|
54126
54133
|
return EMPTY_CELL;
|
|
@@ -54163,7 +54170,6 @@ class Evaluator {
|
|
|
54163
54170
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
54164
54171
|
const nbColumns = formulaReturn.length;
|
|
54165
54172
|
const nbRows = formulaReturn[0].length;
|
|
54166
|
-
this.spreadingRelations.removeNode(formulaPosition);
|
|
54167
54173
|
forEachSpreadPositionInMatrix(nbColumns, nbRows, this.updateSpreadRelation(formulaPosition));
|
|
54168
54174
|
this.assertNoMergedCellsInSpreadZone(formulaPosition, formulaReturn);
|
|
54169
54175
|
forEachSpreadPositionInMatrix(nbColumns, nbRows, this.checkCollision(formulaPosition));
|
|
@@ -54424,6 +54430,7 @@ function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId
|
|
|
54424
54430
|
class EvaluationPlugin extends UIPlugin {
|
|
54425
54431
|
static getters = [
|
|
54426
54432
|
"evaluateFormula",
|
|
54433
|
+
"evaluateFormulaResult",
|
|
54427
54434
|
"getCorrespondingFormulaCell",
|
|
54428
54435
|
"getRangeFormattedValues",
|
|
54429
54436
|
"getRangeValues",
|
|
@@ -54483,12 +54490,14 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
54483
54490
|
// Getters
|
|
54484
54491
|
// ---------------------------------------------------------------------------
|
|
54485
54492
|
evaluateFormula(sheetId, formulaString) {
|
|
54486
|
-
|
|
54487
|
-
|
|
54488
|
-
|
|
54489
|
-
catch (error) {
|
|
54490
|
-
return error.value || CellErrorType.GenericError;
|
|
54493
|
+
const result = this.evaluateFormulaResult(sheetId, formulaString);
|
|
54494
|
+
if (isMatrix(result)) {
|
|
54495
|
+
return matrixMap(result, (cell) => cell.value);
|
|
54491
54496
|
}
|
|
54497
|
+
return result.value;
|
|
54498
|
+
}
|
|
54499
|
+
evaluateFormulaResult(sheetId, formulaString) {
|
|
54500
|
+
return this.evaluator.evaluateFormulaResult(sheetId, formulaString);
|
|
54492
54501
|
}
|
|
54493
54502
|
/**
|
|
54494
54503
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -55871,28 +55880,33 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
55871
55880
|
const pivotRow = position.row - mainPosition.row;
|
|
55872
55881
|
return pivotCells[pivotCol][pivotRow];
|
|
55873
55882
|
}
|
|
55874
|
-
|
|
55875
|
-
|
|
55883
|
+
try {
|
|
55884
|
+
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
55885
|
+
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
55886
|
+
return {
|
|
55887
|
+
type: "MEASURE_HEADER",
|
|
55888
|
+
domain,
|
|
55889
|
+
measure: args.at(-1)?.toString() || "",
|
|
55890
|
+
};
|
|
55891
|
+
}
|
|
55892
|
+
else if (functionName === "PIVOT.HEADER") {
|
|
55893
|
+
const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
|
|
55894
|
+
return {
|
|
55895
|
+
type: "HEADER",
|
|
55896
|
+
domain,
|
|
55897
|
+
};
|
|
55898
|
+
}
|
|
55899
|
+
const [measure, ...domainArgs] = args.slice(1);
|
|
55900
|
+
const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
|
|
55876
55901
|
return {
|
|
55877
|
-
type: "
|
|
55902
|
+
type: "VALUE",
|
|
55878
55903
|
domain,
|
|
55879
|
-
measure:
|
|
55904
|
+
measure: measure?.toString() || "",
|
|
55880
55905
|
};
|
|
55881
55906
|
}
|
|
55882
|
-
|
|
55883
|
-
|
|
55884
|
-
return {
|
|
55885
|
-
type: "HEADER",
|
|
55886
|
-
domain,
|
|
55887
|
-
};
|
|
55907
|
+
catch (_) {
|
|
55908
|
+
return EMPTY_PIVOT_CELL;
|
|
55888
55909
|
}
|
|
55889
|
-
const [measure, ...domainArgs] = args.slice(1);
|
|
55890
|
-
const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
|
|
55891
|
-
return {
|
|
55892
|
-
type: "VALUE",
|
|
55893
|
-
domain,
|
|
55894
|
-
measure: measure?.toString() || "",
|
|
55895
|
-
};
|
|
55896
55910
|
}
|
|
55897
55911
|
getPivot(pivotId) {
|
|
55898
55912
|
return this.pivots[pivotId];
|
|
@@ -57760,6 +57774,7 @@ class FormatPlugin extends UIPlugin {
|
|
|
57760
57774
|
* evaluated and updated with the number type.
|
|
57761
57775
|
*/
|
|
57762
57776
|
setDecimal(sheetId, zones, step) {
|
|
57777
|
+
const positionsByFormat = {};
|
|
57763
57778
|
// Find the each cell with a number value and get the format
|
|
57764
57779
|
for (const zone of recomputeZones(zones)) {
|
|
57765
57780
|
for (const position of positions(zone)) {
|
|
@@ -57769,15 +57784,20 @@ class FormatPlugin extends UIPlugin {
|
|
|
57769
57784
|
// of the format
|
|
57770
57785
|
this.getters.getLocale();
|
|
57771
57786
|
const newFormat = changeDecimalPlaces(numberFormat, step);
|
|
57772
|
-
|
|
57773
|
-
|
|
57774
|
-
sheetId,
|
|
57775
|
-
target: [positionToZone(position)],
|
|
57776
|
-
format: newFormat,
|
|
57777
|
-
});
|
|
57787
|
+
positionsByFormat[newFormat] = positionsByFormat[newFormat] || [];
|
|
57788
|
+
positionsByFormat[newFormat].push(position);
|
|
57778
57789
|
}
|
|
57779
57790
|
}
|
|
57780
57791
|
}
|
|
57792
|
+
// consolidate all positions with the same format in bigger zones
|
|
57793
|
+
for (const newFormat in positionsByFormat) {
|
|
57794
|
+
const zones = recomputeZones(positionsByFormat[newFormat].map((position) => positionToZone(position)));
|
|
57795
|
+
this.dispatch("SET_FORMATTING", {
|
|
57796
|
+
sheetId,
|
|
57797
|
+
format: newFormat,
|
|
57798
|
+
target: zones,
|
|
57799
|
+
});
|
|
57800
|
+
}
|
|
57781
57801
|
}
|
|
57782
57802
|
/**
|
|
57783
57803
|
* Take a range of cells and return the format of the first cell containing a
|
|
@@ -63088,6 +63108,8 @@ css /* scss */ `
|
|
|
63088
63108
|
|
|
63089
63109
|
.o-sidePanel-handle-container {
|
|
63090
63110
|
width: 8px;
|
|
63111
|
+
position: fixed;
|
|
63112
|
+
top: 50%;
|
|
63091
63113
|
}
|
|
63092
63114
|
.o-sidePanel-handle {
|
|
63093
63115
|
cursor: col-resize;
|
|
@@ -65707,7 +65729,7 @@ function createEmptyStructure(node) {
|
|
|
65707
65729
|
}
|
|
65708
65730
|
|
|
65709
65731
|
class StateObserver {
|
|
65710
|
-
changes
|
|
65732
|
+
changes;
|
|
65711
65733
|
commands = [];
|
|
65712
65734
|
/**
|
|
65713
65735
|
* Record the changes which could happen in the given callback, save them in a
|
|
@@ -65739,7 +65761,7 @@ class StateObserver {
|
|
|
65739
65761
|
if (value[key] === val) {
|
|
65740
65762
|
return;
|
|
65741
65763
|
}
|
|
65742
|
-
this.changes
|
|
65764
|
+
this.changes?.push({
|
|
65743
65765
|
key,
|
|
65744
65766
|
target: value,
|
|
65745
65767
|
before: value[key],
|
|
@@ -68362,6 +68384,6 @@ const constants = {
|
|
|
68362
68384
|
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 };
|
|
68363
68385
|
|
|
68364
68386
|
|
|
68365
|
-
__info__.version = "17.4.
|
|
68366
|
-
__info__.date = "2024-
|
|
68367
|
-
__info__.hash = "
|
|
68387
|
+
__info__.version = "17.4.4";
|
|
68388
|
+
__info__.date = "2024-08-09T12:24:07.798Z";
|
|
68389
|
+
__info__.hash = "a43e855";
|