@odoo/o-spreadsheet 18.4.18 → 18.4.22
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 +179 -111
- package/dist/o-spreadsheet.d.ts +10 -25
- package/dist/o-spreadsheet.esm.js +179 -111
- package/dist/o-spreadsheet.iife.js +179 -111
- package/dist/o-spreadsheet.iife.min.js +388 -399
- package/dist/o_spreadsheet.css +192 -0
- package/dist/o_spreadsheet.xml +33 -39
- package/package.json +3 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.4.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.22
|
|
6
|
+
* @date 2025-12-26T10:19:07.786Z
|
|
7
|
+
* @hash 6ddac00
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2615,7 +2615,6 @@ const invalidateEvaluationCommands = new Set([
|
|
|
2615
2615
|
"REDO",
|
|
2616
2616
|
"ADD_MERGE",
|
|
2617
2617
|
"REMOVE_MERGE",
|
|
2618
|
-
"DUPLICATE_SHEET",
|
|
2619
2618
|
"UPDATE_LOCALE",
|
|
2620
2619
|
"ADD_PIVOT",
|
|
2621
2620
|
"UPDATE_PIVOT",
|
|
@@ -5216,17 +5215,41 @@ function toCriterionDateNumber(dateValue) {
|
|
|
5216
5215
|
const today = DateTime.now();
|
|
5217
5216
|
switch (dateValue) {
|
|
5218
5217
|
case "today":
|
|
5219
|
-
return jsDateToNumber(today);
|
|
5220
|
-
case "yesterday":
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5218
|
+
return Math.floor(jsDateToNumber(today));
|
|
5219
|
+
case "yesterday": {
|
|
5220
|
+
today.setDate(today.getDate() - 1);
|
|
5221
|
+
return Math.floor(jsDateToNumber(today));
|
|
5222
|
+
}
|
|
5223
|
+
case "tomorrow": {
|
|
5224
|
+
today.setDate(today.getDate() + 1);
|
|
5225
|
+
return Math.floor(jsDateToNumber(today));
|
|
5226
|
+
}
|
|
5224
5227
|
case "lastWeek":
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
+
today.setDate(today.getDate() - 6);
|
|
5229
|
+
return Math.floor(jsDateToNumber(today));
|
|
5230
|
+
case "lastMonth": {
|
|
5231
|
+
const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
|
|
5232
|
+
const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
|
|
5233
|
+
if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
|
|
5234
|
+
today.setDate(1);
|
|
5235
|
+
}
|
|
5236
|
+
else {
|
|
5237
|
+
today.setDate(today.getDate() + 1);
|
|
5238
|
+
today.setMonth(today.getMonth() - 1);
|
|
5239
|
+
}
|
|
5240
|
+
return Math.floor(jsDateToNumber(today));
|
|
5241
|
+
}
|
|
5228
5242
|
case "lastYear":
|
|
5229
|
-
|
|
5243
|
+
// Handle leap year case
|
|
5244
|
+
if (today.getMonth() === 1 && today.getDate() === 29) {
|
|
5245
|
+
today.setDate(28);
|
|
5246
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
5247
|
+
}
|
|
5248
|
+
else {
|
|
5249
|
+
today.setDate(today.getDate() + 1);
|
|
5250
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
5251
|
+
}
|
|
5252
|
+
return Math.floor(jsDateToNumber(today));
|
|
5230
5253
|
}
|
|
5231
5254
|
}
|
|
5232
5255
|
/** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
|
|
@@ -22584,6 +22607,9 @@ function getTreeMapGroupColors(definition, tree) {
|
|
|
22584
22607
|
}));
|
|
22585
22608
|
}
|
|
22586
22609
|
function getTreeMapColorScale(tree, coloringOption) {
|
|
22610
|
+
if (tree.length === 0) {
|
|
22611
|
+
return undefined;
|
|
22612
|
+
}
|
|
22587
22613
|
const treeNodesByLevel = pyramidizeTree(tree);
|
|
22588
22614
|
const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
|
|
22589
22615
|
const minValue = Math.min(...nodes.map((node) => node.value));
|
|
@@ -24253,11 +24279,18 @@ function chartToImageUrl(runtime, figure, type) {
|
|
|
24253
24279
|
// we have to add the canvas to the DOM otherwise it won't be rendered
|
|
24254
24280
|
document.body.append(div);
|
|
24255
24281
|
if ("chartJsConfig" in runtime) {
|
|
24282
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
24283
|
+
if (!extensionsLoaded) {
|
|
24284
|
+
registerChartJSExtensions();
|
|
24285
|
+
}
|
|
24256
24286
|
const config = deepCopy(runtime.chartJsConfig);
|
|
24257
24287
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
24258
24288
|
const chart = new window.Chart(canvas, config);
|
|
24259
24289
|
imageContent = chart.toBase64Image();
|
|
24260
24290
|
chart.destroy();
|
|
24291
|
+
if (!extensionsLoaded) {
|
|
24292
|
+
unregisterChartJsExtensions();
|
|
24293
|
+
}
|
|
24261
24294
|
}
|
|
24262
24295
|
else if (type === "scorecard") {
|
|
24263
24296
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -24287,11 +24320,18 @@ async function chartToImageFile(runtime, figure, type) {
|
|
|
24287
24320
|
document.body.append(div);
|
|
24288
24321
|
let chartBlob = null;
|
|
24289
24322
|
if ("chartJsConfig" in runtime) {
|
|
24323
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
24324
|
+
if (!extensionsLoaded) {
|
|
24325
|
+
registerChartJSExtensions();
|
|
24326
|
+
}
|
|
24290
24327
|
const config = deepCopy(runtime.chartJsConfig);
|
|
24291
24328
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
24292
24329
|
const chart = new window.Chart(canvas, config);
|
|
24293
24330
|
chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
24294
24331
|
chart.destroy();
|
|
24332
|
+
if (!extensionsLoaded) {
|
|
24333
|
+
unregisterChartJsExtensions();
|
|
24334
|
+
}
|
|
24295
24335
|
}
|
|
24296
24336
|
else if (type === "scorecard") {
|
|
24297
24337
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -29704,7 +29744,7 @@ function escapeQueryNameSpaces(query) {
|
|
|
29704
29744
|
return query.replaceAll(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/g, "NAMESPACE" + "$1" + "NAMESPACE" + "$2");
|
|
29705
29745
|
}
|
|
29706
29746
|
|
|
29707
|
-
function getChartMenuActions(figureId,
|
|
29747
|
+
function getChartMenuActions(figureId, env) {
|
|
29708
29748
|
const menuItemSpecs = [
|
|
29709
29749
|
{
|
|
29710
29750
|
id: "edit",
|
|
@@ -29755,11 +29795,11 @@ function getChartMenuActions(figureId, onFigureDeleted, env) {
|
|
|
29755
29795
|
},
|
|
29756
29796
|
isReadonlyAllowed: true,
|
|
29757
29797
|
},
|
|
29758
|
-
getDeleteMenuItem(figureId,
|
|
29798
|
+
getDeleteMenuItem(figureId, env),
|
|
29759
29799
|
];
|
|
29760
29800
|
return createActions(menuItemSpecs).filter((action) => env.model.getters.isReadonly() ? action.isReadonlyAllowed : true);
|
|
29761
29801
|
}
|
|
29762
|
-
function getImageMenuActions(figureId,
|
|
29802
|
+
function getImageMenuActions(figureId, env) {
|
|
29763
29803
|
const menuItemSpecs = [
|
|
29764
29804
|
getCopyMenuItem(figureId, env, _t("Image copied to clipboard")),
|
|
29765
29805
|
getCutMenuItem(figureId, env),
|
|
@@ -29804,7 +29844,7 @@ function getImageMenuActions(figureId, onFigureDeleted, env) {
|
|
|
29804
29844
|
},
|
|
29805
29845
|
icon: "o-spreadsheet-Icon.DOWNLOAD",
|
|
29806
29846
|
},
|
|
29807
|
-
getDeleteMenuItem(figureId,
|
|
29847
|
+
getDeleteMenuItem(figureId, env),
|
|
29808
29848
|
];
|
|
29809
29849
|
return createActions(menuItemSpecs);
|
|
29810
29850
|
}
|
|
@@ -29840,7 +29880,7 @@ function getCutMenuItem(figureId, env) {
|
|
|
29840
29880
|
icon: "o-spreadsheet-Icon.CUT",
|
|
29841
29881
|
};
|
|
29842
29882
|
}
|
|
29843
|
-
function getDeleteMenuItem(figureId,
|
|
29883
|
+
function getDeleteMenuItem(figureId, env) {
|
|
29844
29884
|
return {
|
|
29845
29885
|
id: "delete",
|
|
29846
29886
|
name: _t("Delete"),
|
|
@@ -29850,7 +29890,6 @@ function getDeleteMenuItem(figureId, onFigureDeleted, env) {
|
|
|
29850
29890
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
29851
29891
|
figureId,
|
|
29852
29892
|
});
|
|
29853
|
-
onFigureDeleted();
|
|
29854
29893
|
},
|
|
29855
29894
|
icon: "o-spreadsheet-Icon.TRASH",
|
|
29856
29895
|
};
|
|
@@ -30695,7 +30734,7 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
30695
30734
|
openContextMenu(ev) {
|
|
30696
30735
|
this.menuState.isOpen = true;
|
|
30697
30736
|
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
30698
|
-
this.menuState.menuItems = getChartMenuActions(this.props.figureUI.id,
|
|
30737
|
+
this.menuState.menuItems = getChartMenuActions(this.props.figureUI.id, this.env);
|
|
30699
30738
|
}
|
|
30700
30739
|
get fullScreenMenuItem() {
|
|
30701
30740
|
const definition = this.env.model.getters.getChartDefinition(this.props.figureUI.id);
|
|
@@ -30737,7 +30776,6 @@ class ChartFigure extends owl.Component {
|
|
|
30737
30776
|
static template = "o-spreadsheet-ChartFigure";
|
|
30738
30777
|
static props = {
|
|
30739
30778
|
figureUI: Object,
|
|
30740
|
-
onFigureDeleted: Function,
|
|
30741
30779
|
};
|
|
30742
30780
|
static components = { ChartDashboardMenu };
|
|
30743
30781
|
onDoubleClick() {
|
|
@@ -30761,7 +30799,6 @@ class ImageFigure extends owl.Component {
|
|
|
30761
30799
|
static template = "o-spreadsheet-ImageFigure";
|
|
30762
30800
|
static props = {
|
|
30763
30801
|
figureUI: Object,
|
|
30764
|
-
onFigureDeleted: Function,
|
|
30765
30802
|
};
|
|
30766
30803
|
static components = {};
|
|
30767
30804
|
// ---------------------------------------------------------------------------
|
|
@@ -30872,13 +30909,11 @@ class FigureComponent extends owl.Component {
|
|
|
30872
30909
|
static props = {
|
|
30873
30910
|
figureUI: Object,
|
|
30874
30911
|
style: { type: String, optional: true },
|
|
30875
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
30876
30912
|
onMouseDown: { type: Function, optional: true },
|
|
30877
30913
|
onClickAnchor: { type: Function, optional: true },
|
|
30878
30914
|
};
|
|
30879
30915
|
static components = { MenuPopover };
|
|
30880
30916
|
static defaultProps = {
|
|
30881
|
-
onFigureDeleted: () => { },
|
|
30882
30917
|
onMouseDown: () => { },
|
|
30883
30918
|
onClickAnchor: () => { },
|
|
30884
30919
|
};
|
|
@@ -30955,9 +30990,6 @@ class FigureComponent extends owl.Component {
|
|
|
30955
30990
|
this.props.figureUI.id,
|
|
30956
30991
|
this.figureRef.el,
|
|
30957
30992
|
]);
|
|
30958
|
-
owl.onWillUnmount(() => {
|
|
30959
|
-
this.props.onFigureDeleted();
|
|
30960
|
-
});
|
|
30961
30993
|
}
|
|
30962
30994
|
clickAnchor(dirX, dirY, ev) {
|
|
30963
30995
|
this.props.onClickAnchor(dirX, dirY, ev);
|
|
@@ -30981,7 +31013,6 @@ class FigureComponent extends owl.Component {
|
|
|
30981
31013
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
30982
31014
|
figureId: this.props.figureUI.id,
|
|
30983
31015
|
});
|
|
30984
|
-
this.props.onFigureDeleted();
|
|
30985
31016
|
ev.preventDefault();
|
|
30986
31017
|
ev.stopPropagation();
|
|
30987
31018
|
break;
|
|
@@ -31074,7 +31105,7 @@ class FigureComponent extends owl.Component {
|
|
|
31074
31105
|
this.menuState.anchorRect = anchorRect;
|
|
31075
31106
|
this.menuState.menuItems = figureRegistry
|
|
31076
31107
|
.get(this.props.figureUI.tag)
|
|
31077
|
-
.menuBuilder(this.props.figureUI.id, this.
|
|
31108
|
+
.menuBuilder(this.props.figureUI.id, this.env);
|
|
31078
31109
|
}
|
|
31079
31110
|
}
|
|
31080
31111
|
|
|
@@ -31439,7 +31470,7 @@ criterionEvaluatorRegistry.add("dateIs", {
|
|
|
31439
31470
|
return false;
|
|
31440
31471
|
}
|
|
31441
31472
|
if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
|
|
31442
|
-
const today =
|
|
31473
|
+
const today = Math.floor(jsDateToNumber(DateTime.now()));
|
|
31443
31474
|
return isDateBetween(dateValue, today, criterionValue);
|
|
31444
31475
|
}
|
|
31445
31476
|
return areDatesSameDay(dateValue, criterionValue);
|
|
@@ -32644,7 +32675,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32644
32675
|
}
|
|
32645
32676
|
this.selectionStart = start;
|
|
32646
32677
|
this.selectionEnd = end;
|
|
32647
|
-
this.
|
|
32678
|
+
this.stopComposerRangeSelection();
|
|
32648
32679
|
this.computeFormulaCursorContext();
|
|
32649
32680
|
this.computeParenthesisRelatedToCursor();
|
|
32650
32681
|
this.updateAutoCompleteProvider();
|
|
@@ -33549,7 +33580,8 @@ class Composer extends owl.Component {
|
|
|
33549
33580
|
assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
|
|
33550
33581
|
// render top
|
|
33551
33582
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
33552
|
-
assistantStyle.
|
|
33583
|
+
assistantStyle.top = `-3px`;
|
|
33584
|
+
assistantStyle.transform = `translate(0, -100%)`;
|
|
33553
33585
|
}
|
|
33554
33586
|
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
33555
33587
|
// render left
|
|
@@ -45240,7 +45272,6 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
|
|
|
45240
45272
|
}
|
|
45241
45273
|
get highlights() {
|
|
45242
45274
|
const position = this.model.getters.getActivePosition();
|
|
45243
|
-
const cell = this.getters.getEvaluatedCell(position);
|
|
45244
45275
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
45245
45276
|
const zone = spreader
|
|
45246
45277
|
? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
|
|
@@ -45248,10 +45279,11 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
|
|
|
45248
45279
|
if (!zone) {
|
|
45249
45280
|
return [];
|
|
45250
45281
|
}
|
|
45282
|
+
const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
|
|
45251
45283
|
return [
|
|
45252
45284
|
{
|
|
45253
45285
|
range: this.model.getters.getRangeFromZone(position.sheetId, zone),
|
|
45254
|
-
dashed:
|
|
45286
|
+
dashed: isArrayFormulaBlocked,
|
|
45255
45287
|
color: "#17A2B8",
|
|
45256
45288
|
noFill: true,
|
|
45257
45289
|
thinLine: true,
|
|
@@ -46349,9 +46381,7 @@ css /*SCSS*/ `
|
|
|
46349
46381
|
*/
|
|
46350
46382
|
class FiguresContainer extends owl.Component {
|
|
46351
46383
|
static template = "o-spreadsheet-FiguresContainer";
|
|
46352
|
-
static props = {
|
|
46353
|
-
onFigureDeleted: Function,
|
|
46354
|
-
};
|
|
46384
|
+
static props = {};
|
|
46355
46385
|
static components = { FigureComponent };
|
|
46356
46386
|
dnd = owl.useState({
|
|
46357
46387
|
draggedFigure: undefined,
|
|
@@ -46726,16 +46756,16 @@ css /* scss */ `
|
|
|
46726
46756
|
`;
|
|
46727
46757
|
class GridAddRowsFooter extends owl.Component {
|
|
46728
46758
|
static template = "o-spreadsheet-GridAddRowsFooter";
|
|
46729
|
-
static props = {
|
|
46730
|
-
focusGrid: Function,
|
|
46731
|
-
};
|
|
46759
|
+
static props = {};
|
|
46732
46760
|
static components = { ValidationMessages };
|
|
46761
|
+
DOMFocusableElementStore;
|
|
46733
46762
|
inputRef = owl.useRef("inputRef");
|
|
46734
46763
|
state = owl.useState({
|
|
46735
46764
|
inputValue: "100",
|
|
46736
46765
|
errorFlag: false,
|
|
46737
46766
|
});
|
|
46738
46767
|
setup() {
|
|
46768
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
46739
46769
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
46740
46770
|
}
|
|
46741
46771
|
get addRowsPosition() {
|
|
@@ -46753,7 +46783,7 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
46753
46783
|
}
|
|
46754
46784
|
onKeydown(ev) {
|
|
46755
46785
|
if (ev.key.toUpperCase() === "ESCAPE") {
|
|
46756
|
-
this.
|
|
46786
|
+
this.focusDefaultElement();
|
|
46757
46787
|
}
|
|
46758
46788
|
else if (ev.key.toUpperCase() === "ENTER") {
|
|
46759
46789
|
this.onConfirm();
|
|
@@ -46780,7 +46810,7 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
46780
46810
|
quantity,
|
|
46781
46811
|
dimension: "ROW",
|
|
46782
46812
|
});
|
|
46783
|
-
this.
|
|
46813
|
+
this.focusDefaultElement();
|
|
46784
46814
|
// After adding new rows, scroll down to the new last row
|
|
46785
46815
|
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
46786
46816
|
const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
|
|
@@ -46793,7 +46823,12 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
46793
46823
|
if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
|
|
46794
46824
|
return;
|
|
46795
46825
|
}
|
|
46796
|
-
this.
|
|
46826
|
+
this.focusDefaultElement();
|
|
46827
|
+
}
|
|
46828
|
+
focusDefaultElement() {
|
|
46829
|
+
if (document.activeElement === this.inputRef.el) {
|
|
46830
|
+
this.DOMFocusableElementStore.focus();
|
|
46831
|
+
}
|
|
46797
46832
|
}
|
|
46798
46833
|
}
|
|
46799
46834
|
|
|
@@ -47068,7 +47103,6 @@ class GridOverlay extends owl.Component {
|
|
|
47068
47103
|
onCellClicked: { type: Function, optional: true },
|
|
47069
47104
|
onCellRightClicked: { type: Function, optional: true },
|
|
47070
47105
|
onGridResized: { type: Function, optional: true },
|
|
47071
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
47072
47106
|
onGridMoved: Function,
|
|
47073
47107
|
gridOverlayDimensions: String,
|
|
47074
47108
|
slots: { type: Object, optional: true },
|
|
@@ -47083,7 +47117,6 @@ class GridOverlay extends owl.Component {
|
|
|
47083
47117
|
onCellClicked: () => { },
|
|
47084
47118
|
onCellRightClicked: () => { },
|
|
47085
47119
|
onGridResized: () => { },
|
|
47086
|
-
onFigureDeleted: () => { },
|
|
47087
47120
|
};
|
|
47088
47121
|
gridOverlay = owl.useRef("gridOverlay");
|
|
47089
47122
|
cellPopovers;
|
|
@@ -51942,7 +51975,7 @@ function useHighlights(highlightProvider) {
|
|
|
51942
51975
|
}
|
|
51943
51976
|
|
|
51944
51977
|
css /* scss */ `
|
|
51945
|
-
.o-cf-preview {
|
|
51978
|
+
.o-spreadsheet .o-cf-preview {
|
|
51946
51979
|
&.o-cf-cursor-ptr {
|
|
51947
51980
|
cursor: pointer;
|
|
51948
51981
|
}
|
|
@@ -51950,6 +51983,7 @@ css /* scss */ `
|
|
|
51950
51983
|
border-bottom: 1px solid ${GRAY_300};
|
|
51951
51984
|
height: 80px;
|
|
51952
51985
|
padding: 10px;
|
|
51986
|
+
box-sizing: border-box;
|
|
51953
51987
|
position: relative;
|
|
51954
51988
|
cursor: pointer;
|
|
51955
51989
|
&:hover,
|
|
@@ -51963,7 +51997,6 @@ css /* scss */ `
|
|
|
51963
51997
|
.o-cf-preview-icon {
|
|
51964
51998
|
border: 1px solid ${GRAY_300};
|
|
51965
51999
|
background-color: #fff;
|
|
51966
|
-
position: absolute;
|
|
51967
52000
|
height: 50px;
|
|
51968
52001
|
width: 50px;
|
|
51969
52002
|
.o-icon {
|
|
@@ -51972,12 +52005,6 @@ css /* scss */ `
|
|
|
51972
52005
|
}
|
|
51973
52006
|
}
|
|
51974
52007
|
.o-cf-preview-description {
|
|
51975
|
-
left: 65px;
|
|
51976
|
-
margin-bottom: auto;
|
|
51977
|
-
margin-right: 8px;
|
|
51978
|
-
margin-top: auto;
|
|
51979
|
-
position: relative;
|
|
51980
|
-
width: 142px;
|
|
51981
52008
|
.o-cf-preview-description-rule {
|
|
51982
52009
|
margin-bottom: 4px;
|
|
51983
52010
|
max-height: 2.8em;
|
|
@@ -51987,16 +52014,11 @@ css /* scss */ `
|
|
|
51987
52014
|
font-size: 12px;
|
|
51988
52015
|
}
|
|
51989
52016
|
}
|
|
51990
|
-
.o-cf-delete {
|
|
51991
|
-
left: 90%;
|
|
51992
|
-
top: 39%;
|
|
51993
|
-
position: absolute;
|
|
51994
|
-
}
|
|
51995
52017
|
&:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
|
|
51996
52018
|
display: none !important;
|
|
51997
52019
|
}
|
|
51998
52020
|
.o-cf-drag-handle {
|
|
51999
|
-
left:
|
|
52021
|
+
left: 2px;
|
|
52000
52022
|
cursor: move;
|
|
52001
52023
|
.o-icon {
|
|
52002
52024
|
width: 6px;
|
|
@@ -56041,12 +56063,41 @@ const dateGranularities = [
|
|
|
56041
56063
|
pivotRegistry.add("SPREADSHEET", {
|
|
56042
56064
|
ui: SpreadsheetPivot,
|
|
56043
56065
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
56044
|
-
externalData: false,
|
|
56045
56066
|
dateGranularities: [...dateGranularities],
|
|
56046
56067
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
56047
56068
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
56048
56069
|
isGroupable: () => true,
|
|
56070
|
+
adaptRanges: (getters, definition, applyChange) => {
|
|
56071
|
+
if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
|
|
56072
|
+
return definition;
|
|
56073
|
+
}
|
|
56074
|
+
const { sheetId, zone } = definition.dataSet;
|
|
56075
|
+
const range = getters.getRangeFromZone(sheetId, zone);
|
|
56076
|
+
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
56077
|
+
if (adaptedRange === range) {
|
|
56078
|
+
return definition;
|
|
56079
|
+
}
|
|
56080
|
+
const dataSet = adaptedRange && {
|
|
56081
|
+
sheetId: adaptedRange.sheetId,
|
|
56082
|
+
zone: adaptedRange.zone,
|
|
56083
|
+
};
|
|
56084
|
+
return { ...definition, dataSet };
|
|
56085
|
+
},
|
|
56049
56086
|
});
|
|
56087
|
+
function adaptPivotRange(range, applyChange) {
|
|
56088
|
+
if (!range) {
|
|
56089
|
+
return undefined;
|
|
56090
|
+
}
|
|
56091
|
+
const change = applyChange(range);
|
|
56092
|
+
switch (change.changeType) {
|
|
56093
|
+
case "NONE":
|
|
56094
|
+
return range;
|
|
56095
|
+
case "REMOVE":
|
|
56096
|
+
return undefined;
|
|
56097
|
+
default:
|
|
56098
|
+
return change.range;
|
|
56099
|
+
}
|
|
56100
|
+
}
|
|
56050
56101
|
|
|
56051
56102
|
class PivotSidePanelStore extends SpreadsheetStore {
|
|
56052
56103
|
pivotId;
|
|
@@ -62199,6 +62250,7 @@ function rangeToMerge(mergeId, range) {
|
|
|
62199
62250
|
class RangeAdapter {
|
|
62200
62251
|
getters;
|
|
62201
62252
|
providers = [];
|
|
62253
|
+
isAdaptingRanges = false;
|
|
62202
62254
|
constructor(getters) {
|
|
62203
62255
|
this.getters = getters;
|
|
62204
62256
|
}
|
|
@@ -62230,6 +62282,9 @@ class RangeAdapter {
|
|
|
62230
62282
|
}
|
|
62231
62283
|
beforeHandle(command) { }
|
|
62232
62284
|
handle(cmd) {
|
|
62285
|
+
if (this.isAdaptingRanges) {
|
|
62286
|
+
throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
|
|
62287
|
+
}
|
|
62233
62288
|
const rangeAdapter = getRangeAdapter(cmd);
|
|
62234
62289
|
if (rangeAdapter?.applyChange) {
|
|
62235
62290
|
this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
|
|
@@ -62252,10 +62307,12 @@ class RangeAdapter {
|
|
|
62252
62307
|
};
|
|
62253
62308
|
}
|
|
62254
62309
|
executeOnAllRanges(adaptRange, sheetId, sheetName) {
|
|
62310
|
+
this.isAdaptingRanges = true;
|
|
62255
62311
|
const func = this.verifyRangeRemoved(adaptRange);
|
|
62256
62312
|
for (const provider of this.providers) {
|
|
62257
62313
|
provider(func, sheetId, sheetName);
|
|
62258
62314
|
}
|
|
62315
|
+
this.isAdaptingRanges = false;
|
|
62259
62316
|
}
|
|
62260
62317
|
/**
|
|
62261
62318
|
* Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
|
|
@@ -64291,6 +64348,18 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64291
64348
|
}
|
|
64292
64349
|
}
|
|
64293
64350
|
adaptRanges(applyChange) {
|
|
64351
|
+
for (const pivotId in this.pivots) {
|
|
64352
|
+
const definition = deepCopy(this.pivots[pivotId]?.definition);
|
|
64353
|
+
if (!definition) {
|
|
64354
|
+
continue;
|
|
64355
|
+
}
|
|
64356
|
+
const newDefinition = pivotRegistry
|
|
64357
|
+
.get(definition.type)
|
|
64358
|
+
?.adaptRanges?.(this.getters, definition, applyChange);
|
|
64359
|
+
if (newDefinition && !deepEquals(definition, newDefinition)) {
|
|
64360
|
+
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
64361
|
+
}
|
|
64362
|
+
}
|
|
64294
64363
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
64295
64364
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
64296
64365
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -64542,20 +64611,6 @@ class SettingsPlugin extends CorePlugin {
|
|
|
64542
64611
|
}
|
|
64543
64612
|
}
|
|
64544
64613
|
|
|
64545
|
-
function adaptPivotRange(range, applyChange) {
|
|
64546
|
-
if (!range) {
|
|
64547
|
-
return undefined;
|
|
64548
|
-
}
|
|
64549
|
-
const change = applyChange(range);
|
|
64550
|
-
switch (change.changeType) {
|
|
64551
|
-
case "NONE":
|
|
64552
|
-
return range;
|
|
64553
|
-
case "REMOVE":
|
|
64554
|
-
return undefined;
|
|
64555
|
-
default:
|
|
64556
|
-
return change.range;
|
|
64557
|
-
}
|
|
64558
|
-
}
|
|
64559
64614
|
class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
64560
64615
|
allowDispatch(cmd) {
|
|
64561
64616
|
switch (cmd.type) {
|
|
@@ -64566,24 +64621,6 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
|
64566
64621
|
}
|
|
64567
64622
|
return "Success" /* CommandResult.Success */;
|
|
64568
64623
|
}
|
|
64569
|
-
adaptRanges(applyChange) {
|
|
64570
|
-
for (const pivotId of this.getters.getPivotIds()) {
|
|
64571
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
64572
|
-
if (definition.type !== "SPREADSHEET") {
|
|
64573
|
-
continue;
|
|
64574
|
-
}
|
|
64575
|
-
if (definition.dataSet) {
|
|
64576
|
-
const { sheetId, zone } = definition.dataSet;
|
|
64577
|
-
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
64578
|
-
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
64579
|
-
const dataSet = adaptedRange && {
|
|
64580
|
-
sheetId: adaptedRange.sheetId,
|
|
64581
|
-
zone: adaptedRange.zone,
|
|
64582
|
-
};
|
|
64583
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
|
|
64584
|
-
}
|
|
64585
|
-
}
|
|
64586
|
-
}
|
|
64587
64624
|
checkDataSetValidity(definition) {
|
|
64588
64625
|
if (definition.type === "SPREADSHEET" && definition.dataSet) {
|
|
64589
64626
|
const { zone, sheetId } = definition.dataSet;
|
|
@@ -65925,6 +65962,9 @@ class Evaluator {
|
|
|
65925
65962
|
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
|
|
65926
65963
|
return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
|
|
65927
65964
|
}
|
|
65965
|
+
isArrayFormulaSpillBlocked(position) {
|
|
65966
|
+
return this.blockedArrayFormulas.has(position);
|
|
65967
|
+
}
|
|
65928
65968
|
updateDependencies(position) {
|
|
65929
65969
|
// removing dependencies is slow because it requires
|
|
65930
65970
|
// to traverse the entire r-tree.
|
|
@@ -65936,13 +65976,8 @@ class Evaluator {
|
|
|
65936
65976
|
addDependencies(position, dependencies) {
|
|
65937
65977
|
this.formulaDependencies().addDependencies(position, dependencies);
|
|
65938
65978
|
for (const range of dependencies) {
|
|
65939
|
-
|
|
65940
|
-
|
|
65941
|
-
for (let col = left; col <= right; col++) {
|
|
65942
|
-
for (let row = top; row <= bottom; row++) {
|
|
65943
|
-
this.computeAndSave({ sheetId, col, row });
|
|
65944
|
-
}
|
|
65945
|
-
}
|
|
65979
|
+
// ensure that all ranges are computed
|
|
65980
|
+
this.compilationParams.ensureRange(range);
|
|
65946
65981
|
}
|
|
65947
65982
|
}
|
|
65948
65983
|
updateCompilationParameters() {
|
|
@@ -66145,6 +66180,10 @@ class Evaluator {
|
|
|
66145
66180
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
66146
66181
|
const nbColumns = formulaReturn.length;
|
|
66147
66182
|
const nbRows = formulaReturn[0].length;
|
|
66183
|
+
if (nbRows === 0) {
|
|
66184
|
+
// empty matrix
|
|
66185
|
+
return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
|
|
66186
|
+
}
|
|
66148
66187
|
const resultZone = {
|
|
66149
66188
|
top: formulaPosition.row,
|
|
66150
66189
|
bottom: formulaPosition.row + nbRows - 1,
|
|
@@ -66420,6 +66459,7 @@ class EvaluationPlugin extends CoreViewPlugin {
|
|
|
66420
66459
|
"getEvaluatedCellsPositions",
|
|
66421
66460
|
"getSpreadZone",
|
|
66422
66461
|
"getArrayFormulaSpreadingOn",
|
|
66462
|
+
"isArrayFormulaSpillBlocked",
|
|
66423
66463
|
"isEmpty",
|
|
66424
66464
|
];
|
|
66425
66465
|
shouldRebuildDependenciesGraph = true;
|
|
@@ -66532,6 +66572,9 @@ class EvaluationPlugin extends CoreViewPlugin {
|
|
|
66532
66572
|
getArrayFormulaSpreadingOn(position) {
|
|
66533
66573
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
66534
66574
|
}
|
|
66575
|
+
isArrayFormulaSpillBlocked(position) {
|
|
66576
|
+
return this.evaluator.isArrayFormulaSpillBlocked(position);
|
|
66577
|
+
}
|
|
66535
66578
|
/**
|
|
66536
66579
|
* Check if a zone only contains empty cells
|
|
66537
66580
|
*/
|
|
@@ -68581,9 +68624,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68581
68624
|
handle(cmd) {
|
|
68582
68625
|
if (invalidateEvaluationCommands.has(cmd.type)) {
|
|
68583
68626
|
for (const pivotId of this.getters.getPivotIds()) {
|
|
68584
|
-
|
|
68585
|
-
this.setupPivot(pivotId, { recreate: true });
|
|
68586
|
-
}
|
|
68627
|
+
this.setupPivot(pivotId, { recreate: true });
|
|
68587
68628
|
}
|
|
68588
68629
|
}
|
|
68589
68630
|
switch (cmd.type) {
|
|
@@ -68791,7 +68832,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68791
68832
|
pivot.init({ reload: true });
|
|
68792
68833
|
}
|
|
68793
68834
|
setupPivot(pivotId, { recreate } = { recreate: false }) {
|
|
68794
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
68835
|
+
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
68795
68836
|
if (!(pivotId in this.pivots)) {
|
|
68796
68837
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
68797
68838
|
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
@@ -78044,16 +78085,18 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
78044
78085
|
get clickableCells() {
|
|
78045
78086
|
const cells = [];
|
|
78046
78087
|
const getters = this.getters;
|
|
78047
|
-
const sheetId = getters.getActiveSheetId();
|
|
78048
78088
|
for (const position of this.getters.getVisibleCellPositions()) {
|
|
78049
78089
|
const item = this.getClickableItem(position);
|
|
78050
78090
|
if (!item) {
|
|
78051
78091
|
continue;
|
|
78052
78092
|
}
|
|
78053
78093
|
const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
|
|
78054
|
-
const
|
|
78094
|
+
const rect = this.getClickableCellRect(position);
|
|
78095
|
+
if (!rect) {
|
|
78096
|
+
continue;
|
|
78097
|
+
}
|
|
78055
78098
|
cells.push({
|
|
78056
|
-
coordinates:
|
|
78099
|
+
coordinates: rect,
|
|
78057
78100
|
position,
|
|
78058
78101
|
action: item.execute,
|
|
78059
78102
|
title: title || "",
|
|
@@ -78061,6 +78104,31 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
78061
78104
|
}
|
|
78062
78105
|
return cells;
|
|
78063
78106
|
}
|
|
78107
|
+
getClickableCellRect(position) {
|
|
78108
|
+
const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
|
|
78109
|
+
const clickableRect = this.getters.getVisibleRect(zone);
|
|
78110
|
+
const icons = this.getters.getCellIcons(position);
|
|
78111
|
+
const iconsAtPosition = {
|
|
78112
|
+
center: icons.find((icon) => icon.horizontalAlign === "center"),
|
|
78113
|
+
left: icons.find((icon) => icon.horizontalAlign === "left"),
|
|
78114
|
+
right: icons.find((icon) => icon.horizontalAlign === "right"),
|
|
78115
|
+
};
|
|
78116
|
+
if (iconsAtPosition.center?.onClick) {
|
|
78117
|
+
return undefined;
|
|
78118
|
+
}
|
|
78119
|
+
if (iconsAtPosition.right?.onClick) {
|
|
78120
|
+
const cellRect = this.getters.getRect(zone);
|
|
78121
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
|
|
78122
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
|
|
78123
|
+
}
|
|
78124
|
+
if (iconsAtPosition.left?.onClick) {
|
|
78125
|
+
const cellRect = this.getters.getRect(zone);
|
|
78126
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
|
|
78127
|
+
clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
|
|
78128
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
|
|
78129
|
+
}
|
|
78130
|
+
return clickableRect;
|
|
78131
|
+
}
|
|
78064
78132
|
}
|
|
78065
78133
|
|
|
78066
78134
|
css /* scss */ `
|
|
@@ -78817,7 +78885,7 @@ class SmallBottomBar extends owl.Component {
|
|
|
78817
78885
|
height: this.focus === "inactive" ? "26px" : "fit-content",
|
|
78818
78886
|
"max-height": `130px`,
|
|
78819
78887
|
}),
|
|
78820
|
-
showAssistant:
|
|
78888
|
+
showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
|
|
78821
78889
|
placeholder: this.composerStore.placeholder,
|
|
78822
78890
|
};
|
|
78823
78891
|
}
|
|
@@ -80309,7 +80377,7 @@ class Spreadsheet extends owl.Component {
|
|
|
80309
80377
|
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
80310
80378
|
this.focusGrid();
|
|
80311
80379
|
}
|
|
80312
|
-
}
|
|
80380
|
+
});
|
|
80313
80381
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
80314
80382
|
// For some reason, the wheel event is not properly registered inside templates
|
|
80315
80383
|
// in Chromium-based browsers based on chromium 125
|
|
@@ -84950,6 +85018,6 @@ exports.tokenColors = tokenColors;
|
|
|
84950
85018
|
exports.tokenize = tokenize;
|
|
84951
85019
|
|
|
84952
85020
|
|
|
84953
|
-
__info__.version = "18.4.
|
|
84954
|
-
__info__.date = "2025-
|
|
84955
|
-
__info__.hash = "
|
|
85021
|
+
__info__.version = "18.4.22";
|
|
85022
|
+
__info__.date = "2025-12-26T10:19:07.786Z";
|
|
85023
|
+
__info__.hash = "6ddac00";
|