@odoo/o-spreadsheet 18.2.6 → 18.2.8
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 +257 -136
- package/dist/o-spreadsheet.d.ts +33 -16
- package/dist/o-spreadsheet.esm.js +257 -136
- package/dist/o-spreadsheet.iife.js +257 -136
- package/dist/o-spreadsheet.iife.min.js +378 -377
- package/dist/o_spreadsheet.xml +38 -36
- 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 18.2.
|
|
6
|
-
* @date 2025-04-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.8
|
|
6
|
+
* @date 2025-04-18T16:26:20.673Z
|
|
7
|
+
* @hash 5da9ddc
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3575,6 +3575,7 @@ const coreTypes = new Set([
|
|
|
3575
3575
|
"CLEAR_FORMATTING",
|
|
3576
3576
|
"SET_BORDER",
|
|
3577
3577
|
"SET_ZONE_BORDERS",
|
|
3578
|
+
"SET_BORDERS_ON_TARGET",
|
|
3578
3579
|
/** CHART */
|
|
3579
3580
|
"CREATE_CHART",
|
|
3580
3581
|
"UPDATE_CHART",
|
|
@@ -6724,6 +6725,7 @@ class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
|
6724
6725
|
}
|
|
6725
6726
|
|
|
6726
6727
|
class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
6728
|
+
queuedBordersToAdd = {};
|
|
6727
6729
|
copy(data) {
|
|
6728
6730
|
const sheetId = data.sheetId;
|
|
6729
6731
|
if (data.zones.length === 0) {
|
|
@@ -6754,6 +6756,7 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6754
6756
|
const { left, top } = zones[0];
|
|
6755
6757
|
this.pasteZone(sheetId, left, top, content.borders);
|
|
6756
6758
|
}
|
|
6759
|
+
this.executeQueuedChanges(sheetId);
|
|
6757
6760
|
}
|
|
6758
6761
|
pasteZone(sheetId, col, row, borders) {
|
|
6759
6762
|
for (const [r, rowBorders] of borders.entries()) {
|
|
@@ -6772,7 +6775,20 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6772
6775
|
...targetBorders,
|
|
6773
6776
|
...originBorders,
|
|
6774
6777
|
};
|
|
6775
|
-
|
|
6778
|
+
const borderKey = JSON.stringify(border);
|
|
6779
|
+
if (!this.queuedBordersToAdd[borderKey]) {
|
|
6780
|
+
this.queuedBordersToAdd[borderKey] = [];
|
|
6781
|
+
}
|
|
6782
|
+
this.queuedBordersToAdd[borderKey].push(positionToZone(target));
|
|
6783
|
+
}
|
|
6784
|
+
executeQueuedChanges(pasteSheetTarget) {
|
|
6785
|
+
for (const borderKey in this.queuedBordersToAdd) {
|
|
6786
|
+
const zones = this.queuedBordersToAdd[borderKey];
|
|
6787
|
+
const border = JSON.parse(borderKey);
|
|
6788
|
+
const target = recomputeZones(zones, []);
|
|
6789
|
+
this.dispatch("SET_BORDERS_ON_TARGET", { sheetId: pasteSheetTarget, target, border });
|
|
6790
|
+
}
|
|
6791
|
+
this.queuedBordersToAdd = {};
|
|
6776
6792
|
}
|
|
6777
6793
|
}
|
|
6778
6794
|
|
|
@@ -6884,6 +6900,12 @@ function tokenizeString(chars) {
|
|
|
6884
6900
|
}
|
|
6885
6901
|
return null;
|
|
6886
6902
|
}
|
|
6903
|
+
/**
|
|
6904
|
+
- \p{L} is for any letter (from any language)
|
|
6905
|
+
- \p{N} is for any number
|
|
6906
|
+
- the u flag at the end is for unicode, which enables the `\p{...}` syntax
|
|
6907
|
+
*/
|
|
6908
|
+
const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
|
|
6887
6909
|
const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
|
|
6888
6910
|
/**
|
|
6889
6911
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
@@ -6924,7 +6946,8 @@ function tokenizeSymbol(chars) {
|
|
|
6924
6946
|
};
|
|
6925
6947
|
}
|
|
6926
6948
|
}
|
|
6927
|
-
while (chars.current &&
|
|
6949
|
+
while (chars.current &&
|
|
6950
|
+
(SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
|
|
6928
6951
|
result += chars.shift();
|
|
6929
6952
|
}
|
|
6930
6953
|
if (result.length) {
|
|
@@ -8712,12 +8735,13 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8712
8735
|
}
|
|
8713
8736
|
pasteCf(origin, target, isCutOperation) {
|
|
8714
8737
|
if (origin?.rules && origin.rules.length > 0) {
|
|
8738
|
+
const originZone = positionToZone(origin.position);
|
|
8715
8739
|
const zone = positionToZone(target);
|
|
8716
8740
|
for (const rule of origin.rules) {
|
|
8717
8741
|
const toRemoveZones = [];
|
|
8718
8742
|
if (isCutOperation) {
|
|
8719
8743
|
//remove from current rule
|
|
8720
|
-
toRemoveZones.push(
|
|
8744
|
+
toRemoveZones.push(originZone);
|
|
8721
8745
|
}
|
|
8722
8746
|
if (origin.position.sheetId === target.sheetId) {
|
|
8723
8747
|
this.adaptCFRules(origin.position.sheetId, rule, [zone], toRemoveZones);
|
|
@@ -8831,6 +8855,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8831
8855
|
pasteDataValidation(origin, target, isCutOperation) {
|
|
8832
8856
|
if (origin) {
|
|
8833
8857
|
const zone = positionToZone(target);
|
|
8858
|
+
const originZone = positionToZone(origin.position);
|
|
8834
8859
|
const rule = origin.rule;
|
|
8835
8860
|
if (!rule) {
|
|
8836
8861
|
const targetRule = this.getters.getValidationRuleForCell(target);
|
|
@@ -8842,7 +8867,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8842
8867
|
}
|
|
8843
8868
|
const toRemoveZone = [];
|
|
8844
8869
|
if (isCutOperation) {
|
|
8845
|
-
toRemoveZone.push(
|
|
8870
|
+
toRemoveZone.push(originZone);
|
|
8846
8871
|
}
|
|
8847
8872
|
if (origin.position.sheetId === target.sheetId) {
|
|
8848
8873
|
const copyToRule = this.getDataValidationRuleToCopyTo(target.sheetId, rule, false);
|
|
@@ -8902,7 +8927,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8902
8927
|
continue;
|
|
8903
8928
|
}
|
|
8904
8929
|
this.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
8905
|
-
rule: dv,
|
|
8930
|
+
rule: { id: dv.id, criterion: dv.criterion, isBlocking: dv.isBlocking },
|
|
8906
8931
|
ranges: newDvZones.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
|
|
8907
8932
|
sheetId,
|
|
8908
8933
|
});
|
|
@@ -9229,7 +9254,7 @@ function transformZone(zone, executed) {
|
|
|
9229
9254
|
if (executed.type === "ADD_COLUMNS_ROWS") {
|
|
9230
9255
|
return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
|
|
9231
9256
|
}
|
|
9232
|
-
return
|
|
9257
|
+
return zone;
|
|
9233
9258
|
}
|
|
9234
9259
|
function transformRangeData(range, executed) {
|
|
9235
9260
|
const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
|
|
@@ -33620,6 +33645,12 @@ function isMacOS() {
|
|
|
33620
33645
|
function isCtrlKey(ev) {
|
|
33621
33646
|
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
33622
33647
|
}
|
|
33648
|
+
/**
|
|
33649
|
+
* Detects if the current browser is Firefox
|
|
33650
|
+
*/
|
|
33651
|
+
function isBrowserFirefox() {
|
|
33652
|
+
return /Firefox/i.test(navigator.userAgent);
|
|
33653
|
+
}
|
|
33623
33654
|
|
|
33624
33655
|
/**
|
|
33625
33656
|
* Repeatedly calls a callback function with a time delay between calls.
|
|
@@ -50415,39 +50446,6 @@ function useCellHovered(env, gridRef, callback) {
|
|
|
50415
50446
|
}
|
|
50416
50447
|
return hoveredPosition;
|
|
50417
50448
|
}
|
|
50418
|
-
function useTouchMove(gridRef, handler, canMoveUp) {
|
|
50419
|
-
let x = null;
|
|
50420
|
-
let y = null;
|
|
50421
|
-
function onTouchStart(ev) {
|
|
50422
|
-
if (ev.touches.length !== 1)
|
|
50423
|
-
return;
|
|
50424
|
-
x = ev.touches[0].clientX;
|
|
50425
|
-
y = ev.touches[0].clientY;
|
|
50426
|
-
}
|
|
50427
|
-
function onTouchEnd() {
|
|
50428
|
-
x = null;
|
|
50429
|
-
y = null;
|
|
50430
|
-
}
|
|
50431
|
-
function onTouchMove(ev) {
|
|
50432
|
-
if (ev.touches.length !== 1)
|
|
50433
|
-
return;
|
|
50434
|
-
// On mobile browsers, swiping down is often associated with "pull to refresh".
|
|
50435
|
-
// We only want this behavior if the grid is already at the top.
|
|
50436
|
-
// Otherwise we only want to move the canvas up, without triggering any refresh.
|
|
50437
|
-
if (canMoveUp()) {
|
|
50438
|
-
ev.preventDefault();
|
|
50439
|
-
ev.stopPropagation();
|
|
50440
|
-
}
|
|
50441
|
-
const currentX = ev.touches[0].clientX;
|
|
50442
|
-
const currentY = ev.touches[0].clientY;
|
|
50443
|
-
handler(x - currentX, y - currentY);
|
|
50444
|
-
x = currentX;
|
|
50445
|
-
y = currentY;
|
|
50446
|
-
}
|
|
50447
|
-
useRefListener(gridRef, "touchstart", onTouchStart);
|
|
50448
|
-
useRefListener(gridRef, "touchend", onTouchEnd);
|
|
50449
|
-
useRefListener(gridRef, "touchmove", onTouchMove);
|
|
50450
|
-
}
|
|
50451
50449
|
class GridOverlay extends owl.Component {
|
|
50452
50450
|
static template = "o-spreadsheet-GridOverlay";
|
|
50453
50451
|
static props = {
|
|
@@ -50495,10 +50493,6 @@ class GridOverlay extends owl.Component {
|
|
|
50495
50493
|
owl.onWillUnmount(() => {
|
|
50496
50494
|
resizeObserver.disconnect();
|
|
50497
50495
|
});
|
|
50498
|
-
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
50499
|
-
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50500
|
-
return scrollY > 0;
|
|
50501
|
-
});
|
|
50502
50496
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
50503
50497
|
this.paintFormatStore = useStore(PaintFormatStore);
|
|
50504
50498
|
}
|
|
@@ -51970,6 +51964,73 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51970
51964
|
}
|
|
51971
51965
|
}
|
|
51972
51966
|
|
|
51967
|
+
const friction = 0.95;
|
|
51968
|
+
const verticalScrollFactor = 1;
|
|
51969
|
+
const horizontalScrollFactor = 1;
|
|
51970
|
+
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
51971
|
+
let lastX = 0;
|
|
51972
|
+
let lastY = 0;
|
|
51973
|
+
let velocityX = 0;
|
|
51974
|
+
let velocityY = 0;
|
|
51975
|
+
let isMouseDown = false;
|
|
51976
|
+
let lastTime = 0;
|
|
51977
|
+
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
51978
|
+
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
51979
|
+
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
51980
|
+
function onTouchStart(event) {
|
|
51981
|
+
isMouseDown = true;
|
|
51982
|
+
({ clientX: lastX, clientY: lastY } = event.touches[0]);
|
|
51983
|
+
velocityX = 0;
|
|
51984
|
+
velocityY = 0;
|
|
51985
|
+
}
|
|
51986
|
+
function onTouchMove(event) {
|
|
51987
|
+
if (!isMouseDown)
|
|
51988
|
+
return;
|
|
51989
|
+
const currentTime = Date.now();
|
|
51990
|
+
const { clientX, clientY } = event.touches[0];
|
|
51991
|
+
let deltaX = lastX - clientX;
|
|
51992
|
+
let deltaY = lastY - clientY;
|
|
51993
|
+
const elapsedTime = currentTime - lastTime;
|
|
51994
|
+
velocityX = deltaX / elapsedTime;
|
|
51995
|
+
velocityY = deltaY / elapsedTime;
|
|
51996
|
+
lastX = clientX;
|
|
51997
|
+
lastY = clientY;
|
|
51998
|
+
lastTime = currentTime;
|
|
51999
|
+
if (canMoveUp()) {
|
|
52000
|
+
if (event.cancelable) {
|
|
52001
|
+
event.preventDefault();
|
|
52002
|
+
}
|
|
52003
|
+
event.stopPropagation();
|
|
52004
|
+
}
|
|
52005
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52006
|
+
}
|
|
52007
|
+
function onTouchEnd(ev) {
|
|
52008
|
+
isMouseDown = false;
|
|
52009
|
+
lastX = lastY = 0;
|
|
52010
|
+
requestAnimationFrame(scroll);
|
|
52011
|
+
}
|
|
52012
|
+
function scroll() {
|
|
52013
|
+
if (Math.abs(velocityX) < 0.05) {
|
|
52014
|
+
velocityX = 0;
|
|
52015
|
+
}
|
|
52016
|
+
if (Math.abs(velocityY) < 0.05) {
|
|
52017
|
+
velocityY = 0;
|
|
52018
|
+
}
|
|
52019
|
+
if (!velocityX && !velocityY) {
|
|
52020
|
+
return;
|
|
52021
|
+
}
|
|
52022
|
+
const currentTime = Date.now();
|
|
52023
|
+
const elapsedTime = Math.abs(currentTime - lastTime);
|
|
52024
|
+
const deltaX = velocityX * elapsedTime;
|
|
52025
|
+
const deltaY = velocityY * elapsedTime;
|
|
52026
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52027
|
+
lastTime = currentTime;
|
|
52028
|
+
velocityX *= friction;
|
|
52029
|
+
velocityY *= friction;
|
|
52030
|
+
requestAnimationFrame(scroll);
|
|
52031
|
+
}
|
|
52032
|
+
}
|
|
52033
|
+
|
|
51973
52034
|
function useWheelHandler(handler) {
|
|
51974
52035
|
function normalize(val, deltaMode) {
|
|
51975
52036
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
@@ -52310,7 +52371,7 @@ class HorizontalScrollBar extends owl.Component {
|
|
|
52310
52371
|
left: `${this.props.leftOffset + x}px`,
|
|
52311
52372
|
bottom: "0px",
|
|
52312
52373
|
height: `${SCROLLBAR_WIDTH}px`,
|
|
52313
|
-
right: `
|
|
52374
|
+
right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52314
52375
|
};
|
|
52315
52376
|
}
|
|
52316
52377
|
onScroll(offset) {
|
|
@@ -52355,7 +52416,7 @@ class VerticalScrollBar extends owl.Component {
|
|
|
52355
52416
|
top: `${this.props.topOffset + y}px`,
|
|
52356
52417
|
right: "0px",
|
|
52357
52418
|
width: `${SCROLLBAR_WIDTH}px`,
|
|
52358
|
-
bottom: `
|
|
52419
|
+
bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52359
52420
|
};
|
|
52360
52421
|
}
|
|
52361
52422
|
onScroll(offset) {
|
|
@@ -52591,6 +52652,10 @@ class Grid extends owl.Component {
|
|
|
52591
52652
|
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
52592
52653
|
}
|
|
52593
52654
|
}, () => [this.sidePanel.isOpen]);
|
|
52655
|
+
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
52656
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
52657
|
+
return scrollY > 0;
|
|
52658
|
+
});
|
|
52594
52659
|
}
|
|
52595
52660
|
onCellHovered({ col, row }) {
|
|
52596
52661
|
this.hoveredCell.hover({ col, row });
|
|
@@ -53313,6 +53378,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
53313
53378
|
case "SET_BORDER":
|
|
53314
53379
|
this.setBorder(cmd.sheetId, cmd.col, cmd.row, cmd.border);
|
|
53315
53380
|
break;
|
|
53381
|
+
case "SET_BORDERS_ON_TARGET":
|
|
53382
|
+
for (const zone of cmd.target) {
|
|
53383
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53384
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
53385
|
+
this.setBorder(cmd.sheetId, col, row, cmd.border);
|
|
53386
|
+
}
|
|
53387
|
+
}
|
|
53388
|
+
}
|
|
53389
|
+
break;
|
|
53316
53390
|
case "SET_ZONE_BORDERS":
|
|
53317
53391
|
if (cmd.border) {
|
|
53318
53392
|
const target = cmd.target.map((zone) => this.getters.expandZone(cmd.sheetId, zone));
|
|
@@ -63075,25 +63149,6 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63075
63149
|
case "AUTOFILL_AUTO":
|
|
63076
63150
|
this.autofillAuto();
|
|
63077
63151
|
break;
|
|
63078
|
-
case "AUTOFILL_CELL":
|
|
63079
|
-
this.autoFillMerge(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
|
|
63080
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
63081
|
-
this.dispatch("UPDATE_CELL", {
|
|
63082
|
-
sheetId,
|
|
63083
|
-
col: cmd.col,
|
|
63084
|
-
row: cmd.row,
|
|
63085
|
-
style: cmd.style || null,
|
|
63086
|
-
content: cmd.content || "",
|
|
63087
|
-
format: cmd.format || "",
|
|
63088
|
-
});
|
|
63089
|
-
this.dispatch("SET_BORDER", {
|
|
63090
|
-
sheetId,
|
|
63091
|
-
col: cmd.col,
|
|
63092
|
-
row: cmd.row,
|
|
63093
|
-
border: cmd.border,
|
|
63094
|
-
});
|
|
63095
|
-
this.autofillCF(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
|
|
63096
|
-
this.autofillDV(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
|
|
63097
63152
|
}
|
|
63098
63153
|
}
|
|
63099
63154
|
// ---------------------------------------------------------------------------
|
|
@@ -63117,6 +63172,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63117
63172
|
}
|
|
63118
63173
|
const source = this.getters.getSelectedZone();
|
|
63119
63174
|
const target = this.autofillZone;
|
|
63175
|
+
const autofillCellsData = [];
|
|
63120
63176
|
switch (this.direction) {
|
|
63121
63177
|
case "down" /* DIRECTION.DOWN */:
|
|
63122
63178
|
for (let col = source.left; col <= source.right; col++) {
|
|
@@ -63126,7 +63182,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63126
63182
|
}
|
|
63127
63183
|
const generator = this.createGenerator(xcs);
|
|
63128
63184
|
for (let row = target.top; row <= target.bottom; row++) {
|
|
63129
|
-
this.computeNewCell(generator, col, row
|
|
63185
|
+
autofillCellsData.push(this.computeNewCell(generator, col, row));
|
|
63130
63186
|
}
|
|
63131
63187
|
}
|
|
63132
63188
|
break;
|
|
@@ -63138,7 +63194,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63138
63194
|
}
|
|
63139
63195
|
const generator = this.createGenerator(xcs);
|
|
63140
63196
|
for (let row = target.bottom; row >= target.top; row--) {
|
|
63141
|
-
this.computeNewCell(generator, col, row
|
|
63197
|
+
autofillCellsData.push(this.computeNewCell(generator, col, row));
|
|
63142
63198
|
}
|
|
63143
63199
|
}
|
|
63144
63200
|
break;
|
|
@@ -63150,7 +63206,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63150
63206
|
}
|
|
63151
63207
|
const generator = this.createGenerator(xcs);
|
|
63152
63208
|
for (let col = target.right; col >= target.left; col--) {
|
|
63153
|
-
this.computeNewCell(generator, col, row
|
|
63209
|
+
autofillCellsData.push(this.computeNewCell(generator, col, row));
|
|
63154
63210
|
}
|
|
63155
63211
|
}
|
|
63156
63212
|
break;
|
|
@@ -63162,12 +63218,26 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63162
63218
|
}
|
|
63163
63219
|
const generator = this.createGenerator(xcs);
|
|
63164
63220
|
for (let col = target.left; col <= target.right; col++) {
|
|
63165
|
-
this.computeNewCell(generator, col, row
|
|
63221
|
+
autofillCellsData.push(this.computeNewCell(generator, col, row));
|
|
63166
63222
|
}
|
|
63167
63223
|
}
|
|
63168
63224
|
break;
|
|
63169
63225
|
}
|
|
63170
63226
|
if (apply) {
|
|
63227
|
+
const bordersZones = {};
|
|
63228
|
+
const cfNewRanges = {};
|
|
63229
|
+
const dvNewZones = {};
|
|
63230
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
63231
|
+
for (const data of autofillCellsData) {
|
|
63232
|
+
this.collectBordersData(data, bordersZones);
|
|
63233
|
+
this.autofillMerge(sheetId, data);
|
|
63234
|
+
this.autofillCell(sheetId, data);
|
|
63235
|
+
this.collectConditionalFormatsData(sheetId, data, cfNewRanges);
|
|
63236
|
+
this.collectDataValidationsData(sheetId, data, dvNewZones);
|
|
63237
|
+
}
|
|
63238
|
+
this.autofillBorders(sheetId, bordersZones);
|
|
63239
|
+
this.autofillConditionalFormats(sheetId, cfNewRanges);
|
|
63240
|
+
this.autofillDataValidations(sheetId, dvNewZones);
|
|
63171
63241
|
this.autofillZone = undefined;
|
|
63172
63242
|
this.selection.resizeAnchorZone(this.direction, this.steps);
|
|
63173
63243
|
this.lastCellSelected = {};
|
|
@@ -63176,6 +63246,95 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63176
63246
|
this.tooltip = undefined;
|
|
63177
63247
|
}
|
|
63178
63248
|
}
|
|
63249
|
+
collectBordersData(data, bordersPositions) {
|
|
63250
|
+
const key = JSON.stringify(data.border);
|
|
63251
|
+
if (!(key in bordersPositions)) {
|
|
63252
|
+
bordersPositions[key] = [];
|
|
63253
|
+
}
|
|
63254
|
+
bordersPositions[key].push(positionToZone({ col: data.col, row: data.row }));
|
|
63255
|
+
}
|
|
63256
|
+
collectConditionalFormatsData(sheetId, data, cfNewRanges) {
|
|
63257
|
+
const { originCol, originRow, col, row } = data;
|
|
63258
|
+
const cfsAtOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
|
|
63259
|
+
const xc = toXC(col, row);
|
|
63260
|
+
for (const cf of cfsAtOrigin) {
|
|
63261
|
+
if (!(cf.id in cfNewRanges)) {
|
|
63262
|
+
cfNewRanges[cf.id] = [];
|
|
63263
|
+
}
|
|
63264
|
+
cfNewRanges[cf.id].push(xc);
|
|
63265
|
+
}
|
|
63266
|
+
}
|
|
63267
|
+
collectDataValidationsData(sheetId, data, dvNewZones) {
|
|
63268
|
+
const { originCol, originRow, col, row } = data;
|
|
63269
|
+
const cellPosition = { sheetId, col: originCol, row: originRow };
|
|
63270
|
+
const dvsAtOrigin = this.getters.getValidationRuleForCell(cellPosition);
|
|
63271
|
+
if (!dvsAtOrigin) {
|
|
63272
|
+
return;
|
|
63273
|
+
}
|
|
63274
|
+
if (!(dvsAtOrigin.id in dvNewZones)) {
|
|
63275
|
+
dvNewZones[dvsAtOrigin.id] = [];
|
|
63276
|
+
}
|
|
63277
|
+
dvNewZones[dvsAtOrigin.id].push(positionToZone({ col, row }));
|
|
63278
|
+
}
|
|
63279
|
+
autofillCell(sheetId, data) {
|
|
63280
|
+
this.dispatch("UPDATE_CELL", {
|
|
63281
|
+
sheetId,
|
|
63282
|
+
col: data.col,
|
|
63283
|
+
row: data.row,
|
|
63284
|
+
content: data.content || "",
|
|
63285
|
+
style: data.style || null,
|
|
63286
|
+
format: data.format || "",
|
|
63287
|
+
});
|
|
63288
|
+
// Still usefull in odoo ATM to autofill field sync
|
|
63289
|
+
this.dispatch("AUTOFILL_CELL", data);
|
|
63290
|
+
}
|
|
63291
|
+
autofillBorders(sheetId, bordersPositions) {
|
|
63292
|
+
for (const stringifiedBorder in bordersPositions) {
|
|
63293
|
+
const border = stringifiedBorder === "undefined" ? undefined : JSON.parse(stringifiedBorder);
|
|
63294
|
+
this.dispatch("SET_BORDERS_ON_TARGET", {
|
|
63295
|
+
sheetId,
|
|
63296
|
+
border,
|
|
63297
|
+
target: recomputeZones(bordersPositions[stringifiedBorder]),
|
|
63298
|
+
});
|
|
63299
|
+
}
|
|
63300
|
+
}
|
|
63301
|
+
autofillConditionalFormats(sheetId, cfNewRanges) {
|
|
63302
|
+
for (const cfId in cfNewRanges) {
|
|
63303
|
+
const changes = cfNewRanges[cfId];
|
|
63304
|
+
const cf = this.getters.getConditionalFormats(sheetId).find((cf) => cf.id === cfId);
|
|
63305
|
+
if (!cf) {
|
|
63306
|
+
continue;
|
|
63307
|
+
}
|
|
63308
|
+
const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, changes.map(toZone), []);
|
|
63309
|
+
if (newCfRanges) {
|
|
63310
|
+
this.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
63311
|
+
cf: {
|
|
63312
|
+
id: cf.id,
|
|
63313
|
+
rule: cf.rule,
|
|
63314
|
+
stopIfTrue: cf.stopIfTrue,
|
|
63315
|
+
},
|
|
63316
|
+
ranges: newCfRanges,
|
|
63317
|
+
sheetId,
|
|
63318
|
+
});
|
|
63319
|
+
}
|
|
63320
|
+
}
|
|
63321
|
+
}
|
|
63322
|
+
autofillDataValidations(sheetId, dvNewZones) {
|
|
63323
|
+
for (const dvId in dvNewZones) {
|
|
63324
|
+
const changes = dvNewZones[dvId];
|
|
63325
|
+
const dvOrigin = this.getters.getDataValidationRule(sheetId, dvId);
|
|
63326
|
+
if (!dvOrigin) {
|
|
63327
|
+
continue;
|
|
63328
|
+
}
|
|
63329
|
+
const dvRangesXcs = dvOrigin.ranges.map((range) => range.zone);
|
|
63330
|
+
const newDvRanges = recomputeZones(dvRangesXcs.concat(changes), []);
|
|
63331
|
+
this.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
63332
|
+
rule: dvOrigin,
|
|
63333
|
+
ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
|
|
63334
|
+
sheetId,
|
|
63335
|
+
});
|
|
63336
|
+
}
|
|
63337
|
+
}
|
|
63179
63338
|
/**
|
|
63180
63339
|
* Select a cell which becomes the last cell of the autofillZone
|
|
63181
63340
|
*/
|
|
@@ -63254,22 +63413,20 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63254
63413
|
/**
|
|
63255
63414
|
* Generate the next cell
|
|
63256
63415
|
*/
|
|
63257
|
-
computeNewCell(generator, col, row
|
|
63416
|
+
computeNewCell(generator, col, row) {
|
|
63258
63417
|
const { cellData, tooltip, origin } = generator.next();
|
|
63259
63418
|
const { content, style, border, format } = cellData;
|
|
63260
63419
|
this.tooltip = tooltip;
|
|
63261
|
-
|
|
63262
|
-
|
|
63263
|
-
|
|
63264
|
-
|
|
63265
|
-
|
|
63266
|
-
|
|
63267
|
-
|
|
63268
|
-
|
|
63269
|
-
|
|
63270
|
-
|
|
63271
|
-
});
|
|
63272
|
-
}
|
|
63420
|
+
return {
|
|
63421
|
+
originCol: origin.col,
|
|
63422
|
+
originRow: origin.row,
|
|
63423
|
+
col,
|
|
63424
|
+
row,
|
|
63425
|
+
content,
|
|
63426
|
+
style,
|
|
63427
|
+
border,
|
|
63428
|
+
format,
|
|
63429
|
+
};
|
|
63273
63430
|
}
|
|
63274
63431
|
/**
|
|
63275
63432
|
* Get the rule associated to the current cell
|
|
@@ -63337,8 +63494,8 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63337
63494
|
? position[first].value
|
|
63338
63495
|
: position[second].value;
|
|
63339
63496
|
}
|
|
63340
|
-
|
|
63341
|
-
const
|
|
63497
|
+
autofillMerge(sheetId, data) {
|
|
63498
|
+
const { originCol, originRow, col, row } = data;
|
|
63342
63499
|
const position = { sheetId, col, row };
|
|
63343
63500
|
const originPosition = { sheetId, col: originCol, row: originRow };
|
|
63344
63501
|
if (this.getters.isInMerge(position) && !this.getters.isInMerge(originPosition)) {
|
|
@@ -63365,35 +63522,6 @@ class AutofillPlugin extends UIPlugin {
|
|
|
63365
63522
|
});
|
|
63366
63523
|
}
|
|
63367
63524
|
}
|
|
63368
|
-
autofillCF(originCol, originRow, col, row) {
|
|
63369
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
63370
|
-
const cfOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
|
|
63371
|
-
for (const cf of cfOrigin) {
|
|
63372
|
-
const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, [positionToZone({ col, row })], []);
|
|
63373
|
-
if (newCfRanges) {
|
|
63374
|
-
this.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
63375
|
-
cf: deepCopy(cf),
|
|
63376
|
-
ranges: newCfRanges,
|
|
63377
|
-
sheetId,
|
|
63378
|
-
});
|
|
63379
|
-
}
|
|
63380
|
-
}
|
|
63381
|
-
}
|
|
63382
|
-
autofillDV(originCol, originRow, col, row) {
|
|
63383
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
63384
|
-
const cellPosition = { sheetId, col: originCol, row: originRow };
|
|
63385
|
-
const dvOrigin = this.getters.getValidationRuleForCell(cellPosition);
|
|
63386
|
-
if (!dvOrigin) {
|
|
63387
|
-
return;
|
|
63388
|
-
}
|
|
63389
|
-
const dvRangesZones = dvOrigin.ranges.map((range) => range.zone);
|
|
63390
|
-
const newDvRanges = recomputeZones(dvRangesZones.concat(positionToZone({ col, row })), []);
|
|
63391
|
-
this.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
63392
|
-
rule: dvOrigin,
|
|
63393
|
-
ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
|
|
63394
|
-
sheetId,
|
|
63395
|
-
});
|
|
63396
|
-
}
|
|
63397
63525
|
// ---------------------------------------------------------------------------
|
|
63398
63526
|
// Grid rendering
|
|
63399
63527
|
// ---------------------------------------------------------------------------
|
|
@@ -63773,10 +63901,8 @@ function mergeTransformation(toTransform, executed) {
|
|
|
63773
63901
|
}
|
|
63774
63902
|
const target = [];
|
|
63775
63903
|
for (const zone1 of toTransform.target) {
|
|
63776
|
-
|
|
63777
|
-
|
|
63778
|
-
target.push({ ...zone1 });
|
|
63779
|
-
}
|
|
63904
|
+
if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
|
|
63905
|
+
target.push(zone1);
|
|
63780
63906
|
}
|
|
63781
63907
|
}
|
|
63782
63908
|
if (target.length) {
|
|
@@ -67908,24 +68034,14 @@ class InternalViewport {
|
|
|
67908
68034
|
first: this.boundaries.top,
|
|
67909
68035
|
last: this.boundaries.bottom,
|
|
67910
68036
|
});
|
|
67911
|
-
const { end: lastColEnd
|
|
67912
|
-
const { end: lastRowEnd
|
|
67913
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
67914
|
-
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
67915
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
67916
|
-
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
68037
|
+
const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
68038
|
+
const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
67917
68039
|
let width = lastColEnd - this.offsetCorrectionX;
|
|
67918
68040
|
if (this.canScrollHorizontally) {
|
|
67919
|
-
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
67920
|
-
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
67921
|
-
);
|
|
67922
68041
|
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
67923
68042
|
}
|
|
67924
68043
|
let height = lastRowEnd - this.offsetCorrectionY;
|
|
67925
68044
|
if (this.canScrollVertically) {
|
|
67926
|
-
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
67927
|
-
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
67928
|
-
);
|
|
67929
68045
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
67930
68046
|
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
67931
68047
|
height += FOOTER_HEIGHT;
|
|
@@ -68490,8 +68606,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68490
68606
|
const { width, height } = this.getMainViewportRect();
|
|
68491
68607
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
68492
68608
|
return {
|
|
68493
|
-
maxOffsetX: Math.max(0, width - viewport.viewportWidth
|
|
68494
|
-
maxOffsetY: Math.max(0, height - viewport.viewportHeight
|
|
68609
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth),
|
|
68610
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight),
|
|
68495
68611
|
};
|
|
68496
68612
|
}
|
|
68497
68613
|
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
@@ -70013,6 +70129,10 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
70013
70129
|
this.hoveredCell.clear();
|
|
70014
70130
|
});
|
|
70015
70131
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
70132
|
+
useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
|
|
70133
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
70134
|
+
return scrollY > 0;
|
|
70135
|
+
});
|
|
70016
70136
|
}
|
|
70017
70137
|
onCellHovered({ col, row }) {
|
|
70018
70138
|
this.hoveredCell.hover({ col, row });
|
|
@@ -71403,6 +71523,7 @@ css /* scss */ `
|
|
|
71403
71523
|
> canvas {
|
|
71404
71524
|
box-sizing: content-box;
|
|
71405
71525
|
border-bottom: 1px solid #e2e3e3;
|
|
71526
|
+
border-right: 1px solid #e2e3e3;
|
|
71406
71527
|
}
|
|
71407
71528
|
|
|
71408
71529
|
.o-grid-overlay {
|
|
@@ -76109,6 +76230,6 @@ exports.tokenColors = tokenColors;
|
|
|
76109
76230
|
exports.tokenize = tokenize;
|
|
76110
76231
|
|
|
76111
76232
|
|
|
76112
|
-
__info__.version = "18.2.
|
|
76113
|
-
__info__.date = "2025-04-
|
|
76114
|
-
__info__.hash = "
|
|
76233
|
+
__info__.version = "18.2.8";
|
|
76234
|
+
__info__.date = "2025-04-18T16:26:20.673Z";
|
|
76235
|
+
__info__.hash = "5da9ddc";
|