@odoo/o-spreadsheet 19.0.4 → 19.0.6
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 +296 -204
- package/dist/o-spreadsheet.d.ts +227 -157
- package/dist/o-spreadsheet.esm.js +296 -204
- package/dist/o-spreadsheet.iife.js +296 -204
- package/dist/o-spreadsheet.iife.min.js +278 -285
- package/dist/o_spreadsheet.xml +66 -17
- package/package.json +1 -1
|
@@ -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 19.0.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.6
|
|
6
|
+
* @date 2025-10-16T06:39:36.282Z
|
|
7
|
+
* @hash 0d4315a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -1382,9 +1382,7 @@ function removeIndexesFromArray(array, indexes) {
|
|
|
1382
1382
|
return newArray;
|
|
1383
1383
|
}
|
|
1384
1384
|
function insertItemsAtIndex(array, items, index) {
|
|
1385
|
-
|
|
1386
|
-
newArray.splice(index, 0, ...items);
|
|
1387
|
-
return newArray;
|
|
1385
|
+
return array.slice(0, index).concat(items).concat(array.slice(index));
|
|
1388
1386
|
}
|
|
1389
1387
|
function replaceItemAtIndex(array, newItem, index) {
|
|
1390
1388
|
const newArray = [...array];
|
|
@@ -4515,7 +4513,17 @@ function toNumberMatrix(data, argName) {
|
|
|
4515
4513
|
return toMatrix(data).map((row) => {
|
|
4516
4514
|
return row.map((cell) => {
|
|
4517
4515
|
if (typeof cell.value !== "number") {
|
|
4518
|
-
|
|
4516
|
+
let message = "";
|
|
4517
|
+
if (typeof cell === "object") {
|
|
4518
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
|
|
4519
|
+
}
|
|
4520
|
+
else if (typeof cell === "string") {
|
|
4521
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
|
|
4522
|
+
}
|
|
4523
|
+
else if (typeof cell === "boolean") {
|
|
4524
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
|
|
4525
|
+
}
|
|
4526
|
+
throw new EvaluationError(message);
|
|
4519
4527
|
}
|
|
4520
4528
|
return cell.value;
|
|
4521
4529
|
});
|
|
@@ -5634,7 +5642,7 @@ function tokensToTextInternalFormat(tokens) {
|
|
|
5634
5642
|
* Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
|
|
5635
5643
|
*
|
|
5636
5644
|
* As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
|
|
5637
|
-
* preceded by a data token "h", then it's not a month but
|
|
5645
|
+
* preceded by a data token "h", then it's not a month but a minute.
|
|
5638
5646
|
*/
|
|
5639
5647
|
function convertTokensToMinutesInDateFormat(tokens) {
|
|
5640
5648
|
const dateParts = tokens.filter((token) => token.type === "DATE_PART");
|
|
@@ -5677,6 +5685,9 @@ function internalFormatPartToFormat(internalFormat) {
|
|
|
5677
5685
|
case "REPEATED_CHAR":
|
|
5678
5686
|
format += "*" + token.value;
|
|
5679
5687
|
break;
|
|
5688
|
+
case "DATE_PART":
|
|
5689
|
+
format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
|
|
5690
|
+
break;
|
|
5680
5691
|
default:
|
|
5681
5692
|
format += token.value;
|
|
5682
5693
|
}
|
|
@@ -9527,7 +9538,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9527
9538
|
pasteCell(origin, target, clipboardOption) {
|
|
9528
9539
|
const { sheetId, col, row } = target;
|
|
9529
9540
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
9530
|
-
const originFormat = origin?.format
|
|
9541
|
+
const originFormat = origin?.format || origin.evaluatedCell.format;
|
|
9531
9542
|
if (clipboardOption?.pasteOption === "asValue") {
|
|
9532
9543
|
this.dispatch("UPDATE_CELL", {
|
|
9533
9544
|
...target,
|
|
@@ -13900,7 +13911,7 @@ const GROWTH = {
|
|
|
13900
13911
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13901
13912
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13902
13913
|
}
|
|
13903
|
-
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "
|
|
13914
|
+
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
|
|
13904
13915
|
},
|
|
13905
13916
|
};
|
|
13906
13917
|
// -----------------------------------------------------------------------------
|
|
@@ -13973,7 +13984,7 @@ const LINEST = {
|
|
|
13973
13984
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13974
13985
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13975
13986
|
}
|
|
13976
|
-
return fullLinearRegression(toNumberMatrix(dataX, "
|
|
13987
|
+
return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
|
|
13977
13988
|
},
|
|
13978
13989
|
isExported: true,
|
|
13979
13990
|
};
|
|
@@ -13992,7 +14003,7 @@ const LOGEST = {
|
|
|
13992
14003
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13993
14004
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13994
14005
|
}
|
|
13995
|
-
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "
|
|
14006
|
+
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
|
|
13996
14007
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13997
14008
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
13998
14009
|
}
|
|
@@ -14613,7 +14624,7 @@ const TREND = {
|
|
|
14613
14624
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
14614
14625
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
14615
14626
|
}
|
|
14616
|
-
return predictLinearValues(toNumberMatrix(knownDataY, "
|
|
14627
|
+
return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
|
|
14617
14628
|
},
|
|
14618
14629
|
};
|
|
14619
14630
|
// -----------------------------------------------------------------------------
|
|
@@ -23134,6 +23145,10 @@ const chartShowValuesPlugin = {
|
|
|
23134
23145
|
}
|
|
23135
23146
|
const ctx = chart.ctx;
|
|
23136
23147
|
ctx.save();
|
|
23148
|
+
const { left, top, height, width } = chart.chartArea;
|
|
23149
|
+
ctx.beginPath();
|
|
23150
|
+
ctx.rect(left, top, width, height);
|
|
23151
|
+
ctx.clip();
|
|
23137
23152
|
ctx.textAlign = "center";
|
|
23138
23153
|
ctx.textBaseline = "middle";
|
|
23139
23154
|
ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
|
|
@@ -24177,7 +24192,7 @@ class ChartJsComponent extends Component {
|
|
|
24177
24192
|
this.chart.update();
|
|
24178
24193
|
}
|
|
24179
24194
|
hasChartDataChanged() {
|
|
24180
|
-
return !deepEquals(this.currentRuntime
|
|
24195
|
+
return !deepEquals(this.getChartDataInRuntime(this.currentRuntime), this.getChartDataInRuntime(this.chartRuntime));
|
|
24181
24196
|
}
|
|
24182
24197
|
enableAnimationInChartData(chartData) {
|
|
24183
24198
|
return {
|
|
@@ -24185,6 +24200,17 @@ class ChartJsComponent extends Component {
|
|
|
24185
24200
|
options: { ...chartData.options, animation: { animateRotate: true } },
|
|
24186
24201
|
};
|
|
24187
24202
|
}
|
|
24203
|
+
getChartDataInRuntime(runtime) {
|
|
24204
|
+
const data = runtime.chartJsConfig.data;
|
|
24205
|
+
return {
|
|
24206
|
+
labels: data.labels,
|
|
24207
|
+
dataset: data.datasets.map((dataset) => ({
|
|
24208
|
+
data: dataset.data,
|
|
24209
|
+
label: dataset.label,
|
|
24210
|
+
tree: dataset.tree,
|
|
24211
|
+
})),
|
|
24212
|
+
};
|
|
24213
|
+
}
|
|
24188
24214
|
get animationChartId() {
|
|
24189
24215
|
return this.props.isFullScreen ? this.props.chartId + "-fullscreen" : this.props.chartId;
|
|
24190
24216
|
}
|
|
@@ -24852,6 +24878,7 @@ class ScorecardChart extends Component {
|
|
|
24852
24878
|
static template = "o-spreadsheet-ScorecardChart";
|
|
24853
24879
|
static props = {
|
|
24854
24880
|
chartId: String,
|
|
24881
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
24855
24882
|
};
|
|
24856
24883
|
canvas = useRef("chartContainer");
|
|
24857
24884
|
get runtime() {
|
|
@@ -25607,6 +25634,7 @@ function getChartTimeOptions(labels, labelFormat, locale) {
|
|
|
25607
25634
|
parser: luxonFormat,
|
|
25608
25635
|
displayFormats,
|
|
25609
25636
|
unit: timeUnit ?? false,
|
|
25637
|
+
tooltipFormat: luxonFormat,
|
|
25610
25638
|
};
|
|
25611
25639
|
}
|
|
25612
25640
|
/**
|
|
@@ -26675,6 +26703,7 @@ function getLineChartScales(definition, args) {
|
|
|
26675
26703
|
};
|
|
26676
26704
|
Object.assign(scales.x, axis);
|
|
26677
26705
|
scales.x.ticks.maxTicksLimit = 15;
|
|
26706
|
+
delete scales?.x?.ticks?.callback;
|
|
26678
26707
|
}
|
|
26679
26708
|
else if (axisType === "linear") {
|
|
26680
26709
|
scales.x.type = "linear";
|
|
@@ -27615,26 +27644,6 @@ function createBarChartRuntime(chart, getters) {
|
|
|
27615
27644
|
return { chartJsConfig: config, background: chart.background || BACKGROUND_CHART_COLOR };
|
|
27616
27645
|
}
|
|
27617
27646
|
|
|
27618
|
-
class FullScreenChartStore extends SpreadsheetStore {
|
|
27619
|
-
mutators = ["toggleFullScreenChart"];
|
|
27620
|
-
fullScreenFigure = undefined;
|
|
27621
|
-
toggleFullScreenChart(figureId) {
|
|
27622
|
-
if (this.fullScreenFigure?.id === figureId) {
|
|
27623
|
-
this.fullScreenFigure = undefined;
|
|
27624
|
-
}
|
|
27625
|
-
else {
|
|
27626
|
-
this.makeFullScreen(figureId);
|
|
27627
|
-
}
|
|
27628
|
-
}
|
|
27629
|
-
makeFullScreen(figureId) {
|
|
27630
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
27631
|
-
const figure = this.getters.getFigure(sheetId, figureId);
|
|
27632
|
-
if (figure) {
|
|
27633
|
-
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
27634
|
-
}
|
|
27635
|
-
}
|
|
27636
|
-
}
|
|
27637
|
-
|
|
27638
27647
|
const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
|
|
27639
27648
|
const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
|
|
27640
27649
|
class ZoomableChartStore extends SpreadsheetStore {
|
|
@@ -27806,7 +27815,6 @@ chartJsExtensionRegistry.add("zoomWindowPlugin", {
|
|
|
27806
27815
|
class ZoomableChartJsComponent extends ChartJsComponent {
|
|
27807
27816
|
static template = "o-spreadsheet-ZoomableChartJsComponent";
|
|
27808
27817
|
store;
|
|
27809
|
-
fullScreenChartStore;
|
|
27810
27818
|
masterChartCanvas = useRef("masterChartCanvas");
|
|
27811
27819
|
masterChart;
|
|
27812
27820
|
mode;
|
|
@@ -27817,7 +27825,6 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27817
27825
|
removeEventListeners = () => { };
|
|
27818
27826
|
setup() {
|
|
27819
27827
|
this.store = useStore(ZoomableChartStore);
|
|
27820
|
-
this.fullScreenChartStore = useStore(FullScreenChartStore);
|
|
27821
27828
|
super.setup();
|
|
27822
27829
|
}
|
|
27823
27830
|
unmount() {
|
|
@@ -27832,12 +27839,8 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27832
27839
|
`;
|
|
27833
27840
|
}
|
|
27834
27841
|
get sliceable() {
|
|
27835
|
-
if (this.
|
|
27836
|
-
|
|
27837
|
-
const chartFigureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
27838
|
-
if (fullScreenFigureId === chartFigureId) {
|
|
27839
|
-
return true;
|
|
27840
|
-
}
|
|
27842
|
+
if (this.props.isFullScreen) {
|
|
27843
|
+
return true;
|
|
27841
27844
|
}
|
|
27842
27845
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27843
27846
|
return ("zoomable" in definition && definition?.zoomable) ?? false;
|
|
@@ -27900,9 +27903,6 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27900
27903
|
const xMax = Math.max(...xValues);
|
|
27901
27904
|
return { xMin, xMax };
|
|
27902
27905
|
}
|
|
27903
|
-
get shouldAnimate() {
|
|
27904
|
-
return this.env.model.getters.isDashboard() && !this.sliceable;
|
|
27905
|
-
}
|
|
27906
27906
|
createChart(chartRuntime) {
|
|
27907
27907
|
const chartData = chartRuntime.chartJsConfig;
|
|
27908
27908
|
this.isBarChart = chartData.type === "bar";
|
|
@@ -27921,6 +27921,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27921
27921
|
const masterChartCtx = this.masterChartCanvas.el.getContext("2d");
|
|
27922
27922
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27923
27923
|
this.resetAxesLimits();
|
|
27924
|
+
if (this.chart?.options) {
|
|
27925
|
+
this.chart.options.animation = false;
|
|
27926
|
+
}
|
|
27924
27927
|
}
|
|
27925
27928
|
updateChartJs(chartRuntime) {
|
|
27926
27929
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27954,6 +27957,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27954
27957
|
}
|
|
27955
27958
|
}
|
|
27956
27959
|
this.resetAxesLimits();
|
|
27960
|
+
if (this.chart?.options) {
|
|
27961
|
+
this.chart.options.animation = false;
|
|
27962
|
+
}
|
|
27957
27963
|
}
|
|
27958
27964
|
resetAxesLimits() {
|
|
27959
27965
|
if (!this.chart) {
|
|
@@ -28051,7 +28057,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28051
28057
|
onPointerDownInMasterChart(ev) {
|
|
28052
28058
|
this.removeEventListeners();
|
|
28053
28059
|
const position = ev.offsetX;
|
|
28054
|
-
if (!this.masterChart?.chartArea || !this.chart?.scales
|
|
28060
|
+
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
28055
28061
|
return;
|
|
28056
28062
|
}
|
|
28057
28063
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
@@ -31609,6 +31615,26 @@ function getCarouselItemTitle(getters, item) {
|
|
|
31609
31615
|
return matchedChart.displayName;
|
|
31610
31616
|
}
|
|
31611
31617
|
|
|
31618
|
+
class FullScreenFigureStore extends SpreadsheetStore {
|
|
31619
|
+
mutators = ["toggleFullScreenFigure"];
|
|
31620
|
+
fullScreenFigure = undefined;
|
|
31621
|
+
toggleFullScreenFigure(figureId) {
|
|
31622
|
+
if (this.fullScreenFigure?.id === figureId) {
|
|
31623
|
+
this.fullScreenFigure = undefined;
|
|
31624
|
+
}
|
|
31625
|
+
else {
|
|
31626
|
+
this.makeFullScreen(figureId);
|
|
31627
|
+
}
|
|
31628
|
+
}
|
|
31629
|
+
makeFullScreen(figureId) {
|
|
31630
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
31631
|
+
const figure = this.getters.getFigure(sheetId, figureId);
|
|
31632
|
+
if (figure) {
|
|
31633
|
+
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
31634
|
+
}
|
|
31635
|
+
}
|
|
31636
|
+
}
|
|
31637
|
+
|
|
31612
31638
|
/**
|
|
31613
31639
|
* Repeatedly calls a callback function with a time delay between calls.
|
|
31614
31640
|
*/
|
|
@@ -32346,12 +32372,13 @@ class MenuPopover extends Component {
|
|
|
32346
32372
|
class ChartDashboardMenu extends Component {
|
|
32347
32373
|
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
32348
32374
|
static components = { MenuPopover };
|
|
32349
|
-
static props = { chartId: String };
|
|
32375
|
+
static props = { chartId: String, hasFullScreenButton: { type: Boolean, optional: true } };
|
|
32376
|
+
static defaultProps = { hasFullScreenButton: true };
|
|
32350
32377
|
fullScreenFigureStore;
|
|
32351
32378
|
menuState = useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32352
32379
|
setup() {
|
|
32353
32380
|
super.setup();
|
|
32354
|
-
this.fullScreenFigureStore = useStore(
|
|
32381
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32355
32382
|
}
|
|
32356
32383
|
getMenuItems() {
|
|
32357
32384
|
return [this.fullScreenMenuItem].filter(isDefined);
|
|
@@ -32362,11 +32389,14 @@ class ChartDashboardMenu extends Component {
|
|
|
32362
32389
|
}
|
|
32363
32390
|
openContextMenu(ev) {
|
|
32364
32391
|
this.menuState.isOpen = true;
|
|
32365
|
-
this.menuState.anchorRect =
|
|
32392
|
+
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
32366
32393
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32367
32394
|
this.menuState.menuItems = getChartMenuActions(figureId, () => { }, this.env);
|
|
32368
32395
|
}
|
|
32369
32396
|
get fullScreenMenuItem() {
|
|
32397
|
+
if (!this.props.hasFullScreenButton) {
|
|
32398
|
+
return undefined;
|
|
32399
|
+
}
|
|
32370
32400
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
32371
32401
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32372
32402
|
if (definition.type === "scorecard") {
|
|
@@ -32378,7 +32408,7 @@ class ChartDashboardMenu extends Component {
|
|
|
32378
32408
|
label: isFullScreen ? _t("Exit Full Screen") : _t("Full Screen"),
|
|
32379
32409
|
class: `text-muted fa ${isFullScreen ? "fa-compress" : "fa-expand"}`,
|
|
32380
32410
|
onClick: () => {
|
|
32381
|
-
this.fullScreenFigureStore.
|
|
32411
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(figureId);
|
|
32382
32412
|
},
|
|
32383
32413
|
};
|
|
32384
32414
|
}
|
|
@@ -32390,6 +32420,8 @@ class CarouselFigure extends Component {
|
|
|
32390
32420
|
figureUI: Object,
|
|
32391
32421
|
onFigureDeleted: Function,
|
|
32392
32422
|
editFigureStyle: { type: Function, optional: true },
|
|
32423
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32424
|
+
openContextMenu: { type: Function, optional: true },
|
|
32393
32425
|
};
|
|
32394
32426
|
static components = { ChartDashboardMenu, MenuPopover };
|
|
32395
32427
|
carouselTabsRef = useRef("carouselTabs");
|
|
@@ -32397,8 +32429,10 @@ class CarouselFigure extends Component {
|
|
|
32397
32429
|
menuState = useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32398
32430
|
hiddenItems = [];
|
|
32399
32431
|
animationStore;
|
|
32432
|
+
fullScreenFigureStore;
|
|
32400
32433
|
setup() {
|
|
32401
32434
|
this.animationStore = useStore(ChartAnimationStore);
|
|
32435
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32402
32436
|
useEffect(() => {
|
|
32403
32437
|
if (this.selectedCarouselItem?.type === "carouselDataView") {
|
|
32404
32438
|
this.props.editFigureStyle?.({ "pointer-events": "none" });
|
|
@@ -32445,7 +32479,8 @@ class CarouselFigure extends Component {
|
|
|
32445
32479
|
item,
|
|
32446
32480
|
});
|
|
32447
32481
|
if (item.type === "chart") {
|
|
32448
|
-
|
|
32482
|
+
const animationChartId = item.chartId + (this.props.isFullScreen ? "-fullscreen" : "");
|
|
32483
|
+
this.animationStore?.enableAnimationForChart(animationChartId);
|
|
32449
32484
|
}
|
|
32450
32485
|
}
|
|
32451
32486
|
get headerStyle() {
|
|
@@ -32509,6 +32544,23 @@ class CarouselFigure extends Component {
|
|
|
32509
32544
|
this.menuState.anchorRect = rect;
|
|
32510
32545
|
this.menuState.menuItems = createActions(menuItems);
|
|
32511
32546
|
}
|
|
32547
|
+
toggleFullScreen() {
|
|
32548
|
+
if (this.selectedCarouselItem?.type === "chart") {
|
|
32549
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.props.figureUI.id);
|
|
32550
|
+
}
|
|
32551
|
+
}
|
|
32552
|
+
get fullScreenButtonTitle() {
|
|
32553
|
+
return this.props.isFullScreen ? _t("Exit Full Screen") : _t("Full Screen");
|
|
32554
|
+
}
|
|
32555
|
+
get visibleCarouselItems() {
|
|
32556
|
+
return this.carousel.items.filter((item) => item.type === "carouselDataView" && this.props.isFullScreen ? false : true);
|
|
32557
|
+
}
|
|
32558
|
+
openContextMenu(event) {
|
|
32559
|
+
const target = event.currentTarget;
|
|
32560
|
+
if (target) {
|
|
32561
|
+
this.props.openContextMenu?.(getBoundingRectAsPOJO(target));
|
|
32562
|
+
}
|
|
32563
|
+
}
|
|
32512
32564
|
}
|
|
32513
32565
|
|
|
32514
32566
|
class ChartFigure extends Component {
|
|
@@ -32517,6 +32569,8 @@ class ChartFigure extends Component {
|
|
|
32517
32569
|
figureUI: Object,
|
|
32518
32570
|
onFigureDeleted: Function,
|
|
32519
32571
|
editFigureStyle: { type: Function, optional: true },
|
|
32572
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32573
|
+
openContextMenu: { type: Function, optional: true },
|
|
32520
32574
|
};
|
|
32521
32575
|
static components = { ChartDashboardMenu };
|
|
32522
32576
|
onDoubleClick() {
|
|
@@ -32549,6 +32603,7 @@ class ImageFigure extends Component {
|
|
|
32549
32603
|
figureUI: Object,
|
|
32550
32604
|
onFigureDeleted: Function,
|
|
32551
32605
|
editFigureStyle: { type: Function, optional: true },
|
|
32606
|
+
openContextMenu: { type: Function, optional: true },
|
|
32552
32607
|
};
|
|
32553
32608
|
static components = {};
|
|
32554
32609
|
// ---------------------------------------------------------------------------
|
|
@@ -34600,8 +34655,11 @@ class Composer extends Component {
|
|
|
34600
34655
|
}
|
|
34601
34656
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
34602
34657
|
this.props.composerStore.stopComposerRangeSelection();
|
|
34603
|
-
this.props.
|
|
34604
|
-
this.props.
|
|
34658
|
+
const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
|
|
34659
|
+
this.props.onComposerContentFocused(newSelection);
|
|
34660
|
+
if (!isCurrentlyInactive) {
|
|
34661
|
+
this.props.composerStore.changeComposerCursorSelection(newSelection.start, newSelection.end);
|
|
34662
|
+
}
|
|
34605
34663
|
this.processTokenAtCursor();
|
|
34606
34664
|
}
|
|
34607
34665
|
onDblClick() {
|
|
@@ -35096,13 +35154,6 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35096
35154
|
}
|
|
35097
35155
|
}
|
|
35098
35156
|
startEdition(text, selection) {
|
|
35099
|
-
if (selection) {
|
|
35100
|
-
const content = text || this.getComposerContent(this.getters.getActivePosition());
|
|
35101
|
-
const validSelection = this.isSelectionValid(content.length, selection.start, selection.end);
|
|
35102
|
-
if (!validSelection) {
|
|
35103
|
-
return;
|
|
35104
|
-
}
|
|
35105
|
-
}
|
|
35106
35157
|
const { col, row } = this.getters.getActivePosition();
|
|
35107
35158
|
this.model.dispatch("SELECT_FIGURE", { figureId: null });
|
|
35108
35159
|
this.model.dispatch("SCROLL_TO_CELL", { col, row });
|
|
@@ -35159,7 +35210,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35159
35210
|
// ---------------------------------------------------------------------------
|
|
35160
35211
|
get currentContent() {
|
|
35161
35212
|
if (this.editionMode === "inactive") {
|
|
35162
|
-
return this.getComposerContent(this.getters.getActivePosition());
|
|
35213
|
+
return this.getComposerContent(this.getters.getActivePosition()).text;
|
|
35163
35214
|
}
|
|
35164
35215
|
return this._currentContent;
|
|
35165
35216
|
}
|
|
@@ -35358,8 +35409,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35358
35409
|
this.sheetId = sheetId;
|
|
35359
35410
|
this.row = row;
|
|
35360
35411
|
this.editionMode = "editing";
|
|
35361
|
-
|
|
35362
|
-
this.
|
|
35412
|
+
const { text, adjustedSelection } = this.getComposerContent({ sheetId, col, row }, selection);
|
|
35413
|
+
this.initialContent = text;
|
|
35414
|
+
this.setContent(str || this.initialContent, adjustedSelection ?? selection);
|
|
35363
35415
|
this.colorIndexByRange = {};
|
|
35364
35416
|
const zone = positionToZone({ col: this.col, row: this.row });
|
|
35365
35417
|
this.captureSelection(zone, col, row);
|
|
@@ -35836,7 +35888,7 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
35836
35888
|
constructor(get, args) {
|
|
35837
35889
|
super(get);
|
|
35838
35890
|
this.args = args;
|
|
35839
|
-
this._currentContent = this.getComposerContent();
|
|
35891
|
+
this._currentContent = this.getComposerContent().text;
|
|
35840
35892
|
}
|
|
35841
35893
|
getAutoCompleteProviders() {
|
|
35842
35894
|
const providersDefinitions = super.getAutoCompleteProviders();
|
|
@@ -35873,7 +35925,7 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
35873
35925
|
})
|
|
35874
35926
|
.join("");
|
|
35875
35927
|
}
|
|
35876
|
-
return localizeContent(content, this.getters.getLocale());
|
|
35928
|
+
return { text: localizeContent(content, this.getters.getLocale()) };
|
|
35877
35929
|
}
|
|
35878
35930
|
stopEdition() {
|
|
35879
35931
|
this._stopEdition();
|
|
@@ -39551,6 +39603,74 @@ function getPath2D(svgPath) {
|
|
|
39551
39603
|
return path2D;
|
|
39552
39604
|
}
|
|
39553
39605
|
|
|
39606
|
+
/**
|
|
39607
|
+
* Get the relative path between two files
|
|
39608
|
+
*
|
|
39609
|
+
* Eg.:
|
|
39610
|
+
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
39611
|
+
*/
|
|
39612
|
+
function getRelativePath(from, to) {
|
|
39613
|
+
const fromPathParts = from.split("/");
|
|
39614
|
+
const toPathParts = to.split("/");
|
|
39615
|
+
let relPath = "";
|
|
39616
|
+
let startIndex = 0;
|
|
39617
|
+
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
39618
|
+
if (fromPathParts[i] === toPathParts[i]) {
|
|
39619
|
+
startIndex++;
|
|
39620
|
+
}
|
|
39621
|
+
else {
|
|
39622
|
+
relPath += "../";
|
|
39623
|
+
}
|
|
39624
|
+
}
|
|
39625
|
+
relPath += toPathParts.slice(startIndex).join("/");
|
|
39626
|
+
return relPath;
|
|
39627
|
+
}
|
|
39628
|
+
/**
|
|
39629
|
+
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
39630
|
+
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
39631
|
+
*
|
|
39632
|
+
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
39633
|
+
*/
|
|
39634
|
+
function arrayToObject(array, indexOffset = 0) {
|
|
39635
|
+
const obj = {};
|
|
39636
|
+
for (let i = 0; i < array.length; i++) {
|
|
39637
|
+
if (array[i]) {
|
|
39638
|
+
obj[i + indexOffset] = array[i];
|
|
39639
|
+
}
|
|
39640
|
+
}
|
|
39641
|
+
return obj;
|
|
39642
|
+
}
|
|
39643
|
+
/**
|
|
39644
|
+
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
39645
|
+
* Replace with characters understandable by JS
|
|
39646
|
+
*/
|
|
39647
|
+
function fixXlsxUnicode(str) {
|
|
39648
|
+
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
39649
|
+
return String.fromCharCode(parseInt(code, 16));
|
|
39650
|
+
});
|
|
39651
|
+
}
|
|
39652
|
+
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
39653
|
+
function getSheetDataHeader(sheetData, dimension, index) {
|
|
39654
|
+
if (dimension === "COL") {
|
|
39655
|
+
if (!sheetData.cols[index]) {
|
|
39656
|
+
sheetData.cols[index] = {};
|
|
39657
|
+
}
|
|
39658
|
+
return sheetData.cols[index];
|
|
39659
|
+
}
|
|
39660
|
+
if (!sheetData.rows[index]) {
|
|
39661
|
+
sheetData.rows[index] = {};
|
|
39662
|
+
}
|
|
39663
|
+
return sheetData.rows[index];
|
|
39664
|
+
}
|
|
39665
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
39666
|
+
function prefixFormulaWithEqual(formula) {
|
|
39667
|
+
if (formula[0] === "=") {
|
|
39668
|
+
return formula;
|
|
39669
|
+
}
|
|
39670
|
+
const tokens = tokenize(formula);
|
|
39671
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
39672
|
+
}
|
|
39673
|
+
|
|
39554
39674
|
/**
|
|
39555
39675
|
* Map of the different types of conversions warnings and their name in error messages
|
|
39556
39676
|
*/
|
|
@@ -40073,66 +40193,6 @@ function hexaToInt(hex) {
|
|
|
40073
40193
|
*/
|
|
40074
40194
|
const DEFAULT_SYSTEM_COLOR = "FF000000";
|
|
40075
40195
|
|
|
40076
|
-
/**
|
|
40077
|
-
* Get the relative path between two files
|
|
40078
|
-
*
|
|
40079
|
-
* Eg.:
|
|
40080
|
-
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
40081
|
-
*/
|
|
40082
|
-
function getRelativePath(from, to) {
|
|
40083
|
-
const fromPathParts = from.split("/");
|
|
40084
|
-
const toPathParts = to.split("/");
|
|
40085
|
-
let relPath = "";
|
|
40086
|
-
let startIndex = 0;
|
|
40087
|
-
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
40088
|
-
if (fromPathParts[i] === toPathParts[i]) {
|
|
40089
|
-
startIndex++;
|
|
40090
|
-
}
|
|
40091
|
-
else {
|
|
40092
|
-
relPath += "../";
|
|
40093
|
-
}
|
|
40094
|
-
}
|
|
40095
|
-
relPath += toPathParts.slice(startIndex).join("/");
|
|
40096
|
-
return relPath;
|
|
40097
|
-
}
|
|
40098
|
-
/**
|
|
40099
|
-
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
40100
|
-
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
40101
|
-
*
|
|
40102
|
-
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
40103
|
-
*/
|
|
40104
|
-
function arrayToObject(array, indexOffset = 0) {
|
|
40105
|
-
const obj = {};
|
|
40106
|
-
for (let i = 0; i < array.length; i++) {
|
|
40107
|
-
if (array[i]) {
|
|
40108
|
-
obj[i + indexOffset] = array[i];
|
|
40109
|
-
}
|
|
40110
|
-
}
|
|
40111
|
-
return obj;
|
|
40112
|
-
}
|
|
40113
|
-
/**
|
|
40114
|
-
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
40115
|
-
* Replace with characters understandable by JS
|
|
40116
|
-
*/
|
|
40117
|
-
function fixXlsxUnicode(str) {
|
|
40118
|
-
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
40119
|
-
return String.fromCharCode(parseInt(code, 16));
|
|
40120
|
-
});
|
|
40121
|
-
}
|
|
40122
|
-
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
40123
|
-
function getSheetDataHeader(sheetData, dimension, index) {
|
|
40124
|
-
if (dimension === "COL") {
|
|
40125
|
-
if (!sheetData.cols[index]) {
|
|
40126
|
-
sheetData.cols[index] = {};
|
|
40127
|
-
}
|
|
40128
|
-
return sheetData.cols[index];
|
|
40129
|
-
}
|
|
40130
|
-
if (!sheetData.rows[index]) {
|
|
40131
|
-
sheetData.rows[index] = {};
|
|
40132
|
-
}
|
|
40133
|
-
return sheetData.rows[index];
|
|
40134
|
-
}
|
|
40135
|
-
|
|
40136
40196
|
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
40137
40197
|
/**
|
|
40138
40198
|
* Convert excel format to o_spreadsheet format
|
|
@@ -40347,9 +40407,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
40347
40407
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
40348
40408
|
continue;
|
|
40349
40409
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
40350
|
-
values.push(
|
|
40410
|
+
values.push(prefixFormulaWithEqual(rule.formula[0]));
|
|
40351
40411
|
if (rule.formula.length === 2) {
|
|
40352
|
-
values.push(
|
|
40412
|
+
values.push(prefixFormulaWithEqual(rule.formula[1]));
|
|
40353
40413
|
}
|
|
40354
40414
|
break;
|
|
40355
40415
|
}
|
|
@@ -40507,11 +40567,6 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
40507
40567
|
? ICON_SETS[iconSet].neutral
|
|
40508
40568
|
: ICON_SETS[iconSet].good;
|
|
40509
40569
|
}
|
|
40510
|
-
/** Prefix the string by "=" if the string looks like a formula */
|
|
40511
|
-
function prefixFormula(formula) {
|
|
40512
|
-
const tokens = tokenize(formula);
|
|
40513
|
-
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
40514
|
-
}
|
|
40515
40570
|
// ---------------------------------------------------------------------------
|
|
40516
40571
|
// Warnings
|
|
40517
40572
|
// ---------------------------------------------------------------------------
|
|
@@ -40987,7 +41042,7 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
|
|
|
40987
41042
|
dvRules.push(decimalRule);
|
|
40988
41043
|
break;
|
|
40989
41044
|
case "list":
|
|
40990
|
-
const listRule =
|
|
41045
|
+
const listRule = convertListRule(dvId++, dv);
|
|
40991
41046
|
dvRules.push(listRule);
|
|
40992
41047
|
break;
|
|
40993
41048
|
case "date":
|
|
@@ -41007,9 +41062,9 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
|
|
|
41007
41062
|
return dvRules;
|
|
41008
41063
|
}
|
|
41009
41064
|
function convertDecimalRule(id, dv) {
|
|
41010
|
-
const values = [dv.formula1.toString()];
|
|
41065
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
41011
41066
|
if (dv.formula2) {
|
|
41012
|
-
values.push(dv.formula2.toString());
|
|
41067
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
41013
41068
|
}
|
|
41014
41069
|
return {
|
|
41015
41070
|
id: id.toString(),
|
|
@@ -41021,7 +41076,7 @@ function convertDecimalRule(id, dv) {
|
|
|
41021
41076
|
},
|
|
41022
41077
|
};
|
|
41023
41078
|
}
|
|
41024
|
-
function
|
|
41079
|
+
function convertListRule(id, dv) {
|
|
41025
41080
|
const formula1 = dv.formula1.toString();
|
|
41026
41081
|
const isRangeRule = rangeReference.test(formula1);
|
|
41027
41082
|
return {
|
|
@@ -41037,9 +41092,9 @@ function convertListrule(id, dv) {
|
|
|
41037
41092
|
}
|
|
41038
41093
|
function convertDateRule(id, dv) {
|
|
41039
41094
|
let criterion;
|
|
41040
|
-
const values = [dv.formula1.toString()];
|
|
41095
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
41041
41096
|
if (dv.formula2) {
|
|
41042
|
-
values.push(dv.formula2.toString());
|
|
41097
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
41043
41098
|
criterion = {
|
|
41044
41099
|
type: XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[dv.operator],
|
|
41045
41100
|
values: getDateCriterionFormattedValues(values, DEFAULT_LOCALE),
|
|
@@ -41066,7 +41121,7 @@ function convertCustomRule(id, dv) {
|
|
|
41066
41121
|
isBlocking: dv.errorStyle !== "warning",
|
|
41067
41122
|
criterion: {
|
|
41068
41123
|
type: "customFormula",
|
|
41069
|
-
values: [
|
|
41124
|
+
values: [prefixFormulaWithEqual(dv.formula1.toString())],
|
|
41070
41125
|
},
|
|
41071
41126
|
};
|
|
41072
41127
|
}
|
|
@@ -49730,39 +49785,63 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
49730
49785
|
this.model.dispatch("AUTOFILL_TABLE_COLUMN", { ...this.currentEditedCell });
|
|
49731
49786
|
this.setContent("");
|
|
49732
49787
|
}
|
|
49733
|
-
getComposerContent(position) {
|
|
49788
|
+
getComposerContent(position, selection) {
|
|
49734
49789
|
const locale = this.getters.getLocale();
|
|
49735
49790
|
const cell = this.getters.getCell(position);
|
|
49736
49791
|
if (cell?.isFormula) {
|
|
49737
49792
|
const prettifiedContent = this.getPrettifiedFormula(cell);
|
|
49738
|
-
|
|
49793
|
+
// when a formula is prettified (multi lines, indented), adapt the cursor position
|
|
49794
|
+
// to take into account line breaks and tabs
|
|
49795
|
+
function adjustCursorIndex(targetIndex) {
|
|
49796
|
+
let adjustedIndex = 0;
|
|
49797
|
+
let originalIndex = 0;
|
|
49798
|
+
while (originalIndex < targetIndex) {
|
|
49799
|
+
adjustedIndex++;
|
|
49800
|
+
const char = prettifiedContent[adjustedIndex];
|
|
49801
|
+
if (char !== "\n" && char !== "\t") {
|
|
49802
|
+
originalIndex++;
|
|
49803
|
+
}
|
|
49804
|
+
}
|
|
49805
|
+
return adjustedIndex;
|
|
49806
|
+
}
|
|
49807
|
+
let adjustedSelection = selection;
|
|
49808
|
+
if (selection) {
|
|
49809
|
+
adjustedSelection = {
|
|
49810
|
+
start: adjustCursorIndex(selection.start),
|
|
49811
|
+
end: adjustCursorIndex(selection.end),
|
|
49812
|
+
};
|
|
49813
|
+
}
|
|
49814
|
+
return {
|
|
49815
|
+
text: localizeFormula(prettifiedContent, locale),
|
|
49816
|
+
adjustedSelection,
|
|
49817
|
+
};
|
|
49739
49818
|
}
|
|
49740
49819
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
49741
49820
|
if (spreader) {
|
|
49742
|
-
return "";
|
|
49821
|
+
return { text: "" };
|
|
49743
49822
|
}
|
|
49744
49823
|
const { format, value, type, formattedValue } = this.getters.getEvaluatedCell(position);
|
|
49745
49824
|
switch (type) {
|
|
49746
49825
|
case CellValueType.empty:
|
|
49747
|
-
return "";
|
|
49826
|
+
return { text: "" };
|
|
49748
49827
|
case CellValueType.text:
|
|
49749
49828
|
case CellValueType.error:
|
|
49750
|
-
return value;
|
|
49829
|
+
return { text: value };
|
|
49751
49830
|
case CellValueType.boolean:
|
|
49752
|
-
return formattedValue;
|
|
49831
|
+
return { text: formattedValue };
|
|
49753
49832
|
case CellValueType.number:
|
|
49754
49833
|
if (format && isDateTimeFormat(format)) {
|
|
49755
49834
|
if (parseDateTime(formattedValue, locale) !== null) {
|
|
49756
49835
|
// formatted string can be parsed again
|
|
49757
|
-
return formattedValue;
|
|
49836
|
+
return { text: formattedValue };
|
|
49758
49837
|
}
|
|
49759
49838
|
// display a simplified and parsable string otherwise
|
|
49760
49839
|
const timeFormat = Number.isInteger(value)
|
|
49761
49840
|
? locale.dateFormat
|
|
49762
49841
|
: getDateTimeFormat(locale);
|
|
49763
|
-
return formatValue(value, { locale, format: timeFormat });
|
|
49842
|
+
return { text: formatValue(value, { locale, format: timeFormat }) };
|
|
49764
49843
|
}
|
|
49765
|
-
return this.numberComposerContent(value, format, locale);
|
|
49844
|
+
return { text: this.numberComposerContent(value, format, locale) };
|
|
49766
49845
|
}
|
|
49767
49846
|
}
|
|
49768
49847
|
getPrettifiedFormula(cell) {
|
|
@@ -49931,8 +50010,9 @@ class GridComposer extends Component {
|
|
|
49931
50010
|
},
|
|
49932
50011
|
focus: this.focus,
|
|
49933
50012
|
isDefaultFocus: true,
|
|
49934
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
50013
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
49935
50014
|
focusMode: "contentFocus",
|
|
50015
|
+
selection,
|
|
49936
50016
|
}),
|
|
49937
50017
|
onComposerCellFocused: (content) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
49938
50018
|
focusMode: "cellFocus",
|
|
@@ -57338,12 +57418,13 @@ class DataValidationEditor extends Component {
|
|
|
57338
57418
|
onCloseSidePanel: { type: Function, optional: true },
|
|
57339
57419
|
};
|
|
57340
57420
|
state = useState({ rule: this.defaultDataValidationRule, errors: [] });
|
|
57421
|
+
editingSheetId;
|
|
57341
57422
|
setup() {
|
|
57423
|
+
this.editingSheetId = this.env.model.getters.getActiveSheetId();
|
|
57342
57424
|
if (this.props.rule) {
|
|
57343
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
57344
57425
|
this.state.rule = {
|
|
57345
57426
|
...this.props.rule,
|
|
57346
|
-
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range,
|
|
57427
|
+
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
|
|
57347
57428
|
};
|
|
57348
57429
|
this.state.rule.criterion.type = this.props.rule.criterion.type;
|
|
57349
57430
|
}
|
|
@@ -57377,7 +57458,6 @@ class DataValidationEditor extends Component {
|
|
|
57377
57458
|
const locale = this.env.model.getters.getLocale();
|
|
57378
57459
|
const criterion = rule.criterion;
|
|
57379
57460
|
const criterionEvaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
57380
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
57381
57461
|
const values = criterion.values
|
|
57382
57462
|
.slice(0, criterionEvaluator.numberOfValues(criterion))
|
|
57383
57463
|
.map((value) => value?.trim())
|
|
@@ -57385,8 +57465,8 @@ class DataValidationEditor extends Component {
|
|
|
57385
57465
|
.map((value) => canonicalizeContent(value, locale));
|
|
57386
57466
|
rule.criterion = { ...criterion, values };
|
|
57387
57467
|
return {
|
|
57388
|
-
sheetId,
|
|
57389
|
-
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(
|
|
57468
|
+
sheetId: this.editingSheetId,
|
|
57469
|
+
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
|
|
57390
57470
|
rule,
|
|
57391
57471
|
};
|
|
57392
57472
|
}
|
|
@@ -57913,6 +57993,7 @@ css /* scss */ `
|
|
|
57913
57993
|
.o-button {
|
|
57914
57994
|
height: 19px;
|
|
57915
57995
|
width: 19px;
|
|
57996
|
+
box-sizing: content-box;
|
|
57916
57997
|
.o-icon {
|
|
57917
57998
|
height: 14px;
|
|
57918
57999
|
width: 14px;
|
|
@@ -58658,7 +58739,7 @@ class PivotMeasureEditor extends Component {
|
|
|
58658
58739
|
return undefined;
|
|
58659
58740
|
}
|
|
58660
58741
|
get isCalculatedMeasureInvalid() {
|
|
58661
|
-
return
|
|
58742
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
58662
58743
|
}
|
|
58663
58744
|
}
|
|
58664
58745
|
|
|
@@ -61536,16 +61617,16 @@ class ClickableCellSortIcon extends Component {
|
|
|
61536
61617
|
}
|
|
61537
61618
|
}
|
|
61538
61619
|
|
|
61539
|
-
class
|
|
61540
|
-
static template = "o-spreadsheet-
|
|
61620
|
+
class FullScreenFigure extends Component {
|
|
61621
|
+
static template = "o-spreadsheet-FullScreenFigure";
|
|
61541
61622
|
static props = {};
|
|
61542
|
-
static components = {
|
|
61543
|
-
|
|
61544
|
-
ref = useRef("
|
|
61623
|
+
static components = { ChartFigure };
|
|
61624
|
+
fullScreenFigureStore;
|
|
61625
|
+
ref = useRef("fullScreenFigure");
|
|
61545
61626
|
spreadsheetRect = useSpreadsheetRect();
|
|
61546
61627
|
figureRegistry = figureRegistry;
|
|
61547
61628
|
setup() {
|
|
61548
|
-
this.
|
|
61629
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
61549
61630
|
const animationStore = useStore(ChartAnimationStore);
|
|
61550
61631
|
let lastFigureId = undefined;
|
|
61551
61632
|
onWillUpdateProps(() => {
|
|
@@ -61557,7 +61638,7 @@ class FullScreenChart extends Component {
|
|
|
61557
61638
|
useEffect((el) => el?.focus(), () => [this.ref.el]);
|
|
61558
61639
|
}
|
|
61559
61640
|
get figureUI() {
|
|
61560
|
-
return this.
|
|
61641
|
+
return this.fullScreenFigureStore.fullScreenFigure;
|
|
61561
61642
|
}
|
|
61562
61643
|
get chartId() {
|
|
61563
61644
|
if (!this.figureUI)
|
|
@@ -61566,7 +61647,7 @@ class FullScreenChart extends Component {
|
|
|
61566
61647
|
}
|
|
61567
61648
|
exitFullScreen() {
|
|
61568
61649
|
if (this.figureUI) {
|
|
61569
|
-
this.
|
|
61650
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.figureUI.id);
|
|
61570
61651
|
}
|
|
61571
61652
|
}
|
|
61572
61653
|
onKeyDown(ev) {
|
|
@@ -61574,15 +61655,10 @@ class FullScreenChart extends Component {
|
|
|
61574
61655
|
this.exitFullScreen();
|
|
61575
61656
|
}
|
|
61576
61657
|
}
|
|
61577
|
-
get
|
|
61578
|
-
if (!this.
|
|
61658
|
+
get figureComponent() {
|
|
61659
|
+
if (!this.figureUI)
|
|
61579
61660
|
return undefined;
|
|
61580
|
-
|
|
61581
|
-
const component = chartComponentRegistry.get(type);
|
|
61582
|
-
if (!component) {
|
|
61583
|
-
throw new Error(`Component is not defined for type ${type}`);
|
|
61584
|
-
}
|
|
61585
|
-
return component;
|
|
61661
|
+
return figureRegistry.get(this.figureUI.tag).Component;
|
|
61586
61662
|
}
|
|
61587
61663
|
}
|
|
61588
61664
|
|
|
@@ -64322,11 +64398,11 @@ class HeaderSizePlugin extends CorePlugin {
|
|
|
64322
64398
|
break;
|
|
64323
64399
|
}
|
|
64324
64400
|
case "ADD_COLUMNS_ROWS": {
|
|
64325
|
-
const sizes =
|
|
64401
|
+
const sizes = this.sizes[cmd.sheetId][cmd.dimension];
|
|
64326
64402
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
64327
64403
|
const baseSize = sizes[cmd.base];
|
|
64328
|
-
sizes
|
|
64329
|
-
this.history.update("sizes", cmd.sheetId, cmd.dimension,
|
|
64404
|
+
const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
|
|
64405
|
+
this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
|
|
64330
64406
|
break;
|
|
64331
64407
|
}
|
|
64332
64408
|
case "RESIZE_COLUMNS_ROWS":
|
|
@@ -64477,9 +64553,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
64477
64553
|
break;
|
|
64478
64554
|
}
|
|
64479
64555
|
case "ADD_COLUMNS_ROWS": {
|
|
64480
|
-
const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
|
|
64481
64556
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
64482
|
-
hiddenHeaders.
|
|
64557
|
+
const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
|
|
64483
64558
|
this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
|
|
64484
64559
|
break;
|
|
64485
64560
|
}
|
|
@@ -68663,12 +68738,12 @@ class SpreadsheetRTree {
|
|
|
68663
68738
|
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
68664
68739
|
}
|
|
68665
68740
|
rtreeItemComparer(left, right) {
|
|
68666
|
-
return (left.
|
|
68667
|
-
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
68741
|
+
return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
68668
68742
|
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
68669
68743
|
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
68670
68744
|
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
68671
|
-
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom
|
|
68745
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
|
|
68746
|
+
deepEquals(left.data, right.data));
|
|
68672
68747
|
}
|
|
68673
68748
|
}
|
|
68674
68749
|
/**
|
|
@@ -68741,7 +68816,7 @@ class FormulaDependencyGraph {
|
|
|
68741
68816
|
* in the correct order they should be evaluated.
|
|
68742
68817
|
* This is called a topological ordering (excluding cycles)
|
|
68743
68818
|
*/
|
|
68744
|
-
getCellsDependingOn(ranges) {
|
|
68819
|
+
getCellsDependingOn(ranges, ignore) {
|
|
68745
68820
|
const visited = this.createEmptyPositionSet();
|
|
68746
68821
|
const queue = Array.from(ranges).reverse();
|
|
68747
68822
|
while (queue.length > 0) {
|
|
@@ -68756,7 +68831,7 @@ class FormulaDependencyGraph {
|
|
|
68756
68831
|
const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
|
|
68757
68832
|
const nextInQueue = {};
|
|
68758
68833
|
for (const position of impactedPositions) {
|
|
68759
|
-
if (!visited.has(position)) {
|
|
68834
|
+
if (!visited.has(position) && !ignore.has(position)) {
|
|
68760
68835
|
if (!nextInQueue[position.sheetId]) {
|
|
68761
68836
|
nextInQueue[position.sheetId] = [];
|
|
68762
68837
|
}
|
|
@@ -69314,7 +69389,7 @@ class Evaluator {
|
|
|
69314
69389
|
}
|
|
69315
69390
|
invalidatePositionsDependingOnSpread(sheetId, resultZone) {
|
|
69316
69391
|
// the result matrix is split in 2 zones to exclude the array formula position
|
|
69317
|
-
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
|
|
69392
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
|
|
69318
69393
|
invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
|
|
69319
69394
|
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
69320
69395
|
}
|
|
@@ -69432,7 +69507,7 @@ class Evaluator {
|
|
|
69432
69507
|
for (const sheetId in zonesBySheetIds) {
|
|
69433
69508
|
ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
|
|
69434
69509
|
}
|
|
69435
|
-
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
69510
|
+
return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
|
|
69436
69511
|
}
|
|
69437
69512
|
}
|
|
69438
69513
|
function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
|
|
@@ -70943,7 +71018,8 @@ class DynamicTablesPlugin extends CoreViewPlugin {
|
|
|
70943
71018
|
const topLeft = { col: unionZone.left, row: unionZone.top, sheetId };
|
|
70944
71019
|
const parentSpreadingCell = this.getters.getArrayFormulaSpreadingOn(topLeft);
|
|
70945
71020
|
if (!parentSpreadingCell) {
|
|
70946
|
-
|
|
71021
|
+
const evaluatedCell = this.getters.getEvaluatedCell(topLeft);
|
|
71022
|
+
return (evaluatedCell.value === CellErrorType.SpilledBlocked && !evaluatedCell.errorOriginPosition);
|
|
70947
71023
|
}
|
|
70948
71024
|
else if (deepEquals(parentSpreadingCell, topLeft) && getZoneArea(unionZone) === 1) {
|
|
70949
71025
|
return true;
|
|
@@ -82115,6 +82191,7 @@ class RibbonMenu extends Component {
|
|
|
82115
82191
|
static components = { Menu };
|
|
82116
82192
|
rootItems = topbarMenuRegistry.getMenuItems();
|
|
82117
82193
|
menuRef = useRef("menu");
|
|
82194
|
+
containerRef = useRef("container");
|
|
82118
82195
|
state = useState({
|
|
82119
82196
|
menuItems: this.rootItems,
|
|
82120
82197
|
title: _t("Menu Bar"),
|
|
@@ -82122,6 +82199,7 @@ class RibbonMenu extends Component {
|
|
|
82122
82199
|
});
|
|
82123
82200
|
setup() {
|
|
82124
82201
|
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
82202
|
+
onMounted(this.updateShadows);
|
|
82125
82203
|
}
|
|
82126
82204
|
onExternalClick(ev) {
|
|
82127
82205
|
if (!this.menuRef.el?.contains(ev.target)) {
|
|
@@ -82134,6 +82212,7 @@ class RibbonMenu extends Component {
|
|
|
82134
82212
|
this.state.parentState = { ...this.state };
|
|
82135
82213
|
this.state.menuItems = children;
|
|
82136
82214
|
this.state.title = menu.name(this.env);
|
|
82215
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
82137
82216
|
}
|
|
82138
82217
|
else {
|
|
82139
82218
|
this.state.menuItems = this.rootItems;
|
|
@@ -82155,6 +82234,19 @@ class RibbonMenu extends Component {
|
|
|
82155
82234
|
height: `${this.props.height}px`,
|
|
82156
82235
|
});
|
|
82157
82236
|
}
|
|
82237
|
+
updateShadows() {
|
|
82238
|
+
if (!this.containerRef.el) {
|
|
82239
|
+
return;
|
|
82240
|
+
}
|
|
82241
|
+
this.containerRef.el.classList.remove("scroll-top", "scroll-bottom");
|
|
82242
|
+
const maxScroll = this.containerRef.el.scrollHeight - this.containerRef.el.clientHeight || 0;
|
|
82243
|
+
if (this.containerRef.el.scrollTop < maxScroll - 1) {
|
|
82244
|
+
this.containerRef.el.classList.add("scroll-bottom");
|
|
82245
|
+
}
|
|
82246
|
+
if (this.containerRef.el.scrollTop > 0) {
|
|
82247
|
+
this.containerRef.el.classList.add("scroll-top");
|
|
82248
|
+
}
|
|
82249
|
+
}
|
|
82158
82250
|
onClickBack() {
|
|
82159
82251
|
if (!this.state.parentState) {
|
|
82160
82252
|
this.props.onClose();
|
|
@@ -82163,6 +82255,7 @@ class RibbonMenu extends Component {
|
|
|
82163
82255
|
this.state.menuItems = this.state.parentState.menuItems;
|
|
82164
82256
|
this.state.title = this.state.parentState.title;
|
|
82165
82257
|
this.state.parentState = this.state.parentState.parentState;
|
|
82258
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
82166
82259
|
}
|
|
82167
82260
|
get backTitle() {
|
|
82168
82261
|
return this.state.parentState ? _t("Go to previous menu") : _t("Close menu bar");
|
|
@@ -82218,6 +82311,11 @@ class SmallBottomBar extends Component {
|
|
|
82218
82311
|
? this.composerFocusStore.focusMode
|
|
82219
82312
|
: "inactive";
|
|
82220
82313
|
}
|
|
82314
|
+
get showFxIcon() {
|
|
82315
|
+
return (this.focus === "inactive" &&
|
|
82316
|
+
!this.composerStore.currentContent &&
|
|
82317
|
+
!this.composerStore.placeholder);
|
|
82318
|
+
}
|
|
82221
82319
|
get rect() {
|
|
82222
82320
|
return this.composerRef.el
|
|
82223
82321
|
? getBoundingRectAsPOJO(this.composerRef.el)
|
|
@@ -82233,8 +82331,9 @@ class SmallBottomBar extends Component {
|
|
|
82233
82331
|
},
|
|
82234
82332
|
focus: this.focus,
|
|
82235
82333
|
composerStore: this.composerStore,
|
|
82236
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
82334
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
82237
82335
|
focusMode: "contentFocus",
|
|
82336
|
+
selection,
|
|
82238
82337
|
}),
|
|
82239
82338
|
isDefaultFocus: false,
|
|
82240
82339
|
inputStyle: cssPropertiesToCss({
|
|
@@ -82242,6 +82341,7 @@ class SmallBottomBar extends Component {
|
|
|
82242
82341
|
"max-height": `130px`,
|
|
82243
82342
|
}),
|
|
82244
82343
|
showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
|
|
82344
|
+
placeholder: this.composerStore.placeholder,
|
|
82245
82345
|
};
|
|
82246
82346
|
}
|
|
82247
82347
|
get symbols() {
|
|
@@ -82260,12 +82360,6 @@ class SmallBottomBar extends Component {
|
|
|
82260
82360
|
}
|
|
82261
82361
|
|
|
82262
82362
|
const COMPOSER_MAX_HEIGHT = 300;
|
|
82263
|
-
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
82264
|
-
const FX_SVG = /*xml*/ `
|
|
82265
|
-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
82266
|
-
<path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
|
|
82267
|
-
</svg>
|
|
82268
|
-
`;
|
|
82269
82363
|
css /* scss */ `
|
|
82270
82364
|
.o-topbar-composer-container {
|
|
82271
82365
|
height: ${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px;
|
|
@@ -82277,14 +82371,6 @@ css /* scss */ `
|
|
|
82277
82371
|
margin-bottom: -1px;
|
|
82278
82372
|
border: 1px solid;
|
|
82279
82373
|
font-family: ${DEFAULT_FONT};
|
|
82280
|
-
|
|
82281
|
-
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
82282
|
-
.o-composer:empty:not(:focus):not(.active)::before,
|
|
82283
|
-
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
82284
|
-
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
82285
|
-
position: relative;
|
|
82286
|
-
top: 20%;
|
|
82287
|
-
}
|
|
82288
82374
|
}
|
|
82289
82375
|
|
|
82290
82376
|
.user-select-text {
|
|
@@ -82317,6 +82403,11 @@ class TopBarComposer extends Component {
|
|
|
82317
82403
|
? this.composerFocusStore.focusMode
|
|
82318
82404
|
: "inactive";
|
|
82319
82405
|
}
|
|
82406
|
+
get showFxIcon() {
|
|
82407
|
+
return (this.focus === "inactive" &&
|
|
82408
|
+
!this.composerStore.currentContent &&
|
|
82409
|
+
!this.composerStore.placeholder);
|
|
82410
|
+
}
|
|
82320
82411
|
get composerStyle() {
|
|
82321
82412
|
const style = {
|
|
82322
82413
|
padding: "5px 0px 5px 8px",
|
|
@@ -83668,7 +83759,7 @@ class Spreadsheet extends Component {
|
|
|
83668
83759
|
SidePanels,
|
|
83669
83760
|
SpreadsheetDashboard,
|
|
83670
83761
|
HeaderGroupContainer,
|
|
83671
|
-
|
|
83762
|
+
FullScreenFigure,
|
|
83672
83763
|
};
|
|
83673
83764
|
sidePanel;
|
|
83674
83765
|
spreadsheetRef = useRef("spreadsheet");
|
|
@@ -88392,6 +88483,7 @@ const components = {
|
|
|
88392
88483
|
Grid,
|
|
88393
88484
|
GridOverlay,
|
|
88394
88485
|
ScorecardChart,
|
|
88486
|
+
GaugeChartComponent,
|
|
88395
88487
|
LineConfigPanel,
|
|
88396
88488
|
BarConfigPanel,
|
|
88397
88489
|
PieChartDesignPanel,
|
|
@@ -88430,7 +88522,7 @@ const components = {
|
|
|
88430
88522
|
RadioSelection,
|
|
88431
88523
|
GeoChartRegionSelectSection,
|
|
88432
88524
|
ChartDashboardMenu,
|
|
88433
|
-
|
|
88525
|
+
FullScreenFigure,
|
|
88434
88526
|
};
|
|
88435
88527
|
const hooks = {
|
|
88436
88528
|
useDragAndDropListItems,
|
|
@@ -88480,6 +88572,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
88480
88572
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
88481
88573
|
|
|
88482
88574
|
|
|
88483
|
-
__info__.version = "19.0.
|
|
88484
|
-
__info__.date = "2025-
|
|
88485
|
-
__info__.hash = "
|
|
88575
|
+
__info__.version = "19.0.6";
|
|
88576
|
+
__info__.date = "2025-10-16T06:39:36.282Z";
|
|
88577
|
+
__info__.hash = "0d4315a";
|