@odoo/o-spreadsheet 17.2.0-alpha.4 → 17.2.0-alpha.5
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 +324 -158
- package/dist/o-spreadsheet.d.ts +186 -140
- package/dist/o-spreadsheet.esm.js +323 -159
- package/dist/o-spreadsheet.iife.js +324 -158
- package/dist/o-spreadsheet.iife.min.js +262 -261
- package/dist/o_spreadsheet.xml +36 -43
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.0-alpha.
|
|
7
|
-
* @date 2024-02-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.0-alpha.5
|
|
7
|
+
* @date 2024-02-16T14:27:52.323Z
|
|
8
|
+
* @hash 0c69dd8
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
@@ -455,8 +455,8 @@ function isObjectEmptyRecursive(argument) {
|
|
|
455
455
|
* If the given item does not exist in the dictionary, it creates one with a new id.
|
|
456
456
|
*/
|
|
457
457
|
function getItemId(item, itemsDic) {
|
|
458
|
-
for (
|
|
459
|
-
if (deepEquals(
|
|
458
|
+
for (const key in itemsDic) {
|
|
459
|
+
if (deepEquals(itemsDic[key], item)) {
|
|
460
460
|
return parseInt(key, 10);
|
|
461
461
|
}
|
|
462
462
|
}
|
|
@@ -560,11 +560,13 @@ function deepEquals(o1, o2) {
|
|
|
560
560
|
if (typeof o1 !== "object")
|
|
561
561
|
return o1 === o2;
|
|
562
562
|
// Objects can have different keys if the values are undefined
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
563
|
+
for (const key in o2) {
|
|
564
|
+
if (!(key in o1) && o2[key] !== undefined) {
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
for (const key in o1) {
|
|
569
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
568
570
|
return false;
|
|
569
571
|
if (typeof o1[key] === "object") {
|
|
570
572
|
if (!deepEquals(o1[key], o2[key]))
|
|
@@ -634,18 +636,18 @@ function isConsecutive(iterable) {
|
|
|
634
636
|
return true;
|
|
635
637
|
}
|
|
636
638
|
class JetSet extends Set {
|
|
637
|
-
|
|
639
|
+
addMany(iterable) {
|
|
638
640
|
for (const element of iterable) {
|
|
639
641
|
super.add(element);
|
|
640
642
|
}
|
|
641
643
|
return this;
|
|
642
644
|
}
|
|
643
|
-
|
|
644
|
-
let
|
|
645
|
+
deleteMany(iterable) {
|
|
646
|
+
let wasDeleted = false;
|
|
645
647
|
for (const element of iterable) {
|
|
646
|
-
|
|
648
|
+
wasDeleted ||= super.delete(element);
|
|
647
649
|
}
|
|
648
|
-
return
|
|
650
|
+
return wasDeleted;
|
|
649
651
|
}
|
|
650
652
|
}
|
|
651
653
|
/**
|
|
@@ -1947,7 +1949,7 @@ class DispatchResult {
|
|
|
1947
1949
|
* Static helper which returns a successful DispatchResult
|
|
1948
1950
|
*/
|
|
1949
1951
|
static get Success() {
|
|
1950
|
-
return
|
|
1952
|
+
return SUCCESS;
|
|
1951
1953
|
}
|
|
1952
1954
|
get isSuccessful() {
|
|
1953
1955
|
return this.reasons.length === 0;
|
|
@@ -1960,6 +1962,7 @@ class DispatchResult {
|
|
|
1960
1962
|
return this.reasons.includes(reason);
|
|
1961
1963
|
}
|
|
1962
1964
|
}
|
|
1965
|
+
const SUCCESS = new DispatchResult();
|
|
1963
1966
|
exports.CommandResult = void 0;
|
|
1964
1967
|
(function (CommandResult) {
|
|
1965
1968
|
CommandResult["Success"] = "Success";
|
|
@@ -2266,7 +2269,7 @@ const normalizeString = memoize(function normalizeString(str) {
|
|
|
2266
2269
|
.normalize("NFD")
|
|
2267
2270
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2268
2271
|
});
|
|
2269
|
-
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a
|
|
2272
|
+
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a boolean.", value);
|
|
2270
2273
|
function toBoolean(data) {
|
|
2271
2274
|
const value = toValue(data);
|
|
2272
2275
|
switch (typeof value) {
|
|
@@ -7530,6 +7533,9 @@ class DependencyContainer {
|
|
|
7530
7533
|
* Also useful for mocking a store.
|
|
7531
7534
|
*/
|
|
7532
7535
|
inject(Store, instance) {
|
|
7536
|
+
if (this.dependencies.has(Store) && this.dependencies.get(Store) !== instance) {
|
|
7537
|
+
throw new Error(`Store ${Store.name} already has an instance`);
|
|
7538
|
+
}
|
|
7533
7539
|
this.dependencies.set(Store, instance);
|
|
7534
7540
|
}
|
|
7535
7541
|
/**
|
|
@@ -11358,8 +11364,10 @@ class ChartFigure extends owl.Component {
|
|
|
11358
11364
|
};
|
|
11359
11365
|
static components = {};
|
|
11360
11366
|
onDoubleClick() {
|
|
11361
|
-
this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
11362
|
-
|
|
11367
|
+
const result = this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
11368
|
+
if (result.isSuccessful) {
|
|
11369
|
+
this.env.openSidePanel("ChartPanel");
|
|
11370
|
+
}
|
|
11363
11371
|
}
|
|
11364
11372
|
get chartType() {
|
|
11365
11373
|
return this.env.model.getters.getChartType(this.props.figure.id);
|
|
@@ -13916,6 +13924,12 @@ const INSERT_LINK = (env) => {
|
|
|
13916
13924
|
let { col, row } = env.model.getters.getActivePosition();
|
|
13917
13925
|
env.getStore(CellPopoverStore).open({ col, row }, "LinkEditor");
|
|
13918
13926
|
};
|
|
13927
|
+
const INSERT_LINK_NAME = (env) => {
|
|
13928
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
13929
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
13930
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
13931
|
+
return cell && cell.link ? _t("Edit link") : _t("Insert link");
|
|
13932
|
+
};
|
|
13919
13933
|
//------------------------------------------------------------------------------
|
|
13920
13934
|
// Filters action
|
|
13921
13935
|
//------------------------------------------------------------------------------
|
|
@@ -21722,6 +21736,68 @@ const INDEX = {
|
|
|
21722
21736
|
isExported: true,
|
|
21723
21737
|
};
|
|
21724
21738
|
// -----------------------------------------------------------------------------
|
|
21739
|
+
// INDEX
|
|
21740
|
+
// -----------------------------------------------------------------------------
|
|
21741
|
+
const INDIRECT = {
|
|
21742
|
+
description: _t("Returns the content of a cell, specified by a string."),
|
|
21743
|
+
args: [
|
|
21744
|
+
arg("reference (string)", _t("The range of cells from which the values are returned.")),
|
|
21745
|
+
arg("use_a1_notation (boolean, default=TRUE)", _t("A boolean indicating whether to use A1 style notation (TRUE) or R1C1 style notation (FALSE).")),
|
|
21746
|
+
],
|
|
21747
|
+
returns: ["ANY"],
|
|
21748
|
+
compute: function (reference, useA1Notation = { value: true }) {
|
|
21749
|
+
let _reference = reference?.value?.toString();
|
|
21750
|
+
if (!_reference) {
|
|
21751
|
+
throw new InvalidReferenceError(_t("Reference should be defined."));
|
|
21752
|
+
}
|
|
21753
|
+
const _useA1Notation = toBoolean(useA1Notation);
|
|
21754
|
+
if (!_useA1Notation) {
|
|
21755
|
+
throw new EvaluationError(_t("R1C1 notation is not supported."));
|
|
21756
|
+
}
|
|
21757
|
+
const sheetId = this.__originSheetId;
|
|
21758
|
+
let originPosition;
|
|
21759
|
+
const __originCellXC = this.__originCellXC?.();
|
|
21760
|
+
if (__originCellXC) {
|
|
21761
|
+
const cellZone = toZone(__originCellXC);
|
|
21762
|
+
originPosition = {
|
|
21763
|
+
sheetId,
|
|
21764
|
+
col: cellZone.left,
|
|
21765
|
+
row: cellZone.top,
|
|
21766
|
+
};
|
|
21767
|
+
// The following line is used to reset the dependencies of the cell, to avoid
|
|
21768
|
+
// keeping dependencies from previous evaluation of the INDIRECT formula (i.e.
|
|
21769
|
+
// in case the reference has been changed).
|
|
21770
|
+
this.updateDependencies?.(originPosition);
|
|
21771
|
+
}
|
|
21772
|
+
const range = this.getters.getRangeFromSheetXC(sheetId, _reference);
|
|
21773
|
+
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
21774
|
+
throw new InvalidReferenceError();
|
|
21775
|
+
}
|
|
21776
|
+
if (originPosition) {
|
|
21777
|
+
this.addDependencies?.(originPosition, [range]);
|
|
21778
|
+
}
|
|
21779
|
+
const values = [];
|
|
21780
|
+
for (let col = range.zone.left; col <= range.zone.right; col++) {
|
|
21781
|
+
const colValues = [];
|
|
21782
|
+
for (let row = range.zone.top; row <= range.zone.bottom; row++) {
|
|
21783
|
+
const position = { sheetId: range.sheetId, col, row };
|
|
21784
|
+
// The below 'value' is typed as CellValue because the evaluateFormula will have to
|
|
21785
|
+
// evaluate a string containing the A1 reference of a single cell, so this will
|
|
21786
|
+
// return a CellValue.
|
|
21787
|
+
const value = this.getters.evaluateFormula(range.sheetId, toXC(col, row));
|
|
21788
|
+
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
21789
|
+
colValues.push({
|
|
21790
|
+
...evaluatedCell,
|
|
21791
|
+
value,
|
|
21792
|
+
});
|
|
21793
|
+
}
|
|
21794
|
+
values.push(colValues);
|
|
21795
|
+
}
|
|
21796
|
+
return values.length === 1 && values[0].length === 1 ? values[0][0] : values;
|
|
21797
|
+
},
|
|
21798
|
+
isExported: true,
|
|
21799
|
+
};
|
|
21800
|
+
// -----------------------------------------------------------------------------
|
|
21725
21801
|
// LOOKUP
|
|
21726
21802
|
// -----------------------------------------------------------------------------
|
|
21727
21803
|
const LOOKUP = {
|
|
@@ -21927,6 +22003,7 @@ var lookup = /*#__PURE__*/Object.freeze({
|
|
|
21927
22003
|
COLUMNS: COLUMNS,
|
|
21928
22004
|
HLOOKUP: HLOOKUP,
|
|
21929
22005
|
INDEX: INDEX,
|
|
22006
|
+
INDIRECT: INDIRECT,
|
|
21930
22007
|
LOOKUP: LOOKUP,
|
|
21931
22008
|
MATCH: MATCH,
|
|
21932
22009
|
ROW: ROW,
|
|
@@ -22902,7 +22979,7 @@ const insertImage = {
|
|
|
22902
22979
|
};
|
|
22903
22980
|
const insertFunction = {
|
|
22904
22981
|
name: _t("Function"),
|
|
22905
|
-
icon: "o-spreadsheet-Icon.
|
|
22982
|
+
icon: "o-spreadsheet-Icon.FORMULA",
|
|
22906
22983
|
};
|
|
22907
22984
|
const insertFunctionSum = {
|
|
22908
22985
|
name: _t("SUM"),
|
|
@@ -23124,7 +23201,7 @@ cellMenuRegistry
|
|
|
23124
23201
|
})
|
|
23125
23202
|
.add("insert_link", {
|
|
23126
23203
|
...insertLink,
|
|
23127
|
-
name:
|
|
23204
|
+
name: INSERT_LINK_NAME,
|
|
23128
23205
|
sequence: 150,
|
|
23129
23206
|
separator: true,
|
|
23130
23207
|
});
|
|
@@ -23789,9 +23866,7 @@ const freezeCurrentCol = {
|
|
|
23789
23866
|
isReadonlyAllowed: true,
|
|
23790
23867
|
};
|
|
23791
23868
|
const viewGridlines = {
|
|
23792
|
-
name: (
|
|
23793
|
-
? _t("Hide gridlines")
|
|
23794
|
-
: _t("Show gridlines"),
|
|
23869
|
+
name: _t("Gridlines"),
|
|
23795
23870
|
execute: (env) => {
|
|
23796
23871
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
23797
23872
|
env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
|
|
@@ -23799,13 +23874,16 @@ const viewGridlines = {
|
|
|
23799
23874
|
areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
|
|
23800
23875
|
});
|
|
23801
23876
|
},
|
|
23802
|
-
|
|
23877
|
+
isActive: (env) => {
|
|
23878
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
23879
|
+
return env.model.getters.getGridLinesVisibility(sheetId);
|
|
23880
|
+
},
|
|
23803
23881
|
};
|
|
23804
23882
|
const viewFormulas = {
|
|
23805
|
-
name:
|
|
23883
|
+
name: _t("Formulas"),
|
|
23884
|
+
isActive: (env) => env.model.getters.shouldShowFormulas(),
|
|
23806
23885
|
execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
|
|
23807
23886
|
isReadonlyAllowed: true,
|
|
23808
|
-
icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
|
|
23809
23887
|
};
|
|
23810
23888
|
const createRemoveFilter = {
|
|
23811
23889
|
name: (env) => selectionContainsFilter(env) ? _t("Remove selected filters") : _t("Create filter"),
|
|
@@ -24362,13 +24440,18 @@ topbarMenuRegistry
|
|
|
24362
24440
|
isVisible: (env) => canUngroupHeaders(env, "ROW"),
|
|
24363
24441
|
sequence: 20,
|
|
24364
24442
|
})
|
|
24365
|
-
.addChild("
|
|
24443
|
+
.addChild("show", ["view"], {
|
|
24444
|
+
name: _t("Show"),
|
|
24445
|
+
sequence: 1,
|
|
24446
|
+
icon: "o-spreadsheet-Icon.SHOW",
|
|
24447
|
+
})
|
|
24448
|
+
.addChild("view_gridlines", ["view", "show"], {
|
|
24366
24449
|
...viewGridlines,
|
|
24367
|
-
sequence:
|
|
24450
|
+
sequence: 5,
|
|
24368
24451
|
})
|
|
24369
|
-
.addChild("view_formulas", ["view"], {
|
|
24452
|
+
.addChild("view_formulas", ["view", "show"], {
|
|
24370
24453
|
...viewFormulas,
|
|
24371
|
-
sequence:
|
|
24454
|
+
sequence: 10,
|
|
24372
24455
|
})
|
|
24373
24456
|
// ---------------------------------------------------------------------
|
|
24374
24457
|
// INSERT MENU ITEMS
|
|
@@ -25351,6 +25434,17 @@ class TextValueProvider extends owl.Component {
|
|
|
25351
25434
|
onValueSelected: Function,
|
|
25352
25435
|
onValueHovered: Function,
|
|
25353
25436
|
};
|
|
25437
|
+
autoCompleteListRef = owl.useRef("autoCompleteList");
|
|
25438
|
+
setup() {
|
|
25439
|
+
owl.useEffect(() => {
|
|
25440
|
+
const selectedIndex = this.props.selectedIndex;
|
|
25441
|
+
if (selectedIndex === undefined) {
|
|
25442
|
+
return;
|
|
25443
|
+
}
|
|
25444
|
+
const selectedElement = this.autoCompleteListRef.el?.children[selectedIndex];
|
|
25445
|
+
selectedElement?.scrollIntoView?.({ block: "nearest" });
|
|
25446
|
+
}, () => [this.props.selectedIndex, this.autoCompleteListRef.el]);
|
|
25447
|
+
}
|
|
25354
25448
|
}
|
|
25355
25449
|
|
|
25356
25450
|
class ContentEditableHelper {
|
|
@@ -25795,6 +25889,7 @@ css /* scss */ `
|
|
|
25795
25889
|
position: absolute;
|
|
25796
25890
|
margin: 1px 4px;
|
|
25797
25891
|
pointer-events: none;
|
|
25892
|
+
overflow: auto;
|
|
25798
25893
|
|
|
25799
25894
|
.o-semi-bold {
|
|
25800
25895
|
/** FIXME: to remove in favor of Bootstrap
|
|
@@ -25854,7 +25949,10 @@ class Composer extends owl.Component {
|
|
|
25854
25949
|
if (this.props.delimitation && this.props.rect) {
|
|
25855
25950
|
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
25856
25951
|
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
25952
|
+
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
25857
25953
|
if (cellY > remainingHeight) {
|
|
25954
|
+
const availableSpaceAbove = cellY;
|
|
25955
|
+
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
25858
25956
|
// render top
|
|
25859
25957
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
25860
25958
|
assistantStyle.top = `-3px`;
|
|
@@ -29459,6 +29557,34 @@ class VerticalScrollBar extends owl.Component {
|
|
|
29459
29557
|
}
|
|
29460
29558
|
}
|
|
29461
29559
|
|
|
29560
|
+
class SidePanelStore extends SpreadsheetStore {
|
|
29561
|
+
isOpen = false;
|
|
29562
|
+
panelProps = {};
|
|
29563
|
+
componentTag = "";
|
|
29564
|
+
open(componentTag, panelProps = {}) {
|
|
29565
|
+
if (this.isOpen && componentTag !== this.componentTag) {
|
|
29566
|
+
this.panelProps?.onCloseSidePanel?.();
|
|
29567
|
+
}
|
|
29568
|
+
this.componentTag = componentTag;
|
|
29569
|
+
this.panelProps = panelProps;
|
|
29570
|
+
this.isOpen = true;
|
|
29571
|
+
}
|
|
29572
|
+
toggle(componentTag, panelProps) {
|
|
29573
|
+
if (this.isOpen && componentTag === this.componentTag) {
|
|
29574
|
+
this.close();
|
|
29575
|
+
}
|
|
29576
|
+
else {
|
|
29577
|
+
this.open(componentTag, panelProps);
|
|
29578
|
+
}
|
|
29579
|
+
}
|
|
29580
|
+
close() {
|
|
29581
|
+
this.panelProps.onCloseSidePanel?.();
|
|
29582
|
+
this.isOpen = false;
|
|
29583
|
+
this.panelProps = {};
|
|
29584
|
+
this.componentTag = "";
|
|
29585
|
+
}
|
|
29586
|
+
}
|
|
29587
|
+
|
|
29462
29588
|
const registries$1 = {
|
|
29463
29589
|
ROW: rowMenuRegistry,
|
|
29464
29590
|
COL: colMenuRegistry,
|
|
@@ -29472,7 +29598,6 @@ const registries$1 = {
|
|
|
29472
29598
|
class Grid extends owl.Component {
|
|
29473
29599
|
static template = "o-spreadsheet-Grid";
|
|
29474
29600
|
static props = {
|
|
29475
|
-
sidePanelIsOpen: Boolean,
|
|
29476
29601
|
exposeFocus: Function,
|
|
29477
29602
|
};
|
|
29478
29603
|
static components = {
|
|
@@ -29501,6 +29626,7 @@ class Grid extends owl.Component {
|
|
|
29501
29626
|
onMouseWheel;
|
|
29502
29627
|
canvasPosition;
|
|
29503
29628
|
hoveredCell;
|
|
29629
|
+
sidePanel;
|
|
29504
29630
|
setup() {
|
|
29505
29631
|
this.highlightStore = useStore(HighlightStore);
|
|
29506
29632
|
this.menuState = owl.useState({
|
|
@@ -29514,6 +29640,7 @@ class Grid extends owl.Component {
|
|
|
29514
29640
|
this.composerStore = useStore(ComposerStore);
|
|
29515
29641
|
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
29516
29642
|
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
29643
|
+
this.sidePanel = useStore(SidePanelStore);
|
|
29517
29644
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
29518
29645
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
29519
29646
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
@@ -29526,6 +29653,11 @@ class Grid extends owl.Component {
|
|
|
29526
29653
|
this.hoveredCell.clear();
|
|
29527
29654
|
});
|
|
29528
29655
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
29656
|
+
owl.useEffect(() => {
|
|
29657
|
+
if (!this.sidePanel.isOpen) {
|
|
29658
|
+
this.DOMFocusableElementStore.focus();
|
|
29659
|
+
}
|
|
29660
|
+
}, () => [this.sidePanel.isOpen]);
|
|
29529
29661
|
}
|
|
29530
29662
|
onCellHovered({ col, row }) {
|
|
29531
29663
|
this.hoveredCell.hover({ col, row });
|
|
@@ -30902,6 +31034,7 @@ class Checkbox extends owl.Component {
|
|
|
30902
31034
|
value: { type: Boolean, optional: true },
|
|
30903
31035
|
className: { type: String, optional: true },
|
|
30904
31036
|
name: { type: String, optional: true },
|
|
31037
|
+
title: { type: String, optional: true },
|
|
30905
31038
|
onChange: Function,
|
|
30906
31039
|
};
|
|
30907
31040
|
static defaultProps = { value: false };
|
|
@@ -31913,6 +32046,35 @@ chartSidePanelComponentRegistry
|
|
|
31913
32046
|
design: ScorecardChartDesignPanel,
|
|
31914
32047
|
});
|
|
31915
32048
|
|
|
32049
|
+
class MainChartPanelStore extends SpreadsheetStore {
|
|
32050
|
+
sidePanel = this.get(SidePanelStore);
|
|
32051
|
+
figureId;
|
|
32052
|
+
panel = "configuration";
|
|
32053
|
+
constructor(get, figureId) {
|
|
32054
|
+
super(get);
|
|
32055
|
+
this.figureId = figureId;
|
|
32056
|
+
}
|
|
32057
|
+
handle(cmd) {
|
|
32058
|
+
switch (cmd.type) {
|
|
32059
|
+
case "DELETE_FIGURE":
|
|
32060
|
+
if (this.sidePanel.componentTag === "ChartPanel" && this.figureId === cmd.id) {
|
|
32061
|
+
this.sidePanel.close();
|
|
32062
|
+
}
|
|
32063
|
+
break;
|
|
32064
|
+
case "SELECT_FIGURE":
|
|
32065
|
+
if (cmd.id) {
|
|
32066
|
+
this.figureId = cmd.id;
|
|
32067
|
+
}
|
|
32068
|
+
else if (this.sidePanel.componentTag === "ChartPanel") {
|
|
32069
|
+
this.sidePanel.close();
|
|
32070
|
+
}
|
|
32071
|
+
}
|
|
32072
|
+
}
|
|
32073
|
+
activatePanel(panel) {
|
|
32074
|
+
this.panel = panel;
|
|
32075
|
+
}
|
|
32076
|
+
}
|
|
32077
|
+
|
|
31916
32078
|
css /* scss */ `
|
|
31917
32079
|
.o-chart {
|
|
31918
32080
|
.o-panel {
|
|
@@ -31941,37 +32103,19 @@ class ChartPanel extends owl.Component {
|
|
|
31941
32103
|
static template = "o-spreadsheet-ChartPanel";
|
|
31942
32104
|
static components = { Section };
|
|
31943
32105
|
static props = { onCloseSidePanel: Function };
|
|
31944
|
-
|
|
32106
|
+
store;
|
|
31945
32107
|
get figureId() {
|
|
31946
|
-
return this.
|
|
32108
|
+
return this.store.figureId;
|
|
31947
32109
|
}
|
|
31948
32110
|
setup() {
|
|
31949
|
-
|
|
31950
|
-
if (!selectedFigureId) {
|
|
31951
|
-
this.props.onCloseSidePanel();
|
|
31952
|
-
return;
|
|
31953
|
-
}
|
|
31954
|
-
this.state = owl.useState({
|
|
31955
|
-
panel: "configuration",
|
|
31956
|
-
figureId: selectedFigureId,
|
|
31957
|
-
});
|
|
31958
|
-
owl.onWillUpdateProps(() => {
|
|
31959
|
-
const selectedFigureId = this.env.model.getters.getSelectedFigureId();
|
|
31960
|
-
if (selectedFigureId && selectedFigureId !== this.state.figureId) {
|
|
31961
|
-
this.state.figureId = selectedFigureId;
|
|
31962
|
-
}
|
|
31963
|
-
if (!this.env.model.getters.isChartDefined(this.figureId)) {
|
|
31964
|
-
this.props.onCloseSidePanel();
|
|
31965
|
-
return;
|
|
31966
|
-
}
|
|
31967
|
-
});
|
|
32111
|
+
this.store = useLocalStore(MainChartPanelStore, this.env.model.getters.getSelectedFigureId());
|
|
31968
32112
|
}
|
|
31969
32113
|
updateChart(figureId, updateDefinition) {
|
|
31970
32114
|
if (figureId !== this.figureId) {
|
|
31971
32115
|
return;
|
|
31972
32116
|
}
|
|
31973
32117
|
const definition = {
|
|
31974
|
-
...this.getChartDefinition(),
|
|
32118
|
+
...this.getChartDefinition(this.figureId),
|
|
31975
32119
|
...updateDefinition,
|
|
31976
32120
|
};
|
|
31977
32121
|
return this.env.model.dispatch("UPDATE_CHART", {
|
|
@@ -31985,7 +32129,7 @@ class ChartPanel extends owl.Component {
|
|
|
31985
32129
|
return;
|
|
31986
32130
|
}
|
|
31987
32131
|
const definition = {
|
|
31988
|
-
...this.getChartDefinition(),
|
|
32132
|
+
...this.getChartDefinition(this.figureId),
|
|
31989
32133
|
...updateDefinition,
|
|
31990
32134
|
};
|
|
31991
32135
|
return this.env.model.canDispatch("UPDATE_CHART", {
|
|
@@ -31995,6 +32139,9 @@ class ChartPanel extends owl.Component {
|
|
|
31995
32139
|
});
|
|
31996
32140
|
}
|
|
31997
32141
|
onTypeChange(type) {
|
|
32142
|
+
if (!this.figureId) {
|
|
32143
|
+
return;
|
|
32144
|
+
}
|
|
31998
32145
|
const context = this.env.model.getters.getContextCreationChart(this.figureId);
|
|
31999
32146
|
if (!context) {
|
|
32000
32147
|
throw new Error("Chart not defined.");
|
|
@@ -32007,6 +32154,9 @@ class ChartPanel extends owl.Component {
|
|
|
32007
32154
|
});
|
|
32008
32155
|
}
|
|
32009
32156
|
get chartPanel() {
|
|
32157
|
+
if (!this.figureId) {
|
|
32158
|
+
throw new Error("Chart not defined.");
|
|
32159
|
+
}
|
|
32010
32160
|
const type = this.env.model.getters.getChartType(this.figureId);
|
|
32011
32161
|
if (!type) {
|
|
32012
32162
|
throw new Error("Chart not defined.");
|
|
@@ -32017,15 +32167,12 @@ class ChartPanel extends owl.Component {
|
|
|
32017
32167
|
}
|
|
32018
32168
|
return chartPanel;
|
|
32019
32169
|
}
|
|
32020
|
-
getChartDefinition(figureId
|
|
32170
|
+
getChartDefinition(figureId) {
|
|
32021
32171
|
return this.env.model.getters.getChartDefinition(figureId);
|
|
32022
32172
|
}
|
|
32023
32173
|
get chartTypes() {
|
|
32024
32174
|
return getChartTypes();
|
|
32025
32175
|
}
|
|
32026
|
-
activatePanel(panel) {
|
|
32027
|
-
this.state.panel = panel;
|
|
32028
|
-
}
|
|
32029
32176
|
}
|
|
32030
32177
|
|
|
32031
32178
|
const BORDER_COLOR = "#8B008B";
|
|
@@ -32119,7 +32266,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32119
32266
|
}
|
|
32120
32267
|
finalize() {
|
|
32121
32268
|
if (this.isSearchDirty) {
|
|
32122
|
-
this.refreshSearch();
|
|
32269
|
+
this.refreshSearch(false);
|
|
32123
32270
|
this.isSearchDirty = false;
|
|
32124
32271
|
}
|
|
32125
32272
|
}
|
|
@@ -32151,10 +32298,10 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32151
32298
|
/**
|
|
32152
32299
|
* refresh the matches according to the current search options
|
|
32153
32300
|
*/
|
|
32154
|
-
refreshSearch() {
|
|
32301
|
+
refreshSearch(jumpToMatchSheet = true) {
|
|
32155
32302
|
this.selectedMatchIndex = null;
|
|
32156
32303
|
this.findMatches();
|
|
32157
|
-
this.selectNextCell(Direction.current);
|
|
32304
|
+
this.selectNextCell(Direction.current, jumpToMatchSheet);
|
|
32158
32305
|
}
|
|
32159
32306
|
getSheetsInSearchOrder() {
|
|
32160
32307
|
switch (this.searchOptions.searchScope) {
|
|
@@ -32224,7 +32371,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32224
32371
|
* It is also used to keep coherence between the selected searchMatch
|
|
32225
32372
|
* and selectedMatchIndex.
|
|
32226
32373
|
*/
|
|
32227
|
-
selectNextCell(indexChange) {
|
|
32374
|
+
selectNextCell(indexChange, jumpToMatchSheet = true) {
|
|
32228
32375
|
const matches = this.searchMatches;
|
|
32229
32376
|
if (!matches.length) {
|
|
32230
32377
|
this.selectedMatchIndex = null;
|
|
@@ -32250,7 +32397,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32250
32397
|
this.selectedMatchIndex = nextIndex;
|
|
32251
32398
|
const selectedMatch = matches[nextIndex];
|
|
32252
32399
|
// Switch to the sheet where the match is located
|
|
32253
|
-
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
32400
|
+
if (jumpToMatchSheet && this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
32254
32401
|
this.model.dispatch("ACTIVATE_SHEET", {
|
|
32255
32402
|
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
32256
32403
|
sheetIdTo: selectedMatch.sheetId,
|
|
@@ -36967,22 +37114,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
36967
37114
|
}
|
|
36968
37115
|
}
|
|
36969
37116
|
export(data) {
|
|
36970
|
-
// Borders
|
|
36971
|
-
let borderId = 0;
|
|
36972
37117
|
const borders = {};
|
|
36973
|
-
/**
|
|
36974
|
-
* Get the id of the given border. If the border does not exist, it creates
|
|
36975
|
-
* one.
|
|
36976
|
-
*/
|
|
36977
|
-
function getBorderId(border) {
|
|
36978
|
-
for (let [key, value] of Object.entries(borders)) {
|
|
36979
|
-
if (deepEquals(value, border)) {
|
|
36980
|
-
return parseInt(key, 10);
|
|
36981
|
-
}
|
|
36982
|
-
}
|
|
36983
|
-
borders[++borderId] = border;
|
|
36984
|
-
return borderId;
|
|
36985
|
-
}
|
|
36986
37118
|
for (let sheet of data.sheets) {
|
|
36987
37119
|
for (let col = 0; col < sheet.colNumber; col++) {
|
|
36988
37120
|
for (let row = 0; row < sheet.rowNumber; row++) {
|
|
@@ -36990,7 +37122,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
36990
37122
|
if (border) {
|
|
36991
37123
|
const xc = toXC(col, row);
|
|
36992
37124
|
const cell = sheet.cells[xc];
|
|
36993
|
-
const borderId =
|
|
37125
|
+
const borderId = getItemId(border, borders);
|
|
36994
37126
|
if (cell) {
|
|
36995
37127
|
cell.border = borderId;
|
|
36996
37128
|
}
|
|
@@ -37687,9 +37819,9 @@ class CellPlugin extends CorePlugin {
|
|
|
37687
37819
|
allowDispatch(cmd) {
|
|
37688
37820
|
switch (cmd.type) {
|
|
37689
37821
|
case "UPDATE_CELL":
|
|
37690
|
-
return this.
|
|
37822
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
37691
37823
|
case "CLEAR_CELL":
|
|
37692
|
-
return this.checkValidations(cmd, this.
|
|
37824
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
37693
37825
|
default:
|
|
37694
37826
|
return "Success" /* CommandResult.Success */;
|
|
37695
37827
|
}
|
|
@@ -37859,8 +37991,8 @@ class CellPlugin extends CorePlugin {
|
|
|
37859
37991
|
}
|
|
37860
37992
|
removeDefaultStyleValues(style) {
|
|
37861
37993
|
const cleanedStyle = { ...style };
|
|
37862
|
-
for (const
|
|
37863
|
-
if (cleanedStyle[property] ===
|
|
37994
|
+
for (const property in DEFAULT_STYLE) {
|
|
37995
|
+
if (cleanedStyle[property] === DEFAULT_STYLE[property]) {
|
|
37864
37996
|
delete cleanedStyle[property];
|
|
37865
37997
|
}
|
|
37866
37998
|
}
|
|
@@ -38016,10 +38148,7 @@ class CellPlugin extends CorePlugin {
|
|
|
38016
38148
|
else {
|
|
38017
38149
|
style = before ? before.style : undefined;
|
|
38018
38150
|
}
|
|
38019
|
-
const
|
|
38020
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
38021
|
-
detectDateFormat(afterContent, locale) ||
|
|
38022
|
-
detectNumberFormat(afterContent);
|
|
38151
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
38023
38152
|
/* Read the following IF as:
|
|
38024
38153
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
38025
38154
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -38060,6 +38189,7 @@ class CellPlugin extends CorePlugin {
|
|
|
38060
38189
|
}
|
|
38061
38190
|
createLiteralCell(id, content, format, style) {
|
|
38062
38191
|
const locale = this.getters.getLocale();
|
|
38192
|
+
format = format || detectDateFormat(content, locale) || detectNumberFormat(content);
|
|
38063
38193
|
if (format !== PLAIN_TEXT_FORMAT && !isEvaluationError(content)) {
|
|
38064
38194
|
content = toString(parseLiteral(content, locale));
|
|
38065
38195
|
}
|
|
@@ -38132,6 +38262,18 @@ class CellPlugin extends CorePlugin {
|
|
|
38132
38262
|
}
|
|
38133
38263
|
return "Success" /* CommandResult.Success */;
|
|
38134
38264
|
}
|
|
38265
|
+
checkUselessUpdateCell(cmd) {
|
|
38266
|
+
const cell = this.getters.getCell(cmd);
|
|
38267
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
38268
|
+
const hasStyle = "style" in cmd;
|
|
38269
|
+
const hasFormat = "format" in cmd;
|
|
38270
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
38271
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
38272
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
38273
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
38274
|
+
}
|
|
38275
|
+
return "Success" /* CommandResult.Success */;
|
|
38276
|
+
}
|
|
38135
38277
|
}
|
|
38136
38278
|
class FormulaCellWithDependencies {
|
|
38137
38279
|
id;
|
|
@@ -42947,7 +43089,15 @@ class SpreadsheetRTree {
|
|
|
42947
43089
|
if (!this.rTrees[sheetId]) {
|
|
42948
43090
|
return;
|
|
42949
43091
|
}
|
|
42950
|
-
this.rTrees[sheetId].remove(item,
|
|
43092
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
43093
|
+
}
|
|
43094
|
+
rtreeItemComparer(left, right) {
|
|
43095
|
+
return (left.data == right.data &&
|
|
43096
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
43097
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
43098
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
43099
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
43100
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
42951
43101
|
}
|
|
42952
43102
|
}
|
|
42953
43103
|
/**
|
|
@@ -43025,7 +43175,7 @@ class FormulaDependencyGraph {
|
|
|
43025
43175
|
const queue = Array.from(ranges).reverse();
|
|
43026
43176
|
while (queue.length > 0) {
|
|
43027
43177
|
const range = queue.pop();
|
|
43028
|
-
visited.
|
|
43178
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
43029
43179
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
43030
43180
|
for (const positionId of impactedPositionIds) {
|
|
43031
43181
|
if (!visited.has(positionId)) {
|
|
@@ -43033,7 +43183,7 @@ class FormulaDependencyGraph {
|
|
|
43033
43183
|
}
|
|
43034
43184
|
}
|
|
43035
43185
|
}
|
|
43036
|
-
visited.
|
|
43186
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
43037
43187
|
return visited;
|
|
43038
43188
|
}
|
|
43039
43189
|
}
|
|
@@ -43119,6 +43269,7 @@ const EMPTY_ARRAY = [];
|
|
|
43119
43269
|
const MAX_ITERATION = 30;
|
|
43120
43270
|
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
43121
43271
|
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
43272
|
+
const EVAL_CONTEXT_INDEX = 2;
|
|
43122
43273
|
class Evaluator {
|
|
43123
43274
|
context;
|
|
43124
43275
|
getters;
|
|
@@ -43164,17 +43315,24 @@ class Evaluator {
|
|
|
43164
43315
|
const dependencies = this.getDirectDependencies(positionId);
|
|
43165
43316
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
43166
43317
|
}
|
|
43318
|
+
addDependencies(position, dependencies) {
|
|
43319
|
+
const positionId = this.encoder.encode(position);
|
|
43320
|
+
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
43321
|
+
}
|
|
43167
43322
|
updateCompilationParameters() {
|
|
43168
43323
|
// rebuild the compilation parameters (with a clean cache)
|
|
43169
43324
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
43325
|
+
this.compilationParams[EVAL_CONTEXT_INDEX].updateDependencies =
|
|
43326
|
+
this.updateDependencies.bind(this);
|
|
43327
|
+
this.compilationParams[EVAL_CONTEXT_INDEX].addDependencies = this.addDependencies.bind(this);
|
|
43170
43328
|
}
|
|
43171
43329
|
evaluateCells(positions) {
|
|
43172
43330
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
43173
43331
|
const cellsToCompute = new JetSet(cells);
|
|
43174
43332
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
43175
|
-
cellsToCompute.
|
|
43176
|
-
cellsToCompute.
|
|
43177
|
-
cellsToCompute.
|
|
43333
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
43334
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
43335
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
43178
43336
|
this.evaluate(cellsToCompute);
|
|
43179
43337
|
}
|
|
43180
43338
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -43188,7 +43346,7 @@ class Evaluator {
|
|
|
43188
43346
|
}
|
|
43189
43347
|
if (!content) {
|
|
43190
43348
|
// The previous content could have blocked some array formulas
|
|
43191
|
-
impactedPositionIds.
|
|
43349
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
43192
43350
|
}
|
|
43193
43351
|
}
|
|
43194
43352
|
return impactedPositionIds;
|
|
@@ -43240,7 +43398,7 @@ class Evaluator {
|
|
|
43240
43398
|
}
|
|
43241
43399
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
43242
43400
|
const cells = new JetSet(arrayFormulas);
|
|
43243
|
-
cells.
|
|
43401
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
43244
43402
|
return cells;
|
|
43245
43403
|
}
|
|
43246
43404
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -43368,7 +43526,7 @@ class Evaluator {
|
|
|
43368
43526
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
43369
43527
|
// check if formula dependencies present in the spread zone
|
|
43370
43528
|
// if so, they need to be recomputed
|
|
43371
|
-
this.nextPositionsToUpdate.
|
|
43529
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
43372
43530
|
};
|
|
43373
43531
|
}
|
|
43374
43532
|
invalidateSpreading(positionId) {
|
|
@@ -43383,8 +43541,8 @@ class Evaluator {
|
|
|
43383
43541
|
continue;
|
|
43384
43542
|
}
|
|
43385
43543
|
this.evaluatedCells.delete(child);
|
|
43386
|
-
this.nextPositionsToUpdate.
|
|
43387
|
-
this.nextPositionsToUpdate.
|
|
43544
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
43545
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
43388
43546
|
}
|
|
43389
43547
|
this.spreadingRelations.removeNode(positionId);
|
|
43390
43548
|
}
|
|
@@ -43513,15 +43671,15 @@ class PositionBitsEncoder {
|
|
|
43513
43671
|
}
|
|
43514
43672
|
}
|
|
43515
43673
|
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
43516
|
-
compilationParams[
|
|
43674
|
+
compilationParams[EVAL_CONTEXT_INDEX].__originCellXC = lazy(() => {
|
|
43517
43675
|
if (!cellId) {
|
|
43518
43676
|
return undefined;
|
|
43519
43677
|
}
|
|
43520
43678
|
// compute the value lazily for performance reasons
|
|
43521
|
-
const position = compilationParams[
|
|
43679
|
+
const position = compilationParams[EVAL_CONTEXT_INDEX].getters.getCellPosition(cellId);
|
|
43522
43680
|
return toXC(position.col, position.row);
|
|
43523
43681
|
});
|
|
43524
|
-
compilationParams[
|
|
43682
|
+
compilationParams[EVAL_CONTEXT_INDEX].__originSheetId = sheetId;
|
|
43525
43683
|
return compiledFormula.execute(compiledFormula.dependencies, ...compilationParams);
|
|
43526
43684
|
}
|
|
43527
43685
|
|
|
@@ -43851,8 +44009,13 @@ function colorDistance(color1, color2) {
|
|
|
43851
44009
|
*/
|
|
43852
44010
|
class CustomColorsPlugin extends UIPlugin {
|
|
43853
44011
|
customColors = {};
|
|
44012
|
+
configCustomColors;
|
|
43854
44013
|
shouldUpdateColors = false;
|
|
43855
44014
|
static getters = ["getCustomColors"];
|
|
44015
|
+
constructor(config) {
|
|
44016
|
+
super(config);
|
|
44017
|
+
this.configCustomColors = config.customColors;
|
|
44018
|
+
}
|
|
43856
44019
|
handle(cmd) {
|
|
43857
44020
|
switch (cmd.type) {
|
|
43858
44021
|
case "UPDATE_CELL":
|
|
@@ -43874,7 +44037,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
43874
44037
|
}
|
|
43875
44038
|
}
|
|
43876
44039
|
getCustomColors() {
|
|
43877
|
-
let usedColors =
|
|
44040
|
+
let usedColors = this.configCustomColors;
|
|
43878
44041
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
43879
44042
|
usedColors = usedColors.concat(this.getColorsFromCells(sheetId), this.getFormattingColors(sheetId), this.getChartColors(sheetId));
|
|
43880
44043
|
}
|
|
@@ -46847,7 +47010,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
46847
47010
|
"getCellText",
|
|
46848
47011
|
"getCellMultiLineText",
|
|
46849
47012
|
"getContiguousZone",
|
|
46850
|
-
"
|
|
47013
|
+
"isEvaluatedCellEmpty",
|
|
46851
47014
|
];
|
|
46852
47015
|
ctx = document.createElement("canvas").getContext("2d");
|
|
46853
47016
|
// ---------------------------------------------------------------------------
|
|
@@ -46975,14 +47138,26 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
46975
47138
|
return zone;
|
|
46976
47139
|
}
|
|
46977
47140
|
/**
|
|
46978
|
-
*
|
|
46979
|
-
* check
|
|
47141
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
47142
|
+
* the check applies to the main cell of the merge.
|
|
46980
47143
|
*/
|
|
46981
|
-
|
|
47144
|
+
//TODORAR this does not fit the new scheme where a cell with an empty string is not empty anymore
|
|
47145
|
+
// this means the navigation was acually altered with the recent change
|
|
47146
|
+
// remove the getter and put it back in selection processor as nobody uses it
|
|
47147
|
+
isEvaluatedCellEmpty(position) {
|
|
46982
47148
|
const mainPosition = this.getters.getMainCellPosition(position);
|
|
46983
47149
|
const cell = this.getters.getEvaluatedCell(mainPosition);
|
|
46984
47150
|
return cell.type === CellValueType.empty;
|
|
46985
47151
|
}
|
|
47152
|
+
/**
|
|
47153
|
+
* Checks if a cell is empty (i.e. does not have a content or a formula does not spread over it).
|
|
47154
|
+
* If the cell is part of a merge, the check applies to the main cell of the merge.
|
|
47155
|
+
*/
|
|
47156
|
+
isCellEmpty(position) {
|
|
47157
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
47158
|
+
return !(this.getters.getCorrespondingFormulaCell(mainPosition) ||
|
|
47159
|
+
this.getters.getCell(mainPosition)?.content);
|
|
47160
|
+
}
|
|
46986
47161
|
getColMaxWidth(sheetId, index) {
|
|
46987
47162
|
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
|
|
46988
47163
|
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
|
|
@@ -51517,7 +51692,7 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
51517
51692
|
if (ev.key === "Enter") {
|
|
51518
51693
|
ev.preventDefault();
|
|
51519
51694
|
ev.stopPropagation();
|
|
51520
|
-
this.store.selectNextMatch();
|
|
51695
|
+
ev.shiftKey ? this.store.selectPreviousMatch() : this.store.selectNextMatch();
|
|
51521
51696
|
}
|
|
51522
51697
|
}
|
|
51523
51698
|
onKeydownReplace(ev) {
|
|
@@ -53213,22 +53388,20 @@ css /* scss */ `
|
|
|
53213
53388
|
`;
|
|
53214
53389
|
class SidePanel extends owl.Component {
|
|
53215
53390
|
static template = "o-spreadsheet-SidePanel";
|
|
53216
|
-
static props = {
|
|
53217
|
-
|
|
53218
|
-
panelProps: { type: Object, optional: true },
|
|
53219
|
-
onCloseSidePanel: Function,
|
|
53220
|
-
};
|
|
53221
|
-
state;
|
|
53391
|
+
static props = {};
|
|
53392
|
+
sidePanelStore;
|
|
53222
53393
|
setup() {
|
|
53223
|
-
this.
|
|
53224
|
-
|
|
53225
|
-
|
|
53226
|
-
|
|
53394
|
+
this.sidePanelStore = useStore(SidePanelStore);
|
|
53395
|
+
}
|
|
53396
|
+
get panel() {
|
|
53397
|
+
return sidePanelRegistry.get(this.sidePanelStore.componentTag);
|
|
53398
|
+
}
|
|
53399
|
+
close() {
|
|
53400
|
+
this.sidePanelStore.close();
|
|
53227
53401
|
}
|
|
53228
53402
|
getTitle() {
|
|
53229
|
-
|
|
53230
|
-
|
|
53231
|
-
: this.state.panel.title;
|
|
53403
|
+
const panel = this.panel;
|
|
53404
|
+
return typeof panel.title === "function" ? panel.title(this.env) : panel.title;
|
|
53232
53405
|
}
|
|
53233
53406
|
}
|
|
53234
53407
|
|
|
@@ -54162,10 +54335,13 @@ class Spreadsheet extends owl.Component {
|
|
|
54162
54335
|
}
|
|
54163
54336
|
setup() {
|
|
54164
54337
|
const stores = useStoreProvider();
|
|
54165
|
-
|
|
54338
|
+
stores.inject(ModelStore, this.model);
|
|
54339
|
+
this.notificationStore = useStore(NotificationStore);
|
|
54340
|
+
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
54341
|
+
this.sidePanel = useStore(SidePanelStore);
|
|
54166
54342
|
this.keyDownMapping = {
|
|
54167
|
-
"CTRL+H": () => this.
|
|
54168
|
-
"CTRL+F": () => this.
|
|
54343
|
+
"CTRL+H": () => this.sidePanel.toggle("FindAndReplace", {}),
|
|
54344
|
+
"CTRL+F": () => this.sidePanel.toggle("FindAndReplace", {}),
|
|
54169
54345
|
};
|
|
54170
54346
|
const fileStore = this.model.config.external.fileStore;
|
|
54171
54347
|
owl.useSubEnv({
|
|
@@ -54174,11 +54350,10 @@ class Spreadsheet extends owl.Component {
|
|
|
54174
54350
|
loadCurrencies: this.model.config.external.loadCurrencies,
|
|
54175
54351
|
loadLocales: this.model.config.external.loadLocales,
|
|
54176
54352
|
isDashboard: () => this.model.getters.isDashboard(),
|
|
54177
|
-
openSidePanel: this.
|
|
54178
|
-
toggleSidePanel: this.
|
|
54353
|
+
openSidePanel: this.sidePanel.open.bind(this.sidePanel),
|
|
54354
|
+
toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
|
|
54179
54355
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
54180
54356
|
startCellEdition: (content) => this.composerFocusStore.focusGridComposerCell(content),
|
|
54181
|
-
//TODORAR: make a store out of this
|
|
54182
54357
|
});
|
|
54183
54358
|
owl.useEffect(() => {
|
|
54184
54359
|
/**
|
|
@@ -54207,9 +54382,6 @@ class Spreadsheet extends owl.Component {
|
|
|
54207
54382
|
owl.onPatched(() => {
|
|
54208
54383
|
this.checkViewportSize();
|
|
54209
54384
|
});
|
|
54210
|
-
stores.inject(ModelStore, this.model);
|
|
54211
|
-
this.notificationStore = useStore(NotificationStore);
|
|
54212
|
-
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
54213
54385
|
}
|
|
54214
54386
|
bindModelEvents() {
|
|
54215
54387
|
this.model.on("update", this, () => this.render(true));
|
|
@@ -54242,28 +54414,6 @@ class Spreadsheet extends owl.Component {
|
|
|
54242
54414
|
this.isViewportTooSmall = false;
|
|
54243
54415
|
}
|
|
54244
54416
|
}
|
|
54245
|
-
openSidePanel(panel, panelProps) {
|
|
54246
|
-
if (this.sidePanel.isOpen && panel !== this.sidePanel.component) {
|
|
54247
|
-
this.sidePanel.panelProps?.onCloseSidePanel?.();
|
|
54248
|
-
}
|
|
54249
|
-
this.sidePanel.component = panel;
|
|
54250
|
-
this.sidePanel.panelProps = panelProps;
|
|
54251
|
-
this.sidePanel.isOpen = true;
|
|
54252
|
-
}
|
|
54253
|
-
closeSidePanel() {
|
|
54254
|
-
this.sidePanel.isOpen = false;
|
|
54255
|
-
this.focusGrid();
|
|
54256
|
-
this.sidePanel.panelProps?.onCloseSidePanel?.();
|
|
54257
|
-
}
|
|
54258
|
-
toggleSidePanel(panel, panelProps) {
|
|
54259
|
-
if (this.sidePanel.isOpen && panel === this.sidePanel.component) {
|
|
54260
|
-
this.sidePanel.isOpen = false;
|
|
54261
|
-
this.focusGrid();
|
|
54262
|
-
}
|
|
54263
|
-
else {
|
|
54264
|
-
this.openSidePanel(panel, panelProps);
|
|
54265
|
-
}
|
|
54266
|
-
}
|
|
54267
54417
|
focusGrid() {
|
|
54268
54418
|
if (!this._focusGrid) {
|
|
54269
54419
|
return;
|
|
@@ -55692,8 +55842,8 @@ class SelectionStreamProcessorImpl {
|
|
|
55692
55842
|
let currentPosition = startPosition;
|
|
55693
55843
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
55694
55844
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
55695
|
-
let mode = !this.
|
|
55696
|
-
!this.
|
|
55845
|
+
let mode = !this.isCellSkippableInCluster({ ...currentPosition, sheetId }) &&
|
|
55846
|
+
!this.isCellSkippableInCluster({ ...nextCellPosition, sheetId })
|
|
55697
55847
|
? "endOfCluster"
|
|
55698
55848
|
: "nextCluster";
|
|
55699
55849
|
while (true) {
|
|
@@ -55703,7 +55853,7 @@ class SelectionStreamProcessorImpl {
|
|
|
55703
55853
|
currentPosition.row === nextCellPosition.row) {
|
|
55704
55854
|
break;
|
|
55705
55855
|
}
|
|
55706
|
-
const isNextCellEmpty = this.
|
|
55856
|
+
const isNextCellEmpty = this.isCellSkippableInCluster({ ...nextCellPosition, sheetId });
|
|
55707
55857
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
55708
55858
|
break;
|
|
55709
55859
|
}
|
|
@@ -55734,6 +55884,11 @@ class SelectionStreamProcessorImpl {
|
|
|
55734
55884
|
getPosition() {
|
|
55735
55885
|
return { ...this.anchor.cell };
|
|
55736
55886
|
}
|
|
55887
|
+
isCellSkippableInCluster(position) {
|
|
55888
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
55889
|
+
const cell = this.getters.getEvaluatedCell(mainPosition);
|
|
55890
|
+
return (cell.type === CellValueType.empty || (cell.type === CellValueType.text && cell.value === ""));
|
|
55891
|
+
}
|
|
55737
55892
|
}
|
|
55738
55893
|
|
|
55739
55894
|
class StateObserver {
|
|
@@ -57600,6 +57755,7 @@ class Model extends EventBus {
|
|
|
57600
57755
|
snapshotRequested: false,
|
|
57601
57756
|
notifyUI: (payload) => this.trigger("notify-ui", payload),
|
|
57602
57757
|
raiseBlockingErrorUI: (text) => this.trigger("raise-error-ui", { text }),
|
|
57758
|
+
customColors: config.customColors || [],
|
|
57603
57759
|
};
|
|
57604
57760
|
}
|
|
57605
57761
|
setupExternalConfig(external) {
|
|
@@ -57631,6 +57787,7 @@ class Model extends EventBus {
|
|
|
57631
57787
|
uiActions: this.config,
|
|
57632
57788
|
session: this.session,
|
|
57633
57789
|
defaultCurrencyFormat: this.config.defaultCurrencyFormat,
|
|
57790
|
+
customColors: this.config.customColors || [],
|
|
57634
57791
|
};
|
|
57635
57792
|
}
|
|
57636
57793
|
// ---------------------------------------------------------------------------
|
|
@@ -57930,6 +58087,10 @@ const helpers = {
|
|
|
57930
58087
|
deepEquals,
|
|
57931
58088
|
overlap,
|
|
57932
58089
|
union,
|
|
58090
|
+
isInside,
|
|
58091
|
+
deepCopy,
|
|
58092
|
+
expandZoneOnInsertion,
|
|
58093
|
+
reduceZoneOnDeletion,
|
|
57933
58094
|
};
|
|
57934
58095
|
const links = {
|
|
57935
58096
|
isMarkdownLink,
|
|
@@ -57984,6 +58145,9 @@ const stores = {
|
|
|
57984
58145
|
RendererStore,
|
|
57985
58146
|
SelectionInputStore,
|
|
57986
58147
|
SpreadsheetStore,
|
|
58148
|
+
useStore,
|
|
58149
|
+
useLocalStore,
|
|
58150
|
+
SidePanelStore,
|
|
57987
58151
|
};
|
|
57988
58152
|
function addFunction(functionName, functionDescription) {
|
|
57989
58153
|
functionRegistry.add(functionName, functionDescription);
|
|
@@ -57996,7 +58160,9 @@ const constants = {
|
|
|
57996
58160
|
SECONDARY_COLOR,
|
|
57997
58161
|
};
|
|
57998
58162
|
|
|
58163
|
+
exports.AbstractCellClipboardHandler = AbstractCellClipboardHandler;
|
|
57999
58164
|
exports.AbstractChart = AbstractChart;
|
|
58165
|
+
exports.AbstractFigureClipboardHandler = AbstractFigureClipboardHandler;
|
|
58000
58166
|
exports.CellErrorType = CellErrorType;
|
|
58001
58167
|
exports.CorePlugin = CorePlugin;
|
|
58002
58168
|
exports.DispatchResult = DispatchResult;
|
|
@@ -58036,6 +58202,6 @@ exports.stores = stores;
|
|
|
58036
58202
|
exports.tokenize = tokenize;
|
|
58037
58203
|
|
|
58038
58204
|
|
|
58039
|
-
__info__.version = "17.2.0-alpha.
|
|
58040
|
-
__info__.date = "2024-02-
|
|
58041
|
-
__info__.hash = "
|
|
58205
|
+
__info__.version = "17.2.0-alpha.5";
|
|
58206
|
+
__info__.date = "2024-02-16T14:27:52.323Z";
|
|
58207
|
+
__info__.hash = "0c69dd8";
|