@odoo/o-spreadsheet 18.0.37 → 18.0.39
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 +114 -56
- package/dist/o-spreadsheet.d.ts +5 -0
- package/dist/o-spreadsheet.esm.js +114 -56
- package/dist/o-spreadsheet.iife.js +114 -56
- package/dist/o-spreadsheet.iife.min.js +74 -74
- package/dist/o_spreadsheet.xml +8 -7
- 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.0.
|
|
6
|
-
* @date 2025-07-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.39
|
|
6
|
+
* @date 2025-07-30T11:19:58.267Z
|
|
7
|
+
* @hash 997e25a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -17377,6 +17377,7 @@ const autoCompleteProviders = new Registry();
|
|
|
17377
17377
|
|
|
17378
17378
|
autoCompleteProviders.add("dataValidation", {
|
|
17379
17379
|
displayAllOnInitialContent: true,
|
|
17380
|
+
canBeToggled: false,
|
|
17380
17381
|
getProposals(tokenAtCursor, content) {
|
|
17381
17382
|
if (content.startsWith("=")) {
|
|
17382
17383
|
return [];
|
|
@@ -17384,31 +17385,40 @@ autoCompleteProviders.add("dataValidation", {
|
|
|
17384
17385
|
if (!this.composer.currentEditedCell) {
|
|
17385
17386
|
return [];
|
|
17386
17387
|
}
|
|
17387
|
-
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
}
|
|
17393
|
-
let values;
|
|
17394
|
-
if (rule.criterion.type === "isValueInList") {
|
|
17395
|
-
values = rule.criterion.values;
|
|
17396
|
-
}
|
|
17397
|
-
else {
|
|
17398
|
-
const range = this.getters.getRangeFromSheetXC(position.sheetId, rule.criterion.values[0]);
|
|
17399
|
-
values = Array.from(new Set(this.getters
|
|
17400
|
-
.getRangeValues(range)
|
|
17401
|
-
.filter(isNotNull)
|
|
17402
|
-
.map((value) => value.toString())
|
|
17403
|
-
.filter((val) => val !== "")));
|
|
17404
|
-
}
|
|
17405
|
-
return values.map((value) => ({ text: value }));
|
|
17388
|
+
return getProposedValues(this.getters, this.composer.currentEditedCell).map((value) => ({
|
|
17389
|
+
text: value.value?.toString() || "",
|
|
17390
|
+
htmlContent: [{ value: value.label }],
|
|
17391
|
+
fuzzySearchKey: value.label,
|
|
17392
|
+
}));
|
|
17406
17393
|
},
|
|
17407
17394
|
selectProposal(tokenAtCursor, value) {
|
|
17408
17395
|
this.composer.setCurrentContent(value);
|
|
17409
17396
|
this.composer.stopEdition();
|
|
17410
17397
|
},
|
|
17411
17398
|
});
|
|
17399
|
+
function getProposedValues(getters, position) {
|
|
17400
|
+
const rule = getters.getValidationRuleForCell(position);
|
|
17401
|
+
if (!rule ||
|
|
17402
|
+
(rule.criterion.type !== "isValueInList" && rule.criterion.type !== "isValueInRange")) {
|
|
17403
|
+
return [];
|
|
17404
|
+
}
|
|
17405
|
+
let values = [];
|
|
17406
|
+
if (rule.criterion.type === "isValueInList") {
|
|
17407
|
+
values = rule.criterion.values.map((value) => ({ label: value, value }));
|
|
17408
|
+
}
|
|
17409
|
+
else {
|
|
17410
|
+
const labelsSet = new Set();
|
|
17411
|
+
const range = getters.getRangeFromSheetXC(position.sheetId, rule.criterion.values[0]);
|
|
17412
|
+
for (const p of positions(range.zone)) {
|
|
17413
|
+
const cell = getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
|
|
17414
|
+
if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
|
|
17415
|
+
labelsSet.add(cell.formattedValue);
|
|
17416
|
+
values.push({ label: cell.formattedValue, value: cell.value });
|
|
17417
|
+
}
|
|
17418
|
+
}
|
|
17419
|
+
}
|
|
17420
|
+
return values;
|
|
17421
|
+
}
|
|
17412
17422
|
|
|
17413
17423
|
function getHtmlContentFromPattern(pattern, value, highlightColor, className) {
|
|
17414
17424
|
const pendingHtmlContent = [];
|
|
@@ -25032,11 +25042,17 @@ const COLUMN = {
|
|
|
25032
25042
|
if (isEvaluationError(cellReference?.value)) {
|
|
25033
25043
|
return cellReference;
|
|
25034
25044
|
}
|
|
25035
|
-
|
|
25036
|
-
|
|
25037
|
-
|
|
25038
|
-
|
|
25039
|
-
|
|
25045
|
+
if (cellReference === undefined) {
|
|
25046
|
+
assert(() => this.__originCellPosition?.col !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
25047
|
+
return this.__originCellPosition.col + 1;
|
|
25048
|
+
}
|
|
25049
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
25050
|
+
if (zone.left === zone.right) {
|
|
25051
|
+
return zone.left + 1;
|
|
25052
|
+
}
|
|
25053
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
25054
|
+
value: zone.left + col + 1,
|
|
25055
|
+
}));
|
|
25040
25056
|
},
|
|
25041
25057
|
isExported: true,
|
|
25042
25058
|
};
|
|
@@ -25255,11 +25271,17 @@ const ROW = {
|
|
|
25255
25271
|
if (isEvaluationError(cellReference?.value)) {
|
|
25256
25272
|
return cellReference;
|
|
25257
25273
|
}
|
|
25258
|
-
|
|
25259
|
-
|
|
25260
|
-
|
|
25261
|
-
|
|
25262
|
-
|
|
25274
|
+
if (cellReference === undefined) {
|
|
25275
|
+
assert(() => this.__originCellPosition?.row !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
25276
|
+
return this.__originCellPosition.row + 1;
|
|
25277
|
+
}
|
|
25278
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
25279
|
+
if (zone.top === zone.bottom) {
|
|
25280
|
+
return zone.top + 1;
|
|
25281
|
+
}
|
|
25282
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
25283
|
+
value: zone.top + row + 1,
|
|
25284
|
+
}));
|
|
25263
25285
|
},
|
|
25264
25286
|
isExported: true,
|
|
25265
25287
|
};
|
|
@@ -27915,9 +27937,13 @@ class Composer extends owl.Component {
|
|
|
27915
27937
|
}
|
|
27916
27938
|
}
|
|
27917
27939
|
closeAssistant() {
|
|
27940
|
+
if (!this.canBeToggled)
|
|
27941
|
+
return;
|
|
27918
27942
|
this.assistant.forcedClosed = true;
|
|
27919
27943
|
}
|
|
27920
27944
|
openAssistant() {
|
|
27945
|
+
if (!this.canBeToggled)
|
|
27946
|
+
return;
|
|
27921
27947
|
this.assistant.forcedClosed = false;
|
|
27922
27948
|
}
|
|
27923
27949
|
onWheel(event) {
|
|
@@ -27927,6 +27953,9 @@ class Composer extends owl.Component {
|
|
|
27927
27953
|
event.stopPropagation();
|
|
27928
27954
|
}
|
|
27929
27955
|
}
|
|
27956
|
+
get canBeToggled() {
|
|
27957
|
+
return this.autoCompleteState.provider?.canBeToggled ?? true;
|
|
27958
|
+
}
|
|
27930
27959
|
// ---------------------------------------------------------------------------
|
|
27931
27960
|
// Private
|
|
27932
27961
|
// ---------------------------------------------------------------------------
|
|
@@ -28109,7 +28138,7 @@ class Composer extends owl.Component {
|
|
|
28109
28138
|
}
|
|
28110
28139
|
}
|
|
28111
28140
|
autoComplete(value) {
|
|
28112
|
-
if (!value || this.assistant.forcedClosed) {
|
|
28141
|
+
if (!value || (this.assistant.forcedClosed && this.canBeToggled)) {
|
|
28113
28142
|
return;
|
|
28114
28143
|
}
|
|
28115
28144
|
this.autoCompleteState.provider?.selectProposal(value);
|
|
@@ -39681,6 +39710,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
39681
39710
|
proposals,
|
|
39682
39711
|
selectProposal: provider.selectProposal,
|
|
39683
39712
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
39713
|
+
canBeToggled: provider.canBeToggled,
|
|
39684
39714
|
};
|
|
39685
39715
|
}
|
|
39686
39716
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -39703,6 +39733,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
39703
39733
|
proposals,
|
|
39704
39734
|
selectProposal: provider.selectProposal,
|
|
39705
39735
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
39736
|
+
canBeToggled: provider.canBeToggled,
|
|
39706
39737
|
};
|
|
39707
39738
|
}
|
|
39708
39739
|
}
|
|
@@ -44742,9 +44773,15 @@ class SpreadsheetPivot {
|
|
|
44742
44773
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
44743
44774
|
}
|
|
44744
44775
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
44745
|
-
const { field, value } = domain;
|
|
44776
|
+
const { field, value, type } = domain;
|
|
44746
44777
|
const { nameWithGranularity } = this.getDimension(field);
|
|
44747
|
-
return dataEntries.filter((entry) =>
|
|
44778
|
+
return dataEntries.filter((entry) => {
|
|
44779
|
+
const cellValue = entry[nameWithGranularity]?.value;
|
|
44780
|
+
if (type === "char") {
|
|
44781
|
+
return String(cellValue) === String(value);
|
|
44782
|
+
}
|
|
44783
|
+
return cellValue === value;
|
|
44784
|
+
});
|
|
44748
44785
|
}
|
|
44749
44786
|
getDimension(nameWithGranularity) {
|
|
44750
44787
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -47219,6 +47256,11 @@ class GridComposer extends owl.Component {
|
|
|
47219
47256
|
rect = this.defaultRect;
|
|
47220
47257
|
isEditing = false;
|
|
47221
47258
|
isCellReferenceVisible = false;
|
|
47259
|
+
currentEditedCell = {
|
|
47260
|
+
col: 0,
|
|
47261
|
+
row: 0,
|
|
47262
|
+
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
47263
|
+
};
|
|
47222
47264
|
composerStore;
|
|
47223
47265
|
composerFocusStore;
|
|
47224
47266
|
composerInterface;
|
|
@@ -47248,7 +47290,7 @@ class GridComposer extends owl.Component {
|
|
|
47248
47290
|
return this.isCellReferenceVisible;
|
|
47249
47291
|
}
|
|
47250
47292
|
get cellReference() {
|
|
47251
|
-
const { col, row, sheetId } = this.
|
|
47293
|
+
const { col, row, sheetId } = this.currentEditedCell;
|
|
47252
47294
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
47253
47295
|
return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
|
|
47254
47296
|
}
|
|
@@ -47341,12 +47383,17 @@ class GridComposer extends owl.Component {
|
|
|
47341
47383
|
if (!isEditing && this.composerFocusStore.activeComposer !== this.composerInterface) {
|
|
47342
47384
|
this.composerFocusStore.focusComposer(this.composerInterface, { focusMode: "inactive" });
|
|
47343
47385
|
}
|
|
47386
|
+
let shouldRecomputeRect = isEditing && !deepEquals(this.currentEditedCell, this.composerStore.currentEditedCell);
|
|
47344
47387
|
if (this.isEditing !== isEditing) {
|
|
47345
47388
|
this.isEditing = isEditing;
|
|
47346
47389
|
if (!isEditing) {
|
|
47347
47390
|
this.rect = this.defaultRect;
|
|
47348
47391
|
return;
|
|
47349
47392
|
}
|
|
47393
|
+
this.currentEditedCell = this.composerStore.currentEditedCell;
|
|
47394
|
+
shouldRecomputeRect = true;
|
|
47395
|
+
}
|
|
47396
|
+
if (shouldRecomputeRect) {
|
|
47350
47397
|
const position = this.env.model.getters.getActivePosition();
|
|
47351
47398
|
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
47352
47399
|
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
@@ -60413,6 +60460,23 @@ class HeaderSizeUIPlugin extends UIPlugin {
|
|
|
60413
60460
|
static getters = ["getRowSize", "getHeaderSize"];
|
|
60414
60461
|
tallestCellInRow = {};
|
|
60415
60462
|
ctx = document.createElement("canvas").getContext("2d");
|
|
60463
|
+
beforeHandle(cmd) {
|
|
60464
|
+
switch (cmd.type) {
|
|
60465
|
+
// Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
|
|
60466
|
+
// "UPDATE_CELL" uses the Sheet core plugin to access row data.
|
|
60467
|
+
// If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
|
|
60468
|
+
// size updates may apply to incorrect (pre-insert) rows.
|
|
60469
|
+
case "ADD_COLUMNS_ROWS":
|
|
60470
|
+
if (cmd.dimension === "COL") {
|
|
60471
|
+
return;
|
|
60472
|
+
}
|
|
60473
|
+
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
60474
|
+
const newCells = Array(cmd.quantity).fill(undefined);
|
|
60475
|
+
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
60476
|
+
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
60477
|
+
break;
|
|
60478
|
+
}
|
|
60479
|
+
}
|
|
60416
60480
|
handle(cmd) {
|
|
60417
60481
|
switch (cmd.type) {
|
|
60418
60482
|
case "START":
|
|
@@ -60442,16 +60506,6 @@ class HeaderSizeUIPlugin extends UIPlugin {
|
|
|
60442
60506
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
60443
60507
|
break;
|
|
60444
60508
|
}
|
|
60445
|
-
case "ADD_COLUMNS_ROWS": {
|
|
60446
|
-
if (cmd.dimension === "COL") {
|
|
60447
|
-
return;
|
|
60448
|
-
}
|
|
60449
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
60450
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
60451
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
60452
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
60453
|
-
break;
|
|
60454
|
-
}
|
|
60455
60509
|
case "RESIZE_COLUMNS_ROWS":
|
|
60456
60510
|
{
|
|
60457
60511
|
const sheetId = cmd.sheetId;
|
|
@@ -66140,6 +66194,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66140
66194
|
const isBasedBefore = cmd.base < start;
|
|
66141
66195
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
66142
66196
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
66197
|
+
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
66198
|
+
const originalSize = Object.fromEntries(toRemove.map((element) => {
|
|
66199
|
+
const size = isCol
|
|
66200
|
+
? this.getters.getColSize(cmd.sheetId, element)
|
|
66201
|
+
: this.getters.getUserRowSize(cmd.sheetId, element);
|
|
66202
|
+
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
66203
|
+
return [element, isDefaultCol || size === undefined ? null : size];
|
|
66204
|
+
}));
|
|
66143
66205
|
const target = [
|
|
66144
66206
|
{
|
|
66145
66207
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -66170,14 +66232,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66170
66232
|
const col = selection.left;
|
|
66171
66233
|
const row = selection.top;
|
|
66172
66234
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
66173
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
66174
66235
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
66175
66236
|
for (const element of toRemove) {
|
|
66176
|
-
const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
|
|
66177
66237
|
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
66178
66238
|
dimension: cmd.dimension,
|
|
66179
66239
|
sheetId: cmd.sheetId,
|
|
66180
|
-
size,
|
|
66240
|
+
size: originalSize[element],
|
|
66181
66241
|
elements: [currentIndex],
|
|
66182
66242
|
});
|
|
66183
66243
|
currentIndex += 1;
|
|
@@ -67889,14 +67949,12 @@ class BottomBarSheet extends owl.Component {
|
|
|
67889
67949
|
this.editionState = "initializing";
|
|
67890
67950
|
}
|
|
67891
67951
|
stopEdition() {
|
|
67892
|
-
|
|
67893
|
-
if (!this.state.isEditing || !input)
|
|
67952
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
67894
67953
|
return;
|
|
67895
67954
|
this.state.isEditing = false;
|
|
67896
67955
|
this.editionState = "initializing";
|
|
67897
|
-
|
|
67956
|
+
this.sheetNameRef.el.blur();
|
|
67898
67957
|
const inputValue = this.getInputContent() || "";
|
|
67899
|
-
input.innerText = inputValue;
|
|
67900
67958
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
67901
67959
|
}
|
|
67902
67960
|
cancelEdition() {
|
|
@@ -74591,6 +74649,6 @@ exports.tokenColors = tokenColors;
|
|
|
74591
74649
|
exports.tokenize = tokenize;
|
|
74592
74650
|
|
|
74593
74651
|
|
|
74594
|
-
__info__.version = "18.0.
|
|
74595
|
-
__info__.date = "2025-07-
|
|
74596
|
-
__info__.hash = "
|
|
74652
|
+
__info__.version = "18.0.39";
|
|
74653
|
+
__info__.date = "2025-07-30T11:19:58.267Z";
|
|
74654
|
+
__info__.hash = "997e25a";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -4750,6 +4750,7 @@ declare class HeaderSizeUIPlugin extends UIPlugin<HeaderSizeState> implements He
|
|
|
4750
4750
|
static getters: readonly ["getRowSize", "getHeaderSize"];
|
|
4751
4751
|
readonly tallestCellInRow: Immutable<Record<UID, Array<CellWithSize | undefined>>>;
|
|
4752
4752
|
private ctx;
|
|
4753
|
+
beforeHandle(cmd: Command): void;
|
|
4753
4754
|
handle(cmd: Command): void;
|
|
4754
4755
|
getRowSize(sheetId: UID, row: HeaderIndex): Pixel;
|
|
4755
4756
|
getHeaderSize(sheetId: UID, dimension: Dimension, index: HeaderIndex): Pixel;
|
|
@@ -8193,6 +8194,7 @@ declare class Composer extends Component<CellComposerProps, SpreadsheetChildEnv>
|
|
|
8193
8194
|
closeAssistant(): void;
|
|
8194
8195
|
openAssistant(): void;
|
|
8195
8196
|
onWheel(event: WheelEvent): void;
|
|
8197
|
+
get canBeToggled(): boolean;
|
|
8196
8198
|
private processContent;
|
|
8197
8199
|
/**
|
|
8198
8200
|
* Get the HTML content corresponding to the current composer token, divided by lines.
|
|
@@ -8234,6 +8236,7 @@ interface AutoCompleteProvider {
|
|
|
8234
8236
|
proposals: AutoCompleteProposal[];
|
|
8235
8237
|
selectProposal(text: string): void;
|
|
8236
8238
|
autoSelectFirstProposal: boolean;
|
|
8239
|
+
canBeToggled?: boolean;
|
|
8237
8240
|
}
|
|
8238
8241
|
interface ComposerStoreInterface {
|
|
8239
8242
|
currentEditedCell?: CellPosition;
|
|
@@ -8253,6 +8256,7 @@ interface ComposerStoreInterface {
|
|
|
8253
8256
|
interface AutoCompleteProviderDefinition {
|
|
8254
8257
|
sequence?: number;
|
|
8255
8258
|
autoSelectFirstProposal?: boolean;
|
|
8259
|
+
canBeToggled?: boolean;
|
|
8256
8260
|
displayAllOnInitialContent?: boolean;
|
|
8257
8261
|
maxDisplayedProposals?: number;
|
|
8258
8262
|
getProposals(this: {
|
|
@@ -8560,6 +8564,7 @@ declare class GridComposer extends Component<Props$H, SpreadsheetChildEnv> {
|
|
|
8560
8564
|
private rect;
|
|
8561
8565
|
private isEditing;
|
|
8562
8566
|
private isCellReferenceVisible;
|
|
8567
|
+
private currentEditedCell;
|
|
8563
8568
|
private composerStore;
|
|
8564
8569
|
composerFocusStore: Store<ComposerFocusStore>;
|
|
8565
8570
|
private composerInterface;
|