@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
|
import { reactive, useEnv, useSubEnv, useState, onWillUnmount, markRaw, toRaw, Component, useRef, onMounted, useEffect, onPatched, useComponent, onWillPatch, onWillUpdateProps, useExternalListener, xml, useChildSubEnv, onWillStart } from '@odoo/owl';
|
|
@@ -453,8 +453,8 @@ function isObjectEmptyRecursive(argument) {
|
|
|
453
453
|
* If the given item does not exist in the dictionary, it creates one with a new id.
|
|
454
454
|
*/
|
|
455
455
|
function getItemId(item, itemsDic) {
|
|
456
|
-
for (
|
|
457
|
-
if (deepEquals(
|
|
456
|
+
for (const key in itemsDic) {
|
|
457
|
+
if (deepEquals(itemsDic[key], item)) {
|
|
458
458
|
return parseInt(key, 10);
|
|
459
459
|
}
|
|
460
460
|
}
|
|
@@ -558,11 +558,13 @@ function deepEquals(o1, o2) {
|
|
|
558
558
|
if (typeof o1 !== "object")
|
|
559
559
|
return o1 === o2;
|
|
560
560
|
// Objects can have different keys if the values are undefined
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
561
|
+
for (const key in o2) {
|
|
562
|
+
if (!(key in o1) && o2[key] !== undefined) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
for (const key in o1) {
|
|
567
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
566
568
|
return false;
|
|
567
569
|
if (typeof o1[key] === "object") {
|
|
568
570
|
if (!deepEquals(o1[key], o2[key]))
|
|
@@ -632,18 +634,18 @@ function isConsecutive(iterable) {
|
|
|
632
634
|
return true;
|
|
633
635
|
}
|
|
634
636
|
class JetSet extends Set {
|
|
635
|
-
|
|
637
|
+
addMany(iterable) {
|
|
636
638
|
for (const element of iterable) {
|
|
637
639
|
super.add(element);
|
|
638
640
|
}
|
|
639
641
|
return this;
|
|
640
642
|
}
|
|
641
|
-
|
|
642
|
-
let
|
|
643
|
+
deleteMany(iterable) {
|
|
644
|
+
let wasDeleted = false;
|
|
643
645
|
for (const element of iterable) {
|
|
644
|
-
|
|
646
|
+
wasDeleted ||= super.delete(element);
|
|
645
647
|
}
|
|
646
|
-
return
|
|
648
|
+
return wasDeleted;
|
|
647
649
|
}
|
|
648
650
|
}
|
|
649
651
|
/**
|
|
@@ -1945,7 +1947,7 @@ class DispatchResult {
|
|
|
1945
1947
|
* Static helper which returns a successful DispatchResult
|
|
1946
1948
|
*/
|
|
1947
1949
|
static get Success() {
|
|
1948
|
-
return
|
|
1950
|
+
return SUCCESS;
|
|
1949
1951
|
}
|
|
1950
1952
|
get isSuccessful() {
|
|
1951
1953
|
return this.reasons.length === 0;
|
|
@@ -1958,6 +1960,7 @@ class DispatchResult {
|
|
|
1958
1960
|
return this.reasons.includes(reason);
|
|
1959
1961
|
}
|
|
1960
1962
|
}
|
|
1963
|
+
const SUCCESS = new DispatchResult();
|
|
1961
1964
|
var CommandResult;
|
|
1962
1965
|
(function (CommandResult) {
|
|
1963
1966
|
CommandResult["Success"] = "Success";
|
|
@@ -2264,7 +2267,7 @@ const normalizeString = memoize(function normalizeString(str) {
|
|
|
2264
2267
|
.normalize("NFD")
|
|
2265
2268
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2266
2269
|
});
|
|
2267
|
-
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a
|
|
2270
|
+
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);
|
|
2268
2271
|
function toBoolean(data) {
|
|
2269
2272
|
const value = toValue(data);
|
|
2270
2273
|
switch (typeof value) {
|
|
@@ -7528,6 +7531,9 @@ class DependencyContainer {
|
|
|
7528
7531
|
* Also useful for mocking a store.
|
|
7529
7532
|
*/
|
|
7530
7533
|
inject(Store, instance) {
|
|
7534
|
+
if (this.dependencies.has(Store) && this.dependencies.get(Store) !== instance) {
|
|
7535
|
+
throw new Error(`Store ${Store.name} already has an instance`);
|
|
7536
|
+
}
|
|
7531
7537
|
this.dependencies.set(Store, instance);
|
|
7532
7538
|
}
|
|
7533
7539
|
/**
|
|
@@ -11356,8 +11362,10 @@ class ChartFigure extends Component {
|
|
|
11356
11362
|
};
|
|
11357
11363
|
static components = {};
|
|
11358
11364
|
onDoubleClick() {
|
|
11359
|
-
this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
11360
|
-
|
|
11365
|
+
const result = this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
11366
|
+
if (result.isSuccessful) {
|
|
11367
|
+
this.env.openSidePanel("ChartPanel");
|
|
11368
|
+
}
|
|
11361
11369
|
}
|
|
11362
11370
|
get chartType() {
|
|
11363
11371
|
return this.env.model.getters.getChartType(this.props.figure.id);
|
|
@@ -13914,6 +13922,12 @@ const INSERT_LINK = (env) => {
|
|
|
13914
13922
|
let { col, row } = env.model.getters.getActivePosition();
|
|
13915
13923
|
env.getStore(CellPopoverStore).open({ col, row }, "LinkEditor");
|
|
13916
13924
|
};
|
|
13925
|
+
const INSERT_LINK_NAME = (env) => {
|
|
13926
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
13927
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
13928
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
13929
|
+
return cell && cell.link ? _t("Edit link") : _t("Insert link");
|
|
13930
|
+
};
|
|
13917
13931
|
//------------------------------------------------------------------------------
|
|
13918
13932
|
// Filters action
|
|
13919
13933
|
//------------------------------------------------------------------------------
|
|
@@ -21720,6 +21734,68 @@ const INDEX = {
|
|
|
21720
21734
|
isExported: true,
|
|
21721
21735
|
};
|
|
21722
21736
|
// -----------------------------------------------------------------------------
|
|
21737
|
+
// INDEX
|
|
21738
|
+
// -----------------------------------------------------------------------------
|
|
21739
|
+
const INDIRECT = {
|
|
21740
|
+
description: _t("Returns the content of a cell, specified by a string."),
|
|
21741
|
+
args: [
|
|
21742
|
+
arg("reference (string)", _t("The range of cells from which the values are returned.")),
|
|
21743
|
+
arg("use_a1_notation (boolean, default=TRUE)", _t("A boolean indicating whether to use A1 style notation (TRUE) or R1C1 style notation (FALSE).")),
|
|
21744
|
+
],
|
|
21745
|
+
returns: ["ANY"],
|
|
21746
|
+
compute: function (reference, useA1Notation = { value: true }) {
|
|
21747
|
+
let _reference = reference?.value?.toString();
|
|
21748
|
+
if (!_reference) {
|
|
21749
|
+
throw new InvalidReferenceError(_t("Reference should be defined."));
|
|
21750
|
+
}
|
|
21751
|
+
const _useA1Notation = toBoolean(useA1Notation);
|
|
21752
|
+
if (!_useA1Notation) {
|
|
21753
|
+
throw new EvaluationError(_t("R1C1 notation is not supported."));
|
|
21754
|
+
}
|
|
21755
|
+
const sheetId = this.__originSheetId;
|
|
21756
|
+
let originPosition;
|
|
21757
|
+
const __originCellXC = this.__originCellXC?.();
|
|
21758
|
+
if (__originCellXC) {
|
|
21759
|
+
const cellZone = toZone(__originCellXC);
|
|
21760
|
+
originPosition = {
|
|
21761
|
+
sheetId,
|
|
21762
|
+
col: cellZone.left,
|
|
21763
|
+
row: cellZone.top,
|
|
21764
|
+
};
|
|
21765
|
+
// The following line is used to reset the dependencies of the cell, to avoid
|
|
21766
|
+
// keeping dependencies from previous evaluation of the INDIRECT formula (i.e.
|
|
21767
|
+
// in case the reference has been changed).
|
|
21768
|
+
this.updateDependencies?.(originPosition);
|
|
21769
|
+
}
|
|
21770
|
+
const range = this.getters.getRangeFromSheetXC(sheetId, _reference);
|
|
21771
|
+
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
21772
|
+
throw new InvalidReferenceError();
|
|
21773
|
+
}
|
|
21774
|
+
if (originPosition) {
|
|
21775
|
+
this.addDependencies?.(originPosition, [range]);
|
|
21776
|
+
}
|
|
21777
|
+
const values = [];
|
|
21778
|
+
for (let col = range.zone.left; col <= range.zone.right; col++) {
|
|
21779
|
+
const colValues = [];
|
|
21780
|
+
for (let row = range.zone.top; row <= range.zone.bottom; row++) {
|
|
21781
|
+
const position = { sheetId: range.sheetId, col, row };
|
|
21782
|
+
// The below 'value' is typed as CellValue because the evaluateFormula will have to
|
|
21783
|
+
// evaluate a string containing the A1 reference of a single cell, so this will
|
|
21784
|
+
// return a CellValue.
|
|
21785
|
+
const value = this.getters.evaluateFormula(range.sheetId, toXC(col, row));
|
|
21786
|
+
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
21787
|
+
colValues.push({
|
|
21788
|
+
...evaluatedCell,
|
|
21789
|
+
value,
|
|
21790
|
+
});
|
|
21791
|
+
}
|
|
21792
|
+
values.push(colValues);
|
|
21793
|
+
}
|
|
21794
|
+
return values.length === 1 && values[0].length === 1 ? values[0][0] : values;
|
|
21795
|
+
},
|
|
21796
|
+
isExported: true,
|
|
21797
|
+
};
|
|
21798
|
+
// -----------------------------------------------------------------------------
|
|
21723
21799
|
// LOOKUP
|
|
21724
21800
|
// -----------------------------------------------------------------------------
|
|
21725
21801
|
const LOOKUP = {
|
|
@@ -21925,6 +22001,7 @@ var lookup = /*#__PURE__*/Object.freeze({
|
|
|
21925
22001
|
COLUMNS: COLUMNS,
|
|
21926
22002
|
HLOOKUP: HLOOKUP,
|
|
21927
22003
|
INDEX: INDEX,
|
|
22004
|
+
INDIRECT: INDIRECT,
|
|
21928
22005
|
LOOKUP: LOOKUP,
|
|
21929
22006
|
MATCH: MATCH,
|
|
21930
22007
|
ROW: ROW,
|
|
@@ -22900,7 +22977,7 @@ const insertImage = {
|
|
|
22900
22977
|
};
|
|
22901
22978
|
const insertFunction = {
|
|
22902
22979
|
name: _t("Function"),
|
|
22903
|
-
icon: "o-spreadsheet-Icon.
|
|
22980
|
+
icon: "o-spreadsheet-Icon.FORMULA",
|
|
22904
22981
|
};
|
|
22905
22982
|
const insertFunctionSum = {
|
|
22906
22983
|
name: _t("SUM"),
|
|
@@ -23122,7 +23199,7 @@ cellMenuRegistry
|
|
|
23122
23199
|
})
|
|
23123
23200
|
.add("insert_link", {
|
|
23124
23201
|
...insertLink,
|
|
23125
|
-
name:
|
|
23202
|
+
name: INSERT_LINK_NAME,
|
|
23126
23203
|
sequence: 150,
|
|
23127
23204
|
separator: true,
|
|
23128
23205
|
});
|
|
@@ -23787,9 +23864,7 @@ const freezeCurrentCol = {
|
|
|
23787
23864
|
isReadonlyAllowed: true,
|
|
23788
23865
|
};
|
|
23789
23866
|
const viewGridlines = {
|
|
23790
|
-
name: (
|
|
23791
|
-
? _t("Hide gridlines")
|
|
23792
|
-
: _t("Show gridlines"),
|
|
23867
|
+
name: _t("Gridlines"),
|
|
23793
23868
|
execute: (env) => {
|
|
23794
23869
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
23795
23870
|
env.model.dispatch("SET_GRID_LINES_VISIBILITY", {
|
|
@@ -23797,13 +23872,16 @@ const viewGridlines = {
|
|
|
23797
23872
|
areGridLinesVisible: !env.model.getters.getGridLinesVisibility(sheetId),
|
|
23798
23873
|
});
|
|
23799
23874
|
},
|
|
23800
|
-
|
|
23875
|
+
isActive: (env) => {
|
|
23876
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
23877
|
+
return env.model.getters.getGridLinesVisibility(sheetId);
|
|
23878
|
+
},
|
|
23801
23879
|
};
|
|
23802
23880
|
const viewFormulas = {
|
|
23803
|
-
name:
|
|
23881
|
+
name: _t("Formulas"),
|
|
23882
|
+
isActive: (env) => env.model.getters.shouldShowFormulas(),
|
|
23804
23883
|
execute: (env) => env.model.dispatch("SET_FORMULA_VISIBILITY", { show: !env.model.getters.shouldShowFormulas() }),
|
|
23805
23884
|
isReadonlyAllowed: true,
|
|
23806
|
-
icon: "o-spreadsheet-Icon.SHOW_HIDE_FORMULA",
|
|
23807
23885
|
};
|
|
23808
23886
|
const createRemoveFilter = {
|
|
23809
23887
|
name: (env) => selectionContainsFilter(env) ? _t("Remove selected filters") : _t("Create filter"),
|
|
@@ -24360,13 +24438,18 @@ topbarMenuRegistry
|
|
|
24360
24438
|
isVisible: (env) => canUngroupHeaders(env, "ROW"),
|
|
24361
24439
|
sequence: 20,
|
|
24362
24440
|
})
|
|
24363
|
-
.addChild("
|
|
24441
|
+
.addChild("show", ["view"], {
|
|
24442
|
+
name: _t("Show"),
|
|
24443
|
+
sequence: 1,
|
|
24444
|
+
icon: "o-spreadsheet-Icon.SHOW",
|
|
24445
|
+
})
|
|
24446
|
+
.addChild("view_gridlines", ["view", "show"], {
|
|
24364
24447
|
...viewGridlines,
|
|
24365
|
-
sequence:
|
|
24448
|
+
sequence: 5,
|
|
24366
24449
|
})
|
|
24367
|
-
.addChild("view_formulas", ["view"], {
|
|
24450
|
+
.addChild("view_formulas", ["view", "show"], {
|
|
24368
24451
|
...viewFormulas,
|
|
24369
|
-
sequence:
|
|
24452
|
+
sequence: 10,
|
|
24370
24453
|
})
|
|
24371
24454
|
// ---------------------------------------------------------------------
|
|
24372
24455
|
// INSERT MENU ITEMS
|
|
@@ -25349,6 +25432,17 @@ class TextValueProvider extends Component {
|
|
|
25349
25432
|
onValueSelected: Function,
|
|
25350
25433
|
onValueHovered: Function,
|
|
25351
25434
|
};
|
|
25435
|
+
autoCompleteListRef = useRef("autoCompleteList");
|
|
25436
|
+
setup() {
|
|
25437
|
+
useEffect(() => {
|
|
25438
|
+
const selectedIndex = this.props.selectedIndex;
|
|
25439
|
+
if (selectedIndex === undefined) {
|
|
25440
|
+
return;
|
|
25441
|
+
}
|
|
25442
|
+
const selectedElement = this.autoCompleteListRef.el?.children[selectedIndex];
|
|
25443
|
+
selectedElement?.scrollIntoView?.({ block: "nearest" });
|
|
25444
|
+
}, () => [this.props.selectedIndex, this.autoCompleteListRef.el]);
|
|
25445
|
+
}
|
|
25352
25446
|
}
|
|
25353
25447
|
|
|
25354
25448
|
class ContentEditableHelper {
|
|
@@ -25793,6 +25887,7 @@ css /* scss */ `
|
|
|
25793
25887
|
position: absolute;
|
|
25794
25888
|
margin: 1px 4px;
|
|
25795
25889
|
pointer-events: none;
|
|
25890
|
+
overflow: auto;
|
|
25796
25891
|
|
|
25797
25892
|
.o-semi-bold {
|
|
25798
25893
|
/** FIXME: to remove in favor of Bootstrap
|
|
@@ -25852,7 +25947,10 @@ class Composer extends Component {
|
|
|
25852
25947
|
if (this.props.delimitation && this.props.rect) {
|
|
25853
25948
|
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
25854
25949
|
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
25950
|
+
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
25855
25951
|
if (cellY > remainingHeight) {
|
|
25952
|
+
const availableSpaceAbove = cellY;
|
|
25953
|
+
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
25856
25954
|
// render top
|
|
25857
25955
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
25858
25956
|
assistantStyle.top = `-3px`;
|
|
@@ -29457,6 +29555,34 @@ class VerticalScrollBar extends Component {
|
|
|
29457
29555
|
}
|
|
29458
29556
|
}
|
|
29459
29557
|
|
|
29558
|
+
class SidePanelStore extends SpreadsheetStore {
|
|
29559
|
+
isOpen = false;
|
|
29560
|
+
panelProps = {};
|
|
29561
|
+
componentTag = "";
|
|
29562
|
+
open(componentTag, panelProps = {}) {
|
|
29563
|
+
if (this.isOpen && componentTag !== this.componentTag) {
|
|
29564
|
+
this.panelProps?.onCloseSidePanel?.();
|
|
29565
|
+
}
|
|
29566
|
+
this.componentTag = componentTag;
|
|
29567
|
+
this.panelProps = panelProps;
|
|
29568
|
+
this.isOpen = true;
|
|
29569
|
+
}
|
|
29570
|
+
toggle(componentTag, panelProps) {
|
|
29571
|
+
if (this.isOpen && componentTag === this.componentTag) {
|
|
29572
|
+
this.close();
|
|
29573
|
+
}
|
|
29574
|
+
else {
|
|
29575
|
+
this.open(componentTag, panelProps);
|
|
29576
|
+
}
|
|
29577
|
+
}
|
|
29578
|
+
close() {
|
|
29579
|
+
this.panelProps.onCloseSidePanel?.();
|
|
29580
|
+
this.isOpen = false;
|
|
29581
|
+
this.panelProps = {};
|
|
29582
|
+
this.componentTag = "";
|
|
29583
|
+
}
|
|
29584
|
+
}
|
|
29585
|
+
|
|
29460
29586
|
const registries$1 = {
|
|
29461
29587
|
ROW: rowMenuRegistry,
|
|
29462
29588
|
COL: colMenuRegistry,
|
|
@@ -29470,7 +29596,6 @@ const registries$1 = {
|
|
|
29470
29596
|
class Grid extends Component {
|
|
29471
29597
|
static template = "o-spreadsheet-Grid";
|
|
29472
29598
|
static props = {
|
|
29473
|
-
sidePanelIsOpen: Boolean,
|
|
29474
29599
|
exposeFocus: Function,
|
|
29475
29600
|
};
|
|
29476
29601
|
static components = {
|
|
@@ -29499,6 +29624,7 @@ class Grid extends Component {
|
|
|
29499
29624
|
onMouseWheel;
|
|
29500
29625
|
canvasPosition;
|
|
29501
29626
|
hoveredCell;
|
|
29627
|
+
sidePanel;
|
|
29502
29628
|
setup() {
|
|
29503
29629
|
this.highlightStore = useStore(HighlightStore);
|
|
29504
29630
|
this.menuState = useState({
|
|
@@ -29512,6 +29638,7 @@ class Grid extends Component {
|
|
|
29512
29638
|
this.composerStore = useStore(ComposerStore);
|
|
29513
29639
|
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
29514
29640
|
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
29641
|
+
this.sidePanel = useStore(SidePanelStore);
|
|
29515
29642
|
useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
29516
29643
|
useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
29517
29644
|
useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
@@ -29524,6 +29651,11 @@ class Grid extends Component {
|
|
|
29524
29651
|
this.hoveredCell.clear();
|
|
29525
29652
|
});
|
|
29526
29653
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
29654
|
+
useEffect(() => {
|
|
29655
|
+
if (!this.sidePanel.isOpen) {
|
|
29656
|
+
this.DOMFocusableElementStore.focus();
|
|
29657
|
+
}
|
|
29658
|
+
}, () => [this.sidePanel.isOpen]);
|
|
29527
29659
|
}
|
|
29528
29660
|
onCellHovered({ col, row }) {
|
|
29529
29661
|
this.hoveredCell.hover({ col, row });
|
|
@@ -30900,6 +31032,7 @@ class Checkbox extends Component {
|
|
|
30900
31032
|
value: { type: Boolean, optional: true },
|
|
30901
31033
|
className: { type: String, optional: true },
|
|
30902
31034
|
name: { type: String, optional: true },
|
|
31035
|
+
title: { type: String, optional: true },
|
|
30903
31036
|
onChange: Function,
|
|
30904
31037
|
};
|
|
30905
31038
|
static defaultProps = { value: false };
|
|
@@ -31911,6 +32044,35 @@ chartSidePanelComponentRegistry
|
|
|
31911
32044
|
design: ScorecardChartDesignPanel,
|
|
31912
32045
|
});
|
|
31913
32046
|
|
|
32047
|
+
class MainChartPanelStore extends SpreadsheetStore {
|
|
32048
|
+
sidePanel = this.get(SidePanelStore);
|
|
32049
|
+
figureId;
|
|
32050
|
+
panel = "configuration";
|
|
32051
|
+
constructor(get, figureId) {
|
|
32052
|
+
super(get);
|
|
32053
|
+
this.figureId = figureId;
|
|
32054
|
+
}
|
|
32055
|
+
handle(cmd) {
|
|
32056
|
+
switch (cmd.type) {
|
|
32057
|
+
case "DELETE_FIGURE":
|
|
32058
|
+
if (this.sidePanel.componentTag === "ChartPanel" && this.figureId === cmd.id) {
|
|
32059
|
+
this.sidePanel.close();
|
|
32060
|
+
}
|
|
32061
|
+
break;
|
|
32062
|
+
case "SELECT_FIGURE":
|
|
32063
|
+
if (cmd.id) {
|
|
32064
|
+
this.figureId = cmd.id;
|
|
32065
|
+
}
|
|
32066
|
+
else if (this.sidePanel.componentTag === "ChartPanel") {
|
|
32067
|
+
this.sidePanel.close();
|
|
32068
|
+
}
|
|
32069
|
+
}
|
|
32070
|
+
}
|
|
32071
|
+
activatePanel(panel) {
|
|
32072
|
+
this.panel = panel;
|
|
32073
|
+
}
|
|
32074
|
+
}
|
|
32075
|
+
|
|
31914
32076
|
css /* scss */ `
|
|
31915
32077
|
.o-chart {
|
|
31916
32078
|
.o-panel {
|
|
@@ -31939,37 +32101,19 @@ class ChartPanel extends Component {
|
|
|
31939
32101
|
static template = "o-spreadsheet-ChartPanel";
|
|
31940
32102
|
static components = { Section };
|
|
31941
32103
|
static props = { onCloseSidePanel: Function };
|
|
31942
|
-
|
|
32104
|
+
store;
|
|
31943
32105
|
get figureId() {
|
|
31944
|
-
return this.
|
|
32106
|
+
return this.store.figureId;
|
|
31945
32107
|
}
|
|
31946
32108
|
setup() {
|
|
31947
|
-
|
|
31948
|
-
if (!selectedFigureId) {
|
|
31949
|
-
this.props.onCloseSidePanel();
|
|
31950
|
-
return;
|
|
31951
|
-
}
|
|
31952
|
-
this.state = useState({
|
|
31953
|
-
panel: "configuration",
|
|
31954
|
-
figureId: selectedFigureId,
|
|
31955
|
-
});
|
|
31956
|
-
onWillUpdateProps(() => {
|
|
31957
|
-
const selectedFigureId = this.env.model.getters.getSelectedFigureId();
|
|
31958
|
-
if (selectedFigureId && selectedFigureId !== this.state.figureId) {
|
|
31959
|
-
this.state.figureId = selectedFigureId;
|
|
31960
|
-
}
|
|
31961
|
-
if (!this.env.model.getters.isChartDefined(this.figureId)) {
|
|
31962
|
-
this.props.onCloseSidePanel();
|
|
31963
|
-
return;
|
|
31964
|
-
}
|
|
31965
|
-
});
|
|
32109
|
+
this.store = useLocalStore(MainChartPanelStore, this.env.model.getters.getSelectedFigureId());
|
|
31966
32110
|
}
|
|
31967
32111
|
updateChart(figureId, updateDefinition) {
|
|
31968
32112
|
if (figureId !== this.figureId) {
|
|
31969
32113
|
return;
|
|
31970
32114
|
}
|
|
31971
32115
|
const definition = {
|
|
31972
|
-
...this.getChartDefinition(),
|
|
32116
|
+
...this.getChartDefinition(this.figureId),
|
|
31973
32117
|
...updateDefinition,
|
|
31974
32118
|
};
|
|
31975
32119
|
return this.env.model.dispatch("UPDATE_CHART", {
|
|
@@ -31983,7 +32127,7 @@ class ChartPanel extends Component {
|
|
|
31983
32127
|
return;
|
|
31984
32128
|
}
|
|
31985
32129
|
const definition = {
|
|
31986
|
-
...this.getChartDefinition(),
|
|
32130
|
+
...this.getChartDefinition(this.figureId),
|
|
31987
32131
|
...updateDefinition,
|
|
31988
32132
|
};
|
|
31989
32133
|
return this.env.model.canDispatch("UPDATE_CHART", {
|
|
@@ -31993,6 +32137,9 @@ class ChartPanel extends Component {
|
|
|
31993
32137
|
});
|
|
31994
32138
|
}
|
|
31995
32139
|
onTypeChange(type) {
|
|
32140
|
+
if (!this.figureId) {
|
|
32141
|
+
return;
|
|
32142
|
+
}
|
|
31996
32143
|
const context = this.env.model.getters.getContextCreationChart(this.figureId);
|
|
31997
32144
|
if (!context) {
|
|
31998
32145
|
throw new Error("Chart not defined.");
|
|
@@ -32005,6 +32152,9 @@ class ChartPanel extends Component {
|
|
|
32005
32152
|
});
|
|
32006
32153
|
}
|
|
32007
32154
|
get chartPanel() {
|
|
32155
|
+
if (!this.figureId) {
|
|
32156
|
+
throw new Error("Chart not defined.");
|
|
32157
|
+
}
|
|
32008
32158
|
const type = this.env.model.getters.getChartType(this.figureId);
|
|
32009
32159
|
if (!type) {
|
|
32010
32160
|
throw new Error("Chart not defined.");
|
|
@@ -32015,15 +32165,12 @@ class ChartPanel extends Component {
|
|
|
32015
32165
|
}
|
|
32016
32166
|
return chartPanel;
|
|
32017
32167
|
}
|
|
32018
|
-
getChartDefinition(figureId
|
|
32168
|
+
getChartDefinition(figureId) {
|
|
32019
32169
|
return this.env.model.getters.getChartDefinition(figureId);
|
|
32020
32170
|
}
|
|
32021
32171
|
get chartTypes() {
|
|
32022
32172
|
return getChartTypes();
|
|
32023
32173
|
}
|
|
32024
|
-
activatePanel(panel) {
|
|
32025
|
-
this.state.panel = panel;
|
|
32026
|
-
}
|
|
32027
32174
|
}
|
|
32028
32175
|
|
|
32029
32176
|
const BORDER_COLOR = "#8B008B";
|
|
@@ -32117,7 +32264,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32117
32264
|
}
|
|
32118
32265
|
finalize() {
|
|
32119
32266
|
if (this.isSearchDirty) {
|
|
32120
|
-
this.refreshSearch();
|
|
32267
|
+
this.refreshSearch(false);
|
|
32121
32268
|
this.isSearchDirty = false;
|
|
32122
32269
|
}
|
|
32123
32270
|
}
|
|
@@ -32149,10 +32296,10 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32149
32296
|
/**
|
|
32150
32297
|
* refresh the matches according to the current search options
|
|
32151
32298
|
*/
|
|
32152
|
-
refreshSearch() {
|
|
32299
|
+
refreshSearch(jumpToMatchSheet = true) {
|
|
32153
32300
|
this.selectedMatchIndex = null;
|
|
32154
32301
|
this.findMatches();
|
|
32155
|
-
this.selectNextCell(Direction.current);
|
|
32302
|
+
this.selectNextCell(Direction.current, jumpToMatchSheet);
|
|
32156
32303
|
}
|
|
32157
32304
|
getSheetsInSearchOrder() {
|
|
32158
32305
|
switch (this.searchOptions.searchScope) {
|
|
@@ -32222,7 +32369,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32222
32369
|
* It is also used to keep coherence between the selected searchMatch
|
|
32223
32370
|
* and selectedMatchIndex.
|
|
32224
32371
|
*/
|
|
32225
|
-
selectNextCell(indexChange) {
|
|
32372
|
+
selectNextCell(indexChange, jumpToMatchSheet = true) {
|
|
32226
32373
|
const matches = this.searchMatches;
|
|
32227
32374
|
if (!matches.length) {
|
|
32228
32375
|
this.selectedMatchIndex = null;
|
|
@@ -32248,7 +32395,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
32248
32395
|
this.selectedMatchIndex = nextIndex;
|
|
32249
32396
|
const selectedMatch = matches[nextIndex];
|
|
32250
32397
|
// Switch to the sheet where the match is located
|
|
32251
|
-
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
32398
|
+
if (jumpToMatchSheet && this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
32252
32399
|
this.model.dispatch("ACTIVATE_SHEET", {
|
|
32253
32400
|
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
32254
32401
|
sheetIdTo: selectedMatch.sheetId,
|
|
@@ -36965,22 +37112,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
36965
37112
|
}
|
|
36966
37113
|
}
|
|
36967
37114
|
export(data) {
|
|
36968
|
-
// Borders
|
|
36969
|
-
let borderId = 0;
|
|
36970
37115
|
const borders = {};
|
|
36971
|
-
/**
|
|
36972
|
-
* Get the id of the given border. If the border does not exist, it creates
|
|
36973
|
-
* one.
|
|
36974
|
-
*/
|
|
36975
|
-
function getBorderId(border) {
|
|
36976
|
-
for (let [key, value] of Object.entries(borders)) {
|
|
36977
|
-
if (deepEquals(value, border)) {
|
|
36978
|
-
return parseInt(key, 10);
|
|
36979
|
-
}
|
|
36980
|
-
}
|
|
36981
|
-
borders[++borderId] = border;
|
|
36982
|
-
return borderId;
|
|
36983
|
-
}
|
|
36984
37116
|
for (let sheet of data.sheets) {
|
|
36985
37117
|
for (let col = 0; col < sheet.colNumber; col++) {
|
|
36986
37118
|
for (let row = 0; row < sheet.rowNumber; row++) {
|
|
@@ -36988,7 +37120,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
36988
37120
|
if (border) {
|
|
36989
37121
|
const xc = toXC(col, row);
|
|
36990
37122
|
const cell = sheet.cells[xc];
|
|
36991
|
-
const borderId =
|
|
37123
|
+
const borderId = getItemId(border, borders);
|
|
36992
37124
|
if (cell) {
|
|
36993
37125
|
cell.border = borderId;
|
|
36994
37126
|
}
|
|
@@ -37685,9 +37817,9 @@ class CellPlugin extends CorePlugin {
|
|
|
37685
37817
|
allowDispatch(cmd) {
|
|
37686
37818
|
switch (cmd.type) {
|
|
37687
37819
|
case "UPDATE_CELL":
|
|
37688
|
-
return this.
|
|
37820
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
37689
37821
|
case "CLEAR_CELL":
|
|
37690
|
-
return this.checkValidations(cmd, this.
|
|
37822
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
37691
37823
|
default:
|
|
37692
37824
|
return "Success" /* CommandResult.Success */;
|
|
37693
37825
|
}
|
|
@@ -37857,8 +37989,8 @@ class CellPlugin extends CorePlugin {
|
|
|
37857
37989
|
}
|
|
37858
37990
|
removeDefaultStyleValues(style) {
|
|
37859
37991
|
const cleanedStyle = { ...style };
|
|
37860
|
-
for (const
|
|
37861
|
-
if (cleanedStyle[property] ===
|
|
37992
|
+
for (const property in DEFAULT_STYLE) {
|
|
37993
|
+
if (cleanedStyle[property] === DEFAULT_STYLE[property]) {
|
|
37862
37994
|
delete cleanedStyle[property];
|
|
37863
37995
|
}
|
|
37864
37996
|
}
|
|
@@ -38014,10 +38146,7 @@ class CellPlugin extends CorePlugin {
|
|
|
38014
38146
|
else {
|
|
38015
38147
|
style = before ? before.style : undefined;
|
|
38016
38148
|
}
|
|
38017
|
-
const
|
|
38018
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
38019
|
-
detectDateFormat(afterContent, locale) ||
|
|
38020
|
-
detectNumberFormat(afterContent);
|
|
38149
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
38021
38150
|
/* Read the following IF as:
|
|
38022
38151
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
38023
38152
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -38058,6 +38187,7 @@ class CellPlugin extends CorePlugin {
|
|
|
38058
38187
|
}
|
|
38059
38188
|
createLiteralCell(id, content, format, style) {
|
|
38060
38189
|
const locale = this.getters.getLocale();
|
|
38190
|
+
format = format || detectDateFormat(content, locale) || detectNumberFormat(content);
|
|
38061
38191
|
if (format !== PLAIN_TEXT_FORMAT && !isEvaluationError(content)) {
|
|
38062
38192
|
content = toString(parseLiteral(content, locale));
|
|
38063
38193
|
}
|
|
@@ -38130,6 +38260,18 @@ class CellPlugin extends CorePlugin {
|
|
|
38130
38260
|
}
|
|
38131
38261
|
return "Success" /* CommandResult.Success */;
|
|
38132
38262
|
}
|
|
38263
|
+
checkUselessUpdateCell(cmd) {
|
|
38264
|
+
const cell = this.getters.getCell(cmd);
|
|
38265
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
38266
|
+
const hasStyle = "style" in cmd;
|
|
38267
|
+
const hasFormat = "format" in cmd;
|
|
38268
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
38269
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
38270
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
38271
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
38272
|
+
}
|
|
38273
|
+
return "Success" /* CommandResult.Success */;
|
|
38274
|
+
}
|
|
38133
38275
|
}
|
|
38134
38276
|
class FormulaCellWithDependencies {
|
|
38135
38277
|
id;
|
|
@@ -42945,7 +43087,15 @@ class SpreadsheetRTree {
|
|
|
42945
43087
|
if (!this.rTrees[sheetId]) {
|
|
42946
43088
|
return;
|
|
42947
43089
|
}
|
|
42948
|
-
this.rTrees[sheetId].remove(item,
|
|
43090
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
43091
|
+
}
|
|
43092
|
+
rtreeItemComparer(left, right) {
|
|
43093
|
+
return (left.data == right.data &&
|
|
43094
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
43095
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
43096
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
43097
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
43098
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
42949
43099
|
}
|
|
42950
43100
|
}
|
|
42951
43101
|
/**
|
|
@@ -43023,7 +43173,7 @@ class FormulaDependencyGraph {
|
|
|
43023
43173
|
const queue = Array.from(ranges).reverse();
|
|
43024
43174
|
while (queue.length > 0) {
|
|
43025
43175
|
const range = queue.pop();
|
|
43026
|
-
visited.
|
|
43176
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
43027
43177
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
43028
43178
|
for (const positionId of impactedPositionIds) {
|
|
43029
43179
|
if (!visited.has(positionId)) {
|
|
@@ -43031,7 +43181,7 @@ class FormulaDependencyGraph {
|
|
|
43031
43181
|
}
|
|
43032
43182
|
}
|
|
43033
43183
|
}
|
|
43034
|
-
visited.
|
|
43184
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
43035
43185
|
return visited;
|
|
43036
43186
|
}
|
|
43037
43187
|
}
|
|
@@ -43117,6 +43267,7 @@ const EMPTY_ARRAY = [];
|
|
|
43117
43267
|
const MAX_ITERATION = 30;
|
|
43118
43268
|
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
43119
43269
|
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
43270
|
+
const EVAL_CONTEXT_INDEX = 2;
|
|
43120
43271
|
class Evaluator {
|
|
43121
43272
|
context;
|
|
43122
43273
|
getters;
|
|
@@ -43162,17 +43313,24 @@ class Evaluator {
|
|
|
43162
43313
|
const dependencies = this.getDirectDependencies(positionId);
|
|
43163
43314
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
43164
43315
|
}
|
|
43316
|
+
addDependencies(position, dependencies) {
|
|
43317
|
+
const positionId = this.encoder.encode(position);
|
|
43318
|
+
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
43319
|
+
}
|
|
43165
43320
|
updateCompilationParameters() {
|
|
43166
43321
|
// rebuild the compilation parameters (with a clean cache)
|
|
43167
43322
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
43323
|
+
this.compilationParams[EVAL_CONTEXT_INDEX].updateDependencies =
|
|
43324
|
+
this.updateDependencies.bind(this);
|
|
43325
|
+
this.compilationParams[EVAL_CONTEXT_INDEX].addDependencies = this.addDependencies.bind(this);
|
|
43168
43326
|
}
|
|
43169
43327
|
evaluateCells(positions) {
|
|
43170
43328
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
43171
43329
|
const cellsToCompute = new JetSet(cells);
|
|
43172
43330
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
43173
|
-
cellsToCompute.
|
|
43174
|
-
cellsToCompute.
|
|
43175
|
-
cellsToCompute.
|
|
43331
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
43332
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
43333
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
43176
43334
|
this.evaluate(cellsToCompute);
|
|
43177
43335
|
}
|
|
43178
43336
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -43186,7 +43344,7 @@ class Evaluator {
|
|
|
43186
43344
|
}
|
|
43187
43345
|
if (!content) {
|
|
43188
43346
|
// The previous content could have blocked some array formulas
|
|
43189
|
-
impactedPositionIds.
|
|
43347
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
43190
43348
|
}
|
|
43191
43349
|
}
|
|
43192
43350
|
return impactedPositionIds;
|
|
@@ -43238,7 +43396,7 @@ class Evaluator {
|
|
|
43238
43396
|
}
|
|
43239
43397
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
43240
43398
|
const cells = new JetSet(arrayFormulas);
|
|
43241
|
-
cells.
|
|
43399
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
43242
43400
|
return cells;
|
|
43243
43401
|
}
|
|
43244
43402
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -43366,7 +43524,7 @@ class Evaluator {
|
|
|
43366
43524
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
43367
43525
|
// check if formula dependencies present in the spread zone
|
|
43368
43526
|
// if so, they need to be recomputed
|
|
43369
|
-
this.nextPositionsToUpdate.
|
|
43527
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
43370
43528
|
};
|
|
43371
43529
|
}
|
|
43372
43530
|
invalidateSpreading(positionId) {
|
|
@@ -43381,8 +43539,8 @@ class Evaluator {
|
|
|
43381
43539
|
continue;
|
|
43382
43540
|
}
|
|
43383
43541
|
this.evaluatedCells.delete(child);
|
|
43384
|
-
this.nextPositionsToUpdate.
|
|
43385
|
-
this.nextPositionsToUpdate.
|
|
43542
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
43543
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
43386
43544
|
}
|
|
43387
43545
|
this.spreadingRelations.removeNode(positionId);
|
|
43388
43546
|
}
|
|
@@ -43511,15 +43669,15 @@ class PositionBitsEncoder {
|
|
|
43511
43669
|
}
|
|
43512
43670
|
}
|
|
43513
43671
|
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
43514
|
-
compilationParams[
|
|
43672
|
+
compilationParams[EVAL_CONTEXT_INDEX].__originCellXC = lazy(() => {
|
|
43515
43673
|
if (!cellId) {
|
|
43516
43674
|
return undefined;
|
|
43517
43675
|
}
|
|
43518
43676
|
// compute the value lazily for performance reasons
|
|
43519
|
-
const position = compilationParams[
|
|
43677
|
+
const position = compilationParams[EVAL_CONTEXT_INDEX].getters.getCellPosition(cellId);
|
|
43520
43678
|
return toXC(position.col, position.row);
|
|
43521
43679
|
});
|
|
43522
|
-
compilationParams[
|
|
43680
|
+
compilationParams[EVAL_CONTEXT_INDEX].__originSheetId = sheetId;
|
|
43523
43681
|
return compiledFormula.execute(compiledFormula.dependencies, ...compilationParams);
|
|
43524
43682
|
}
|
|
43525
43683
|
|
|
@@ -43849,8 +44007,13 @@ function colorDistance(color1, color2) {
|
|
|
43849
44007
|
*/
|
|
43850
44008
|
class CustomColorsPlugin extends UIPlugin {
|
|
43851
44009
|
customColors = {};
|
|
44010
|
+
configCustomColors;
|
|
43852
44011
|
shouldUpdateColors = false;
|
|
43853
44012
|
static getters = ["getCustomColors"];
|
|
44013
|
+
constructor(config) {
|
|
44014
|
+
super(config);
|
|
44015
|
+
this.configCustomColors = config.customColors;
|
|
44016
|
+
}
|
|
43854
44017
|
handle(cmd) {
|
|
43855
44018
|
switch (cmd.type) {
|
|
43856
44019
|
case "UPDATE_CELL":
|
|
@@ -43872,7 +44035,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
43872
44035
|
}
|
|
43873
44036
|
}
|
|
43874
44037
|
getCustomColors() {
|
|
43875
|
-
let usedColors =
|
|
44038
|
+
let usedColors = this.configCustomColors;
|
|
43876
44039
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
43877
44040
|
usedColors = usedColors.concat(this.getColorsFromCells(sheetId), this.getFormattingColors(sheetId), this.getChartColors(sheetId));
|
|
43878
44041
|
}
|
|
@@ -46845,7 +47008,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
46845
47008
|
"getCellText",
|
|
46846
47009
|
"getCellMultiLineText",
|
|
46847
47010
|
"getContiguousZone",
|
|
46848
|
-
"
|
|
47011
|
+
"isEvaluatedCellEmpty",
|
|
46849
47012
|
];
|
|
46850
47013
|
ctx = document.createElement("canvas").getContext("2d");
|
|
46851
47014
|
// ---------------------------------------------------------------------------
|
|
@@ -46973,14 +47136,26 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
46973
47136
|
return zone;
|
|
46974
47137
|
}
|
|
46975
47138
|
/**
|
|
46976
|
-
*
|
|
46977
|
-
* check
|
|
47139
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
47140
|
+
* the check applies to the main cell of the merge.
|
|
46978
47141
|
*/
|
|
46979
|
-
|
|
47142
|
+
//TODORAR this does not fit the new scheme where a cell with an empty string is not empty anymore
|
|
47143
|
+
// this means the navigation was acually altered with the recent change
|
|
47144
|
+
// remove the getter and put it back in selection processor as nobody uses it
|
|
47145
|
+
isEvaluatedCellEmpty(position) {
|
|
46980
47146
|
const mainPosition = this.getters.getMainCellPosition(position);
|
|
46981
47147
|
const cell = this.getters.getEvaluatedCell(mainPosition);
|
|
46982
47148
|
return cell.type === CellValueType.empty;
|
|
46983
47149
|
}
|
|
47150
|
+
/**
|
|
47151
|
+
* Checks if a cell is empty (i.e. does not have a content or a formula does not spread over it).
|
|
47152
|
+
* If the cell is part of a merge, the check applies to the main cell of the merge.
|
|
47153
|
+
*/
|
|
47154
|
+
isCellEmpty(position) {
|
|
47155
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
47156
|
+
return !(this.getters.getCorrespondingFormulaCell(mainPosition) ||
|
|
47157
|
+
this.getters.getCell(mainPosition)?.content);
|
|
47158
|
+
}
|
|
46984
47159
|
getColMaxWidth(sheetId, index) {
|
|
46985
47160
|
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
|
|
46986
47161
|
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
|
|
@@ -51515,7 +51690,7 @@ class FindAndReplacePanel extends Component {
|
|
|
51515
51690
|
if (ev.key === "Enter") {
|
|
51516
51691
|
ev.preventDefault();
|
|
51517
51692
|
ev.stopPropagation();
|
|
51518
|
-
this.store.selectNextMatch();
|
|
51693
|
+
ev.shiftKey ? this.store.selectPreviousMatch() : this.store.selectNextMatch();
|
|
51519
51694
|
}
|
|
51520
51695
|
}
|
|
51521
51696
|
onKeydownReplace(ev) {
|
|
@@ -53211,22 +53386,20 @@ css /* scss */ `
|
|
|
53211
53386
|
`;
|
|
53212
53387
|
class SidePanel extends Component {
|
|
53213
53388
|
static template = "o-spreadsheet-SidePanel";
|
|
53214
|
-
static props = {
|
|
53215
|
-
|
|
53216
|
-
panelProps: { type: Object, optional: true },
|
|
53217
|
-
onCloseSidePanel: Function,
|
|
53218
|
-
};
|
|
53219
|
-
state;
|
|
53389
|
+
static props = {};
|
|
53390
|
+
sidePanelStore;
|
|
53220
53391
|
setup() {
|
|
53221
|
-
this.
|
|
53222
|
-
|
|
53223
|
-
|
|
53224
|
-
|
|
53392
|
+
this.sidePanelStore = useStore(SidePanelStore);
|
|
53393
|
+
}
|
|
53394
|
+
get panel() {
|
|
53395
|
+
return sidePanelRegistry.get(this.sidePanelStore.componentTag);
|
|
53396
|
+
}
|
|
53397
|
+
close() {
|
|
53398
|
+
this.sidePanelStore.close();
|
|
53225
53399
|
}
|
|
53226
53400
|
getTitle() {
|
|
53227
|
-
|
|
53228
|
-
|
|
53229
|
-
: this.state.panel.title;
|
|
53401
|
+
const panel = this.panel;
|
|
53402
|
+
return typeof panel.title === "function" ? panel.title(this.env) : panel.title;
|
|
53230
53403
|
}
|
|
53231
53404
|
}
|
|
53232
53405
|
|
|
@@ -54160,10 +54333,13 @@ class Spreadsheet extends Component {
|
|
|
54160
54333
|
}
|
|
54161
54334
|
setup() {
|
|
54162
54335
|
const stores = useStoreProvider();
|
|
54163
|
-
|
|
54336
|
+
stores.inject(ModelStore, this.model);
|
|
54337
|
+
this.notificationStore = useStore(NotificationStore);
|
|
54338
|
+
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
54339
|
+
this.sidePanel = useStore(SidePanelStore);
|
|
54164
54340
|
this.keyDownMapping = {
|
|
54165
|
-
"CTRL+H": () => this.
|
|
54166
|
-
"CTRL+F": () => this.
|
|
54341
|
+
"CTRL+H": () => this.sidePanel.toggle("FindAndReplace", {}),
|
|
54342
|
+
"CTRL+F": () => this.sidePanel.toggle("FindAndReplace", {}),
|
|
54167
54343
|
};
|
|
54168
54344
|
const fileStore = this.model.config.external.fileStore;
|
|
54169
54345
|
useSubEnv({
|
|
@@ -54172,11 +54348,10 @@ class Spreadsheet extends Component {
|
|
|
54172
54348
|
loadCurrencies: this.model.config.external.loadCurrencies,
|
|
54173
54349
|
loadLocales: this.model.config.external.loadLocales,
|
|
54174
54350
|
isDashboard: () => this.model.getters.isDashboard(),
|
|
54175
|
-
openSidePanel: this.
|
|
54176
|
-
toggleSidePanel: this.
|
|
54351
|
+
openSidePanel: this.sidePanel.open.bind(this.sidePanel),
|
|
54352
|
+
toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
|
|
54177
54353
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
54178
54354
|
startCellEdition: (content) => this.composerFocusStore.focusGridComposerCell(content),
|
|
54179
|
-
//TODORAR: make a store out of this
|
|
54180
54355
|
});
|
|
54181
54356
|
useEffect(() => {
|
|
54182
54357
|
/**
|
|
@@ -54205,9 +54380,6 @@ class Spreadsheet extends Component {
|
|
|
54205
54380
|
onPatched(() => {
|
|
54206
54381
|
this.checkViewportSize();
|
|
54207
54382
|
});
|
|
54208
|
-
stores.inject(ModelStore, this.model);
|
|
54209
|
-
this.notificationStore = useStore(NotificationStore);
|
|
54210
|
-
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
54211
54383
|
}
|
|
54212
54384
|
bindModelEvents() {
|
|
54213
54385
|
this.model.on("update", this, () => this.render(true));
|
|
@@ -54240,28 +54412,6 @@ class Spreadsheet extends Component {
|
|
|
54240
54412
|
this.isViewportTooSmall = false;
|
|
54241
54413
|
}
|
|
54242
54414
|
}
|
|
54243
|
-
openSidePanel(panel, panelProps) {
|
|
54244
|
-
if (this.sidePanel.isOpen && panel !== this.sidePanel.component) {
|
|
54245
|
-
this.sidePanel.panelProps?.onCloseSidePanel?.();
|
|
54246
|
-
}
|
|
54247
|
-
this.sidePanel.component = panel;
|
|
54248
|
-
this.sidePanel.panelProps = panelProps;
|
|
54249
|
-
this.sidePanel.isOpen = true;
|
|
54250
|
-
}
|
|
54251
|
-
closeSidePanel() {
|
|
54252
|
-
this.sidePanel.isOpen = false;
|
|
54253
|
-
this.focusGrid();
|
|
54254
|
-
this.sidePanel.panelProps?.onCloseSidePanel?.();
|
|
54255
|
-
}
|
|
54256
|
-
toggleSidePanel(panel, panelProps) {
|
|
54257
|
-
if (this.sidePanel.isOpen && panel === this.sidePanel.component) {
|
|
54258
|
-
this.sidePanel.isOpen = false;
|
|
54259
|
-
this.focusGrid();
|
|
54260
|
-
}
|
|
54261
|
-
else {
|
|
54262
|
-
this.openSidePanel(panel, panelProps);
|
|
54263
|
-
}
|
|
54264
|
-
}
|
|
54265
54415
|
focusGrid() {
|
|
54266
54416
|
if (!this._focusGrid) {
|
|
54267
54417
|
return;
|
|
@@ -55690,8 +55840,8 @@ class SelectionStreamProcessorImpl {
|
|
|
55690
55840
|
let currentPosition = startPosition;
|
|
55691
55841
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
55692
55842
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
55693
|
-
let mode = !this.
|
|
55694
|
-
!this.
|
|
55843
|
+
let mode = !this.isCellSkippableInCluster({ ...currentPosition, sheetId }) &&
|
|
55844
|
+
!this.isCellSkippableInCluster({ ...nextCellPosition, sheetId })
|
|
55695
55845
|
? "endOfCluster"
|
|
55696
55846
|
: "nextCluster";
|
|
55697
55847
|
while (true) {
|
|
@@ -55701,7 +55851,7 @@ class SelectionStreamProcessorImpl {
|
|
|
55701
55851
|
currentPosition.row === nextCellPosition.row) {
|
|
55702
55852
|
break;
|
|
55703
55853
|
}
|
|
55704
|
-
const isNextCellEmpty = this.
|
|
55854
|
+
const isNextCellEmpty = this.isCellSkippableInCluster({ ...nextCellPosition, sheetId });
|
|
55705
55855
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
55706
55856
|
break;
|
|
55707
55857
|
}
|
|
@@ -55732,6 +55882,11 @@ class SelectionStreamProcessorImpl {
|
|
|
55732
55882
|
getPosition() {
|
|
55733
55883
|
return { ...this.anchor.cell };
|
|
55734
55884
|
}
|
|
55885
|
+
isCellSkippableInCluster(position) {
|
|
55886
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
55887
|
+
const cell = this.getters.getEvaluatedCell(mainPosition);
|
|
55888
|
+
return (cell.type === CellValueType.empty || (cell.type === CellValueType.text && cell.value === ""));
|
|
55889
|
+
}
|
|
55735
55890
|
}
|
|
55736
55891
|
|
|
55737
55892
|
class StateObserver {
|
|
@@ -57598,6 +57753,7 @@ class Model extends EventBus {
|
|
|
57598
57753
|
snapshotRequested: false,
|
|
57599
57754
|
notifyUI: (payload) => this.trigger("notify-ui", payload),
|
|
57600
57755
|
raiseBlockingErrorUI: (text) => this.trigger("raise-error-ui", { text }),
|
|
57756
|
+
customColors: config.customColors || [],
|
|
57601
57757
|
};
|
|
57602
57758
|
}
|
|
57603
57759
|
setupExternalConfig(external) {
|
|
@@ -57629,6 +57785,7 @@ class Model extends EventBus {
|
|
|
57629
57785
|
uiActions: this.config,
|
|
57630
57786
|
session: this.session,
|
|
57631
57787
|
defaultCurrencyFormat: this.config.defaultCurrencyFormat,
|
|
57788
|
+
customColors: this.config.customColors || [],
|
|
57632
57789
|
};
|
|
57633
57790
|
}
|
|
57634
57791
|
// ---------------------------------------------------------------------------
|
|
@@ -57928,6 +58085,10 @@ const helpers = {
|
|
|
57928
58085
|
deepEquals,
|
|
57929
58086
|
overlap,
|
|
57930
58087
|
union,
|
|
58088
|
+
isInside,
|
|
58089
|
+
deepCopy,
|
|
58090
|
+
expandZoneOnInsertion,
|
|
58091
|
+
reduceZoneOnDeletion,
|
|
57931
58092
|
};
|
|
57932
58093
|
const links = {
|
|
57933
58094
|
isMarkdownLink,
|
|
@@ -57982,6 +58143,9 @@ const stores = {
|
|
|
57982
58143
|
RendererStore,
|
|
57983
58144
|
SelectionInputStore,
|
|
57984
58145
|
SpreadsheetStore,
|
|
58146
|
+
useStore,
|
|
58147
|
+
useLocalStore,
|
|
58148
|
+
SidePanelStore,
|
|
57985
58149
|
};
|
|
57986
58150
|
function addFunction(functionName, functionDescription) {
|
|
57987
58151
|
functionRegistry.add(functionName, functionDescription);
|
|
@@ -57994,9 +58158,9 @@ const constants = {
|
|
|
57994
58158
|
SECONDARY_COLOR,
|
|
57995
58159
|
};
|
|
57996
58160
|
|
|
57997
|
-
export { AbstractChart, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenize };
|
|
58161
|
+
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenize };
|
|
57998
58162
|
|
|
57999
58163
|
|
|
58000
|
-
__info__.version = "17.2.0-alpha.
|
|
58001
|
-
__info__.date = "2024-02-
|
|
58002
|
-
__info__.hash = "
|
|
58164
|
+
__info__.version = "17.2.0-alpha.5";
|
|
58165
|
+
__info__.date = "2024-02-16T14:27:52.323Z";
|
|
58166
|
+
__info__.hash = "0c69dd8";
|