@odoo/o-spreadsheet 19.0.11 → 19.0.12
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 +281 -181
- package/dist/o-spreadsheet.d.ts +37 -7
- package/dist/o-spreadsheet.esm.js +281 -181
- package/dist/o-spreadsheet.iife.js +281 -181
- package/dist/o-spreadsheet.iife.min.js +431 -431
- package/dist/o_spreadsheet.xml +50 -10
- 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.12
|
|
6
|
+
* @date 2025-12-02T05:34:17.495Z
|
|
7
|
+
* @hash 32203f1
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -183,7 +183,6 @@ const invalidateEvaluationCommands = new Set([
|
|
|
183
183
|
"REDO",
|
|
184
184
|
"ADD_MERGE",
|
|
185
185
|
"REMOVE_MERGE",
|
|
186
|
-
"DUPLICATE_SHEET",
|
|
187
186
|
"UPDATE_LOCALE",
|
|
188
187
|
"ADD_PIVOT",
|
|
189
188
|
"UPDATE_PIVOT",
|
|
@@ -23879,6 +23878,9 @@ function getTreeMapGroupColors(definition, tree) {
|
|
|
23879
23878
|
}));
|
|
23880
23879
|
}
|
|
23881
23880
|
function getTreeMapColorScale(tree, coloringOption) {
|
|
23881
|
+
if (tree.length === 0) {
|
|
23882
|
+
return undefined;
|
|
23883
|
+
}
|
|
23882
23884
|
const treeNodesByLevel = pyramidizeTree(tree);
|
|
23883
23885
|
const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
|
|
23884
23886
|
const minValue = Math.min(...nodes.map((node) => node.value));
|
|
@@ -25564,11 +25566,18 @@ function chartToImageUrl(runtime, figure, type) {
|
|
|
25564
25566
|
// we have to add the canvas to the DOM otherwise it won't be rendered
|
|
25565
25567
|
document.body.append(div);
|
|
25566
25568
|
if ("chartJsConfig" in runtime) {
|
|
25569
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25570
|
+
if (!extensionsLoaded) {
|
|
25571
|
+
registerChartJSExtensions();
|
|
25572
|
+
}
|
|
25567
25573
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25568
25574
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25569
25575
|
const chart = new window.Chart(canvas, config);
|
|
25570
25576
|
imageContent = chart.toBase64Image();
|
|
25571
25577
|
chart.destroy();
|
|
25578
|
+
if (!extensionsLoaded) {
|
|
25579
|
+
unregisterChartJsExtensions();
|
|
25580
|
+
}
|
|
25572
25581
|
}
|
|
25573
25582
|
else if (type === "scorecard") {
|
|
25574
25583
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -25598,11 +25607,18 @@ async function chartToImageFile(runtime, figure, type) {
|
|
|
25598
25607
|
document.body.append(div);
|
|
25599
25608
|
let chartBlob = null;
|
|
25600
25609
|
if ("chartJsConfig" in runtime) {
|
|
25610
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25611
|
+
if (!extensionsLoaded) {
|
|
25612
|
+
registerChartJSExtensions();
|
|
25613
|
+
}
|
|
25601
25614
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25602
25615
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25603
25616
|
const chart = new window.Chart(canvas, config);
|
|
25604
25617
|
chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
25605
25618
|
chart.destroy();
|
|
25619
|
+
if (!extensionsLoaded) {
|
|
25620
|
+
unregisterChartJsExtensions();
|
|
25621
|
+
}
|
|
25606
25622
|
}
|
|
25607
25623
|
else if (type === "scorecard") {
|
|
25608
25624
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -27728,29 +27744,19 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27728
27744
|
}
|
|
27729
27745
|
resetAxisLimits(chartId, limits) {
|
|
27730
27746
|
for (const axisId of ZOOMABLE_AXIS_IDS) {
|
|
27731
|
-
if (limits
|
|
27732
|
-
|
|
27733
|
-
this.originalAxisLimits[chartId]
|
|
27734
|
-
|
|
27735
|
-
|
|
27736
|
-
};
|
|
27737
|
-
}
|
|
27738
|
-
this.originalAxisLimits[chartId][axisId]["min"] = limits[axisId].min;
|
|
27739
|
-
this.originalAxisLimits[chartId][axisId]["max"] = limits[axisId].max;
|
|
27747
|
+
if (limits[axisId]) {
|
|
27748
|
+
this.originalAxisLimits[chartId] = {
|
|
27749
|
+
...this.originalAxisLimits[chartId],
|
|
27750
|
+
[axisId]: { ...limits[axisId] },
|
|
27751
|
+
};
|
|
27740
27752
|
}
|
|
27741
|
-
else {
|
|
27742
|
-
|
|
27743
|
-
delete this.originalAxisLimits[chartId][axisId];
|
|
27744
|
-
}
|
|
27753
|
+
else if (this.originalAxisLimits[chartId]?.[axisId]) {
|
|
27754
|
+
delete this.originalAxisLimits[chartId][axisId];
|
|
27745
27755
|
}
|
|
27746
27756
|
}
|
|
27747
27757
|
return "noStateChange";
|
|
27748
27758
|
}
|
|
27749
27759
|
updateAxisLimits(chartId, limits) {
|
|
27750
|
-
if (limits === undefined) {
|
|
27751
|
-
delete this.currentAxesLimits[chartId];
|
|
27752
|
-
return "noStateChange";
|
|
27753
|
-
}
|
|
27754
27760
|
let { min, max } = limits;
|
|
27755
27761
|
if (min > max) {
|
|
27756
27762
|
[min, max] = [max, min];
|
|
@@ -27766,26 +27772,14 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27766
27772
|
* for the current trend line axes.
|
|
27767
27773
|
*/
|
|
27768
27774
|
updateTrendLineConfiguration(chartId) {
|
|
27769
|
-
if (!this.originalAxisLimits[chartId]) {
|
|
27775
|
+
if (!this.originalAxisLimits[chartId]?.x || !this.currentAxesLimits[chartId]?.x) {
|
|
27770
27776
|
return "noStateChange";
|
|
27771
27777
|
}
|
|
27772
27778
|
const chartLimits = this.originalAxisLimits[chartId].x;
|
|
27773
|
-
if (chartLimits === undefined) {
|
|
27774
|
-
return "noStateChange";
|
|
27775
|
-
}
|
|
27776
27779
|
for (const axisId of TREND_LINE_AXES_IDS) {
|
|
27777
27780
|
if (!this.originalAxisLimits[chartId][axisId]) {
|
|
27778
27781
|
continue;
|
|
27779
27782
|
}
|
|
27780
|
-
if (!this.currentAxesLimits[chartId]?.[axisId]) {
|
|
27781
|
-
this.currentAxesLimits[chartId] = {
|
|
27782
|
-
...this.currentAxesLimits[chartId],
|
|
27783
|
-
[axisId]: {},
|
|
27784
|
-
};
|
|
27785
|
-
}
|
|
27786
|
-
if (this.currentAxesLimits[chartId]?.x === undefined) {
|
|
27787
|
-
return "noStateChange";
|
|
27788
|
-
}
|
|
27789
27783
|
const realRange = chartLimits.max - chartLimits.min;
|
|
27790
27784
|
const trendingLimits = this.originalAxisLimits[chartId][axisId];
|
|
27791
27785
|
const trendingRange = trendingLimits.max - trendingLimits.min;
|
|
@@ -27793,8 +27787,10 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27793
27787
|
const intercept = trendingLimits.min - chartLimits.min * slope;
|
|
27794
27788
|
const newXMin = this.currentAxesLimits[chartId].x.min;
|
|
27795
27789
|
const newXMax = this.currentAxesLimits[chartId].x.max;
|
|
27796
|
-
this.currentAxesLimits[chartId][axisId]
|
|
27797
|
-
|
|
27790
|
+
this.currentAxesLimits[chartId][axisId] = {
|
|
27791
|
+
min: newXMin * slope + intercept,
|
|
27792
|
+
max: newXMax * slope + intercept,
|
|
27793
|
+
};
|
|
27798
27794
|
}
|
|
27799
27795
|
return "noStateChange";
|
|
27800
27796
|
}
|
|
@@ -27863,8 +27859,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27863
27859
|
hasLinearScale;
|
|
27864
27860
|
isBarChart;
|
|
27865
27861
|
chartId = "";
|
|
27866
|
-
datasetBoundaries = {
|
|
27862
|
+
datasetBoundaries = { min: 0, max: 0 };
|
|
27867
27863
|
removeEventListeners = () => { };
|
|
27864
|
+
isMasterChartAllowed = false;
|
|
27868
27865
|
setup() {
|
|
27869
27866
|
this.store = useStore(ZoomableChartStore);
|
|
27870
27867
|
super.setup();
|
|
@@ -27880,12 +27877,19 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27880
27877
|
height:${height};
|
|
27881
27878
|
`;
|
|
27882
27879
|
}
|
|
27880
|
+
get masterChartContainerStyle() {
|
|
27881
|
+
const runtime = this.env.model.getters.getChartRuntime(this.props.chartId);
|
|
27882
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27883
|
+
return "opacity: 0.3;";
|
|
27884
|
+
}
|
|
27885
|
+
return "";
|
|
27886
|
+
}
|
|
27883
27887
|
get sliceable() {
|
|
27884
27888
|
if (this.props.isFullScreen) {
|
|
27885
27889
|
return true;
|
|
27886
27890
|
}
|
|
27887
27891
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27888
|
-
return ("zoomable" in definition && definition
|
|
27892
|
+
return ("zoomable" in definition && definition.zoomable) ?? false;
|
|
27889
27893
|
}
|
|
27890
27894
|
get axisOffset() {
|
|
27891
27895
|
return !this.hasLinearScale && this.isBarChart ? 0.5 : 0;
|
|
@@ -27910,15 +27914,13 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27910
27914
|
if (!this.sliceable) {
|
|
27911
27915
|
return chartData;
|
|
27912
27916
|
}
|
|
27913
|
-
|
|
27914
|
-
const
|
|
27915
|
-
|
|
27916
|
-
|
|
27917
|
-
|
|
27918
|
-
|
|
27919
|
-
|
|
27920
|
-
if (xAxis?.max !== undefined) {
|
|
27921
|
-
xScale.max = this.hasLinearScale ? xAxis.max : Math.floor(xAxis.max) - this.axisOffset;
|
|
27917
|
+
let x = chartData.options.scales.x;
|
|
27918
|
+
const limits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
27919
|
+
if (limits) {
|
|
27920
|
+
x = {
|
|
27921
|
+
...x,
|
|
27922
|
+
...this.getStoredBoundaries(),
|
|
27923
|
+
};
|
|
27922
27924
|
}
|
|
27923
27925
|
return {
|
|
27924
27926
|
...chartData,
|
|
@@ -27926,7 +27928,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27926
27928
|
...chartData.options,
|
|
27927
27929
|
scales: {
|
|
27928
27930
|
...chartData.options.scales,
|
|
27929
|
-
x
|
|
27931
|
+
x,
|
|
27930
27932
|
},
|
|
27931
27933
|
layout: {
|
|
27932
27934
|
...chartData.options.layout,
|
|
@@ -27941,9 +27943,19 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27941
27943
|
getAxisLimitsFromDataset(chartData) {
|
|
27942
27944
|
const data = chartData.data.datasets.map((ds) => ds.data).flat();
|
|
27943
27945
|
const xValues = data.map((d, i) => (typeof d === "object" && d !== null ? d.x : i));
|
|
27944
|
-
const
|
|
27945
|
-
const
|
|
27946
|
-
return {
|
|
27946
|
+
const min = Math.min(...xValues);
|
|
27947
|
+
const max = Math.max(...xValues);
|
|
27948
|
+
return { min, max };
|
|
27949
|
+
}
|
|
27950
|
+
setMasterChartCursor(runtime) {
|
|
27951
|
+
const masterElement = this.masterChartCanvas?.el;
|
|
27952
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27953
|
+
masterElement.style.cursor = "not-allowed";
|
|
27954
|
+
this.isMasterChartAllowed = false;
|
|
27955
|
+
return;
|
|
27956
|
+
}
|
|
27957
|
+
masterElement.style.cursor = "default";
|
|
27958
|
+
this.isMasterChartAllowed = true;
|
|
27947
27959
|
}
|
|
27948
27960
|
createChart(chartRuntime) {
|
|
27949
27961
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27955,12 +27967,14 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27955
27967
|
chartRuntime.chartJsConfig = updatedData;
|
|
27956
27968
|
}
|
|
27957
27969
|
super.createChart(chartRuntime);
|
|
27958
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
27970
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27959
27971
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
27972
|
+
this.isMasterChartAllowed = false;
|
|
27960
27973
|
return;
|
|
27961
27974
|
}
|
|
27962
27975
|
this.masterChart?.destroy();
|
|
27963
|
-
const masterChartCtx = this.masterChartCanvas
|
|
27976
|
+
const masterChartCtx = (this.masterChartCanvas?.el).getContext("2d");
|
|
27977
|
+
this.setMasterChartCursor(chartRuntime);
|
|
27964
27978
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27965
27979
|
this.resetAxesLimits();
|
|
27966
27980
|
if (this.chart?.options) {
|
|
@@ -27969,11 +27983,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27969
27983
|
}
|
|
27970
27984
|
updateChartJs(chartRuntime) {
|
|
27971
27985
|
const chartData = chartRuntime.chartJsConfig;
|
|
27972
|
-
const
|
|
27973
|
-
if (this.datasetBoundaries.
|
|
27974
|
-
this.datasetBoundaries.xMax !== newDatasetBoundaries.xMax) {
|
|
27986
|
+
const { min, max } = this.getAxisLimitsFromDataset(chartData);
|
|
27987
|
+
if (this.datasetBoundaries.min !== min || this.datasetBoundaries.max !== max) {
|
|
27975
27988
|
this.store.clearAxisLimits(this.chartId);
|
|
27976
|
-
this.datasetBoundaries =
|
|
27989
|
+
this.datasetBoundaries = { min, max };
|
|
27977
27990
|
}
|
|
27978
27991
|
this.isBarChart = chartData?.type === "bar";
|
|
27979
27992
|
this.chartId = `${chartData.type}-${this.props.chartId}`;
|
|
@@ -27982,9 +27995,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27982
27995
|
chartRuntime.chartJsConfig = updatedData;
|
|
27983
27996
|
}
|
|
27984
27997
|
super.updateChartJs(chartRuntime);
|
|
27985
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
27998
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27986
27999
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
27987
28000
|
this.masterChart = undefined;
|
|
28001
|
+
this.isMasterChartAllowed = false;
|
|
27988
28002
|
}
|
|
27989
28003
|
else {
|
|
27990
28004
|
const masterChartConfig = this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]);
|
|
@@ -27997,6 +28011,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27997
28011
|
this.masterChart.config.options = masterChartConfig.options;
|
|
27998
28012
|
this.masterChart.update();
|
|
27999
28013
|
}
|
|
28014
|
+
this.setMasterChartCursor(chartRuntime);
|
|
28000
28015
|
}
|
|
28001
28016
|
this.resetAxesLimits();
|
|
28002
28017
|
if (this.chart?.options) {
|
|
@@ -28007,18 +28022,15 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28007
28022
|
if (!this.chart) {
|
|
28008
28023
|
return;
|
|
28009
28024
|
}
|
|
28010
|
-
const
|
|
28011
|
-
if (
|
|
28025
|
+
const storedLimits = this.store.originalAxisLimits[this.chartId]?.x;
|
|
28026
|
+
if (!storedLimits) {
|
|
28012
28027
|
let scales = this.masterChart
|
|
28013
28028
|
? this.masterChart.scales
|
|
28014
28029
|
: this.chart.scales;
|
|
28015
|
-
if (!this.hasLinearScale && scales
|
|
28030
|
+
if (!this.hasLinearScale && scales.x) {
|
|
28016
28031
|
scales = {
|
|
28017
28032
|
...scales,
|
|
28018
|
-
x:
|
|
28019
|
-
min: Math.ceil(scales.x.min) - this.axisOffset,
|
|
28020
|
-
max: Math.floor(scales.x.max) + this.axisOffset,
|
|
28021
|
-
},
|
|
28033
|
+
x: this.adjustBoundaries(scales.x),
|
|
28022
28034
|
};
|
|
28023
28035
|
}
|
|
28024
28036
|
this.store.resetAxisLimits(this.chartId, scales);
|
|
@@ -28033,13 +28045,13 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28033
28045
|
}
|
|
28034
28046
|
updateTrendingLineAxes() {
|
|
28035
28047
|
this.store.updateTrendLineConfiguration(this.chartId);
|
|
28036
|
-
const
|
|
28048
|
+
const limits = this.store.currentAxesLimits[this.chartId];
|
|
28037
28049
|
for (const axisId of [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
|
|
28038
|
-
if (!this.chart?.config
|
|
28050
|
+
if (!this.chart?.config?.options?.scales?.[axisId] || !limits?.[axisId]) {
|
|
28039
28051
|
continue;
|
|
28040
28052
|
}
|
|
28041
|
-
this.chart.config.options.scales[axisId].min =
|
|
28042
|
-
this.chart.config.options.scales[axisId].max =
|
|
28053
|
+
this.chart.config.options.scales[axisId].min = limits[axisId].min;
|
|
28054
|
+
this.chart.config.options.scales[axisId].max = limits[axisId].max;
|
|
28043
28055
|
}
|
|
28044
28056
|
}
|
|
28045
28057
|
get upperBound() {
|
|
@@ -28082,29 +28094,71 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28082
28094
|
offset +
|
|
28083
28095
|
((scale.max + 2 * offset - scale.min) * (position - left)) / (right - left));
|
|
28084
28096
|
}
|
|
28085
|
-
|
|
28097
|
+
/**
|
|
28098
|
+
* Compute min and max from the store, adjusting them if needed for non linear scales.
|
|
28099
|
+
* Getting the value from the store, we have to ensure that the values are integers for
|
|
28100
|
+
* non linear scales (bar and category). To select a bar in the chart, we have to include
|
|
28101
|
+
* the whole bar, which means that for the i-th bar, the selected min should be <= i and
|
|
28102
|
+
* the selected max should be >= i, so using the Math.floor and Math.ceil functions is
|
|
28103
|
+
* the right way to do it.
|
|
28104
|
+
* Sometimes, we can get a minimal value > the maximal value, which arise when the user
|
|
28105
|
+
* select a very small area in the master chart, and hasn't selected the middle of a bar
|
|
28106
|
+
* or a group of bars (in case of more than one data series).
|
|
28107
|
+
* Assuming we have to select the middle of a bar/a groupe of bars, we will reject the
|
|
28108
|
+
* coming value afterward. In this case, we do not update the chart because it would lead
|
|
28109
|
+
* to an empty chart.
|
|
28110
|
+
*/
|
|
28111
|
+
getStoredBoundaries() {
|
|
28112
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId].x;
|
|
28086
28113
|
if (!this.hasLinearScale) {
|
|
28087
|
-
|
|
28088
|
-
|
|
28114
|
+
min = Math.ceil(min);
|
|
28115
|
+
max = Math.floor(max);
|
|
28089
28116
|
}
|
|
28090
|
-
|
|
28091
|
-
|
|
28092
|
-
|
|
28117
|
+
return { min, max };
|
|
28118
|
+
}
|
|
28119
|
+
/**
|
|
28120
|
+
* Adjust the min and max values of an axis if needed for non linear scales.
|
|
28121
|
+
* Here, after rounding (see docstring of getStoredBoundaries), we adjust the min by
|
|
28122
|
+
* substracting the axis offset, and we add it to the max, because when computing from the
|
|
28123
|
+
* scale, chartJs use integer values as the limits for non linear scales. If we have a min
|
|
28124
|
+
* value of 1, it means we want to start displaying from 0.5, and if we have a max value of
|
|
28125
|
+
* 4, it means we want to display until 4.5.
|
|
28126
|
+
* Here, we don't have to check if min > max because we are computing from the scale, and
|
|
28127
|
+
* chartJs ensures that this won't happen, even after our adjustments.
|
|
28128
|
+
*/
|
|
28129
|
+
adjustBoundaries({ min, max }) {
|
|
28130
|
+
if (!this.hasLinearScale) {
|
|
28131
|
+
min = Math.ceil(min) - this.axisOffset;
|
|
28132
|
+
max = Math.floor(max) + this.axisOffset;
|
|
28133
|
+
}
|
|
28134
|
+
return { min, max };
|
|
28135
|
+
}
|
|
28136
|
+
updateAxisLimits(xMin, xMax) {
|
|
28137
|
+
if (xMin === xMax) {
|
|
28138
|
+
return;
|
|
28139
|
+
}
|
|
28140
|
+
if (!this.chart) {
|
|
28141
|
+
return;
|
|
28093
28142
|
}
|
|
28094
28143
|
this.store.updateAxisLimits(this.chartId, { min: xMin, max: xMax });
|
|
28095
|
-
this.
|
|
28144
|
+
const { min, max } = this.getStoredBoundaries();
|
|
28145
|
+
if (max > min || (this.isBarChart && max === min)) {
|
|
28146
|
+
this.chart.config.options.scales.x.min = min;
|
|
28147
|
+
this.chart.config.options.scales.x.max = max;
|
|
28148
|
+
this.updateTrendingLineAxes();
|
|
28149
|
+
this.chart.update();
|
|
28150
|
+
}
|
|
28096
28151
|
this.masterChart?.update();
|
|
28097
|
-
this.chart?.update();
|
|
28098
28152
|
}
|
|
28099
|
-
|
|
28153
|
+
onMasterChartPointerDown(ev) {
|
|
28100
28154
|
this.removeEventListeners();
|
|
28101
28155
|
const position = ev.offsetX;
|
|
28102
28156
|
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
28103
28157
|
return;
|
|
28104
28158
|
}
|
|
28105
28159
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
28106
|
-
const
|
|
28107
|
-
const
|
|
28160
|
+
const upperBound = this.upperBound ?? right;
|
|
28161
|
+
const lowerBound = this.lowerBound ?? left;
|
|
28108
28162
|
if (position < left - 5 || position > right + 5 || ev.offsetY < top || ev.offsetY > bottom) {
|
|
28109
28163
|
return;
|
|
28110
28164
|
}
|
|
@@ -28112,8 +28166,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28112
28166
|
ev.stopPropagation();
|
|
28113
28167
|
let startingPositionOnChart, windowSize, startX;
|
|
28114
28168
|
const startingEventPosition = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28115
|
-
if ((
|
|
28116
|
-
|
|
28169
|
+
if ((lowerBound !== left || upperBound !== right) &&
|
|
28170
|
+
position > lowerBound + 5 &&
|
|
28171
|
+
position < upperBound - 5) {
|
|
28172
|
+
startingPositionOnChart = ev.offsetX - lowerBound;
|
|
28117
28173
|
this.mode = "moveInMaster";
|
|
28118
28174
|
const currentLimits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
28119
28175
|
windowSize =
|
|
@@ -28122,31 +28178,29 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28122
28178
|
}
|
|
28123
28179
|
else {
|
|
28124
28180
|
this.mode = "selectInMaster";
|
|
28125
|
-
if (Math.abs(position -
|
|
28126
|
-
startingPositionOnChart =
|
|
28181
|
+
if (Math.abs(position - lowerBound) < 5) {
|
|
28182
|
+
startingPositionOnChart = upperBound;
|
|
28127
28183
|
}
|
|
28128
|
-
else if (Math.abs(position -
|
|
28129
|
-
startingPositionOnChart =
|
|
28184
|
+
else if (Math.abs(position - upperBound) < 5) {
|
|
28185
|
+
startingPositionOnChart = lowerBound;
|
|
28130
28186
|
}
|
|
28131
28187
|
else {
|
|
28132
28188
|
startingPositionOnChart = clip(position, left, right);
|
|
28133
28189
|
}
|
|
28134
28190
|
startX = this.computeCoordinate(startingPositionOnChart);
|
|
28135
28191
|
}
|
|
28136
|
-
const
|
|
28137
|
-
const
|
|
28192
|
+
const storedMin = this.store.originalAxisLimits[this.chartId].x.min;
|
|
28193
|
+
const storedMax = this.store.originalAxisLimits[this.chartId].x.max;
|
|
28138
28194
|
const computeNewAxisLimits = (position) => {
|
|
28139
|
-
let xMin, xMax;
|
|
28140
|
-
const { left, right } = this.masterChart.chartArea;
|
|
28141
28195
|
if (this.mode === "moveInMaster") {
|
|
28142
|
-
|
|
28143
|
-
if (
|
|
28144
|
-
|
|
28196
|
+
let min = this.computeCoordinate(position - startingPositionOnChart);
|
|
28197
|
+
if (min < storedMin) {
|
|
28198
|
+
min = storedMin;
|
|
28145
28199
|
}
|
|
28146
|
-
else if (
|
|
28147
|
-
|
|
28200
|
+
else if (min > storedMax - windowSize) {
|
|
28201
|
+
min = storedMax - windowSize;
|
|
28148
28202
|
}
|
|
28149
|
-
|
|
28203
|
+
return { min, max: min + windowSize };
|
|
28150
28204
|
}
|
|
28151
28205
|
else if (this.mode === "selectInMaster") {
|
|
28152
28206
|
const upperBound = clip(position, left, right);
|
|
@@ -28155,54 +28209,52 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28155
28209
|
if (startX === undefined || endX === undefined) {
|
|
28156
28210
|
return {};
|
|
28157
28211
|
}
|
|
28158
|
-
|
|
28159
|
-
|
|
28212
|
+
return {
|
|
28213
|
+
min: Math.min(startX, endX),
|
|
28214
|
+
max: Math.max(startX, endX),
|
|
28215
|
+
};
|
|
28160
28216
|
}
|
|
28161
28217
|
}
|
|
28162
|
-
return {
|
|
28218
|
+
return {};
|
|
28163
28219
|
};
|
|
28164
|
-
const
|
|
28220
|
+
const onMasterChartDrag = (ev) => {
|
|
28165
28221
|
const position = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28166
28222
|
if (Math.abs(position - startingEventPosition) < 5) {
|
|
28167
28223
|
return;
|
|
28168
28224
|
}
|
|
28169
|
-
const { min
|
|
28170
|
-
if (
|
|
28171
|
-
this.updateAxisLimits(
|
|
28225
|
+
const { min, max } = computeNewAxisLimits(position);
|
|
28226
|
+
if (min !== undefined && max !== undefined) {
|
|
28227
|
+
this.updateAxisLimits(min, max);
|
|
28172
28228
|
}
|
|
28173
28229
|
};
|
|
28174
|
-
const
|
|
28230
|
+
const onMasterChartPointerUp = (ev) => {
|
|
28175
28231
|
this.removeEventListeners();
|
|
28176
|
-
|
|
28177
|
-
if (
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28183
|
-
|
|
28184
|
-
}
|
|
28185
|
-
else {
|
|
28186
|
-
xMin = Math.ceil(xMin) - this.axisOffset;
|
|
28187
|
-
xMax = Math.floor(xMax) + this.axisOffset;
|
|
28188
|
-
}
|
|
28189
|
-
}
|
|
28190
|
-
this.updateAxisLimits(xMin, xMax);
|
|
28232
|
+
let { min, max } = this.chart.scales.x;
|
|
28233
|
+
if (!this.hasLinearScale) {
|
|
28234
|
+
if (this.mode === "moveInMaster") {
|
|
28235
|
+
min = Math.round(min) - this.axisOffset;
|
|
28236
|
+
max = min + windowSize;
|
|
28237
|
+
}
|
|
28238
|
+
else {
|
|
28239
|
+
({ min, max } = this.adjustBoundaries({ min, max }));
|
|
28191
28240
|
}
|
|
28192
28241
|
}
|
|
28242
|
+
this.updateAxisLimits(min, max);
|
|
28193
28243
|
this.mode = undefined;
|
|
28194
28244
|
};
|
|
28195
28245
|
this.removeEventListeners = () => {
|
|
28196
|
-
window.removeEventListener("pointermove",
|
|
28197
|
-
window.removeEventListener("pointerup",
|
|
28246
|
+
window.removeEventListener("pointermove", onMasterChartDrag, true);
|
|
28247
|
+
window.removeEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28198
28248
|
};
|
|
28199
|
-
window.addEventListener("pointermove",
|
|
28200
|
-
window.addEventListener("pointerup",
|
|
28249
|
+
window.addEventListener("pointermove", onMasterChartDrag, true);
|
|
28250
|
+
window.addEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28201
28251
|
}
|
|
28202
|
-
|
|
28203
|
-
const { offsetX: x, offsetY: y } = ev;
|
|
28252
|
+
onMasterChartPointerMove(ev) {
|
|
28253
|
+
const { offsetX: x, offsetY: y, target } = ev;
|
|
28254
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28255
|
+
return;
|
|
28256
|
+
}
|
|
28204
28257
|
if (this.mode === undefined) {
|
|
28205
|
-
const target = ev.target;
|
|
28206
28258
|
if (!this.masterChart?.chartArea) {
|
|
28207
28259
|
target["style"].cursor = "default";
|
|
28208
28260
|
return;
|
|
@@ -28224,14 +28276,14 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28224
28276
|
}
|
|
28225
28277
|
}
|
|
28226
28278
|
}
|
|
28227
|
-
|
|
28279
|
+
onMasterChartMouseLeave(ev) {
|
|
28228
28280
|
const target = ev.target;
|
|
28229
|
-
if (!target) {
|
|
28281
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28230
28282
|
return;
|
|
28231
28283
|
}
|
|
28232
28284
|
target["style"].cursor = "default";
|
|
28233
28285
|
}
|
|
28234
|
-
|
|
28286
|
+
onMasterChartDoubleClick(ev) {
|
|
28235
28287
|
this.mode = undefined;
|
|
28236
28288
|
const position = ev.offsetX;
|
|
28237
28289
|
if (!this.masterChart?.chartArea || !this.chart?.scales.x) {
|
|
@@ -28248,33 +28300,25 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28248
28300
|
}
|
|
28249
28301
|
ev.preventDefault();
|
|
28250
28302
|
ev.stopPropagation();
|
|
28251
|
-
let { min
|
|
28303
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId]?.x ?? this.chart.scales.x;
|
|
28252
28304
|
const originalAxisLimits = this.store.originalAxisLimits[this.chartId].x;
|
|
28253
28305
|
if (!originalAxisLimits) {
|
|
28254
28306
|
return;
|
|
28255
28307
|
}
|
|
28256
|
-
let originalXMin = originalAxisLimits.min;
|
|
28257
|
-
let originalXMax = originalAxisLimits.max;
|
|
28258
|
-
if (this.hasLinearScale) {
|
|
28259
|
-
originalXMin = Math.ceil(originalXMin) - this.axisOffset;
|
|
28260
|
-
originalXMax = Math.floor(originalXMax) + this.axisOffset;
|
|
28261
|
-
}
|
|
28262
28308
|
if (Math.abs(position - lowerBound) < 5) {
|
|
28263
|
-
|
|
28264
|
-
xMin = originalXMin;
|
|
28309
|
+
min = originalAxisLimits.min;
|
|
28265
28310
|
}
|
|
28266
28311
|
else if (Math.abs(position - upperBound) < 5) {
|
|
28267
|
-
|
|
28312
|
+
max = originalAxisLimits.max;
|
|
28268
28313
|
}
|
|
28269
28314
|
else if (lowerBound < position && position < upperBound) {
|
|
28270
|
-
|
|
28271
|
-
|
|
28272
|
-
xMax = originalXMax;
|
|
28315
|
+
min = originalAxisLimits.min;
|
|
28316
|
+
max = originalAxisLimits.max;
|
|
28273
28317
|
}
|
|
28274
28318
|
else {
|
|
28275
28319
|
return;
|
|
28276
28320
|
}
|
|
28277
|
-
this.updateAxisLimits(
|
|
28321
|
+
this.updateAxisLimits(min, max);
|
|
28278
28322
|
}
|
|
28279
28323
|
}
|
|
28280
28324
|
|
|
@@ -34405,7 +34449,8 @@ class Composer extends owl.Component {
|
|
|
34405
34449
|
assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
|
|
34406
34450
|
// render top
|
|
34407
34451
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
34408
|
-
assistantStyle.
|
|
34452
|
+
assistantStyle.top = `-3px`;
|
|
34453
|
+
assistantStyle.transform = `translate(0, -100%)`;
|
|
34409
34454
|
}
|
|
34410
34455
|
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
34411
34456
|
// render left
|
|
@@ -35196,7 +35241,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35196
35241
|
}
|
|
35197
35242
|
this.selectionStart = start;
|
|
35198
35243
|
this.selectionEnd = end;
|
|
35199
|
-
this.
|
|
35244
|
+
this.stopComposerRangeSelection();
|
|
35200
35245
|
this.computeFormulaCursorContext();
|
|
35201
35246
|
this.computeParenthesisRelatedToCursor();
|
|
35202
35247
|
this.updateAutoCompleteProvider();
|
|
@@ -44193,18 +44238,22 @@ function dropCommands(initialMessages, commandType) {
|
|
|
44193
44238
|
return messages;
|
|
44194
44239
|
}
|
|
44195
44240
|
function fixChartDefinitions(data, initialMessages) {
|
|
44241
|
+
/**
|
|
44242
|
+
* Revisions created after version 18.5.1 contain the full chart definition in the command
|
|
44243
|
+
* if the data was alreay updated to 18.5.1, then those older revision cannot (by definition) be reaplied
|
|
44244
|
+
* and should not be replayed.
|
|
44245
|
+
* FIXME: every command should be versionned when upgraded to allow finer tuning.
|
|
44246
|
+
*/
|
|
44247
|
+
if (!data.version || compareVersions(String(data.version), "18.5.1") >= 0) {
|
|
44248
|
+
return initialMessages;
|
|
44249
|
+
}
|
|
44196
44250
|
const messages = [];
|
|
44197
44251
|
const map = {};
|
|
44198
44252
|
for (const sheet of data.sheets || []) {
|
|
44199
44253
|
sheet.figures?.forEach((figure) => {
|
|
44200
44254
|
if (figure.tag === "chart") {
|
|
44201
44255
|
// chart definition
|
|
44202
|
-
|
|
44203
|
-
map[figure.data.chartId] = figure.data;
|
|
44204
|
-
}
|
|
44205
|
-
else {
|
|
44206
|
-
map[figure.id] = figure.data;
|
|
44207
|
-
}
|
|
44256
|
+
map[figure.id] = figure.data;
|
|
44208
44257
|
}
|
|
44209
44258
|
});
|
|
44210
44259
|
}
|
|
@@ -47787,7 +47836,6 @@ const dateGranularities = [
|
|
|
47787
47836
|
pivotRegistry.add("SPREADSHEET", {
|
|
47788
47837
|
ui: SpreadsheetPivot,
|
|
47789
47838
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
47790
|
-
externalData: false,
|
|
47791
47839
|
dateGranularities: [...dateGranularities],
|
|
47792
47840
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
47793
47841
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
@@ -53823,7 +53871,9 @@ class FontSizeEditor extends owl.Component {
|
|
|
53823
53871
|
inputRef = owl.useRef("inputFontSize");
|
|
53824
53872
|
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
53825
53873
|
fontSizeListRef = owl.useRef("fontSizeList");
|
|
53874
|
+
DOMFocusableElementStore;
|
|
53826
53875
|
setup() {
|
|
53876
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
53827
53877
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
53828
53878
|
}
|
|
53829
53879
|
get popoverProps() {
|
|
@@ -53877,6 +53927,13 @@ class FontSizeEditor extends owl.Component {
|
|
|
53877
53927
|
}
|
|
53878
53928
|
this.props.onToggle?.();
|
|
53879
53929
|
}
|
|
53930
|
+
if (ev.key === "Tab") {
|
|
53931
|
+
ev.preventDefault();
|
|
53932
|
+
ev.stopPropagation();
|
|
53933
|
+
this.closeFontList();
|
|
53934
|
+
this.DOMFocusableElementStore.focus();
|
|
53935
|
+
return;
|
|
53936
|
+
}
|
|
53880
53937
|
}
|
|
53881
53938
|
}
|
|
53882
53939
|
|
|
@@ -55212,19 +55269,6 @@ class ChartWithAxisDesignPanel extends owl.Component {
|
|
|
55212
55269
|
}
|
|
55213
55270
|
}
|
|
55214
55271
|
|
|
55215
|
-
class ChartShowDataMarkers extends owl.Component {
|
|
55216
|
-
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55217
|
-
static components = {
|
|
55218
|
-
Checkbox,
|
|
55219
|
-
};
|
|
55220
|
-
static props = {
|
|
55221
|
-
chartId: String,
|
|
55222
|
-
definition: Object,
|
|
55223
|
-
updateChart: Function,
|
|
55224
|
-
canUpdateChart: Function,
|
|
55225
|
-
};
|
|
55226
|
-
}
|
|
55227
|
-
|
|
55228
55272
|
class GenericZoomableChartDesignPanel extends ChartWithAxisDesignPanel {
|
|
55229
55273
|
static template = "o-spreadsheet-GenericZoomableChartDesignPanel";
|
|
55230
55274
|
static components = {
|
|
@@ -55238,6 +55282,26 @@ class GenericZoomableChartDesignPanel extends ChartWithAxisDesignPanel {
|
|
|
55238
55282
|
}
|
|
55239
55283
|
}
|
|
55240
55284
|
|
|
55285
|
+
class BarChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55286
|
+
static template = "o-spreadsheet-BarChartDesignPanel";
|
|
55287
|
+
get isZoomable() {
|
|
55288
|
+
return !this.props.definition.horizontal;
|
|
55289
|
+
}
|
|
55290
|
+
}
|
|
55291
|
+
|
|
55292
|
+
class ChartShowDataMarkers extends owl.Component {
|
|
55293
|
+
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55294
|
+
static components = {
|
|
55295
|
+
Checkbox,
|
|
55296
|
+
};
|
|
55297
|
+
static props = {
|
|
55298
|
+
chartId: String,
|
|
55299
|
+
definition: Object,
|
|
55300
|
+
updateChart: Function,
|
|
55301
|
+
canUpdateChart: Function,
|
|
55302
|
+
};
|
|
55303
|
+
}
|
|
55304
|
+
|
|
55241
55305
|
class ComboChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55242
55306
|
static template = "o-spreadsheet-ComboChartDesignPanel";
|
|
55243
55307
|
static components = {
|
|
@@ -56166,7 +56230,7 @@ chartSidePanelComponentRegistry
|
|
|
56166
56230
|
})
|
|
56167
56231
|
.add("bar", {
|
|
56168
56232
|
configuration: BarConfigPanel,
|
|
56169
|
-
design:
|
|
56233
|
+
design: BarChartDesignPanel,
|
|
56170
56234
|
})
|
|
56171
56235
|
.add("combo", {
|
|
56172
56236
|
configuration: GenericChartConfigPanel,
|
|
@@ -64258,7 +64322,8 @@ class FigurePlugin extends CorePlugin {
|
|
|
64258
64322
|
}
|
|
64259
64323
|
break;
|
|
64260
64324
|
case "DUPLICATE_SHEET": {
|
|
64261
|
-
for (const
|
|
64325
|
+
for (const figure of this.getFigures(cmd.sheetId)) {
|
|
64326
|
+
const figureId = figure.id;
|
|
64262
64327
|
const fig = this.figures[cmd.sheetId]?.[figureId];
|
|
64263
64328
|
if (!fig) {
|
|
64264
64329
|
continue;
|
|
@@ -67736,10 +67801,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67736
67801
|
if (!pivot) {
|
|
67737
67802
|
continue;
|
|
67738
67803
|
}
|
|
67739
|
-
|
|
67804
|
+
const def = deepCopy(pivot.definition);
|
|
67805
|
+
for (const measure of def.measures) {
|
|
67740
67806
|
if (measure.computedBy?.formula === formulaString) {
|
|
67741
|
-
const measureIndex =
|
|
67742
|
-
|
|
67807
|
+
const measureIndex = def.measures.indexOf(measure);
|
|
67808
|
+
if (measureIndex !== -1) {
|
|
67809
|
+
def.measures[measureIndex].computedBy = {
|
|
67810
|
+
formula: newFormulaString,
|
|
67811
|
+
sheetId,
|
|
67812
|
+
};
|
|
67813
|
+
}
|
|
67814
|
+
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
|
|
67743
67815
|
}
|
|
67744
67816
|
}
|
|
67745
67817
|
}
|
|
@@ -67900,6 +67972,9 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
|
67900
67972
|
const { sheetId, zone } = definition.dataSet;
|
|
67901
67973
|
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
67902
67974
|
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
67975
|
+
if (adaptedRange === range) {
|
|
67976
|
+
return;
|
|
67977
|
+
}
|
|
67903
67978
|
const dataSet = adaptedRange && {
|
|
67904
67979
|
sheetId: adaptedRange.sheetId,
|
|
67905
67980
|
zone: adaptedRange.zone,
|
|
@@ -72219,9 +72294,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72219
72294
|
handle(cmd) {
|
|
72220
72295
|
if (invalidateEvaluationCommands.has(cmd.type)) {
|
|
72221
72296
|
for (const pivotId of this.getters.getPivotIds()) {
|
|
72222
|
-
|
|
72223
|
-
this.setupPivot(pivotId, { recreate: true });
|
|
72224
|
-
}
|
|
72297
|
+
this.setupPivot(pivotId, { recreate: true });
|
|
72225
72298
|
}
|
|
72226
72299
|
}
|
|
72227
72300
|
switch (cmd.type) {
|
|
@@ -72443,7 +72516,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72443
72516
|
pivot.init({ reload: true });
|
|
72444
72517
|
}
|
|
72445
72518
|
setupPivot(pivotId, { recreate } = { recreate: false }) {
|
|
72446
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
72519
|
+
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
72447
72520
|
if (!(pivotId in this.pivots)) {
|
|
72448
72521
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
72449
72522
|
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
@@ -81950,16 +82023,18 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
81950
82023
|
get clickableCells() {
|
|
81951
82024
|
const cells = [];
|
|
81952
82025
|
const getters = this.getters;
|
|
81953
|
-
const sheetId = getters.getActiveSheetId();
|
|
81954
82026
|
for (const position of this.getters.getVisibleCellPositions()) {
|
|
81955
82027
|
const item = this.getClickableItem(position);
|
|
81956
82028
|
if (!item) {
|
|
81957
82029
|
continue;
|
|
81958
82030
|
}
|
|
81959
82031
|
const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
|
|
81960
|
-
const
|
|
82032
|
+
const rect = this.getClickableCellRect(position);
|
|
82033
|
+
if (!rect) {
|
|
82034
|
+
continue;
|
|
82035
|
+
}
|
|
81961
82036
|
cells.push({
|
|
81962
|
-
coordinates:
|
|
82037
|
+
coordinates: rect,
|
|
81963
82038
|
position,
|
|
81964
82039
|
action: item.execute,
|
|
81965
82040
|
title: title || "",
|
|
@@ -81969,6 +82044,31 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
81969
82044
|
}
|
|
81970
82045
|
return cells;
|
|
81971
82046
|
}
|
|
82047
|
+
getClickableCellRect(position) {
|
|
82048
|
+
const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
|
|
82049
|
+
const clickableRect = this.getters.getVisibleRect(zone);
|
|
82050
|
+
const icons = this.getters.getCellIcons(position);
|
|
82051
|
+
const iconsAtPosition = {
|
|
82052
|
+
center: icons.find((icon) => icon.horizontalAlign === "center"),
|
|
82053
|
+
left: icons.find((icon) => icon.horizontalAlign === "left"),
|
|
82054
|
+
right: icons.find((icon) => icon.horizontalAlign === "right"),
|
|
82055
|
+
};
|
|
82056
|
+
if (iconsAtPosition.center?.onClick) {
|
|
82057
|
+
return undefined;
|
|
82058
|
+
}
|
|
82059
|
+
if (iconsAtPosition.right?.onClick) {
|
|
82060
|
+
const cellRect = this.getters.getRect(zone);
|
|
82061
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
|
|
82062
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
|
|
82063
|
+
}
|
|
82064
|
+
if (iconsAtPosition.left?.onClick) {
|
|
82065
|
+
const cellRect = this.getters.getRect(zone);
|
|
82066
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
|
|
82067
|
+
clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
|
|
82068
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
|
|
82069
|
+
}
|
|
82070
|
+
return clickableRect;
|
|
82071
|
+
}
|
|
81972
82072
|
}
|
|
81973
82073
|
|
|
81974
82074
|
css /* scss */ `
|
|
@@ -82726,7 +82826,7 @@ class SmallBottomBar extends owl.Component {
|
|
|
82726
82826
|
height: this.focus === "inactive" ? "26px" : "fit-content",
|
|
82727
82827
|
"max-height": `130px`,
|
|
82728
82828
|
}),
|
|
82729
|
-
showAssistant:
|
|
82829
|
+
showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
|
|
82730
82830
|
placeholder: this.composerStore.placeholder,
|
|
82731
82831
|
};
|
|
82732
82832
|
}
|
|
@@ -89008,6 +89108,6 @@ exports.tokenColors = tokenColors;
|
|
|
89008
89108
|
exports.tokenize = tokenize;
|
|
89009
89109
|
|
|
89010
89110
|
|
|
89011
|
-
__info__.version = "19.0.
|
|
89012
|
-
__info__.date = "2025-
|
|
89013
|
-
__info__.hash = "
|
|
89111
|
+
__info__.version = "19.0.12";
|
|
89112
|
+
__info__.date = "2025-12-02T05:34:17.495Z";
|
|
89113
|
+
__info__.hash = "32203f1";
|