@odoo/o-spreadsheet 16.4.5 → 16.4.7
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 +200 -54
- package/dist/o-spreadsheet.d.ts +11 -5
- package/dist/o-spreadsheet.esm.js +200 -54
- package/dist/o-spreadsheet.iife.js +200 -54
- package/dist/o-spreadsheet.iife.min.js +257 -256
- package/package.json +1 -1
|
@@ -614,13 +614,17 @@ function getAddHeaderStartIndex(position, base) {
|
|
|
614
614
|
return position === "after" ? base + 1 : base;
|
|
615
615
|
}
|
|
616
616
|
/**
|
|
617
|
-
*
|
|
617
|
+
* Compares two objects.
|
|
618
618
|
*/
|
|
619
619
|
function deepEquals(o1, o2) {
|
|
620
620
|
if (o1 === o2)
|
|
621
621
|
return true;
|
|
622
622
|
if ((o1 && !o2) || (o2 && !o1))
|
|
623
623
|
return false;
|
|
624
|
+
if (typeof o1 !== typeof o2)
|
|
625
|
+
return false;
|
|
626
|
+
if (typeof o1 !== "object")
|
|
627
|
+
return o1 === o2;
|
|
624
628
|
// Objects can have different keys if the values are undefined
|
|
625
629
|
const keys = new Set();
|
|
626
630
|
Object.keys(o1).forEach((key) => keys.add(key));
|
|
@@ -5265,6 +5269,7 @@ css /* scss */ `
|
|
|
5265
5269
|
padding: 10px;
|
|
5266
5270
|
width: ${ERROR_TOOLTIP_WIDTH}px;
|
|
5267
5271
|
box-sizing: border-box !important;
|
|
5272
|
+
overflow-wrap: break-word;
|
|
5268
5273
|
}
|
|
5269
5274
|
`;
|
|
5270
5275
|
class ErrorToolTip extends owl.Component {
|
|
@@ -15120,13 +15125,42 @@ function isValidLocale(locale) {
|
|
|
15120
15125
|
}
|
|
15121
15126
|
return true;
|
|
15122
15127
|
}
|
|
15123
|
-
/**
|
|
15128
|
+
/**
|
|
15129
|
+
* Change a content string from the given locale to its canonical form (en_US locale). Don't convert date string.
|
|
15130
|
+
*
|
|
15131
|
+
* @example
|
|
15132
|
+
* canonicalizeNumberContent("=SUM(1,5; 02/12/2012)", FR_LOCALE) // "=SUM(1.5, 02/12/2012)"
|
|
15133
|
+
* canonicalizeNumberContent("125,9", FR_LOCALE) // "125.9"
|
|
15134
|
+
* canonicalizeNumberContent("02/12/2012", FR_LOCALE) // "02/12/2012"
|
|
15135
|
+
*/
|
|
15136
|
+
function canonicalizeNumberContent(content, locale) {
|
|
15137
|
+
return content.startsWith("=")
|
|
15138
|
+
? canonicalizeFormula$1(content, locale)
|
|
15139
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
15140
|
+
}
|
|
15141
|
+
/**
|
|
15142
|
+
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
15143
|
+
* This is destructive and won't preserve the original format.
|
|
15144
|
+
*
|
|
15145
|
+
* @example
|
|
15146
|
+
* canonicalizeContent("=SUM(1,5; 5)", FR_LOCALE) // "=SUM(1.5, 5)"
|
|
15147
|
+
* canonicalizeContent("125,9", FR_LOCALE) // "125.9"
|
|
15148
|
+
* canonicalizeContent("02/12/2012", FR_LOCALE) // "12/02/2012"
|
|
15149
|
+
* canonicalizeContent("02-12-2012", FR_LOCALE) // "12/02/2012"
|
|
15150
|
+
*/
|
|
15124
15151
|
function canonicalizeContent(content, locale) {
|
|
15125
15152
|
return content.startsWith("=")
|
|
15126
15153
|
? canonicalizeFormula$1(content, locale)
|
|
15127
|
-
:
|
|
15154
|
+
: canonicalizeLiteral(content, locale);
|
|
15128
15155
|
}
|
|
15129
|
-
/**
|
|
15156
|
+
/**
|
|
15157
|
+
* Change a content string from its canonical form (en_US locale) to the given locale. Also convert date string.
|
|
15158
|
+
*
|
|
15159
|
+
* @example
|
|
15160
|
+
* localizeContent("=SUM(1.5, 5)", FR_LOCALE) // "=SUM(1,5; 5)"
|
|
15161
|
+
* localizeContent("125.9", FR_LOCALE) // "125,9"
|
|
15162
|
+
* localizeContent("12/02/2012", FR_LOCALE) // "02/12/2012"
|
|
15163
|
+
*/
|
|
15130
15164
|
function localizeContent(content, locale) {
|
|
15131
15165
|
return content.startsWith("=")
|
|
15132
15166
|
? localizeFormula(content, locale)
|
|
@@ -15161,24 +15195,75 @@ function _localizeFormula$1(formula, fromLocale, toLocale) {
|
|
|
15161
15195
|
return localizedFormula;
|
|
15162
15196
|
}
|
|
15163
15197
|
/**
|
|
15164
|
-
*
|
|
15198
|
+
* Change a literal string from the given locale to its canonical form (en_US locale). Don't convert date string.
|
|
15199
|
+
*
|
|
15200
|
+
* @example
|
|
15201
|
+
* canonicalizeNumberLiteral("125,9", FR_LOCALE) // "125.9"
|
|
15202
|
+
* canonicalizeNumberLiteral("02/12/2012", FR_LOCALE) // "02/12/2012"
|
|
15165
15203
|
*/
|
|
15166
|
-
function
|
|
15204
|
+
function canonicalizeNumberLiteral(content, locale) {
|
|
15167
15205
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
15168
15206
|
return content;
|
|
15169
15207
|
}
|
|
15170
15208
|
return content.replace(locale.decimalSeparator, ".");
|
|
15171
15209
|
}
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15210
|
+
/**
|
|
15211
|
+
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
15212
|
+
* This is destructive and won't preserve the original format.
|
|
15213
|
+
*
|
|
15214
|
+
* @example
|
|
15215
|
+
* canonicalizeLiteral("125,9", FR_LOCALE) // "125.9"
|
|
15216
|
+
* canonicalizeLiteral("02/12/2012", FR_LOCALE) // "12/02/2012"
|
|
15217
|
+
* canonicalizeLiteral("02-12-2012", FR_LOCALE) // "12/02/2012"
|
|
15218
|
+
*/
|
|
15219
|
+
function canonicalizeLiteral(content, locale) {
|
|
15220
|
+
if (isDateTime(content, locale)) {
|
|
15221
|
+
const dateNumber = toNumber(content, locale);
|
|
15222
|
+
let format = DEFAULT_LOCALE.dateFormat;
|
|
15223
|
+
if (!Number.isInteger(dateNumber)) {
|
|
15224
|
+
format += " " + DEFAULT_LOCALE.timeFormat;
|
|
15225
|
+
}
|
|
15226
|
+
return formatValue(dateNumber, { locale: DEFAULT_LOCALE, format });
|
|
15227
|
+
}
|
|
15228
|
+
return canonicalizeNumberLiteral(content, locale);
|
|
15229
|
+
}
|
|
15230
|
+
/**
|
|
15231
|
+
* Change a literal string from its canonical form (en_US locale) to the given locale. Don't convert date string.
|
|
15232
|
+
* This is destructive and won't preserve the original format.
|
|
15233
|
+
*
|
|
15234
|
+
* @example
|
|
15235
|
+
* localizeNumberLiteral("125.9", FR_LOCALE) // "125,9"
|
|
15236
|
+
* localizeNumberLiteral("12/02/2012", FR_LOCALE) // "12/02/2012"
|
|
15237
|
+
* localizeNumberLiteral("12-02-2012", FR_LOCALE) // "12/02/2012"
|
|
15238
|
+
*/
|
|
15239
|
+
function localizeNumberLiteral(literal, locale) {
|
|
15240
|
+
if (locale.decimalSeparator === "." || !isNumber(literal, DEFAULT_LOCALE)) {
|
|
15241
|
+
return literal;
|
|
15175
15242
|
}
|
|
15176
15243
|
const decimalNumberRegex = getDecimalNumberRegex(DEFAULT_LOCALE);
|
|
15177
|
-
const localized =
|
|
15244
|
+
const localized = literal.replace(decimalNumberRegex, (match) => {
|
|
15178
15245
|
return match.replace(".", locale.decimalSeparator);
|
|
15179
15246
|
});
|
|
15180
15247
|
return localized;
|
|
15181
15248
|
}
|
|
15249
|
+
/**
|
|
15250
|
+
* Change a literal string from its canonical form (en_US locale) to the given locale. Also convert date string.
|
|
15251
|
+
*
|
|
15252
|
+
* @example
|
|
15253
|
+
* localizeLiteral("125.9", FR_LOCALE) // "125,9"
|
|
15254
|
+
* localizeLiteral("12/02/2012", FR_LOCALE) // "02/12/2012"
|
|
15255
|
+
*/
|
|
15256
|
+
function localizeLiteral(literal, locale) {
|
|
15257
|
+
if (isDateTime(literal, DEFAULT_LOCALE)) {
|
|
15258
|
+
const dateNumber = toNumber(literal, DEFAULT_LOCALE);
|
|
15259
|
+
let format = locale.dateFormat;
|
|
15260
|
+
if (!Number.isInteger(dateNumber)) {
|
|
15261
|
+
format += " " + locale.timeFormat;
|
|
15262
|
+
}
|
|
15263
|
+
return formatValue(dateNumber, { locale, format });
|
|
15264
|
+
}
|
|
15265
|
+
return localizeNumberLiteral(literal, locale);
|
|
15266
|
+
}
|
|
15182
15267
|
function canonicalizeCFRule(cf, locale) {
|
|
15183
15268
|
return changeCFRuleLocale(cf, (content) => canonicalizeContent(content, locale));
|
|
15184
15269
|
}
|
|
@@ -15535,7 +15620,9 @@ class LinkEditor extends owl.Component {
|
|
|
15535
15620
|
save() {
|
|
15536
15621
|
const { col, row } = this.props.cellPosition;
|
|
15537
15622
|
const locale = this.env.model.getters.getLocale();
|
|
15538
|
-
const label = this.link.label
|
|
15623
|
+
const label = this.link.label
|
|
15624
|
+
? canonicalizeNumberContent(this.link.label, locale)
|
|
15625
|
+
: this.link.url;
|
|
15539
15626
|
this.env.model.dispatch("UPDATE_CELL", {
|
|
15540
15627
|
col: col,
|
|
15541
15628
|
row: row,
|
|
@@ -16878,6 +16965,7 @@ class LineChart extends AbstractChart {
|
|
|
16878
16965
|
aggregated;
|
|
16879
16966
|
type = "line";
|
|
16880
16967
|
dataSetsHaveTitle;
|
|
16968
|
+
cumulative;
|
|
16881
16969
|
constructor(definition, sheetId, getters) {
|
|
16882
16970
|
super(definition, sheetId, getters);
|
|
16883
16971
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
@@ -16889,6 +16977,7 @@ class LineChart extends AbstractChart {
|
|
|
16889
16977
|
this.stacked = definition.stacked;
|
|
16890
16978
|
this.aggregated = definition.aggregated;
|
|
16891
16979
|
this.dataSetsHaveTitle = definition.dataSetsHaveTitle;
|
|
16980
|
+
this.cumulative = definition.cumulative;
|
|
16892
16981
|
}
|
|
16893
16982
|
static validateChartDefinition(validator, definition) {
|
|
16894
16983
|
return validator.checkValidations(definition, checkDataset, checkLabelRange);
|
|
@@ -16909,6 +16998,7 @@ class LineChart extends AbstractChart {
|
|
|
16909
16998
|
labelRange: context.auxiliaryRange || undefined,
|
|
16910
16999
|
stacked: false,
|
|
16911
17000
|
aggregated: false,
|
|
17001
|
+
cumulative: false,
|
|
16912
17002
|
};
|
|
16913
17003
|
}
|
|
16914
17004
|
getDefinition() {
|
|
@@ -16929,6 +17019,7 @@ class LineChart extends AbstractChart {
|
|
|
16929
17019
|
labelsAsText: this.labelsAsText,
|
|
16930
17020
|
stacked: this.stacked,
|
|
16931
17021
|
aggregated: this.aggregated,
|
|
17022
|
+
cumulative: this.cumulative,
|
|
16932
17023
|
};
|
|
16933
17024
|
}
|
|
16934
17025
|
getContextCreation() {
|
|
@@ -17139,6 +17230,16 @@ function createLineChartRuntime(chart, getters) {
|
|
|
17139
17230
|
if (chart.stacked) {
|
|
17140
17231
|
backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
|
|
17141
17232
|
}
|
|
17233
|
+
if (chart.cumulative) {
|
|
17234
|
+
let accumulator = 0;
|
|
17235
|
+
data = data.map((value) => {
|
|
17236
|
+
if (!isNaN(value)) {
|
|
17237
|
+
accumulator += parseFloat(value);
|
|
17238
|
+
return accumulator;
|
|
17239
|
+
}
|
|
17240
|
+
return value;
|
|
17241
|
+
});
|
|
17242
|
+
}
|
|
17142
17243
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
17143
17244
|
const dataset = {
|
|
17144
17245
|
label,
|
|
@@ -18013,6 +18114,7 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
18013
18114
|
labelsAsText: false,
|
|
18014
18115
|
stacked: false,
|
|
18015
18116
|
aggregated: false,
|
|
18117
|
+
cumulative: false,
|
|
18016
18118
|
labelRange: labelRangeXc,
|
|
18017
18119
|
type: "line",
|
|
18018
18120
|
dataSetsHaveTitle,
|
|
@@ -18176,6 +18278,13 @@ const REMOVE_ROWS_ACTION = (env) => {
|
|
|
18176
18278
|
elements: rows,
|
|
18177
18279
|
});
|
|
18178
18280
|
};
|
|
18281
|
+
const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
|
|
18282
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18283
|
+
const selectedElements = env.model.getters.getElementsFromSelection(dimension);
|
|
18284
|
+
const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
|
|
18285
|
+
const includesAllNonFrozenHeaders = env.model.getters.checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, selectedElements);
|
|
18286
|
+
return !includesAllVisibleHeaders && !includesAllNonFrozenHeaders;
|
|
18287
|
+
};
|
|
18179
18288
|
const REMOVE_COLUMNS_NAME = (env) => {
|
|
18180
18289
|
if (env.model.getters.getSelectedZones().length > 1) {
|
|
18181
18290
|
return _lt("Delete columns");
|
|
@@ -18200,7 +18309,7 @@ const REMOVE_COLUMNS_NAME = (env) => {
|
|
|
18200
18309
|
const NOT_ALL_VISIBLE_ROWS_SELECTED = (env) => {
|
|
18201
18310
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
18202
18311
|
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
18203
|
-
return env.model.getters.
|
|
18312
|
+
return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "ROW", selectedRows);
|
|
18204
18313
|
};
|
|
18205
18314
|
const REMOVE_COLUMNS_ACTION = (env) => {
|
|
18206
18315
|
let columns = [...env.model.getters.getActiveCols()];
|
|
@@ -18219,7 +18328,7 @@ const REMOVE_COLUMNS_ACTION = (env) => {
|
|
|
18219
18328
|
const NOT_ALL_VISIBLE_COLS_SELECTED = (env) => {
|
|
18220
18329
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
18221
18330
|
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
18222
|
-
return env.model.getters.
|
|
18331
|
+
return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "COL", selectedCols);
|
|
18223
18332
|
};
|
|
18224
18333
|
const INSERT_ROWS_BEFORE_ACTION = (env) => {
|
|
18225
18334
|
const activeRows = env.model.getters.getActiveRows();
|
|
@@ -18491,7 +18600,7 @@ const deleteValues = {
|
|
|
18491
18600
|
const deleteRows = {
|
|
18492
18601
|
name: REMOVE_ROWS_NAME,
|
|
18493
18602
|
execute: REMOVE_ROWS_ACTION,
|
|
18494
|
-
isVisible:
|
|
18603
|
+
isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("ROW", env),
|
|
18495
18604
|
};
|
|
18496
18605
|
const deleteRow = {
|
|
18497
18606
|
...deleteRows,
|
|
@@ -18504,7 +18613,7 @@ const clearRows = {
|
|
|
18504
18613
|
const deleteCols = {
|
|
18505
18614
|
name: REMOVE_COLUMNS_NAME,
|
|
18506
18615
|
execute: REMOVE_COLUMNS_ACTION,
|
|
18507
|
-
isVisible:
|
|
18616
|
+
isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("COL", env),
|
|
18508
18617
|
};
|
|
18509
18618
|
const deleteCol = {
|
|
18510
18619
|
...deleteCols,
|
|
@@ -21479,6 +21588,11 @@ class LineConfigPanel extends LineBarPieConfigPanel {
|
|
|
21479
21588
|
aggregated: ev.target.checked,
|
|
21480
21589
|
});
|
|
21481
21590
|
}
|
|
21591
|
+
onUpdateCumulative(ev) {
|
|
21592
|
+
this.props.updateChart(this.props.figureId, {
|
|
21593
|
+
cumulative: ev.target.checked,
|
|
21594
|
+
});
|
|
21595
|
+
}
|
|
21482
21596
|
}
|
|
21483
21597
|
|
|
21484
21598
|
class LineChartDesignPanel extends LineBarPieDesignPanel {
|
|
@@ -25278,9 +25392,11 @@ function useCellHovered(env, gridRef, callback) {
|
|
|
25278
25392
|
}
|
|
25279
25393
|
}
|
|
25280
25394
|
function updateMousePosition(e) {
|
|
25281
|
-
|
|
25282
|
-
|
|
25283
|
-
|
|
25395
|
+
if (gridRef.el === e.target) {
|
|
25396
|
+
x = e.offsetX;
|
|
25397
|
+
y = e.offsetY;
|
|
25398
|
+
lastMoved = Date.now();
|
|
25399
|
+
}
|
|
25284
25400
|
}
|
|
25285
25401
|
function recompute() {
|
|
25286
25402
|
const { col, row } = getPosition();
|
|
@@ -28452,6 +28568,7 @@ function convertChartData(chartData) {
|
|
|
28452
28568
|
legendPosition: chartData.legendPosition,
|
|
28453
28569
|
stacked: chartData.stacked || false,
|
|
28454
28570
|
aggregated: false,
|
|
28571
|
+
cumulative: chartData.cumulative || false,
|
|
28455
28572
|
labelsAsText: false,
|
|
28456
28573
|
};
|
|
28457
28574
|
}
|
|
@@ -33112,7 +33229,7 @@ class HeaderSizePlugin extends CorePlugin {
|
|
|
33112
33229
|
|
|
33113
33230
|
class HeaderVisibilityPlugin extends CorePlugin {
|
|
33114
33231
|
static getters = [
|
|
33115
|
-
"
|
|
33232
|
+
"checkElementsIncludeAllVisibleHeaders",
|
|
33116
33233
|
"getHiddenColsGroups",
|
|
33117
33234
|
"getHiddenRowsGroups",
|
|
33118
33235
|
"isRowHiddenByUser",
|
|
@@ -33146,7 +33263,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
33146
33263
|
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
33147
33264
|
return 28 /* CommandResult.InvalidSheetId */;
|
|
33148
33265
|
}
|
|
33149
|
-
if (
|
|
33266
|
+
if (this.checkElementsIncludeAllVisibleHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
33150
33267
|
return 8 /* CommandResult.NotEnoughElements */;
|
|
33151
33268
|
}
|
|
33152
33269
|
return 0 /* CommandResult.Success */;
|
|
@@ -33196,9 +33313,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
33196
33313
|
}
|
|
33197
33314
|
return;
|
|
33198
33315
|
}
|
|
33199
|
-
|
|
33316
|
+
checkElementsIncludeAllVisibleHeaders(sheetId, dimension, elements) {
|
|
33200
33317
|
const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
|
|
33201
|
-
return
|
|
33318
|
+
return includesAll(elements, visibleHeaders);
|
|
33202
33319
|
}
|
|
33203
33320
|
isRowHiddenByUser(sheetId, index) {
|
|
33204
33321
|
return this.hiddenHeaders[sheetId].ROW[index];
|
|
@@ -34303,6 +34420,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
34303
34420
|
"checkZonesExistInSheet",
|
|
34304
34421
|
"getCommandZones",
|
|
34305
34422
|
"getUnboundedZone",
|
|
34423
|
+
"checkElementsIncludeAllNonFrozenHeaders",
|
|
34306
34424
|
];
|
|
34307
34425
|
sheetIdsMapName = {};
|
|
34308
34426
|
orderedSheetIds = [];
|
|
@@ -34359,6 +34477,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
34359
34477
|
if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
|
|
34360
34478
|
return 87 /* CommandResult.InvalidHeaderIndex */;
|
|
34361
34479
|
}
|
|
34480
|
+
else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
34481
|
+
return 8 /* CommandResult.NotEnoughElements */;
|
|
34482
|
+
}
|
|
34362
34483
|
else {
|
|
34363
34484
|
return 0 /* CommandResult.Success */;
|
|
34364
34485
|
}
|
|
@@ -34651,6 +34772,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
34651
34772
|
}
|
|
34652
34773
|
this.history.update("sheets", sheetId, "panes", panes);
|
|
34653
34774
|
}
|
|
34775
|
+
/**
|
|
34776
|
+
* Checks if all non-frozen header indices are present in the provided elements of selected rows/columns.
|
|
34777
|
+
* This validation ensures that all rows or columns cannot be deleted when frozen panes exist.
|
|
34778
|
+
*/
|
|
34779
|
+
checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, elements) {
|
|
34780
|
+
const paneDivisions = this.getters.getPaneDivisions(sheetId);
|
|
34781
|
+
const startIndex = dimension === "ROW" ? paneDivisions.ySplit : paneDivisions.xSplit;
|
|
34782
|
+
const endIndex = this.getters.getNumberHeaders(sheetId, dimension);
|
|
34783
|
+
if (!startIndex) {
|
|
34784
|
+
return false;
|
|
34785
|
+
}
|
|
34786
|
+
const indicesToCheck = range(startIndex, endIndex);
|
|
34787
|
+
return includesAll(elements, indicesToCheck);
|
|
34788
|
+
}
|
|
34654
34789
|
// ---------------------------------------------------------------------------
|
|
34655
34790
|
// Row/Col manipulation
|
|
34656
34791
|
// ---------------------------------------------------------------------------
|
|
@@ -36634,8 +36769,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
36634
36769
|
if (cell.type === CellValueType.error) {
|
|
36635
36770
|
return false;
|
|
36636
36771
|
}
|
|
36637
|
-
const
|
|
36638
|
-
const values = rule.values.map((val) => parseLiteral(val, locale));
|
|
36772
|
+
const values = rule.values.map((val) => parseLiteral(val, DEFAULT_LOCALE));
|
|
36639
36773
|
switch (rule.operator) {
|
|
36640
36774
|
case "IsEmpty":
|
|
36641
36775
|
return cell.value.toString().trim() === "";
|
|
@@ -38719,7 +38853,7 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
38719
38853
|
const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
|
|
38720
38854
|
const toReplace = this.getSearchableString({ sheetId, col, row });
|
|
38721
38855
|
const content = toReplace.replace(replaceRegex, replaceWith);
|
|
38722
|
-
const canonicalContent =
|
|
38856
|
+
const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
|
|
38723
38857
|
this.dispatch("UPDATE_CELL", { sheetId, col, row, content: canonicalContent });
|
|
38724
38858
|
}
|
|
38725
38859
|
/**
|
|
@@ -40893,7 +41027,7 @@ class SplitToColumnsPlugin extends UIPlugin {
|
|
|
40893
41027
|
sheetId,
|
|
40894
41028
|
col: col + index,
|
|
40895
41029
|
row,
|
|
40896
|
-
content:
|
|
41030
|
+
content: canonicalizeNumberContent(content, this.getters.getLocale()),
|
|
40897
41031
|
format: "",
|
|
40898
41032
|
style: mainCell?.style || null,
|
|
40899
41033
|
});
|
|
@@ -41079,6 +41213,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
41079
41213
|
cells;
|
|
41080
41214
|
copiedTables;
|
|
41081
41215
|
zones;
|
|
41216
|
+
uuidGenerator = new UuidGenerator();
|
|
41082
41217
|
constructor(zones, operation, getters, dispatch, selection) {
|
|
41083
41218
|
super(operation, getters, dispatch, selection);
|
|
41084
41219
|
if (!zones.length) {
|
|
@@ -41540,8 +41675,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
41540
41675
|
this.adaptCFRules(origin.sheetId, cf, [xc], toRemoveRange);
|
|
41541
41676
|
}
|
|
41542
41677
|
else {
|
|
41543
|
-
this.adaptCFRules(target.sheetId, cf, [xc], []);
|
|
41544
41678
|
this.adaptCFRules(origin.sheetId, cf, [], toRemoveRange);
|
|
41679
|
+
const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
|
|
41680
|
+
this.adaptCFRules(target.sheetId, cfToCopyTo, [xc], []);
|
|
41545
41681
|
}
|
|
41546
41682
|
}
|
|
41547
41683
|
}
|
|
@@ -41565,6 +41701,12 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
41565
41701
|
sheetId,
|
|
41566
41702
|
});
|
|
41567
41703
|
}
|
|
41704
|
+
getCFToCopyTo(targetSheetId, originCF) {
|
|
41705
|
+
const cfInTarget = this.getters
|
|
41706
|
+
.getConditionalFormats(targetSheetId)
|
|
41707
|
+
.find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
|
|
41708
|
+
return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
|
|
41709
|
+
}
|
|
41568
41710
|
}
|
|
41569
41711
|
|
|
41570
41712
|
/** State of the clipboard when copying/cutting figures */
|
|
@@ -41696,7 +41838,7 @@ class ClipboardFigureImage {
|
|
|
41696
41838
|
function canonicalizeNumberValue(content, locale) {
|
|
41697
41839
|
return content.startsWith("=")
|
|
41698
41840
|
? canonicalizeFormula(content, locale)
|
|
41699
|
-
:
|
|
41841
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
41700
41842
|
}
|
|
41701
41843
|
/** Change a formula to its canonical form (en_US locale) */
|
|
41702
41844
|
function canonicalizeFormula(formula, locale) {
|
|
@@ -41813,7 +41955,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
41813
41955
|
allowDispatch(cmd) {
|
|
41814
41956
|
switch (cmd.type) {
|
|
41815
41957
|
case "CUT":
|
|
41816
|
-
const zones =
|
|
41958
|
+
const zones = this.getters.getSelectedZones();
|
|
41817
41959
|
const state = this.getClipboardState(zones, cmd.type);
|
|
41818
41960
|
return state.isCutAllowed(zones);
|
|
41819
41961
|
case "PASTE":
|
|
@@ -41848,7 +41990,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
41848
41990
|
switch (cmd.type) {
|
|
41849
41991
|
case "COPY":
|
|
41850
41992
|
case "CUT":
|
|
41851
|
-
const zones =
|
|
41993
|
+
const zones = this.getters.getSelectedZones();
|
|
41852
41994
|
this.state = this.getClipboardState(zones, cmd.type);
|
|
41853
41995
|
this.status = "visible";
|
|
41854
41996
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
@@ -42498,7 +42640,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
42498
42640
|
if (content) {
|
|
42499
42641
|
const sheetId = this.getters.getActiveSheetId();
|
|
42500
42642
|
const cell = this.getters.getEvaluatedCell({ sheetId, col: this.col, row: this.row });
|
|
42501
|
-
content =
|
|
42643
|
+
content = canonicalizeNumberContent(content, this.getters.getLocale());
|
|
42502
42644
|
if (content.startsWith("=")) {
|
|
42503
42645
|
const left = this.currentTokens.filter((t) => t.type === "LEFT_PAREN").length;
|
|
42504
42646
|
const right = this.currentTokens.filter((t) => t.type === "RIGHT_PAREN").length;
|
|
@@ -43519,26 +43661,24 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
43519
43661
|
const isBasedBefore = cmd.base < start;
|
|
43520
43662
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
43521
43663
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
43522
|
-
|
|
43523
|
-
|
|
43524
|
-
|
|
43525
|
-
|
|
43526
|
-
|
|
43527
|
-
|
|
43528
|
-
|
|
43529
|
-
|
|
43530
|
-
|
|
43531
|
-
|
|
43532
|
-
|
|
43533
|
-
|
|
43534
|
-
|
|
43535
|
-
|
|
43536
|
-
|
|
43537
|
-
|
|
43538
|
-
|
|
43539
|
-
|
|
43540
|
-
],
|
|
43541
|
-
});
|
|
43664
|
+
const target = [
|
|
43665
|
+
{
|
|
43666
|
+
left: isCol ? start + deltaCol : 0,
|
|
43667
|
+
right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
43668
|
+
top: !isCol ? start + deltaRow : 0,
|
|
43669
|
+
bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
43670
|
+
},
|
|
43671
|
+
];
|
|
43672
|
+
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
43673
|
+
const pasteTarget = [
|
|
43674
|
+
{
|
|
43675
|
+
left: isCol ? cmd.base : 0,
|
|
43676
|
+
right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
43677
|
+
top: !isCol ? cmd.base : 0,
|
|
43678
|
+
bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
43679
|
+
},
|
|
43680
|
+
];
|
|
43681
|
+
state.paste(pasteTarget, { selectTarget: true });
|
|
43542
43682
|
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
43543
43683
|
let currentIndex = cmd.base;
|
|
43544
43684
|
for (const element of toRemove) {
|
|
@@ -43937,6 +44077,9 @@ class InternalViewport {
|
|
|
43937
44077
|
const sheetId = this.sheetId;
|
|
43938
44078
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
43939
44079
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
44080
|
+
if (this.left === -1) {
|
|
44081
|
+
this.left = this.boundaries.left;
|
|
44082
|
+
}
|
|
43940
44083
|
if (this.right === -1) {
|
|
43941
44084
|
this.right = this.getters.getNumberCols(sheetId) - 1;
|
|
43942
44085
|
}
|
|
@@ -43950,6 +44093,9 @@ class InternalViewport {
|
|
|
43950
44093
|
const sheetId = this.sheetId;
|
|
43951
44094
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
43952
44095
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
44096
|
+
if (this.top === -1) {
|
|
44097
|
+
this.top = this.boundaries.top;
|
|
44098
|
+
}
|
|
43953
44099
|
if (this.bottom === -1) {
|
|
43954
44100
|
this.bottom = this.getters.getNumberRows(sheetId) - 1;
|
|
43955
44101
|
}
|
|
@@ -50550,6 +50696,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
50550
50696
|
exports.tokenize = tokenize;
|
|
50551
50697
|
|
|
50552
50698
|
|
|
50553
|
-
__info__.version = '16.4.
|
|
50554
|
-
__info__.date = '2023-
|
|
50555
|
-
__info__.hash = '
|
|
50699
|
+
__info__.version = '16.4.7';
|
|
50700
|
+
__info__.date = '2023-09-21T15:58:11.039Z';
|
|
50701
|
+
__info__.hash = 'eccdcce';
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -424,6 +424,7 @@ interface LineChartDefinition {
|
|
|
424
424
|
readonly labelsAsText: boolean;
|
|
425
425
|
readonly stacked: boolean;
|
|
426
426
|
readonly aggregated?: boolean;
|
|
427
|
+
readonly cumulative: boolean;
|
|
427
428
|
}
|
|
428
429
|
type LineChartRuntime = {
|
|
429
430
|
chartJsConfig: ChartConfiguration;
|
|
@@ -490,6 +491,7 @@ interface ExcelChartDefinition {
|
|
|
490
491
|
readonly verticalAxisPosition: VerticalAxisPosition;
|
|
491
492
|
readonly legendPosition: LegendPosition;
|
|
492
493
|
readonly stacked?: boolean;
|
|
494
|
+
readonly cumulative?: boolean;
|
|
493
495
|
}
|
|
494
496
|
interface ChartCreationContext {
|
|
495
497
|
readonly range?: string[];
|
|
@@ -1895,8 +1897,6 @@ interface CopyCommand {
|
|
|
1895
1897
|
}
|
|
1896
1898
|
interface CutCommand {
|
|
1897
1899
|
type: "CUT";
|
|
1898
|
-
/** Zones to cut. If none were given, will copy the zones in the selection*/
|
|
1899
|
-
cutTarget?: Zone[];
|
|
1900
1900
|
}
|
|
1901
1901
|
interface PasteCommand {
|
|
1902
1902
|
type: "PASTE";
|
|
@@ -3462,11 +3462,11 @@ declare class HeaderSizePlugin extends CorePlugin<HeaderSizeState$1> implements
|
|
|
3462
3462
|
}
|
|
3463
3463
|
|
|
3464
3464
|
declare class HeaderVisibilityPlugin extends CorePlugin {
|
|
3465
|
-
static getters: readonly ["
|
|
3465
|
+
static getters: readonly ["checkElementsIncludeAllVisibleHeaders", "getHiddenColsGroups", "getHiddenRowsGroups", "isRowHiddenByUser", "isColHiddenByUser"];
|
|
3466
3466
|
private readonly hiddenHeaders;
|
|
3467
3467
|
allowDispatch(cmd: Command): CommandResult.Success | CommandResult.NotEnoughElements | CommandResult.InvalidSheetId | CommandResult.TooManyHiddenElements | CommandResult.InvalidHeaderIndex;
|
|
3468
3468
|
handle(cmd: Command): void;
|
|
3469
|
-
|
|
3469
|
+
checkElementsIncludeAllVisibleHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean;
|
|
3470
3470
|
isRowHiddenByUser(sheetId: UID, index: HeaderIndex): boolean;
|
|
3471
3471
|
isColHiddenByUser(sheetId: UID, index: HeaderIndex): boolean;
|
|
3472
3472
|
getHiddenColsGroups(sheetId: UID): ConsecutiveIndexes[];
|
|
@@ -3603,7 +3603,7 @@ interface SheetState$1 {
|
|
|
3603
3603
|
readonly cellPosition: Record<UID, CellPosition | undefined>;
|
|
3604
3604
|
}
|
|
3605
3605
|
declare class SheetPlugin extends CorePlugin<SheetState$1> implements SheetState$1 {
|
|
3606
|
-
static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "getEvaluationSheets", "doesHeaderExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "isEmpty", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone"];
|
|
3606
|
+
static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "getEvaluationSheets", "doesHeaderExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "isEmpty", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone", "checkElementsIncludeAllNonFrozenHeaders"];
|
|
3607
3607
|
readonly sheetIdsMapName: Record<string, UID | undefined>;
|
|
3608
3608
|
readonly orderedSheetIds: UID[];
|
|
3609
3609
|
readonly sheets: Record<UID, Sheet | undefined>;
|
|
@@ -3646,6 +3646,11 @@ declare class SheetPlugin extends CorePlugin<SheetState$1> implements SheetState
|
|
|
3646
3646
|
getUnboundedZone(sheetId: UID, zone: Zone): UnboundedZone;
|
|
3647
3647
|
getPaneDivisions(sheetId: UID): Readonly<PaneDivision>;
|
|
3648
3648
|
private setPaneDivisions;
|
|
3649
|
+
/**
|
|
3650
|
+
* Checks if all non-frozen header indices are present in the provided elements of selected rows/columns.
|
|
3651
|
+
* This validation ensures that all rows or columns cannot be deleted when frozen panes exist.
|
|
3652
|
+
*/
|
|
3653
|
+
checkElementsIncludeAllNonFrozenHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean;
|
|
3649
3654
|
/**
|
|
3650
3655
|
* Check if a zone only contains empty cells
|
|
3651
3656
|
*/
|
|
@@ -5354,6 +5359,7 @@ declare class LineConfigPanel extends LineBarPieConfigPanel {
|
|
|
5354
5359
|
onUpdateLabelsAsText(ev: any): void;
|
|
5355
5360
|
onUpdateStacked(ev: any): void;
|
|
5356
5361
|
onUpdateAggregated(ev: any): void;
|
|
5362
|
+
onUpdateCumulative(ev: any): void;
|
|
5357
5363
|
}
|
|
5358
5364
|
|
|
5359
5365
|
interface Props$y {
|