@odoo/o-spreadsheet 19.1.0-alpha.3 → 19.1.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 +544 -261
- package/dist/o-spreadsheet.d.ts +245 -157
- package/dist/o-spreadsheet.esm.js +544 -261
- package/dist/o-spreadsheet.iife.js +544 -261
- package/dist/o-spreadsheet.iife.min.js +317 -317
- package/dist/o_spreadsheet.xml +87 -18
- package/package.json +5 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.1.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.1.0-alpha.5
|
|
6
|
+
* @date 2025-10-16T06:39:55.925Z
|
|
7
|
+
* @hash 1a0e3d5
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -592,7 +592,6 @@
|
|
|
592
592
|
const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
|
|
593
593
|
const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
|
|
594
594
|
const TEXT_HEADER_COLOR = "#666666";
|
|
595
|
-
const FIGURE_BORDER_COLOR = "#c9ccd2";
|
|
596
595
|
const SELECTION_BORDER_COLOR = "#3266ca";
|
|
597
596
|
const HEADER_BORDER_COLOR = "#C0C0C0";
|
|
598
597
|
const CELL_BORDER_COLOR = "#E2E3E3";
|
|
@@ -600,7 +599,6 @@
|
|
|
600
599
|
const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
|
|
601
600
|
const LINK_COLOR = HIGHLIGHT_COLOR;
|
|
602
601
|
const FILTERS_COLOR = "#188038";
|
|
603
|
-
const HEADER_GROUPING_BORDER_COLOR = "#999";
|
|
604
602
|
const FROZEN_PANE_HEADER_BORDER_COLOR = "#BCBCBC";
|
|
605
603
|
const FROZEN_PANE_BORDER_COLOR = "#DADFE8";
|
|
606
604
|
const COMPOSER_ASSISTANT_COLOR = "#9B359B";
|
|
@@ -843,22 +841,6 @@
|
|
|
843
841
|
// Miscellaneous
|
|
844
842
|
//------------------------------------------------------------------------------
|
|
845
843
|
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
846
|
-
/**
|
|
847
|
-
* Remove quotes from a quoted string
|
|
848
|
-
* ```js
|
|
849
|
-
* removeStringQuotes('"Hello"')
|
|
850
|
-
* > 'Hello'
|
|
851
|
-
* ```
|
|
852
|
-
*/
|
|
853
|
-
function removeStringQuotes(str) {
|
|
854
|
-
if (str[0] === '"') {
|
|
855
|
-
str = str.slice(1);
|
|
856
|
-
}
|
|
857
|
-
if (str[str.length - 1] === '"' && str[str.length - 2] !== "\\") {
|
|
858
|
-
return str.slice(0, str.length - 1);
|
|
859
|
-
}
|
|
860
|
-
return str;
|
|
861
|
-
}
|
|
862
844
|
function isCloneable(obj) {
|
|
863
845
|
return "clone" in obj && obj.clone instanceof Function;
|
|
864
846
|
}
|
|
@@ -927,6 +909,13 @@
|
|
|
927
909
|
function getUnquotedSheetName(sheetName) {
|
|
928
910
|
return unquote(sheetName, "'");
|
|
929
911
|
}
|
|
912
|
+
/**
|
|
913
|
+
* Remove quotes from a quoted string
|
|
914
|
+
* ```js
|
|
915
|
+
* unquote('"Hello"')
|
|
916
|
+
* > 'Hello'
|
|
917
|
+
* ```
|
|
918
|
+
*/
|
|
930
919
|
function unquote(string, quoteChar = '"') {
|
|
931
920
|
if (string.startsWith(quoteChar)) {
|
|
932
921
|
string = string.slice(1);
|
|
@@ -1331,9 +1320,7 @@
|
|
|
1331
1320
|
return newArray;
|
|
1332
1321
|
}
|
|
1333
1322
|
function insertItemsAtIndex(array, items, index) {
|
|
1334
|
-
|
|
1335
|
-
newArray.splice(index, 0, ...items);
|
|
1336
|
-
return newArray;
|
|
1323
|
+
return array.slice(0, index).concat(items).concat(array.slice(index));
|
|
1337
1324
|
}
|
|
1338
1325
|
function replaceItemAtIndex(array, newItem, index) {
|
|
1339
1326
|
const newArray = [...array];
|
|
@@ -4464,7 +4451,17 @@
|
|
|
4464
4451
|
return toMatrix(data).map((row) => {
|
|
4465
4452
|
return row.map((cell) => {
|
|
4466
4453
|
if (typeof cell.value !== "number") {
|
|
4467
|
-
|
|
4454
|
+
let message = "";
|
|
4455
|
+
if (typeof cell === "object") {
|
|
4456
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
|
|
4457
|
+
}
|
|
4458
|
+
else if (typeof cell === "string") {
|
|
4459
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
|
|
4460
|
+
}
|
|
4461
|
+
else if (typeof cell === "boolean") {
|
|
4462
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
|
|
4463
|
+
}
|
|
4464
|
+
throw new EvaluationError(message);
|
|
4468
4465
|
}
|
|
4469
4466
|
return cell.value;
|
|
4470
4467
|
});
|
|
@@ -5583,7 +5580,7 @@
|
|
|
5583
5580
|
* Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
|
|
5584
5581
|
*
|
|
5585
5582
|
* As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
|
|
5586
|
-
* preceded by a data token "h", then it's not a month but
|
|
5583
|
+
* preceded by a data token "h", then it's not a month but a minute.
|
|
5587
5584
|
*/
|
|
5588
5585
|
function convertTokensToMinutesInDateFormat(tokens) {
|
|
5589
5586
|
const dateParts = tokens.filter((token) => token.type === "DATE_PART");
|
|
@@ -5626,6 +5623,9 @@
|
|
|
5626
5623
|
case "REPEATED_CHAR":
|
|
5627
5624
|
format += "*" + token.value;
|
|
5628
5625
|
break;
|
|
5626
|
+
case "DATE_PART":
|
|
5627
|
+
format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
|
|
5628
|
+
break;
|
|
5629
5629
|
default:
|
|
5630
5630
|
format += token.value;
|
|
5631
5631
|
}
|
|
@@ -5699,7 +5699,7 @@
|
|
|
5699
5699
|
return value;
|
|
5700
5700
|
}
|
|
5701
5701
|
const internalFormat = parseFormat(format);
|
|
5702
|
-
const formatToApply =
|
|
5702
|
+
const formatToApply = getFormatToApply(value, internalFormat).format;
|
|
5703
5703
|
if (!formatToApply || formatToApply.type !== "text") {
|
|
5704
5704
|
return value;
|
|
5705
5705
|
}
|
|
@@ -5710,16 +5710,15 @@
|
|
|
5710
5710
|
format = createDefaultFormat(value);
|
|
5711
5711
|
}
|
|
5712
5712
|
const internalFormat = parseFormat(format);
|
|
5713
|
-
|
|
5714
|
-
|
|
5713
|
+
const { format: formatToApply, isNegativeFormat } = getFormatToApply(value, internalFormat);
|
|
5714
|
+
if (!formatToApply) {
|
|
5715
|
+
return value.toString();
|
|
5715
5716
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
formatToApply = internalFormat.negative;
|
|
5719
|
-
value = -value;
|
|
5717
|
+
if (formatToApply.type === "text") {
|
|
5718
|
+
return applyTextInternalFormat(value.toString(), formatToApply, formatWidth);
|
|
5720
5719
|
}
|
|
5721
|
-
|
|
5722
|
-
|
|
5720
|
+
if (isNegativeFormat) {
|
|
5721
|
+
value = Math.abs(value);
|
|
5723
5722
|
}
|
|
5724
5723
|
if (formatToApply.type === "date") {
|
|
5725
5724
|
return repeatCharToFitWidth(applyDateTimeFormat(value, formatToApply), formatWidth);
|
|
@@ -5731,6 +5730,31 @@
|
|
|
5731
5730
|
return "";
|
|
5732
5731
|
}
|
|
5733
5732
|
}
|
|
5733
|
+
function getFormatToApply(value, internalFormat) {
|
|
5734
|
+
let formatToApply = undefined;
|
|
5735
|
+
let isNegativeFormat = false;
|
|
5736
|
+
switch (typeof value) {
|
|
5737
|
+
case "number":
|
|
5738
|
+
if (value < 0 && internalFormat.negative) {
|
|
5739
|
+
formatToApply = internalFormat.negative;
|
|
5740
|
+
isNegativeFormat = true;
|
|
5741
|
+
}
|
|
5742
|
+
else if (value === 0 && internalFormat.zero) {
|
|
5743
|
+
formatToApply = internalFormat.zero;
|
|
5744
|
+
}
|
|
5745
|
+
else {
|
|
5746
|
+
formatToApply = internalFormat.positive;
|
|
5747
|
+
}
|
|
5748
|
+
break;
|
|
5749
|
+
case "string":
|
|
5750
|
+
const format = internalFormat.text || internalFormat.positive;
|
|
5751
|
+
if (format.type === "text") {
|
|
5752
|
+
formatToApply = format;
|
|
5753
|
+
}
|
|
5754
|
+
break;
|
|
5755
|
+
}
|
|
5756
|
+
return { format: formatToApply, isNegativeFormat };
|
|
5757
|
+
}
|
|
5734
5758
|
function applyTextInternalFormat(value, internalFormat, formatWidth) {
|
|
5735
5759
|
let formattedValue = "";
|
|
5736
5760
|
for (const token of internalFormat.tokens) {
|
|
@@ -6342,6 +6366,27 @@
|
|
|
6342
6366
|
return false;
|
|
6343
6367
|
}
|
|
6344
6368
|
}
|
|
6369
|
+
function formatHasRepeatedChar(value, format) {
|
|
6370
|
+
if (!format) {
|
|
6371
|
+
return false;
|
|
6372
|
+
}
|
|
6373
|
+
try {
|
|
6374
|
+
const internalFormat = parseFormat(format);
|
|
6375
|
+
const { format: formatToApply } = getFormatToApply(value, internalFormat);
|
|
6376
|
+
if (formatToApply?.type === "text" || formatToApply?.type === "date") {
|
|
6377
|
+
const tokens = formatToApply.tokens;
|
|
6378
|
+
return tokens.some((token) => token.type === "REPEATED_CHAR");
|
|
6379
|
+
}
|
|
6380
|
+
else if (formatToApply?.type === "number") {
|
|
6381
|
+
return (formatToApply.integerPart.some((token) => token.type === "REPEATED_CHAR") ||
|
|
6382
|
+
(formatToApply.decimalPart
|
|
6383
|
+
? formatToApply.decimalPart.some((token) => token.type === "REPEATED_CHAR")
|
|
6384
|
+
: false));
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6387
|
+
catch { }
|
|
6388
|
+
return false;
|
|
6389
|
+
}
|
|
6345
6390
|
|
|
6346
6391
|
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
6347
6392
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
@@ -6354,6 +6399,9 @@
|
|
|
6354
6399
|
if (content.startsWith("=")) {
|
|
6355
6400
|
throw new Error(`Cannot parse "${content}" because it's not a literal value. It's a formula`);
|
|
6356
6401
|
}
|
|
6402
|
+
if (content.startsWith("'")) {
|
|
6403
|
+
return content.slice(1);
|
|
6404
|
+
}
|
|
6357
6405
|
if (content === "") {
|
|
6358
6406
|
return null;
|
|
6359
6407
|
}
|
|
@@ -9303,6 +9351,32 @@
|
|
|
9303
9351
|
groups: [],
|
|
9304
9352
|
});
|
|
9305
9353
|
}
|
|
9354
|
+
function togglePivotCollapse(position, env) {
|
|
9355
|
+
const pivotCell = env.model.getters.getPivotCellFromPosition(position);
|
|
9356
|
+
const pivotId = env.model.getters.getPivotIdFromPosition(position);
|
|
9357
|
+
if (!pivotId || pivotCell.type !== "HEADER") {
|
|
9358
|
+
return;
|
|
9359
|
+
}
|
|
9360
|
+
const definition = env.model.getters.getPivotCoreDefinition(pivotId);
|
|
9361
|
+
const collapsedDomains = definition.collapsedDomains?.[pivotCell.dimension]
|
|
9362
|
+
? [...definition.collapsedDomains[pivotCell.dimension]]
|
|
9363
|
+
: [];
|
|
9364
|
+
const index = collapsedDomains.findIndex((domain) => deepEquals(domain, pivotCell.domain));
|
|
9365
|
+
if (index !== -1) {
|
|
9366
|
+
collapsedDomains.splice(index, 1);
|
|
9367
|
+
}
|
|
9368
|
+
else {
|
|
9369
|
+
collapsedDomains.push(pivotCell.domain);
|
|
9370
|
+
}
|
|
9371
|
+
const newDomains = definition.collapsedDomains
|
|
9372
|
+
? { ...definition.collapsedDomains }
|
|
9373
|
+
: { COL: [], ROW: [] };
|
|
9374
|
+
newDomains[pivotCell.dimension] = collapsedDomains;
|
|
9375
|
+
env.model.dispatch("UPDATE_PIVOT", {
|
|
9376
|
+
pivotId,
|
|
9377
|
+
pivot: { ...definition, collapsedDomains: newDomains },
|
|
9378
|
+
});
|
|
9379
|
+
}
|
|
9306
9380
|
|
|
9307
9381
|
class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
9308
9382
|
isCutAllowed(data) {
|
|
@@ -9476,7 +9550,7 @@
|
|
|
9476
9550
|
pasteCell(origin, target, clipboardOption) {
|
|
9477
9551
|
const { sheetId, col, row } = target;
|
|
9478
9552
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
9479
|
-
const originFormat = origin?.format
|
|
9553
|
+
const originFormat = origin?.format || origin.evaluatedCell.format;
|
|
9480
9554
|
if (clipboardOption?.pasteOption === "asValue") {
|
|
9481
9555
|
this.dispatch("UPDATE_CELL", {
|
|
9482
9556
|
...target,
|
|
@@ -13702,7 +13776,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13702
13776
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13703
13777
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13704
13778
|
}
|
|
13705
|
-
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "
|
|
13779
|
+
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
|
|
13706
13780
|
},
|
|
13707
13781
|
};
|
|
13708
13782
|
// -----------------------------------------------------------------------------
|
|
@@ -13775,7 +13849,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13775
13849
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13776
13850
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13777
13851
|
}
|
|
13778
|
-
return fullLinearRegression(toNumberMatrix(dataX, "
|
|
13852
|
+
return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
|
|
13779
13853
|
},
|
|
13780
13854
|
isExported: true,
|
|
13781
13855
|
};
|
|
@@ -13794,7 +13868,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13794
13868
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13795
13869
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13796
13870
|
}
|
|
13797
|
-
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "
|
|
13871
|
+
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
|
|
13798
13872
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13799
13873
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
13800
13874
|
}
|
|
@@ -14415,7 +14489,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14415
14489
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
14416
14490
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
14417
14491
|
}
|
|
14418
|
-
return predictLinearValues(toNumberMatrix(knownDataY, "
|
|
14492
|
+
return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
|
|
14419
14493
|
},
|
|
14420
14494
|
};
|
|
14421
14495
|
// -----------------------------------------------------------------------------
|
|
@@ -18636,7 +18710,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18636
18710
|
case "STRING":
|
|
18637
18711
|
return {
|
|
18638
18712
|
type: "STRING",
|
|
18639
|
-
value:
|
|
18713
|
+
value: unquote(current.value),
|
|
18640
18714
|
tokenStartIndex: current.tokenIndex,
|
|
18641
18715
|
tokenEndIndex: current.tokenIndex,
|
|
18642
18716
|
};
|
|
@@ -22393,7 +22467,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22393
22467
|
dependencies.push(token.value);
|
|
22394
22468
|
break;
|
|
22395
22469
|
case "STRING":
|
|
22396
|
-
const value =
|
|
22470
|
+
const value = unquote(token.value);
|
|
22397
22471
|
literalValues.strings.push({ value });
|
|
22398
22472
|
break;
|
|
22399
22473
|
case "NUMBER": {
|
|
@@ -22936,6 +23010,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22936
23010
|
}
|
|
22937
23011
|
const ctx = chart.ctx;
|
|
22938
23012
|
ctx.save();
|
|
23013
|
+
const { left, top, height, width } = chart.chartArea;
|
|
23014
|
+
ctx.beginPath();
|
|
23015
|
+
ctx.rect(left, top, width, height);
|
|
23016
|
+
ctx.clip();
|
|
22939
23017
|
ctx.textAlign = "center";
|
|
22940
23018
|
ctx.textBaseline = "middle";
|
|
22941
23019
|
ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
|
|
@@ -23970,7 +24048,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23970
24048
|
this.chart.update();
|
|
23971
24049
|
}
|
|
23972
24050
|
hasChartDataChanged() {
|
|
23973
|
-
return !deepEquals(this.currentRuntime
|
|
24051
|
+
return !deepEquals(this.getChartDataInRuntime(this.currentRuntime), this.getChartDataInRuntime(this.chartRuntime));
|
|
23974
24052
|
}
|
|
23975
24053
|
enableAnimationInChartData(chartData) {
|
|
23976
24054
|
return {
|
|
@@ -23978,6 +24056,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23978
24056
|
options: { ...chartData.options, animation: { animateRotate: true } },
|
|
23979
24057
|
};
|
|
23980
24058
|
}
|
|
24059
|
+
getChartDataInRuntime(runtime) {
|
|
24060
|
+
const data = runtime.chartJsConfig.data;
|
|
24061
|
+
return {
|
|
24062
|
+
labels: data.labels,
|
|
24063
|
+
dataset: data.datasets.map((dataset) => ({
|
|
24064
|
+
data: dataset.data,
|
|
24065
|
+
label: dataset.label,
|
|
24066
|
+
tree: dataset.tree,
|
|
24067
|
+
})),
|
|
24068
|
+
};
|
|
24069
|
+
}
|
|
23981
24070
|
get animationChartId() {
|
|
23982
24071
|
return this.props.isFullScreen ? this.props.chartId + "-fullscreen" : this.props.chartId;
|
|
23983
24072
|
}
|
|
@@ -24645,6 +24734,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24645
24734
|
static template = "o-spreadsheet-ScorecardChart";
|
|
24646
24735
|
static props = {
|
|
24647
24736
|
chartId: String,
|
|
24737
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
24648
24738
|
};
|
|
24649
24739
|
canvas = owl.useRef("chartContainer");
|
|
24650
24740
|
get runtime() {
|
|
@@ -25400,6 +25490,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25400
25490
|
parser: luxonFormat,
|
|
25401
25491
|
displayFormats,
|
|
25402
25492
|
unit: timeUnit ?? false,
|
|
25493
|
+
tooltipFormat: luxonFormat,
|
|
25403
25494
|
};
|
|
25404
25495
|
}
|
|
25405
25496
|
/**
|
|
@@ -26468,6 +26559,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26468
26559
|
};
|
|
26469
26560
|
Object.assign(scales.x, axis);
|
|
26470
26561
|
scales.x.ticks.maxTicksLimit = 15;
|
|
26562
|
+
delete scales?.x?.ticks?.callback;
|
|
26471
26563
|
}
|
|
26472
26564
|
else if (axisType === "linear") {
|
|
26473
26565
|
scales.x.type = "linear";
|
|
@@ -27408,26 +27500,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27408
27500
|
return { chartJsConfig: config, background: chart.background || BACKGROUND_CHART_COLOR };
|
|
27409
27501
|
}
|
|
27410
27502
|
|
|
27411
|
-
class FullScreenChartStore extends SpreadsheetStore {
|
|
27412
|
-
mutators = ["toggleFullScreenChart"];
|
|
27413
|
-
fullScreenFigure = undefined;
|
|
27414
|
-
toggleFullScreenChart(figureId) {
|
|
27415
|
-
if (this.fullScreenFigure?.id === figureId) {
|
|
27416
|
-
this.fullScreenFigure = undefined;
|
|
27417
|
-
}
|
|
27418
|
-
else {
|
|
27419
|
-
this.makeFullScreen(figureId);
|
|
27420
|
-
}
|
|
27421
|
-
}
|
|
27422
|
-
makeFullScreen(figureId) {
|
|
27423
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
27424
|
-
const figure = this.getters.getFigure(sheetId, figureId);
|
|
27425
|
-
if (figure) {
|
|
27426
|
-
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
27427
|
-
}
|
|
27428
|
-
}
|
|
27429
|
-
}
|
|
27430
|
-
|
|
27431
27503
|
const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
|
|
27432
27504
|
const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
|
|
27433
27505
|
class ZoomableChartStore extends SpreadsheetStore {
|
|
@@ -27592,7 +27664,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27592
27664
|
class ZoomableChartJsComponent extends ChartJsComponent {
|
|
27593
27665
|
static template = "o-spreadsheet-ZoomableChartJsComponent";
|
|
27594
27666
|
store;
|
|
27595
|
-
fullScreenChartStore;
|
|
27596
27667
|
masterChartCanvas = owl.useRef("masterChartCanvas");
|
|
27597
27668
|
masterChart;
|
|
27598
27669
|
mode;
|
|
@@ -27603,7 +27674,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27603
27674
|
removeEventListeners = () => { };
|
|
27604
27675
|
setup() {
|
|
27605
27676
|
this.store = useStore(ZoomableChartStore);
|
|
27606
|
-
this.fullScreenChartStore = useStore(FullScreenChartStore);
|
|
27607
27677
|
super.setup();
|
|
27608
27678
|
}
|
|
27609
27679
|
unmount() {
|
|
@@ -27618,12 +27688,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27618
27688
|
`;
|
|
27619
27689
|
}
|
|
27620
27690
|
get sliceable() {
|
|
27621
|
-
if (this.
|
|
27622
|
-
|
|
27623
|
-
const chartFigureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
27624
|
-
if (fullScreenFigureId === chartFigureId) {
|
|
27625
|
-
return true;
|
|
27626
|
-
}
|
|
27691
|
+
if (this.props.isFullScreen) {
|
|
27692
|
+
return true;
|
|
27627
27693
|
}
|
|
27628
27694
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27629
27695
|
return ("zoomable" in definition && definition?.zoomable) ?? false;
|
|
@@ -27686,9 +27752,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27686
27752
|
const xMax = Math.max(...xValues);
|
|
27687
27753
|
return { xMin, xMax };
|
|
27688
27754
|
}
|
|
27689
|
-
get shouldAnimate() {
|
|
27690
|
-
return this.env.model.getters.isDashboard() && !this.sliceable;
|
|
27691
|
-
}
|
|
27692
27755
|
createChart(chartRuntime) {
|
|
27693
27756
|
const chartData = chartRuntime.chartJsConfig;
|
|
27694
27757
|
this.isBarChart = chartData.type === "bar";
|
|
@@ -27707,6 +27770,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27707
27770
|
const masterChartCtx = this.masterChartCanvas.el.getContext("2d");
|
|
27708
27771
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27709
27772
|
this.resetAxesLimits();
|
|
27773
|
+
if (this.chart?.options) {
|
|
27774
|
+
this.chart.options.animation = false;
|
|
27775
|
+
}
|
|
27710
27776
|
}
|
|
27711
27777
|
updateChartJs(chartRuntime) {
|
|
27712
27778
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27740,6 +27806,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27740
27806
|
}
|
|
27741
27807
|
}
|
|
27742
27808
|
this.resetAxesLimits();
|
|
27809
|
+
if (this.chart?.options) {
|
|
27810
|
+
this.chart.options.animation = false;
|
|
27811
|
+
}
|
|
27743
27812
|
}
|
|
27744
27813
|
resetAxesLimits() {
|
|
27745
27814
|
if (!this.chart) {
|
|
@@ -27837,7 +27906,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27837
27906
|
onPointerDownInMasterChart(ev) {
|
|
27838
27907
|
this.removeEventListeners();
|
|
27839
27908
|
const position = ev.offsetX;
|
|
27840
|
-
if (!this.masterChart?.chartArea || !this.chart?.scales
|
|
27909
|
+
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
27841
27910
|
return;
|
|
27842
27911
|
}
|
|
27843
27912
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
@@ -31395,6 +31464,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31395
31464
|
return matchedChart.displayName;
|
|
31396
31465
|
}
|
|
31397
31466
|
|
|
31467
|
+
class FullScreenFigureStore extends SpreadsheetStore {
|
|
31468
|
+
mutators = ["toggleFullScreenFigure"];
|
|
31469
|
+
fullScreenFigure = undefined;
|
|
31470
|
+
toggleFullScreenFigure(figureId) {
|
|
31471
|
+
if (this.fullScreenFigure?.id === figureId) {
|
|
31472
|
+
this.fullScreenFigure = undefined;
|
|
31473
|
+
}
|
|
31474
|
+
else {
|
|
31475
|
+
this.makeFullScreen(figureId);
|
|
31476
|
+
}
|
|
31477
|
+
}
|
|
31478
|
+
makeFullScreen(figureId) {
|
|
31479
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
31480
|
+
const figure = this.getters.getFigure(sheetId, figureId);
|
|
31481
|
+
if (figure) {
|
|
31482
|
+
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
31483
|
+
}
|
|
31484
|
+
}
|
|
31485
|
+
}
|
|
31486
|
+
|
|
31398
31487
|
/**
|
|
31399
31488
|
* This file is largely inspired by owl 1.
|
|
31400
31489
|
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
@@ -31549,7 +31638,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31549
31638
|
const menuItemsAndSeparators = [];
|
|
31550
31639
|
for (let i = 0; i < this.props.menuItems.length; i++) {
|
|
31551
31640
|
const menuItem = this.props.menuItems[i];
|
|
31552
|
-
if (menuItem.isVisible(this.env)
|
|
31641
|
+
if (menuItem.isVisible(this.env) &&
|
|
31642
|
+
(!this.isRoot(menuItem) || this.hasVisibleChildren(menuItem))) {
|
|
31553
31643
|
menuItemsAndSeparators.push(menuItem);
|
|
31554
31644
|
}
|
|
31555
31645
|
if (menuItem.separator &&
|
|
@@ -31591,6 +31681,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31591
31681
|
isRoot(menu) {
|
|
31592
31682
|
return !menu.execute;
|
|
31593
31683
|
}
|
|
31684
|
+
hasVisibleChildren(menu) {
|
|
31685
|
+
return menu.children(this.env).some((child) => child.isVisible(this.env));
|
|
31686
|
+
}
|
|
31594
31687
|
isEnabled(menu) {
|
|
31595
31688
|
if (menu.isEnabled(this.env)) {
|
|
31596
31689
|
return this.env.model.getters.isReadonly() ? menu.isReadonlyAllowed : true;
|
|
@@ -32132,12 +32225,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32132
32225
|
class ChartDashboardMenu extends owl.Component {
|
|
32133
32226
|
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
32134
32227
|
static components = { MenuPopover };
|
|
32135
|
-
static props = { chartId: String };
|
|
32228
|
+
static props = { chartId: String, hasFullScreenButton: { type: Boolean, optional: true } };
|
|
32229
|
+
static defaultProps = { hasFullScreenButton: true };
|
|
32136
32230
|
fullScreenFigureStore;
|
|
32137
32231
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32138
32232
|
setup() {
|
|
32139
32233
|
super.setup();
|
|
32140
|
-
this.fullScreenFigureStore = useStore(
|
|
32234
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32141
32235
|
}
|
|
32142
32236
|
getMenuItems() {
|
|
32143
32237
|
return [this.fullScreenMenuItem].filter(isDefined);
|
|
@@ -32148,11 +32242,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32148
32242
|
}
|
|
32149
32243
|
openContextMenu(ev) {
|
|
32150
32244
|
this.menuState.isOpen = true;
|
|
32151
|
-
this.menuState.anchorRect =
|
|
32245
|
+
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
32152
32246
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32153
32247
|
this.menuState.menuItems = getChartMenuActions(figureId, () => { }, this.env);
|
|
32154
32248
|
}
|
|
32155
32249
|
get fullScreenMenuItem() {
|
|
32250
|
+
if (!this.props.hasFullScreenButton) {
|
|
32251
|
+
return undefined;
|
|
32252
|
+
}
|
|
32156
32253
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
32157
32254
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32158
32255
|
if (definition.type === "scorecard") {
|
|
@@ -32164,7 +32261,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32164
32261
|
label: isFullScreen ? _t("Exit Full Screen") : _t("Full Screen"),
|
|
32165
32262
|
class: `text-muted fa ${isFullScreen ? "fa-compress" : "fa-expand"}`,
|
|
32166
32263
|
onClick: () => {
|
|
32167
|
-
this.fullScreenFigureStore.
|
|
32264
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(figureId);
|
|
32168
32265
|
},
|
|
32169
32266
|
};
|
|
32170
32267
|
}
|
|
@@ -32176,6 +32273,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32176
32273
|
figureUI: Object,
|
|
32177
32274
|
onFigureDeleted: Function,
|
|
32178
32275
|
editFigureStyle: { type: Function, optional: true },
|
|
32276
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32277
|
+
openContextMenu: { type: Function, optional: true },
|
|
32179
32278
|
};
|
|
32180
32279
|
static components = { ChartDashboardMenu, MenuPopover };
|
|
32181
32280
|
carouselTabsRef = owl.useRef("carouselTabs");
|
|
@@ -32183,8 +32282,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32183
32282
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32184
32283
|
hiddenItems = [];
|
|
32185
32284
|
animationStore;
|
|
32285
|
+
fullScreenFigureStore;
|
|
32186
32286
|
setup() {
|
|
32187
32287
|
this.animationStore = useStore(ChartAnimationStore);
|
|
32288
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32188
32289
|
owl.useEffect(() => {
|
|
32189
32290
|
if (this.selectedCarouselItem?.type === "carouselDataView") {
|
|
32190
32291
|
this.props.editFigureStyle?.({ "pointer-events": "none" });
|
|
@@ -32231,7 +32332,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32231
32332
|
item,
|
|
32232
32333
|
});
|
|
32233
32334
|
if (item.type === "chart") {
|
|
32234
|
-
|
|
32335
|
+
const animationChartId = item.chartId + (this.props.isFullScreen ? "-fullscreen" : "");
|
|
32336
|
+
this.animationStore?.enableAnimationForChart(animationChartId);
|
|
32235
32337
|
}
|
|
32236
32338
|
}
|
|
32237
32339
|
get headerStyle() {
|
|
@@ -32295,6 +32397,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32295
32397
|
this.menuState.anchorRect = rect;
|
|
32296
32398
|
this.menuState.menuItems = createActions(menuItems);
|
|
32297
32399
|
}
|
|
32400
|
+
toggleFullScreen() {
|
|
32401
|
+
if (this.selectedCarouselItem?.type === "chart") {
|
|
32402
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.props.figureUI.id);
|
|
32403
|
+
}
|
|
32404
|
+
}
|
|
32405
|
+
get fullScreenButtonTitle() {
|
|
32406
|
+
return this.props.isFullScreen ? _t("Exit Full Screen") : _t("Full Screen");
|
|
32407
|
+
}
|
|
32408
|
+
get visibleCarouselItems() {
|
|
32409
|
+
return this.carousel.items.filter((item) => item.type === "carouselDataView" && this.props.isFullScreen ? false : true);
|
|
32410
|
+
}
|
|
32411
|
+
openContextMenu(event) {
|
|
32412
|
+
const target = event.currentTarget;
|
|
32413
|
+
if (target) {
|
|
32414
|
+
this.props.openContextMenu?.(getBoundingRectAsPOJO(target));
|
|
32415
|
+
}
|
|
32416
|
+
}
|
|
32298
32417
|
}
|
|
32299
32418
|
|
|
32300
32419
|
class ChartFigure extends owl.Component {
|
|
@@ -32303,6 +32422,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32303
32422
|
figureUI: Object,
|
|
32304
32423
|
onFigureDeleted: Function,
|
|
32305
32424
|
editFigureStyle: { type: Function, optional: true },
|
|
32425
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32426
|
+
openContextMenu: { type: Function, optional: true },
|
|
32306
32427
|
};
|
|
32307
32428
|
static components = { ChartDashboardMenu };
|
|
32308
32429
|
onDoubleClick() {
|
|
@@ -32335,6 +32456,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32335
32456
|
figureUI: Object,
|
|
32336
32457
|
onFigureDeleted: Function,
|
|
32337
32458
|
editFigureStyle: { type: Function, optional: true },
|
|
32459
|
+
openContextMenu: { type: Function, optional: true },
|
|
32338
32460
|
};
|
|
32339
32461
|
static components = {};
|
|
32340
32462
|
// ---------------------------------------------------------------------------
|
|
@@ -32405,9 +32527,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32405
32527
|
return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
|
|
32406
32528
|
}
|
|
32407
32529
|
getBorderStyle(position) {
|
|
32408
|
-
|
|
32409
|
-
const borderColor = this.isSelected ? SELECTION_BORDER_COLOR : FIGURE_BORDER_COLOR;
|
|
32410
|
-
return `border-${position}: ${borderWidth}px solid ${borderColor};`;
|
|
32530
|
+
return `border-${position}-width: ${this.getBorderWidth()}px;`;
|
|
32411
32531
|
}
|
|
32412
32532
|
get wrapperStyle() {
|
|
32413
32533
|
const { x, y, width, height } = this.props.figureUI;
|
|
@@ -34139,8 +34259,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34139
34259
|
}
|
|
34140
34260
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
34141
34261
|
this.props.composerStore.stopComposerRangeSelection();
|
|
34142
|
-
this.props.
|
|
34143
|
-
this.props.
|
|
34262
|
+
const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
|
|
34263
|
+
this.props.onComposerContentFocused(newSelection);
|
|
34264
|
+
if (!isCurrentlyInactive) {
|
|
34265
|
+
this.props.composerStore.changeComposerCursorSelection(newSelection.start, newSelection.end);
|
|
34266
|
+
}
|
|
34144
34267
|
this.processTokenAtCursor();
|
|
34145
34268
|
}
|
|
34146
34269
|
onDblClick() {
|
|
@@ -34635,13 +34758,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34635
34758
|
}
|
|
34636
34759
|
}
|
|
34637
34760
|
startEdition(text, selection) {
|
|
34638
|
-
if (selection) {
|
|
34639
|
-
const content = text || this.getComposerContent(this.getters.getActivePosition());
|
|
34640
|
-
const validSelection = this.isSelectionValid(content.length, selection.start, selection.end);
|
|
34641
|
-
if (!validSelection) {
|
|
34642
|
-
return;
|
|
34643
|
-
}
|
|
34644
|
-
}
|
|
34645
34761
|
const { col, row } = this.getters.getActivePosition();
|
|
34646
34762
|
this.model.dispatch("SELECT_FIGURE", { figureId: null });
|
|
34647
34763
|
this.model.dispatch("SCROLL_TO_CELL", { col, row });
|
|
@@ -34698,7 +34814,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34698
34814
|
// ---------------------------------------------------------------------------
|
|
34699
34815
|
get currentContent() {
|
|
34700
34816
|
if (this.editionMode === "inactive") {
|
|
34701
|
-
return this.getComposerContent(this.getters.getActivePosition());
|
|
34817
|
+
return this.getComposerContent(this.getters.getActivePosition()).text;
|
|
34702
34818
|
}
|
|
34703
34819
|
return this._currentContent;
|
|
34704
34820
|
}
|
|
@@ -34897,8 +35013,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34897
35013
|
this.sheetId = sheetId;
|
|
34898
35014
|
this.row = row;
|
|
34899
35015
|
this.editionMode = "editing";
|
|
34900
|
-
|
|
34901
|
-
this.
|
|
35016
|
+
const { text, adjustedSelection } = this.getComposerContent({ sheetId, col, row }, selection);
|
|
35017
|
+
this.initialContent = text;
|
|
35018
|
+
this.setContent(str || this.initialContent, adjustedSelection ?? selection);
|
|
34902
35019
|
this.colorIndexByRange = {};
|
|
34903
35020
|
const zone = positionToZone({ col: this.col, row: this.row });
|
|
34904
35021
|
this.captureSelection(zone, col, row);
|
|
@@ -35375,7 +35492,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35375
35492
|
constructor(get, args) {
|
|
35376
35493
|
super(get);
|
|
35377
35494
|
this.args = args;
|
|
35378
|
-
this._currentContent = this.getComposerContent();
|
|
35495
|
+
this._currentContent = this.getComposerContent().text;
|
|
35379
35496
|
}
|
|
35380
35497
|
getAutoCompleteProviders() {
|
|
35381
35498
|
const providersDefinitions = super.getAutoCompleteProviders();
|
|
@@ -35412,7 +35529,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35412
35529
|
})
|
|
35413
35530
|
.join("");
|
|
35414
35531
|
}
|
|
35415
|
-
return localizeContent(content, this.getters.getLocale());
|
|
35532
|
+
return { text: localizeContent(content, this.getters.getLocale()) };
|
|
35416
35533
|
}
|
|
35417
35534
|
stopEdition() {
|
|
35418
35535
|
this._stopEdition();
|
|
@@ -38632,6 +38749,74 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
38632
38749
|
return path2D;
|
|
38633
38750
|
}
|
|
38634
38751
|
|
|
38752
|
+
/**
|
|
38753
|
+
* Get the relative path between two files
|
|
38754
|
+
*
|
|
38755
|
+
* Eg.:
|
|
38756
|
+
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
38757
|
+
*/
|
|
38758
|
+
function getRelativePath(from, to) {
|
|
38759
|
+
const fromPathParts = from.split("/");
|
|
38760
|
+
const toPathParts = to.split("/");
|
|
38761
|
+
let relPath = "";
|
|
38762
|
+
let startIndex = 0;
|
|
38763
|
+
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
38764
|
+
if (fromPathParts[i] === toPathParts[i]) {
|
|
38765
|
+
startIndex++;
|
|
38766
|
+
}
|
|
38767
|
+
else {
|
|
38768
|
+
relPath += "../";
|
|
38769
|
+
}
|
|
38770
|
+
}
|
|
38771
|
+
relPath += toPathParts.slice(startIndex).join("/");
|
|
38772
|
+
return relPath;
|
|
38773
|
+
}
|
|
38774
|
+
/**
|
|
38775
|
+
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
38776
|
+
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
38777
|
+
*
|
|
38778
|
+
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
38779
|
+
*/
|
|
38780
|
+
function arrayToObject(array, indexOffset = 0) {
|
|
38781
|
+
const obj = {};
|
|
38782
|
+
for (let i = 0; i < array.length; i++) {
|
|
38783
|
+
if (array[i]) {
|
|
38784
|
+
obj[i + indexOffset] = array[i];
|
|
38785
|
+
}
|
|
38786
|
+
}
|
|
38787
|
+
return obj;
|
|
38788
|
+
}
|
|
38789
|
+
/**
|
|
38790
|
+
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
38791
|
+
* Replace with characters understandable by JS
|
|
38792
|
+
*/
|
|
38793
|
+
function fixXlsxUnicode(str) {
|
|
38794
|
+
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
38795
|
+
return String.fromCharCode(parseInt(code, 16));
|
|
38796
|
+
});
|
|
38797
|
+
}
|
|
38798
|
+
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
38799
|
+
function getSheetDataHeader(sheetData, dimension, index) {
|
|
38800
|
+
if (dimension === "COL") {
|
|
38801
|
+
if (!sheetData.cols[index]) {
|
|
38802
|
+
sheetData.cols[index] = {};
|
|
38803
|
+
}
|
|
38804
|
+
return sheetData.cols[index];
|
|
38805
|
+
}
|
|
38806
|
+
if (!sheetData.rows[index]) {
|
|
38807
|
+
sheetData.rows[index] = {};
|
|
38808
|
+
}
|
|
38809
|
+
return sheetData.rows[index];
|
|
38810
|
+
}
|
|
38811
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
38812
|
+
function prefixFormulaWithEqual(formula) {
|
|
38813
|
+
if (formula[0] === "=") {
|
|
38814
|
+
return formula;
|
|
38815
|
+
}
|
|
38816
|
+
const tokens = tokenize(formula);
|
|
38817
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
38818
|
+
}
|
|
38819
|
+
|
|
38635
38820
|
/**
|
|
38636
38821
|
* Map of the different types of conversions warnings and their name in error messages
|
|
38637
38822
|
*/
|
|
@@ -39154,66 +39339,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39154
39339
|
*/
|
|
39155
39340
|
const DEFAULT_SYSTEM_COLOR = "FF000000";
|
|
39156
39341
|
|
|
39157
|
-
/**
|
|
39158
|
-
* Get the relative path between two files
|
|
39159
|
-
*
|
|
39160
|
-
* Eg.:
|
|
39161
|
-
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
39162
|
-
*/
|
|
39163
|
-
function getRelativePath(from, to) {
|
|
39164
|
-
const fromPathParts = from.split("/");
|
|
39165
|
-
const toPathParts = to.split("/");
|
|
39166
|
-
let relPath = "";
|
|
39167
|
-
let startIndex = 0;
|
|
39168
|
-
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
39169
|
-
if (fromPathParts[i] === toPathParts[i]) {
|
|
39170
|
-
startIndex++;
|
|
39171
|
-
}
|
|
39172
|
-
else {
|
|
39173
|
-
relPath += "../";
|
|
39174
|
-
}
|
|
39175
|
-
}
|
|
39176
|
-
relPath += toPathParts.slice(startIndex).join("/");
|
|
39177
|
-
return relPath;
|
|
39178
|
-
}
|
|
39179
|
-
/**
|
|
39180
|
-
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
39181
|
-
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
39182
|
-
*
|
|
39183
|
-
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
39184
|
-
*/
|
|
39185
|
-
function arrayToObject(array, indexOffset = 0) {
|
|
39186
|
-
const obj = {};
|
|
39187
|
-
for (let i = 0; i < array.length; i++) {
|
|
39188
|
-
if (array[i]) {
|
|
39189
|
-
obj[i + indexOffset] = array[i];
|
|
39190
|
-
}
|
|
39191
|
-
}
|
|
39192
|
-
return obj;
|
|
39193
|
-
}
|
|
39194
|
-
/**
|
|
39195
|
-
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
39196
|
-
* Replace with characters understandable by JS
|
|
39197
|
-
*/
|
|
39198
|
-
function fixXlsxUnicode(str) {
|
|
39199
|
-
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
39200
|
-
return String.fromCharCode(parseInt(code, 16));
|
|
39201
|
-
});
|
|
39202
|
-
}
|
|
39203
|
-
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
39204
|
-
function getSheetDataHeader(sheetData, dimension, index) {
|
|
39205
|
-
if (dimension === "COL") {
|
|
39206
|
-
if (!sheetData.cols[index]) {
|
|
39207
|
-
sheetData.cols[index] = {};
|
|
39208
|
-
}
|
|
39209
|
-
return sheetData.cols[index];
|
|
39210
|
-
}
|
|
39211
|
-
if (!sheetData.rows[index]) {
|
|
39212
|
-
sheetData.rows[index] = {};
|
|
39213
|
-
}
|
|
39214
|
-
return sheetData.rows[index];
|
|
39215
|
-
}
|
|
39216
|
-
|
|
39217
39342
|
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
39218
39343
|
/**
|
|
39219
39344
|
* Convert excel format to o_spreadsheet format
|
|
@@ -39428,9 +39553,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39428
39553
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
39429
39554
|
continue;
|
|
39430
39555
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
39431
|
-
values.push(
|
|
39556
|
+
values.push(prefixFormulaWithEqual(rule.formula[0]));
|
|
39432
39557
|
if (rule.formula.length === 2) {
|
|
39433
|
-
values.push(
|
|
39558
|
+
values.push(prefixFormulaWithEqual(rule.formula[1]));
|
|
39434
39559
|
}
|
|
39435
39560
|
break;
|
|
39436
39561
|
}
|
|
@@ -39588,11 +39713,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39588
39713
|
? ICON_SETS[iconSet].neutral
|
|
39589
39714
|
: ICON_SETS[iconSet].good;
|
|
39590
39715
|
}
|
|
39591
|
-
/** Prefix the string by "=" if the string looks like a formula */
|
|
39592
|
-
function prefixFormula(formula) {
|
|
39593
|
-
const tokens = tokenize(formula);
|
|
39594
|
-
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
39595
|
-
}
|
|
39596
39716
|
// ---------------------------------------------------------------------------
|
|
39597
39717
|
// Warnings
|
|
39598
39718
|
// ---------------------------------------------------------------------------
|
|
@@ -40068,7 +40188,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40068
40188
|
dvRules.push(decimalRule);
|
|
40069
40189
|
break;
|
|
40070
40190
|
case "list":
|
|
40071
|
-
const listRule =
|
|
40191
|
+
const listRule = convertListRule(dvId++, dv);
|
|
40072
40192
|
dvRules.push(listRule);
|
|
40073
40193
|
break;
|
|
40074
40194
|
case "date":
|
|
@@ -40088,9 +40208,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40088
40208
|
return dvRules;
|
|
40089
40209
|
}
|
|
40090
40210
|
function convertDecimalRule(id, dv) {
|
|
40091
|
-
const values = [dv.formula1.toString()];
|
|
40211
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
40092
40212
|
if (dv.formula2) {
|
|
40093
|
-
values.push(dv.formula2.toString());
|
|
40213
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
40094
40214
|
}
|
|
40095
40215
|
return {
|
|
40096
40216
|
id: id.toString(),
|
|
@@ -40102,7 +40222,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40102
40222
|
},
|
|
40103
40223
|
};
|
|
40104
40224
|
}
|
|
40105
|
-
function
|
|
40225
|
+
function convertListRule(id, dv) {
|
|
40106
40226
|
const formula1 = dv.formula1.toString();
|
|
40107
40227
|
const isRangeRule = rangeReference.test(formula1);
|
|
40108
40228
|
return {
|
|
@@ -40118,9 +40238,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40118
40238
|
}
|
|
40119
40239
|
function convertDateRule(id, dv) {
|
|
40120
40240
|
let criterion;
|
|
40121
|
-
const values = [dv.formula1.toString()];
|
|
40241
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
40122
40242
|
if (dv.formula2) {
|
|
40123
|
-
values.push(dv.formula2.toString());
|
|
40243
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
40124
40244
|
criterion = {
|
|
40125
40245
|
type: XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[dv.operator],
|
|
40126
40246
|
values: getDateCriterionFormattedValues(values, DEFAULT_LOCALE),
|
|
@@ -40147,7 +40267,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40147
40267
|
isBlocking: dv.errorStyle !== "warning",
|
|
40148
40268
|
criterion: {
|
|
40149
40269
|
type: "customFormula",
|
|
40150
|
-
values: [
|
|
40270
|
+
values: [prefixFormulaWithEqual(dv.formula1.toString())],
|
|
40151
40271
|
},
|
|
40152
40272
|
};
|
|
40153
40273
|
}
|
|
@@ -45921,6 +46041,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
45921
46041
|
get numberOfCells() {
|
|
45922
46042
|
return this.rows.length * this.getNumberOfDataColumns();
|
|
45923
46043
|
}
|
|
46044
|
+
getColumnDomainsAtDepth(depth) {
|
|
46045
|
+
if (depth < 0 || depth >= this.columns.length - 1) {
|
|
46046
|
+
return [];
|
|
46047
|
+
}
|
|
46048
|
+
return this.columns[depth].map((col) => this.getDomain(col)).filter((d) => d.length);
|
|
46049
|
+
}
|
|
46050
|
+
getRowDomainsAtDepth(depth) {
|
|
46051
|
+
if (depth < 0 || depth > this.maxIndent) {
|
|
46052
|
+
return [];
|
|
46053
|
+
}
|
|
46054
|
+
return this.rows.filter((row) => row.indent === depth + 1).map((row) => this.getDomain(row));
|
|
46055
|
+
}
|
|
45924
46056
|
}
|
|
45925
46057
|
const EMPTY_PIVOT_CELL = { type: "EMPTY" };
|
|
45926
46058
|
|
|
@@ -46913,6 +47045,109 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46913
47045
|
return areFieldValuesInGroups(definition, values, field, pivot.getFields());
|
|
46914
47046
|
},
|
|
46915
47047
|
};
|
|
47048
|
+
const toggleCollapsePivotGroupAction = {
|
|
47049
|
+
name: (env) => {
|
|
47050
|
+
const position = env.model.getters.getActivePosition();
|
|
47051
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47052
|
+
if (pivotCellState.isPivotGroup) {
|
|
47053
|
+
return pivotCellState.isCollapsed ? _t("Expand") : _t("Collapse");
|
|
47054
|
+
}
|
|
47055
|
+
return "";
|
|
47056
|
+
},
|
|
47057
|
+
execute(env) {
|
|
47058
|
+
const position = env.model.getters.getActivePosition();
|
|
47059
|
+
togglePivotCollapse(position, env);
|
|
47060
|
+
},
|
|
47061
|
+
isVisible: (env) => {
|
|
47062
|
+
const position = env.model.getters.getActivePosition();
|
|
47063
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47064
|
+
return pivotCellState.isPivotGroup;
|
|
47065
|
+
},
|
|
47066
|
+
};
|
|
47067
|
+
const collapseAllPivotGroupAction = {
|
|
47068
|
+
name: _t("Collapse all"),
|
|
47069
|
+
execute(env) {
|
|
47070
|
+
const position = env.model.getters.getActivePosition();
|
|
47071
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47072
|
+
if (!pivotCellState.isPivotGroup) {
|
|
47073
|
+
return;
|
|
47074
|
+
}
|
|
47075
|
+
const { pivotCell, pivotId, siblingDomains } = pivotCellState;
|
|
47076
|
+
const definition = deepCopy(env.model.getters.getPivotCoreDefinition(pivotId));
|
|
47077
|
+
definition.collapsedDomains = definition.collapsedDomains || { COL: [], ROW: [] };
|
|
47078
|
+
const newCollapsed = [
|
|
47079
|
+
...(definition.collapsedDomains[pivotCell.dimension] || []),
|
|
47080
|
+
...siblingDomains,
|
|
47081
|
+
];
|
|
47082
|
+
const filteredCollapsed = newCollapsed.filter((domain, index) => index === newCollapsed.findIndex((d) => deepEquals(d, domain)));
|
|
47083
|
+
definition.collapsedDomains[pivotCell.dimension] = filteredCollapsed;
|
|
47084
|
+
env.model.dispatch("UPDATE_PIVOT", { pivotId, pivot: definition });
|
|
47085
|
+
},
|
|
47086
|
+
isVisible: (env) => {
|
|
47087
|
+
const position = env.model.getters.getActivePosition();
|
|
47088
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47089
|
+
if (!pivotCellState.isPivotGroup) {
|
|
47090
|
+
return false;
|
|
47091
|
+
}
|
|
47092
|
+
const { pivotCell, pivotId, siblingDomains } = pivotCellState;
|
|
47093
|
+
const definition = env.model.getters.getPivotCoreDefinition(pivotId);
|
|
47094
|
+
return !siblingDomains.every((domain) => (definition.collapsedDomains?.[pivotCell.dimension] || []).some((d) => deepEquals(d, domain)));
|
|
47095
|
+
},
|
|
47096
|
+
};
|
|
47097
|
+
const expandAllPivotGroupAction = {
|
|
47098
|
+
name: _t("Expand all"),
|
|
47099
|
+
execute(env) {
|
|
47100
|
+
const position = env.model.getters.getActivePosition();
|
|
47101
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47102
|
+
if (!pivotCellState.isPivotGroup) {
|
|
47103
|
+
return;
|
|
47104
|
+
}
|
|
47105
|
+
const { pivotCell, pivotId, siblingDomains } = pivotCellState;
|
|
47106
|
+
const definition = deepCopy(env.model.getters.getPivotCoreDefinition(pivotId));
|
|
47107
|
+
definition.collapsedDomains = definition.collapsedDomains || { COL: [], ROW: [] };
|
|
47108
|
+
const domains = definition.collapsedDomains[pivotCell.dimension] || [];
|
|
47109
|
+
const filteredDomains = domains.filter((domain) => !siblingDomains.find((d) => deepEquals(d, domain)));
|
|
47110
|
+
definition.collapsedDomains[pivotCell.dimension] = filteredDomains;
|
|
47111
|
+
env.model.dispatch("UPDATE_PIVOT", { pivotId, pivot: definition });
|
|
47112
|
+
},
|
|
47113
|
+
isVisible: (env) => {
|
|
47114
|
+
const position = env.model.getters.getActivePosition();
|
|
47115
|
+
const pivotCellState = getPivotCellCollapseState(env.model.getters, position);
|
|
47116
|
+
if (!pivotCellState.isPivotGroup) {
|
|
47117
|
+
return false;
|
|
47118
|
+
}
|
|
47119
|
+
const { pivotCell, pivotId, siblingDomains } = pivotCellState;
|
|
47120
|
+
const definition = env.model.getters.getPivotCoreDefinition(pivotId);
|
|
47121
|
+
const collapsedDomains = definition.collapsedDomains?.[pivotCell.dimension] || [];
|
|
47122
|
+
return collapsedDomains.some((domain) => siblingDomains.some((d) => deepEquals(d, domain)));
|
|
47123
|
+
},
|
|
47124
|
+
};
|
|
47125
|
+
function getPivotCellCollapseState(getters, position) {
|
|
47126
|
+
if (!getters.isSpillPivotFormula(position)) {
|
|
47127
|
+
return { isPivotGroup: false };
|
|
47128
|
+
}
|
|
47129
|
+
const pivotCell = getters.getPivotCellFromPosition(position);
|
|
47130
|
+
const pivotId = getters.getPivotIdFromPosition(position);
|
|
47131
|
+
if (pivotCell.type !== "HEADER" || !pivotId || !pivotCell.domain.length) {
|
|
47132
|
+
return { isPivotGroup: false };
|
|
47133
|
+
}
|
|
47134
|
+
const definition = getters.getPivotCoreDefinition(pivotId);
|
|
47135
|
+
const isDashboard = getters.isDashboard();
|
|
47136
|
+
const fields = pivotCell.dimension === "COL" ? definition.columns : definition.rows;
|
|
47137
|
+
const hasIcon = !isDashboard && pivotCell.domain.length !== fields.length;
|
|
47138
|
+
if (!hasIcon) {
|
|
47139
|
+
return { isPivotGroup: false };
|
|
47140
|
+
}
|
|
47141
|
+
const domains = definition.collapsedDomains?.[pivotCell.dimension] ?? [];
|
|
47142
|
+
const isCollapsed = domains.some((domain) => deepEquals(domain, pivotCell.domain));
|
|
47143
|
+
const pivot = getters.getPivot(pivotId);
|
|
47144
|
+
const table = pivot.getExpandedTableStructure();
|
|
47145
|
+
const depth = pivotCell.domain.length - 1;
|
|
47146
|
+
const siblingDomains = pivotCell.dimension === "ROW"
|
|
47147
|
+
? table.getRowDomainsAtDepth(depth)
|
|
47148
|
+
: table.getColumnDomainsAtDepth(depth);
|
|
47149
|
+
return { isPivotGroup: true, isCollapsed, pivotCell, pivotId, siblingDomains };
|
|
47150
|
+
}
|
|
46916
47151
|
function canSortPivot(getters, position) {
|
|
46917
47152
|
const pivotId = getters.getPivotIdFromPosition(position);
|
|
46918
47153
|
if (!pivotId || !getters.isExistingPivot(pivotId) || !getters.isSpillPivotFormula(position)) {
|
|
@@ -47248,6 +47483,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47248
47483
|
sequence: 155,
|
|
47249
47484
|
icon: "o-spreadsheet-Icon.MINUS_IN_BOX",
|
|
47250
47485
|
...ungroupPivotHeadersAction,
|
|
47486
|
+
})
|
|
47487
|
+
.add("collapse_pivot", {
|
|
47488
|
+
sequence: 156,
|
|
47489
|
+
name: _t("Expand/Collapse"),
|
|
47490
|
+
icon: "o-spreadsheet-Icon.COLLAPSE",
|
|
47491
|
+
})
|
|
47492
|
+
.addChild("toggle_collapse_pivot_cell", ["collapse_pivot"], {
|
|
47493
|
+
sequence: 10,
|
|
47494
|
+
...toggleCollapsePivotGroupAction,
|
|
47495
|
+
})
|
|
47496
|
+
.addChild("collapse_all_pivot", ["collapse_pivot"], {
|
|
47497
|
+
sequence: 20,
|
|
47498
|
+
...collapseAllPivotGroupAction,
|
|
47499
|
+
})
|
|
47500
|
+
.addChild("expand_all_pivot", ["collapse_pivot"], {
|
|
47501
|
+
sequence: 30,
|
|
47502
|
+
...expandAllPivotGroupAction,
|
|
47251
47503
|
})
|
|
47252
47504
|
.add("pivot_sorting", {
|
|
47253
47505
|
name: _t("Sort pivot"),
|
|
@@ -47872,6 +48124,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47872
48124
|
execute: (env) => {
|
|
47873
48125
|
env.model.dispatch("UNFOLD_ALL_HEADER_GROUPS", { sheetId, dimension });
|
|
47874
48126
|
},
|
|
48127
|
+
icon: "o-spreadsheet-Icon.EXPAND",
|
|
47875
48128
|
},
|
|
47876
48129
|
{
|
|
47877
48130
|
id: "fold_all",
|
|
@@ -47879,6 +48132,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47879
48132
|
execute: (env) => {
|
|
47880
48133
|
env.model.dispatch("FOLD_ALL_HEADER_GROUPS", { sheetId, dimension });
|
|
47881
48134
|
},
|
|
48135
|
+
icon: "o-spreadsheet-Icon.COLLAPSE",
|
|
47882
48136
|
},
|
|
47883
48137
|
]);
|
|
47884
48138
|
}
|
|
@@ -47900,6 +48154,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47900
48154
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
47901
48155
|
interactiveToggleGroup(env, sheetId, dimension, start, end);
|
|
47902
48156
|
},
|
|
48157
|
+
icon: (env) => {
|
|
48158
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
48159
|
+
const groupIsFolded = env.model.getters.isGroupFolded(sheetId, dimension, start, end);
|
|
48160
|
+
return groupIsFolded ? "o-spreadsheet-Icon.EXPAND" : "o-spreadsheet-Icon.COLLAPSE";
|
|
48161
|
+
},
|
|
47903
48162
|
},
|
|
47904
48163
|
{
|
|
47905
48164
|
id: "remove_group",
|
|
@@ -47908,6 +48167,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47908
48167
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
47909
48168
|
env.model.dispatch("UNGROUP_HEADERS", { sheetId, dimension, start, end });
|
|
47910
48169
|
},
|
|
48170
|
+
icon: "o-spreadsheet-Icon.TRASH",
|
|
47911
48171
|
separator: true,
|
|
47912
48172
|
},
|
|
47913
48173
|
]);
|
|
@@ -48770,39 +49030,66 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
48770
49030
|
this.model.dispatch("AUTOFILL_TABLE_COLUMN", { ...this.currentEditedCell });
|
|
48771
49031
|
this.setContent("");
|
|
48772
49032
|
}
|
|
48773
|
-
getComposerContent(position) {
|
|
49033
|
+
getComposerContent(position, selection) {
|
|
48774
49034
|
const locale = this.getters.getLocale();
|
|
48775
49035
|
const cell = this.getters.getCell(position);
|
|
48776
49036
|
if (cell?.isFormula) {
|
|
48777
49037
|
const prettifiedContent = this.getPrettifiedFormula(cell);
|
|
48778
|
-
|
|
49038
|
+
// when a formula is prettified (multi lines, indented), adapt the cursor position
|
|
49039
|
+
// to take into account line breaks and tabs
|
|
49040
|
+
function adjustCursorIndex(targetIndex) {
|
|
49041
|
+
let adjustedIndex = 0;
|
|
49042
|
+
let originalIndex = 0;
|
|
49043
|
+
while (originalIndex < targetIndex) {
|
|
49044
|
+
adjustedIndex++;
|
|
49045
|
+
const char = prettifiedContent[adjustedIndex];
|
|
49046
|
+
if (char !== "\n" && char !== "\t") {
|
|
49047
|
+
originalIndex++;
|
|
49048
|
+
}
|
|
49049
|
+
}
|
|
49050
|
+
return adjustedIndex;
|
|
49051
|
+
}
|
|
49052
|
+
let adjustedSelection = selection;
|
|
49053
|
+
if (selection) {
|
|
49054
|
+
adjustedSelection = {
|
|
49055
|
+
start: adjustCursorIndex(selection.start),
|
|
49056
|
+
end: adjustCursorIndex(selection.end),
|
|
49057
|
+
};
|
|
49058
|
+
}
|
|
49059
|
+
return {
|
|
49060
|
+
text: localizeFormula(prettifiedContent, locale),
|
|
49061
|
+
adjustedSelection,
|
|
49062
|
+
};
|
|
48779
49063
|
}
|
|
48780
49064
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
48781
49065
|
if (spreader) {
|
|
48782
|
-
return "";
|
|
49066
|
+
return { text: "" };
|
|
49067
|
+
}
|
|
49068
|
+
if (cell?.content.startsWith("'")) {
|
|
49069
|
+
return { text: cell.content };
|
|
48783
49070
|
}
|
|
48784
49071
|
const { format, value, type, formattedValue } = this.getters.getEvaluatedCell(position);
|
|
48785
49072
|
switch (type) {
|
|
48786
49073
|
case CellValueType.empty:
|
|
48787
|
-
return "";
|
|
49074
|
+
return { text: "" };
|
|
48788
49075
|
case CellValueType.text:
|
|
48789
49076
|
case CellValueType.error:
|
|
48790
|
-
return value;
|
|
49077
|
+
return { text: value };
|
|
48791
49078
|
case CellValueType.boolean:
|
|
48792
|
-
return formattedValue;
|
|
49079
|
+
return { text: formattedValue };
|
|
48793
49080
|
case CellValueType.number:
|
|
48794
49081
|
if (format && isDateTimeFormat(format)) {
|
|
48795
49082
|
if (parseDateTime(formattedValue, locale) !== null) {
|
|
48796
49083
|
// formatted string can be parsed again
|
|
48797
|
-
return formattedValue;
|
|
49084
|
+
return { text: formattedValue };
|
|
48798
49085
|
}
|
|
48799
49086
|
// display a simplified and parsable string otherwise
|
|
48800
49087
|
const timeFormat = Number.isInteger(value)
|
|
48801
49088
|
? locale.dateFormat
|
|
48802
49089
|
: getDateTimeFormat(locale);
|
|
48803
|
-
return formatValue(value, { locale, format: timeFormat });
|
|
49090
|
+
return { text: formatValue(value, { locale, format: timeFormat }) };
|
|
48804
49091
|
}
|
|
48805
|
-
return this.numberComposerContent(value, format, locale);
|
|
49092
|
+
return { text: this.numberComposerContent(value, format, locale) };
|
|
48806
49093
|
}
|
|
48807
49094
|
}
|
|
48808
49095
|
getPrettifiedFormula(cell) {
|
|
@@ -48949,8 +49236,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
48949
49236
|
},
|
|
48950
49237
|
focus: this.focus,
|
|
48951
49238
|
isDefaultFocus: true,
|
|
48952
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
49239
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
48953
49240
|
focusMode: "contentFocus",
|
|
49241
|
+
selection,
|
|
48954
49242
|
}),
|
|
48955
49243
|
onComposerCellFocused: (content) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
48956
49244
|
focusMode: "cellFocus",
|
|
@@ -51343,6 +51631,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51343
51631
|
}
|
|
51344
51632
|
const { align } = this.getters.getCellStyle(position);
|
|
51345
51633
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
51634
|
+
if (formatHasRepeatedChar(evaluatedCell.value, evaluatedCell.format)) {
|
|
51635
|
+
return "left";
|
|
51636
|
+
}
|
|
51346
51637
|
if (isOverflowing && evaluatedCell.type === CellValueType.number) {
|
|
51347
51638
|
return align !== "center" ? "left" : align;
|
|
51348
51639
|
}
|
|
@@ -55635,12 +55926,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55635
55926
|
onCloseSidePanel: { type: Function, optional: true },
|
|
55636
55927
|
};
|
|
55637
55928
|
state = owl.useState({ rule: this.defaultDataValidationRule, errors: [] });
|
|
55929
|
+
editingSheetId;
|
|
55638
55930
|
setup() {
|
|
55931
|
+
this.editingSheetId = this.env.model.getters.getActiveSheetId();
|
|
55639
55932
|
if (this.props.rule) {
|
|
55640
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
55641
55933
|
this.state.rule = {
|
|
55642
55934
|
...this.props.rule,
|
|
55643
|
-
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range,
|
|
55935
|
+
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
|
|
55644
55936
|
};
|
|
55645
55937
|
this.state.rule.criterion.type = this.props.rule.criterion.type;
|
|
55646
55938
|
}
|
|
@@ -55674,7 +55966,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55674
55966
|
const locale = this.env.model.getters.getLocale();
|
|
55675
55967
|
const criterion = rule.criterion;
|
|
55676
55968
|
const criterionEvaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
55677
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
55678
55969
|
const values = criterion.values
|
|
55679
55970
|
.slice(0, criterionEvaluator.numberOfValues(criterion))
|
|
55680
55971
|
.map((value) => value?.trim())
|
|
@@ -55682,8 +55973,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55682
55973
|
.map((value) => canonicalizeContent(value, locale));
|
|
55683
55974
|
rule.criterion = { ...criterion, values };
|
|
55684
55975
|
return {
|
|
55685
|
-
sheetId,
|
|
55686
|
-
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(
|
|
55976
|
+
sheetId: this.editingSheetId,
|
|
55977
|
+
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
|
|
55687
55978
|
rule,
|
|
55688
55979
|
};
|
|
55689
55980
|
}
|
|
@@ -56814,7 +57105,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56814
57105
|
return undefined;
|
|
56815
57106
|
}
|
|
56816
57107
|
get isCalculatedMeasureInvalid() {
|
|
56817
|
-
return
|
|
57108
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
56818
57109
|
}
|
|
56819
57110
|
}
|
|
56820
57111
|
|
|
@@ -59529,16 +59820,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59529
59820
|
}
|
|
59530
59821
|
}
|
|
59531
59822
|
|
|
59532
|
-
class
|
|
59533
|
-
static template = "o-spreadsheet-
|
|
59823
|
+
class FullScreenFigure extends owl.Component {
|
|
59824
|
+
static template = "o-spreadsheet-FullScreenFigure";
|
|
59534
59825
|
static props = {};
|
|
59535
|
-
static components = {
|
|
59536
|
-
|
|
59537
|
-
ref = owl.useRef("
|
|
59826
|
+
static components = { ChartFigure };
|
|
59827
|
+
fullScreenFigureStore;
|
|
59828
|
+
ref = owl.useRef("fullScreenFigure");
|
|
59538
59829
|
spreadsheetRect = useSpreadsheetRect();
|
|
59539
59830
|
figureRegistry = figureRegistry;
|
|
59540
59831
|
setup() {
|
|
59541
|
-
this.
|
|
59832
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
59542
59833
|
const animationStore = useStore(ChartAnimationStore);
|
|
59543
59834
|
let lastFigureId = undefined;
|
|
59544
59835
|
owl.onWillUpdateProps(() => {
|
|
@@ -59550,7 +59841,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59550
59841
|
owl.useEffect((el) => el?.focus(), () => [this.ref.el]);
|
|
59551
59842
|
}
|
|
59552
59843
|
get figureUI() {
|
|
59553
|
-
return this.
|
|
59844
|
+
return this.fullScreenFigureStore.fullScreenFigure;
|
|
59554
59845
|
}
|
|
59555
59846
|
get chartId() {
|
|
59556
59847
|
if (!this.figureUI)
|
|
@@ -59559,7 +59850,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59559
59850
|
}
|
|
59560
59851
|
exitFullScreen() {
|
|
59561
59852
|
if (this.figureUI) {
|
|
59562
|
-
this.
|
|
59853
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.figureUI.id);
|
|
59563
59854
|
}
|
|
59564
59855
|
}
|
|
59565
59856
|
onKeyDown(ev) {
|
|
@@ -59567,15 +59858,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59567
59858
|
this.exitFullScreen();
|
|
59568
59859
|
}
|
|
59569
59860
|
}
|
|
59570
|
-
get
|
|
59571
|
-
if (!this.
|
|
59861
|
+
get figureComponent() {
|
|
59862
|
+
if (!this.figureUI)
|
|
59572
59863
|
return undefined;
|
|
59573
|
-
|
|
59574
|
-
const component = chartComponentRegistry.get(type);
|
|
59575
|
-
if (!component) {
|
|
59576
|
-
throw new Error(`Component is not defined for type ${type}`);
|
|
59577
|
-
}
|
|
59578
|
-
return component;
|
|
59864
|
+
return figureRegistry.get(this.figureUI.tag).Component;
|
|
59579
59865
|
}
|
|
59580
59866
|
}
|
|
59581
59867
|
|
|
@@ -60798,7 +61084,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60798
61084
|
(typeof parsedValue === "number"
|
|
60799
61085
|
? detectDateFormat(content, locale) || detectNumberFormat(content)
|
|
60800
61086
|
: undefined);
|
|
60801
|
-
if (!isTextFormat(format) && !isEvaluationError(content)) {
|
|
61087
|
+
if (!isTextFormat(format) && !content.startsWith("'") && !isEvaluationError(content)) {
|
|
60802
61088
|
content = toString(parsedValue);
|
|
60803
61089
|
}
|
|
60804
61090
|
return {
|
|
@@ -62278,11 +62564,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62278
62564
|
break;
|
|
62279
62565
|
}
|
|
62280
62566
|
case "ADD_COLUMNS_ROWS": {
|
|
62281
|
-
const sizes =
|
|
62567
|
+
const sizes = this.sizes[cmd.sheetId][cmd.dimension];
|
|
62282
62568
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62283
62569
|
const baseSize = sizes[cmd.base];
|
|
62284
|
-
sizes
|
|
62285
|
-
this.history.update("sizes", cmd.sheetId, cmd.dimension,
|
|
62570
|
+
const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
|
|
62571
|
+
this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
|
|
62286
62572
|
break;
|
|
62287
62573
|
}
|
|
62288
62574
|
case "RESIZE_COLUMNS_ROWS":
|
|
@@ -62433,9 +62719,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62433
62719
|
break;
|
|
62434
62720
|
}
|
|
62435
62721
|
case "ADD_COLUMNS_ROWS": {
|
|
62436
|
-
const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
|
|
62437
62722
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62438
|
-
hiddenHeaders.
|
|
62723
|
+
const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
|
|
62439
62724
|
this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
|
|
62440
62725
|
break;
|
|
62441
62726
|
}
|
|
@@ -66619,12 +66904,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66619
66904
|
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
66620
66905
|
}
|
|
66621
66906
|
rtreeItemComparer(left, right) {
|
|
66622
|
-
return (left.
|
|
66623
|
-
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66907
|
+
return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66624
66908
|
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
66625
66909
|
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
66626
66910
|
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
66627
|
-
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom
|
|
66911
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
|
|
66912
|
+
deepEquals(left.data, right.data));
|
|
66628
66913
|
}
|
|
66629
66914
|
}
|
|
66630
66915
|
/**
|
|
@@ -66697,7 +66982,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66697
66982
|
* in the correct order they should be evaluated.
|
|
66698
66983
|
* This is called a topological ordering (excluding cycles)
|
|
66699
66984
|
*/
|
|
66700
|
-
getCellsDependingOn(ranges) {
|
|
66985
|
+
getCellsDependingOn(ranges, ignore) {
|
|
66701
66986
|
const visited = this.createEmptyPositionSet();
|
|
66702
66987
|
const queue = Array.from(ranges).reverse();
|
|
66703
66988
|
while (queue.length > 0) {
|
|
@@ -66712,7 +66997,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66712
66997
|
const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
|
|
66713
66998
|
const nextInQueue = {};
|
|
66714
66999
|
for (const position of impactedPositions) {
|
|
66715
|
-
if (!visited.has(position)) {
|
|
67000
|
+
if (!visited.has(position) && !ignore.has(position)) {
|
|
66716
67001
|
if (!nextInQueue[position.sheetId]) {
|
|
66717
67002
|
nextInQueue[position.sheetId] = [];
|
|
66718
67003
|
}
|
|
@@ -67270,7 +67555,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67270
67555
|
}
|
|
67271
67556
|
invalidatePositionsDependingOnSpread(sheetId, resultZone) {
|
|
67272
67557
|
// the result matrix is split in 2 zones to exclude the array formula position
|
|
67273
|
-
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
|
|
67558
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
|
|
67274
67559
|
invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
|
|
67275
67560
|
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
67276
67561
|
}
|
|
@@ -67388,7 +67673,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67388
67673
|
for (const sheetId in zonesBySheetIds) {
|
|
67389
67674
|
ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
|
|
67390
67675
|
}
|
|
67391
|
-
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
67676
|
+
return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
|
|
67392
67677
|
}
|
|
67393
67678
|
}
|
|
67394
67679
|
function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
|
|
@@ -68655,32 +68940,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68655
68940
|
}
|
|
68656
68941
|
return undefined;
|
|
68657
68942
|
});
|
|
68658
|
-
function togglePivotCollapse(position, env) {
|
|
68659
|
-
const pivotCell = env.model.getters.getPivotCellFromPosition(position);
|
|
68660
|
-
const pivotId = env.model.getters.getPivotIdFromPosition(position);
|
|
68661
|
-
if (!pivotId || pivotCell.type !== "HEADER") {
|
|
68662
|
-
return;
|
|
68663
|
-
}
|
|
68664
|
-
const definition = env.model.getters.getPivotCoreDefinition(pivotId);
|
|
68665
|
-
const collapsedDomains = definition.collapsedDomains?.[pivotCell.dimension]
|
|
68666
|
-
? [...definition.collapsedDomains[pivotCell.dimension]]
|
|
68667
|
-
: [];
|
|
68668
|
-
const index = collapsedDomains.findIndex((domain) => deepEquals(domain, pivotCell.domain));
|
|
68669
|
-
if (index !== -1) {
|
|
68670
|
-
collapsedDomains.splice(index, 1);
|
|
68671
|
-
}
|
|
68672
|
-
else {
|
|
68673
|
-
collapsedDomains.push(pivotCell.domain);
|
|
68674
|
-
}
|
|
68675
|
-
const newDomains = definition.collapsedDomains
|
|
68676
|
-
? { ...definition.collapsedDomains }
|
|
68677
|
-
: { COL: [], ROW: [] };
|
|
68678
|
-
newDomains[pivotCell.dimension] = collapsedDomains;
|
|
68679
|
-
env.model.dispatch("UPDATE_PIVOT", {
|
|
68680
|
-
pivotId,
|
|
68681
|
-
pivot: { ...definition, collapsedDomains: newDomains },
|
|
68682
|
-
});
|
|
68683
|
-
}
|
|
68684
68943
|
iconsOnCellRegistry.add("pivot_dashboard_sorting", (getters, position) => {
|
|
68685
68944
|
if (!getters.isDashboard()) {
|
|
68686
68945
|
return undefined;
|
|
@@ -68899,7 +69158,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68899
69158
|
const topLeft = { col: unionZone.left, row: unionZone.top, sheetId };
|
|
68900
69159
|
const parentSpreadingCell = this.getters.getArrayFormulaSpreadingOn(topLeft);
|
|
68901
69160
|
if (!parentSpreadingCell) {
|
|
68902
|
-
|
|
69161
|
+
const evaluatedCell = this.getters.getEvaluatedCell(topLeft);
|
|
69162
|
+
return (evaluatedCell.value === CellErrorType.SpilledBlocked && !evaluatedCell.errorOriginPosition);
|
|
68903
69163
|
}
|
|
68904
69164
|
else if (deepEquals(parentSpreadingCell, topLeft) && getZoneArea(unionZone) === 1) {
|
|
68905
69165
|
return true;
|
|
@@ -79472,8 +79732,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79472
79732
|
left: `calc(50% - 1px)`, // -1px: we want the border to be on the center
|
|
79473
79733
|
width: `30%`,
|
|
79474
79734
|
height: `calc(100% - ${groupBox.headerRect.height / 2}px)`,
|
|
79475
|
-
"border-left": `1px solid
|
|
79476
|
-
"border-bottom": groupBox.isEndHidden ? "" : `1px solid
|
|
79735
|
+
"border-left": `1px solid`,
|
|
79736
|
+
"border-bottom": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79477
79737
|
});
|
|
79478
79738
|
}
|
|
79479
79739
|
get groupHeaderStyle() {
|
|
@@ -79525,8 +79785,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79525
79785
|
left: `${groupBox.headerRect.width / 2}px`,
|
|
79526
79786
|
width: `calc(100% - ${groupBox.headerRect.width / 2}px)`,
|
|
79527
79787
|
height: `30%`,
|
|
79528
|
-
"border-top": `1px solid
|
|
79529
|
-
"border-right": groupBox.isEndHidden ? "" : `1px solid
|
|
79788
|
+
"border-top": `1px solid`,
|
|
79789
|
+
"border-right": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79530
79790
|
});
|
|
79531
79791
|
}
|
|
79532
79792
|
get groupHeaderStyle() {
|
|
@@ -79765,6 +80025,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79765
80025
|
static components = { Menu };
|
|
79766
80026
|
rootItems = topbarMenuRegistry.getMenuItems();
|
|
79767
80027
|
menuRef = owl.useRef("menu");
|
|
80028
|
+
containerRef = owl.useRef("container");
|
|
79768
80029
|
state = owl.useState({
|
|
79769
80030
|
menuItems: this.rootItems,
|
|
79770
80031
|
title: _t("Menu Bar"),
|
|
@@ -79772,6 +80033,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79772
80033
|
});
|
|
79773
80034
|
setup() {
|
|
79774
80035
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
80036
|
+
owl.onMounted(this.updateShadows);
|
|
79775
80037
|
}
|
|
79776
80038
|
onExternalClick(ev) {
|
|
79777
80039
|
if (!this.menuRef.el?.contains(ev.target)) {
|
|
@@ -79784,6 +80046,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79784
80046
|
this.state.parentState = { ...this.state };
|
|
79785
80047
|
this.state.menuItems = children;
|
|
79786
80048
|
this.state.title = menu.name(this.env);
|
|
80049
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
79787
80050
|
}
|
|
79788
80051
|
else {
|
|
79789
80052
|
this.state.menuItems = this.rootItems;
|
|
@@ -79805,6 +80068,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79805
80068
|
height: `${this.props.height}px`,
|
|
79806
80069
|
});
|
|
79807
80070
|
}
|
|
80071
|
+
updateShadows() {
|
|
80072
|
+
if (!this.containerRef.el) {
|
|
80073
|
+
return;
|
|
80074
|
+
}
|
|
80075
|
+
this.containerRef.el.classList.remove("scroll-top", "scroll-bottom");
|
|
80076
|
+
const maxScroll = this.containerRef.el.scrollHeight - this.containerRef.el.clientHeight || 0;
|
|
80077
|
+
if (this.containerRef.el.scrollTop < maxScroll - 1) {
|
|
80078
|
+
this.containerRef.el.classList.add("scroll-bottom");
|
|
80079
|
+
}
|
|
80080
|
+
if (this.containerRef.el.scrollTop > 0) {
|
|
80081
|
+
this.containerRef.el.classList.add("scroll-top");
|
|
80082
|
+
}
|
|
80083
|
+
}
|
|
79808
80084
|
onClickBack() {
|
|
79809
80085
|
if (!this.state.parentState) {
|
|
79810
80086
|
this.props.onClose();
|
|
@@ -79813,6 +80089,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79813
80089
|
this.state.menuItems = this.state.parentState.menuItems;
|
|
79814
80090
|
this.state.title = this.state.parentState.title;
|
|
79815
80091
|
this.state.parentState = this.state.parentState.parentState;
|
|
80092
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
79816
80093
|
}
|
|
79817
80094
|
get backTitle() {
|
|
79818
80095
|
return this.state.parentState ? _t("Go to previous menu") : _t("Close menu bar");
|
|
@@ -79863,6 +80140,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79863
80140
|
? this.composerFocusStore.focusMode
|
|
79864
80141
|
: "inactive";
|
|
79865
80142
|
}
|
|
80143
|
+
get showFxIcon() {
|
|
80144
|
+
return (this.focus === "inactive" &&
|
|
80145
|
+
!this.composerStore.currentContent &&
|
|
80146
|
+
!this.composerStore.placeholder);
|
|
80147
|
+
}
|
|
79866
80148
|
get rect() {
|
|
79867
80149
|
return this.composerRef.el
|
|
79868
80150
|
? getBoundingRectAsPOJO(this.composerRef.el)
|
|
@@ -79878,8 +80160,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79878
80160
|
},
|
|
79879
80161
|
focus: this.focus,
|
|
79880
80162
|
composerStore: this.composerStore,
|
|
79881
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
80163
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
79882
80164
|
focusMode: "contentFocus",
|
|
80165
|
+
selection,
|
|
79883
80166
|
}),
|
|
79884
80167
|
isDefaultFocus: false,
|
|
79885
80168
|
inputStyle: cssPropertiesToCss({
|
|
@@ -79887,6 +80170,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79887
80170
|
"max-height": `130px`,
|
|
79888
80171
|
}),
|
|
79889
80172
|
showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
|
|
80173
|
+
placeholder: this.composerStore.placeholder,
|
|
79890
80174
|
};
|
|
79891
80175
|
}
|
|
79892
80176
|
get symbols() {
|
|
@@ -79905,13 +80189,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79905
80189
|
}
|
|
79906
80190
|
|
|
79907
80191
|
const COMPOSER_MAX_HEIGHT = 300;
|
|
79908
|
-
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
79909
|
-
// FIXME This svg is hardcoded in the css file. We should find a better way to handle it.
|
|
79910
|
-
// const FX_SVG = /*xml*/ `
|
|
79911
|
-
// <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
79912
|
-
// <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
|
|
79913
|
-
// </svg>
|
|
79914
|
-
// `;
|
|
79915
80192
|
class TopBarComposer extends owl.Component {
|
|
79916
80193
|
static template = "o-spreadsheet-TopBarComposer";
|
|
79917
80194
|
static props = {};
|
|
@@ -79938,6 +80215,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79938
80215
|
? this.composerFocusStore.focusMode
|
|
79939
80216
|
: "inactive";
|
|
79940
80217
|
}
|
|
80218
|
+
get showFxIcon() {
|
|
80219
|
+
return (this.focus === "inactive" &&
|
|
80220
|
+
!this.composerStore.currentContent &&
|
|
80221
|
+
!this.composerStore.placeholder);
|
|
80222
|
+
}
|
|
79941
80223
|
get composerStyle() {
|
|
79942
80224
|
const style = {
|
|
79943
80225
|
padding: "5px 0px 5px 8px",
|
|
@@ -80875,7 +81157,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
80875
81157
|
SidePanels,
|
|
80876
81158
|
SpreadsheetDashboard,
|
|
80877
81159
|
HeaderGroupContainer,
|
|
80878
|
-
|
|
81160
|
+
FullScreenFigure,
|
|
80879
81161
|
};
|
|
80880
81162
|
sidePanel;
|
|
80881
81163
|
spreadsheetRef = owl.useRef("spreadsheet");
|
|
@@ -85599,6 +85881,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85599
85881
|
Grid,
|
|
85600
85882
|
GridOverlay,
|
|
85601
85883
|
ScorecardChart,
|
|
85884
|
+
GaugeChartComponent,
|
|
85602
85885
|
LineConfigPanel,
|
|
85603
85886
|
BarConfigPanel,
|
|
85604
85887
|
PieChartDesignPanel,
|
|
@@ -85637,7 +85920,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85637
85920
|
RadioSelection,
|
|
85638
85921
|
GeoChartRegionSelectSection,
|
|
85639
85922
|
ChartDashboardMenu,
|
|
85640
|
-
|
|
85923
|
+
FullScreenFigure,
|
|
85641
85924
|
};
|
|
85642
85925
|
const hooks = {
|
|
85643
85926
|
useDragAndDropListItems,
|
|
@@ -85737,9 +86020,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85737
86020
|
exports.tokenize = tokenize;
|
|
85738
86021
|
|
|
85739
86022
|
|
|
85740
|
-
__info__.version = "19.1.0-alpha.
|
|
85741
|
-
__info__.date = "2025-
|
|
85742
|
-
__info__.hash = "
|
|
86023
|
+
__info__.version = "19.1.0-alpha.5";
|
|
86024
|
+
__info__.date = "2025-10-16T06:39:55.925Z";
|
|
86025
|
+
__info__.hash = "1a0e3d5";
|
|
85743
86026
|
|
|
85744
86027
|
|
|
85745
86028
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|