@odoo/o-spreadsheet 16.3.0-alpha.7 → 16.3.0
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 +751 -293
- package/dist/o-spreadsheet.d.ts +212 -118
- package/dist/o-spreadsheet.esm.js +751 -293
- package/dist/o-spreadsheet.iife.js +751 -293
- package/dist/o-spreadsheet.iife.min.js +384 -289
- package/package.json +2 -2
|
@@ -237,8 +237,8 @@
|
|
|
237
237
|
const DEFAULT_FONT = "'Roboto', arial";
|
|
238
238
|
const DEFAULT_VERTICAL_ALIGN = "bottom";
|
|
239
239
|
// Borders
|
|
240
|
-
const DEFAULT_BORDER_DESC =
|
|
241
|
-
const DEFAULT_FILTER_BORDER_DESC =
|
|
240
|
+
const DEFAULT_BORDER_DESC = { style: "thin", color: "#000000" };
|
|
241
|
+
const DEFAULT_FILTER_BORDER_DESC = { style: "thin", color: FILTERS_COLOR };
|
|
242
242
|
// Ranges
|
|
243
243
|
const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
|
|
244
244
|
// Max Number of history steps kept in memory
|
|
@@ -1102,6 +1102,18 @@
|
|
|
1102
1102
|
text = text.replace(whiteSpaceRegexp, " ");
|
|
1103
1103
|
text = text.replace(newLineRegex, NEWLINE);
|
|
1104
1104
|
return text;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Determine if the numbers are consecutive.
|
|
1108
|
+
*/
|
|
1109
|
+
function isConsecutive(iterable) {
|
|
1110
|
+
const array = Array.from(iterable).sort((a, b) => a - b); // sort numerically rather than lexicographically
|
|
1111
|
+
for (let i = 1; i < array.length; i++) {
|
|
1112
|
+
if (array[i] - array[i - 1] !== 1) {
|
|
1113
|
+
return false;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return true;
|
|
1105
1117
|
}
|
|
1106
1118
|
|
|
1107
1119
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
@@ -4244,6 +4256,7 @@
|
|
|
4244
4256
|
"SET_FORMATTING",
|
|
4245
4257
|
"CLEAR_FORMATTING",
|
|
4246
4258
|
"SET_BORDER",
|
|
4259
|
+
"SET_ZONE_BORDERS",
|
|
4247
4260
|
/** CHART */
|
|
4248
4261
|
"CREATE_CHART",
|
|
4249
4262
|
"UPDATE_CHART",
|
|
@@ -4384,8 +4397,10 @@
|
|
|
4384
4397
|
CommandResult[CommandResult["EmptySplitSeparator"] = 89] = "EmptySplitSeparator";
|
|
4385
4398
|
CommandResult[CommandResult["SplitWillOverwriteContent"] = 90] = "SplitWillOverwriteContent";
|
|
4386
4399
|
CommandResult[CommandResult["NoSplitSeparatorInSelection"] = 91] = "NoSplitSeparatorInSelection";
|
|
4400
|
+
CommandResult[CommandResult["NoActiveSheet"] = 92] = "NoActiveSheet";
|
|
4387
4401
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
4388
4402
|
|
|
4403
|
+
const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
4389
4404
|
var DIRECTION;
|
|
4390
4405
|
(function (DIRECTION) {
|
|
4391
4406
|
DIRECTION["UP"] = "up";
|
|
@@ -5479,12 +5494,6 @@
|
|
|
5479
5494
|
cursor: pointer;
|
|
5480
5495
|
user-select: none;
|
|
5481
5496
|
|
|
5482
|
-
.o-menu-item-name {
|
|
5483
|
-
overflow: hidden;
|
|
5484
|
-
white-space: nowrap;
|
|
5485
|
-
text-overflow: ellipsis;
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5488
5497
|
&.o-menu-root {
|
|
5489
5498
|
display: flex;
|
|
5490
5499
|
justify-content: space-between;
|
|
@@ -5495,10 +5504,6 @@
|
|
|
5495
5504
|
margin: 0px 8px 0px 0px;
|
|
5496
5505
|
width: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
5497
5506
|
line-height: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
5498
|
-
|
|
5499
|
-
.o-icon {
|
|
5500
|
-
color: ${ICONS_COLOR};
|
|
5501
|
-
}
|
|
5502
5507
|
}
|
|
5503
5508
|
.o-menu-item-root {
|
|
5504
5509
|
width: 10px;
|
|
@@ -5512,6 +5517,11 @@
|
|
|
5512
5517
|
.o-menu-item-description {
|
|
5513
5518
|
color: grey;
|
|
5514
5519
|
}
|
|
5520
|
+
.o-menu-item-icon {
|
|
5521
|
+
.o-icon {
|
|
5522
|
+
color: ${ICONS_COLOR};
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5515
5525
|
}
|
|
5516
5526
|
&.disabled {
|
|
5517
5527
|
color: ${MENU_ITEM_DISABLED_COLOR};
|
|
@@ -6328,8 +6338,14 @@
|
|
|
6328
6338
|
: undefined));
|
|
6329
6339
|
}
|
|
6330
6340
|
}
|
|
6341
|
+
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
6342
|
+
// A single cell. If it's only the title, the dataset is not added.
|
|
6343
|
+
if (!dataSetsHaveTitle) {
|
|
6344
|
+
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
6331
6347
|
else {
|
|
6332
|
-
/* 1
|
|
6348
|
+
/* 1 row or 1 column */
|
|
6333
6349
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
6334
6350
|
? {
|
|
6335
6351
|
top: zone.top,
|
|
@@ -8940,7 +8956,7 @@
|
|
|
8940
8956
|
handlePasteResult(env, result);
|
|
8941
8957
|
};
|
|
8942
8958
|
const MENU_INSERT_ROWS_NAME = (env) => {
|
|
8943
|
-
const number =
|
|
8959
|
+
const number = getRowsNumber(env);
|
|
8944
8960
|
return number === 1 ? _lt("Insert row") : _lt("Insert %s rows", number.toString());
|
|
8945
8961
|
};
|
|
8946
8962
|
const MENU_INSERT_ROWS_BEFORE_NAME = (env) => {
|
|
@@ -15305,7 +15321,11 @@
|
|
|
15305
15321
|
: getNormalizedValueFromRowRange;
|
|
15306
15322
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
15307
15323
|
const index = dichotomicSearch(searchArray, _searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
15308
|
-
|
|
15324
|
+
if (index === -1)
|
|
15325
|
+
assertAvailable(undefined, searchKey);
|
|
15326
|
+
verticalSearch
|
|
15327
|
+
? assertAvailable(searchArray[0][index], searchKey)
|
|
15328
|
+
: assertAvailable(searchArray[index][nbRow - 1], searchKey);
|
|
15309
15329
|
if (resultRange === undefined) {
|
|
15310
15330
|
return (verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1]);
|
|
15311
15331
|
}
|
|
@@ -16212,75 +16232,97 @@
|
|
|
16212
16232
|
|
|
16213
16233
|
const insertRow = {
|
|
16214
16234
|
name: MENU_INSERT_ROWS_NAME,
|
|
16215
|
-
isVisible:
|
|
16235
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveRows()) &&
|
|
16236
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16237
|
+
env.model.getters.getActiveCols().size === 0,
|
|
16216
16238
|
icon: "o-spreadsheet-Icon.INSERT_ROW",
|
|
16217
16239
|
};
|
|
16218
16240
|
const rowInsertRowBefore = {
|
|
16219
16241
|
name: ROW_INSERT_ROWS_BEFORE_NAME,
|
|
16220
16242
|
execute: INSERT_ROWS_BEFORE_ACTION,
|
|
16243
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveRows()) &&
|
|
16244
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16245
|
+
env.model.getters.getActiveCols().size === 0,
|
|
16246
|
+
icon: "o-spreadsheet-Icon.INSERT_ROW_BEFORE",
|
|
16221
16247
|
};
|
|
16222
16248
|
const topBarInsertRowsBefore = {
|
|
16223
16249
|
...rowInsertRowBefore,
|
|
16224
16250
|
name: MENU_INSERT_ROWS_BEFORE_NAME,
|
|
16225
|
-
isVisible: (env) => env.model.getters.getActiveCols().size === 0,
|
|
16226
16251
|
};
|
|
16227
16252
|
const cellInsertRowsBefore = {
|
|
16228
16253
|
...rowInsertRowBefore,
|
|
16229
16254
|
name: CELL_INSERT_ROWS_BEFORE_NAME,
|
|
16230
16255
|
isVisible: IS_ONLY_ONE_RANGE,
|
|
16231
|
-
icon: "o-spreadsheet-Icon.
|
|
16256
|
+
icon: "o-spreadsheet-Icon.INSERT_ROW_BEFORE",
|
|
16232
16257
|
};
|
|
16233
16258
|
const rowInsertRowsAfter = {
|
|
16234
16259
|
execute: INSERT_ROWS_AFTER_ACTION,
|
|
16235
16260
|
name: ROW_INSERT_ROWS_AFTER_NAME,
|
|
16261
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveRows()) &&
|
|
16262
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16263
|
+
env.model.getters.getActiveCols().size === 0,
|
|
16264
|
+
icon: "o-spreadsheet-Icon.INSERT_ROW_AFTER",
|
|
16236
16265
|
};
|
|
16237
16266
|
const topBarInsertRowsAfter = {
|
|
16238
16267
|
...rowInsertRowsAfter,
|
|
16239
16268
|
name: MENU_INSERT_ROWS_AFTER_NAME,
|
|
16240
|
-
isVisible: (env) => env.model.getters.getActiveCols().size === 0,
|
|
16241
16269
|
};
|
|
16242
16270
|
const insertCol = {
|
|
16243
16271
|
name: MENU_INSERT_COLUMNS_NAME,
|
|
16244
|
-
isVisible:
|
|
16272
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveCols()) &&
|
|
16273
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16274
|
+
env.model.getters.getActiveRows().size === 0,
|
|
16245
16275
|
icon: "o-spreadsheet-Icon.INSERT_COL",
|
|
16246
16276
|
};
|
|
16247
16277
|
const colInsertColsBefore = {
|
|
16248
16278
|
name: COLUMN_INSERT_COLUMNS_BEFORE_NAME,
|
|
16249
16279
|
execute: INSERT_COLUMNS_BEFORE_ACTION,
|
|
16280
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveCols()) &&
|
|
16281
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16282
|
+
env.model.getters.getActiveRows().size === 0,
|
|
16283
|
+
icon: "o-spreadsheet-Icon.INSERT_COL_BEFORE",
|
|
16250
16284
|
};
|
|
16251
16285
|
const topBarInsertColsBefore = {
|
|
16252
16286
|
...colInsertColsBefore,
|
|
16253
16287
|
name: MENU_INSERT_COLUMNS_BEFORE_NAME,
|
|
16254
|
-
isVisible: (env) => env.model.getters.getActiveRows().size === 0,
|
|
16255
16288
|
};
|
|
16256
16289
|
const cellInsertColsBefore = {
|
|
16257
16290
|
...colInsertColsBefore,
|
|
16258
16291
|
name: CELL_INSERT_COLUMNS_BEFORE_NAME,
|
|
16259
16292
|
isVisible: IS_ONLY_ONE_RANGE,
|
|
16260
|
-
icon: "o-spreadsheet-Icon.
|
|
16293
|
+
icon: "o-spreadsheet-Icon.INSERT_COL_BEFORE",
|
|
16261
16294
|
};
|
|
16262
16295
|
const colInsertColsAfter = {
|
|
16263
16296
|
name: COLUMN_INSERT_COLUMNS_AFTER_NAME,
|
|
16264
16297
|
execute: INSERT_COLUMNS_AFTER_ACTION,
|
|
16298
|
+
isVisible: (env) => isConsecutive(env.model.getters.getActiveCols()) &&
|
|
16299
|
+
IS_ONLY_ONE_RANGE(env) &&
|
|
16300
|
+
env.model.getters.getActiveRows().size === 0,
|
|
16301
|
+
icon: "o-spreadsheet-Icon.INSERT_COL_AFTER",
|
|
16265
16302
|
};
|
|
16266
16303
|
const topBarInsertColsAfter = {
|
|
16267
16304
|
...colInsertColsAfter,
|
|
16268
16305
|
name: MENU_INSERT_COLUMNS_AFTER_NAME,
|
|
16269
16306
|
execute: INSERT_COLUMNS_AFTER_ACTION,
|
|
16270
|
-
isVisible: (env) => env.model.getters.getActiveRows().size === 0,
|
|
16271
16307
|
};
|
|
16272
16308
|
const insertCell = {
|
|
16273
16309
|
name: _lt("Insert cells"),
|
|
16274
|
-
isVisible: IS_ONLY_ONE_RANGE
|
|
16310
|
+
isVisible: (env) => IS_ONLY_ONE_RANGE(env) &&
|
|
16311
|
+
env.model.getters.getActiveCols().size === 0 &&
|
|
16312
|
+
env.model.getters.getActiveRows().size === 0,
|
|
16275
16313
|
icon: "o-spreadsheet-Icon.INSERT_CELL",
|
|
16276
16314
|
};
|
|
16277
16315
|
const insertCellShiftDown = {
|
|
16278
16316
|
name: _lt("Insert cells and shift down"),
|
|
16279
16317
|
execute: INSERT_CELL_SHIFT_DOWN,
|
|
16318
|
+
isVisible: (env) => env.model.getters.getActiveRows().size === 0 && env.model.getters.getActiveCols().size === 0,
|
|
16319
|
+
icon: "o-spreadsheet-Icon.INSERT_CELL_SHIFT_DOWN",
|
|
16280
16320
|
};
|
|
16281
16321
|
const insertCellShiftRight = {
|
|
16282
16322
|
name: _lt("Insert cells and shift right"),
|
|
16283
16323
|
execute: INSERT_CELL_SHIFT_RIGHT,
|
|
16324
|
+
isVisible: (env) => env.model.getters.getActiveRows().size === 0 && env.model.getters.getActiveCols().size === 0,
|
|
16325
|
+
icon: "o-spreadsheet-Icon.INSERT_CELL_SHIFT_RIGHT",
|
|
16284
16326
|
};
|
|
16285
16327
|
const insertChart = {
|
|
16286
16328
|
name: _lt("Chart"),
|
|
@@ -16478,6 +16520,7 @@
|
|
|
16478
16520
|
sequence: 1,
|
|
16479
16521
|
execute: (env) => env.openSidePanel("SplitToColumns", {}),
|
|
16480
16522
|
isEnabled: (env) => env.model.getters.isSingleColSelected(),
|
|
16523
|
+
icon: "o-spreadsheet-Icon.SPLIT_TEXT",
|
|
16481
16524
|
};
|
|
16482
16525
|
|
|
16483
16526
|
const formatNumberAutomatic = {
|
|
@@ -16693,60 +16736,6 @@
|
|
|
16693
16736
|
execute: FORMAT_CLEARFORMAT_ACTION,
|
|
16694
16737
|
icon: "o-spreadsheet-Icon.CLEAR_FORMAT",
|
|
16695
16738
|
};
|
|
16696
|
-
const borders = {
|
|
16697
|
-
name: _lt("Borders"),
|
|
16698
|
-
icon: "o-spreadsheet-Icon.BORDERS",
|
|
16699
|
-
};
|
|
16700
|
-
const bordersAll = {
|
|
16701
|
-
name: _lt("All borders"),
|
|
16702
|
-
execute: (env) => setBorder(env, "all"),
|
|
16703
|
-
icon: "o-spreadsheet-Icon.BORDERS",
|
|
16704
|
-
};
|
|
16705
|
-
const bordersInner = {
|
|
16706
|
-
name: _lt("Inner borders"),
|
|
16707
|
-
execute: (env) => setBorder(env, "hv"),
|
|
16708
|
-
icon: "o-spreadsheet-Icon.BORDER_HV",
|
|
16709
|
-
};
|
|
16710
|
-
const bordersHorizontal = {
|
|
16711
|
-
name: _lt("Horizontal borders"),
|
|
16712
|
-
execute: (env) => setBorder(env, "h"),
|
|
16713
|
-
icon: "o-spreadsheet-Icon.BORDER_H",
|
|
16714
|
-
};
|
|
16715
|
-
const bordersVertical = {
|
|
16716
|
-
name: _lt("Vertical borders"),
|
|
16717
|
-
execute: (env) => setBorder(env, "v"),
|
|
16718
|
-
icon: "o-spreadsheet-Icon.BORDER_V",
|
|
16719
|
-
};
|
|
16720
|
-
const bordersExternal = {
|
|
16721
|
-
name: _lt("External borders"),
|
|
16722
|
-
execute: (env) => setBorder(env, "external"),
|
|
16723
|
-
icon: "o-spreadsheet-Icon.BORDER_EXTERNAL",
|
|
16724
|
-
};
|
|
16725
|
-
const bordersLeft = {
|
|
16726
|
-
name: _lt("Left borders"),
|
|
16727
|
-
execute: (env) => setBorder(env, "left"),
|
|
16728
|
-
icon: "o-spreadsheet-Icon.BORDER_LEFT",
|
|
16729
|
-
};
|
|
16730
|
-
const bordersTop = {
|
|
16731
|
-
name: _lt("Top borders"),
|
|
16732
|
-
execute: (env) => setBorder(env, "top"),
|
|
16733
|
-
icon: "o-spreadsheet-Icon.BORDER_TOP",
|
|
16734
|
-
};
|
|
16735
|
-
const bordersRight = {
|
|
16736
|
-
name: _lt("Right borders"),
|
|
16737
|
-
execute: (env) => setBorder(env, "right"),
|
|
16738
|
-
icon: "o-spreadsheet-Icon.BORDER_RIGHT",
|
|
16739
|
-
};
|
|
16740
|
-
const bordersBottom = {
|
|
16741
|
-
name: _lt("Bottom borders"),
|
|
16742
|
-
execute: (env) => setBorder(env, "bottom"),
|
|
16743
|
-
icon: "o-spreadsheet-Icon.BORDER_BOTTOM",
|
|
16744
|
-
};
|
|
16745
|
-
const bordersClear = {
|
|
16746
|
-
name: _lt("Clear borders"),
|
|
16747
|
-
execute: (env) => setBorder(env, "clear"),
|
|
16748
|
-
icon: "o-spreadsheet-Icon.BORDER_CLEAR",
|
|
16749
|
-
};
|
|
16750
16739
|
function fontSizeMenuBuilder() {
|
|
16751
16740
|
return FONT_SIZES.map((fs) => {
|
|
16752
16741
|
return {
|
|
@@ -16759,24 +16748,17 @@
|
|
|
16759
16748
|
});
|
|
16760
16749
|
}
|
|
16761
16750
|
function isAutomaticFormatSelected(env) {
|
|
16762
|
-
const activeCell = env.model.getters.
|
|
16751
|
+
const activeCell = env.model.getters.getCell(env.model.getters.getActivePosition());
|
|
16763
16752
|
return !activeCell || !activeCell.format;
|
|
16764
16753
|
}
|
|
16765
16754
|
function isFormatSelected(env, format) {
|
|
16766
|
-
const activeCell = env.model.getters.
|
|
16767
|
-
return activeCell
|
|
16755
|
+
const activeCell = env.model.getters.getCell(env.model.getters.getActivePosition());
|
|
16756
|
+
return activeCell?.format === format;
|
|
16768
16757
|
}
|
|
16769
16758
|
function isFontSizeSelected(env, fontSize) {
|
|
16770
16759
|
const currentFontSize = env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
16771
16760
|
return currentFontSize === fontSize;
|
|
16772
16761
|
}
|
|
16773
|
-
function setBorder(env, command) {
|
|
16774
|
-
env.model.dispatch("SET_FORMATTING", {
|
|
16775
|
-
sheetId: env.model.getters.getActiveSheetId(),
|
|
16776
|
-
target: env.model.getters.getSelectedZones(),
|
|
16777
|
-
border: command,
|
|
16778
|
-
});
|
|
16779
|
-
}
|
|
16780
16762
|
function getHorizontalAlign(env) {
|
|
16781
16763
|
const style = env.model.getters.getCurrentStyle();
|
|
16782
16764
|
if (style.align) {
|
|
@@ -16823,18 +16805,7 @@
|
|
|
16823
16805
|
fillColor: fillColor,
|
|
16824
16806
|
formatCF: formatCF,
|
|
16825
16807
|
paintFormat: paintFormat,
|
|
16826
|
-
clearFormat: clearFormat
|
|
16827
|
-
borders: borders,
|
|
16828
|
-
bordersAll: bordersAll,
|
|
16829
|
-
bordersInner: bordersInner,
|
|
16830
|
-
bordersHorizontal: bordersHorizontal,
|
|
16831
|
-
bordersVertical: bordersVertical,
|
|
16832
|
-
bordersExternal: bordersExternal,
|
|
16833
|
-
bordersLeft: bordersLeft,
|
|
16834
|
-
bordersTop: bordersTop,
|
|
16835
|
-
bordersRight: bordersRight,
|
|
16836
|
-
bordersBottom: bordersBottom,
|
|
16837
|
-
bordersClear: bordersClear
|
|
16808
|
+
clearFormat: clearFormat
|
|
16838
16809
|
});
|
|
16839
16810
|
|
|
16840
16811
|
function interactiveFreezeColumnsRows(env, dimension, base) {
|
|
@@ -16850,6 +16821,7 @@
|
|
|
16850
16821
|
name: HIDE_COLUMNS_NAME,
|
|
16851
16822
|
execute: HIDE_COLUMNS_ACTION,
|
|
16852
16823
|
isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
|
|
16824
|
+
icon: "o-spreadsheet-Icon.HIDE_COL",
|
|
16853
16825
|
};
|
|
16854
16826
|
const unhideCols = {
|
|
16855
16827
|
name: _lt("Unhide columns"),
|
|
@@ -16871,6 +16843,7 @@
|
|
|
16871
16843
|
name: HIDE_ROWS_NAME,
|
|
16872
16844
|
execute: HIDE_ROWS_ACTION,
|
|
16873
16845
|
isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
|
|
16846
|
+
icon: "o-spreadsheet-Icon.HIDE_ROW",
|
|
16874
16847
|
};
|
|
16875
16848
|
const unhideRows = {
|
|
16876
16849
|
name: _lt("Unhide rows"),
|
|
@@ -17074,19 +17047,21 @@
|
|
|
17074
17047
|
.add("delete_column", {
|
|
17075
17048
|
...deleteCols,
|
|
17076
17049
|
sequence: 90,
|
|
17050
|
+
icon: "o-spreadsheet-Icon.DELETE",
|
|
17077
17051
|
})
|
|
17078
17052
|
.add("clear_column", {
|
|
17079
17053
|
...clearCols,
|
|
17080
17054
|
sequence: 100,
|
|
17055
|
+
icon: "o-spreadsheet-Icon.CLEAR",
|
|
17081
17056
|
})
|
|
17082
17057
|
.add("hide_columns", {
|
|
17083
17058
|
...hideCols,
|
|
17084
|
-
sequence:
|
|
17059
|
+
sequence: 105,
|
|
17085
17060
|
separator: true,
|
|
17086
17061
|
})
|
|
17087
17062
|
.add("unhide_columns", {
|
|
17088
17063
|
...unhideCols,
|
|
17089
|
-
sequence:
|
|
17064
|
+
sequence: 106,
|
|
17090
17065
|
separator: true,
|
|
17091
17066
|
})
|
|
17092
17067
|
.add("conditional_formatting", {
|
|
@@ -17184,10 +17159,12 @@
|
|
|
17184
17159
|
.add("delete_row", {
|
|
17185
17160
|
...deleteRows,
|
|
17186
17161
|
sequence: 70,
|
|
17162
|
+
icon: "o-spreadsheet-Icon.DELETE",
|
|
17187
17163
|
})
|
|
17188
17164
|
.add("clear_row", {
|
|
17189
17165
|
...clearRows,
|
|
17190
17166
|
sequence: 80,
|
|
17167
|
+
icon: "o-spreadsheet-Icon.CLEAR",
|
|
17191
17168
|
})
|
|
17192
17169
|
.add("hide_rows", {
|
|
17193
17170
|
...hideRows,
|
|
@@ -17570,7 +17547,7 @@
|
|
|
17570
17547
|
})
|
|
17571
17548
|
.addChild("sort_range", ["data"], {
|
|
17572
17549
|
...sortRange,
|
|
17573
|
-
sequence:
|
|
17550
|
+
sequence: 10,
|
|
17574
17551
|
separator: true,
|
|
17575
17552
|
})
|
|
17576
17553
|
.addChild("sort_ascending", ["data", "sort_range"], {
|
|
@@ -17583,16 +17560,16 @@
|
|
|
17583
17560
|
})
|
|
17584
17561
|
.addChild("split_to_columns", ["data"], {
|
|
17585
17562
|
...splitToColumns,
|
|
17586
|
-
sequence:
|
|
17563
|
+
sequence: 20,
|
|
17587
17564
|
separator: true,
|
|
17588
17565
|
})
|
|
17589
17566
|
.addChild("add_data_filter", ["data"], {
|
|
17590
17567
|
...addDataFilter,
|
|
17591
|
-
sequence:
|
|
17568
|
+
sequence: 30,
|
|
17592
17569
|
})
|
|
17593
17570
|
.addChild("remove_data_filter", ["data"], {
|
|
17594
17571
|
...removeDataFilter,
|
|
17595
|
-
sequence:
|
|
17572
|
+
sequence: 30,
|
|
17596
17573
|
});
|
|
17597
17574
|
|
|
17598
17575
|
class OTRegistry extends Registry {
|
|
@@ -17680,6 +17657,12 @@
|
|
|
17680
17657
|
height: 25px;
|
|
17681
17658
|
}
|
|
17682
17659
|
}
|
|
17660
|
+
/** Make the character a bit bigger
|
|
17661
|
+
compared to its neighbor INPUT box */
|
|
17662
|
+
.o-remove-selection {
|
|
17663
|
+
font-weight: bold;
|
|
17664
|
+
font-size: calc(100% + 4px);
|
|
17665
|
+
}
|
|
17683
17666
|
}
|
|
17684
17667
|
`;
|
|
17685
17668
|
/**
|
|
@@ -17775,6 +17758,9 @@
|
|
|
17775
17758
|
this.confirm();
|
|
17776
17759
|
}
|
|
17777
17760
|
}
|
|
17761
|
+
extractRanges(value) {
|
|
17762
|
+
return this.props.hasSingleRange ? value.split(",")[0] : value;
|
|
17763
|
+
}
|
|
17778
17764
|
focus(rangeId) {
|
|
17779
17765
|
this.state.isMissing = false;
|
|
17780
17766
|
this.state.mode = "select-range";
|
|
@@ -17793,10 +17779,11 @@
|
|
|
17793
17779
|
}
|
|
17794
17780
|
onInputChanged(rangeId, ev) {
|
|
17795
17781
|
const target = ev.target;
|
|
17782
|
+
const value = this.extractRanges(target.value);
|
|
17796
17783
|
this.env.model.dispatch("CHANGE_RANGE", {
|
|
17797
17784
|
id: this.id,
|
|
17798
17785
|
rangeId,
|
|
17799
|
-
value
|
|
17786
|
+
value,
|
|
17800
17787
|
});
|
|
17801
17788
|
this.triggerChange();
|
|
17802
17789
|
}
|
|
@@ -18689,6 +18676,18 @@
|
|
|
18689
18676
|
onCloseSidePanel: Function,
|
|
18690
18677
|
};
|
|
18691
18678
|
|
|
18679
|
+
css /* scss */ `
|
|
18680
|
+
.o-spreadsheet {
|
|
18681
|
+
.o-icon {
|
|
18682
|
+
.small-text {
|
|
18683
|
+
font: bold 9px sans-serif;
|
|
18684
|
+
}
|
|
18685
|
+
.heavy-text {
|
|
18686
|
+
font: bold 16px sans-serif;
|
|
18687
|
+
}
|
|
18688
|
+
}
|
|
18689
|
+
}
|
|
18690
|
+
`;
|
|
18692
18691
|
// -----------------------------------------------------------------------------
|
|
18693
18692
|
// We need here the svg of the icons that we need to convert to images for the renderer
|
|
18694
18693
|
// -----------------------------------------------------------------------------
|
|
@@ -20565,14 +20564,31 @@
|
|
|
20565
20564
|
* */
|
|
20566
20565
|
getCurrentSelection() {
|
|
20567
20566
|
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
|
|
20568
|
-
let startSizeBefore = this.
|
|
20569
|
-
let endSizeBefore = this.
|
|
20567
|
+
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
20568
|
+
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
20570
20569
|
return {
|
|
20571
|
-
start: startSizeBefore
|
|
20572
|
-
end: endSizeBefore
|
|
20570
|
+
start: startSizeBefore,
|
|
20571
|
+
end: endSizeBefore,
|
|
20573
20572
|
};
|
|
20574
20573
|
}
|
|
20575
|
-
|
|
20574
|
+
/**
|
|
20575
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
20576
|
+
* The selected node is either a Text node or an Element node.
|
|
20577
|
+
*
|
|
20578
|
+
* case 1 -Text node:
|
|
20579
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
20580
|
+
* content length of all previous nodes.
|
|
20581
|
+
*
|
|
20582
|
+
* case 2 - Element node:
|
|
20583
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
20584
|
+
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
20585
|
+
*
|
|
20586
|
+
* See the MDN documentation for more details.
|
|
20587
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
20588
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
20589
|
+
*
|
|
20590
|
+
*/
|
|
20591
|
+
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
20576
20592
|
let usedCharacters = 0;
|
|
20577
20593
|
let it = iterateChildren(this.el);
|
|
20578
20594
|
let current = it.next();
|
|
@@ -20599,6 +20615,28 @@
|
|
|
20599
20615
|
if (current.value !== nodeToFind) {
|
|
20600
20616
|
throw new Error("Cannot find the node in the children of the element");
|
|
20601
20617
|
}
|
|
20618
|
+
else {
|
|
20619
|
+
if (!current.value.hasChildNodes()) {
|
|
20620
|
+
usedCharacters += nodeOffset;
|
|
20621
|
+
}
|
|
20622
|
+
else {
|
|
20623
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
20624
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
20625
|
+
if (child.textContent !== null) {
|
|
20626
|
+
// need to account for paragraph nodes that implicitely add a new line
|
|
20627
|
+
// except for the last paragraph
|
|
20628
|
+
let chars = child.textContent.length;
|
|
20629
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
20630
|
+
chars++;
|
|
20631
|
+
}
|
|
20632
|
+
return acc + chars;
|
|
20633
|
+
}
|
|
20634
|
+
else {
|
|
20635
|
+
return acc;
|
|
20636
|
+
}
|
|
20637
|
+
}, 0);
|
|
20638
|
+
}
|
|
20639
|
+
}
|
|
20602
20640
|
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent == "") {
|
|
20603
20641
|
usedCharacters++;
|
|
20604
20642
|
}
|
|
@@ -21399,13 +21437,13 @@
|
|
|
21399
21437
|
|
|
21400
21438
|
const CSS$1 = css /* scss */ `
|
|
21401
21439
|
.o-filter-icon {
|
|
21440
|
+
color: ${FILTERS_COLOR};
|
|
21402
21441
|
position: absolute;
|
|
21403
21442
|
display: flex;
|
|
21404
21443
|
align-items: center;
|
|
21405
21444
|
justify-content: center;
|
|
21406
21445
|
width: ${FILTER_ICON_EDGE_LENGTH}px;
|
|
21407
21446
|
height: ${FILTER_ICON_EDGE_LENGTH}px;
|
|
21408
|
-
color: #4a4f59;
|
|
21409
21447
|
}
|
|
21410
21448
|
.o-filter-icon:hover {
|
|
21411
21449
|
background: ${FILTERS_COLOR};
|
|
@@ -24136,17 +24174,17 @@
|
|
|
24136
24174
|
const BORDER_STYLE_CONVERSION_MAP = {
|
|
24137
24175
|
dashDot: "thin",
|
|
24138
24176
|
dashDotDot: "thin",
|
|
24139
|
-
dashed: "
|
|
24140
|
-
dotted: "
|
|
24177
|
+
dashed: "dashed",
|
|
24178
|
+
dotted: "dotted",
|
|
24141
24179
|
double: "thin",
|
|
24142
24180
|
hair: "thin",
|
|
24143
|
-
medium: "
|
|
24181
|
+
medium: "medium",
|
|
24144
24182
|
mediumDashDot: "thin",
|
|
24145
24183
|
mediumDashDotDot: "thin",
|
|
24146
24184
|
mediumDashed: "thin",
|
|
24147
24185
|
none: undefined,
|
|
24148
24186
|
slantDashDot: "thin",
|
|
24149
|
-
thick: "
|
|
24187
|
+
thick: "thick",
|
|
24150
24188
|
thin: "thin",
|
|
24151
24189
|
};
|
|
24152
24190
|
/** Conversion map Horizontal Alignment in XLSX <=> Horizontal Alignment in o_spreadsheet*/
|
|
@@ -24645,7 +24683,7 @@
|
|
|
24645
24683
|
return undefined;
|
|
24646
24684
|
addBorderDescrWarnings(borderDescr, warningManager);
|
|
24647
24685
|
const style = BORDER_STYLE_CONVERSION_MAP[borderDescr.style];
|
|
24648
|
-
return style ?
|
|
24686
|
+
return style ? { style, color: convertColor(borderDescr.color) } : undefined;
|
|
24649
24687
|
}
|
|
24650
24688
|
function convertStyles(data, warningManager) {
|
|
24651
24689
|
const stylesArray = data.styles.map((style) => {
|
|
@@ -26043,8 +26081,8 @@
|
|
|
26043
26081
|
return undefined;
|
|
26044
26082
|
}
|
|
26045
26083
|
return {
|
|
26046
|
-
style: descr
|
|
26047
|
-
color: { rgb: descr
|
|
26084
|
+
style: descr.style,
|
|
26085
|
+
color: { rgb: descr.color },
|
|
26048
26086
|
};
|
|
26049
26087
|
}
|
|
26050
26088
|
function extractStyle(cell, data) {
|
|
@@ -26622,7 +26660,7 @@
|
|
|
26622
26660
|
const TABLE_HIGHLIGHTED_CELL_STYLE = {
|
|
26623
26661
|
bold: true,
|
|
26624
26662
|
};
|
|
26625
|
-
const TABLE_BORDER_STYLE =
|
|
26663
|
+
const TABLE_BORDER_STYLE = { style: "thin", color: "#000000FF" };
|
|
26626
26664
|
/**
|
|
26627
26665
|
* Convert the imported XLSX tables.
|
|
26628
26666
|
*
|
|
@@ -28191,7 +28229,7 @@
|
|
|
28191
28229
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
28192
28230
|
* function should be defined
|
|
28193
28231
|
*/
|
|
28194
|
-
const CURRENT_VERSION =
|
|
28232
|
+
const CURRENT_VERSION = 13;
|
|
28195
28233
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
28196
28234
|
/**
|
|
28197
28235
|
* This function tries to load anything that could look like a valid
|
|
@@ -28455,6 +28493,25 @@
|
|
|
28455
28493
|
return data;
|
|
28456
28494
|
},
|
|
28457
28495
|
},
|
|
28496
|
+
{
|
|
28497
|
+
description: "Change Border description structure",
|
|
28498
|
+
from: 12,
|
|
28499
|
+
to: 13,
|
|
28500
|
+
applyMigration(data) {
|
|
28501
|
+
for (const borderId in data.borders) {
|
|
28502
|
+
const border = data.borders[borderId];
|
|
28503
|
+
for (const position in border) {
|
|
28504
|
+
if (Array.isArray(border[position])) {
|
|
28505
|
+
border[position] = {
|
|
28506
|
+
style: border[position][0],
|
|
28507
|
+
color: border[position][1],
|
|
28508
|
+
};
|
|
28509
|
+
}
|
|
28510
|
+
}
|
|
28511
|
+
}
|
|
28512
|
+
return data;
|
|
28513
|
+
},
|
|
28514
|
+
},
|
|
28458
28515
|
];
|
|
28459
28516
|
/**
|
|
28460
28517
|
* This function is used to repair faulty data independently of the migration.
|
|
@@ -28790,7 +28847,7 @@
|
|
|
28790
28847
|
* - borders
|
|
28791
28848
|
*/
|
|
28792
28849
|
class BordersPlugin extends CorePlugin {
|
|
28793
|
-
static getters = ["getCellBorder"];
|
|
28850
|
+
static getters = ["getCellBorder", "getBordersColors"];
|
|
28794
28851
|
borders = {};
|
|
28795
28852
|
// ---------------------------------------------------------------------------
|
|
28796
28853
|
// Command Handling
|
|
@@ -28821,10 +28878,15 @@
|
|
|
28821
28878
|
case "SET_BORDER":
|
|
28822
28879
|
this.setBorder(cmd.sheetId, cmd.col, cmd.row, cmd.border);
|
|
28823
28880
|
break;
|
|
28824
|
-
case "
|
|
28881
|
+
case "SET_ZONE_BORDERS":
|
|
28825
28882
|
if (cmd.border) {
|
|
28826
28883
|
const target = cmd.target.map((zone) => this.getters.expandZone(cmd.sheetId, zone));
|
|
28827
|
-
this.setBorders(cmd.sheetId, target, cmd.border
|
|
28884
|
+
this.setBorders(cmd.sheetId, target, cmd.border.position, cmd.border.color === ""
|
|
28885
|
+
? undefined
|
|
28886
|
+
: {
|
|
28887
|
+
style: cmd.border.style || DEFAULT_BORDER_DESC.style,
|
|
28888
|
+
color: cmd.border.color || DEFAULT_BORDER_DESC.color,
|
|
28889
|
+
});
|
|
28828
28890
|
}
|
|
28829
28891
|
break;
|
|
28830
28892
|
case "CLEAR_FORMATTING":
|
|
@@ -28913,6 +28975,23 @@
|
|
|
28913
28975
|
}
|
|
28914
28976
|
return border;
|
|
28915
28977
|
}
|
|
28978
|
+
getBordersColors(sheetId) {
|
|
28979
|
+
const colors = [];
|
|
28980
|
+
const sheetBorders = this.borders[sheetId];
|
|
28981
|
+
if (sheetBorders) {
|
|
28982
|
+
for (const borders of sheetBorders.filter(isDefined$1)) {
|
|
28983
|
+
for (const cellBorder of borders) {
|
|
28984
|
+
if (cellBorder?.horizontal) {
|
|
28985
|
+
colors.push(cellBorder.horizontal.color);
|
|
28986
|
+
}
|
|
28987
|
+
if (cellBorder?.vertical) {
|
|
28988
|
+
colors.push(cellBorder.vertical.color);
|
|
28989
|
+
}
|
|
28990
|
+
}
|
|
28991
|
+
}
|
|
28992
|
+
}
|
|
28993
|
+
return colors;
|
|
28994
|
+
}
|
|
28916
28995
|
// ---------------------------------------------------------------------------
|
|
28917
28996
|
// Private
|
|
28918
28997
|
// ---------------------------------------------------------------------------
|
|
@@ -29124,43 +29203,43 @@
|
|
|
29124
29203
|
* Set the borders of a zone by computing the borders to add from the given
|
|
29125
29204
|
* command
|
|
29126
29205
|
*/
|
|
29127
|
-
setBorders(sheetId, zones,
|
|
29128
|
-
if (
|
|
29206
|
+
setBorders(sheetId, zones, position, border) {
|
|
29207
|
+
if (position === "clear") {
|
|
29129
29208
|
return this.clearBorders(sheetId, zones);
|
|
29130
29209
|
}
|
|
29131
29210
|
for (let zone of zones) {
|
|
29132
|
-
if (
|
|
29211
|
+
if (position === "h" || position === "hv" || position === "all") {
|
|
29133
29212
|
for (let row = zone.top + 1; row <= zone.bottom; row++) {
|
|
29134
29213
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
29135
|
-
this.addBorder(sheetId, col, row, { top:
|
|
29214
|
+
this.addBorder(sheetId, col, row, { top: border });
|
|
29136
29215
|
}
|
|
29137
29216
|
}
|
|
29138
29217
|
}
|
|
29139
|
-
if (
|
|
29218
|
+
if (position === "v" || position === "hv" || position === "all") {
|
|
29140
29219
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
29141
29220
|
for (let col = zone.left + 1; col <= zone.right; col++) {
|
|
29142
|
-
this.addBorder(sheetId, col, row, { left:
|
|
29221
|
+
this.addBorder(sheetId, col, row, { left: border });
|
|
29143
29222
|
}
|
|
29144
29223
|
}
|
|
29145
29224
|
}
|
|
29146
|
-
if (
|
|
29225
|
+
if (position === "left" || position === "all" || position === "external") {
|
|
29147
29226
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
29148
|
-
this.addBorder(sheetId, zone.left, row, { left:
|
|
29227
|
+
this.addBorder(sheetId, zone.left, row, { left: border });
|
|
29149
29228
|
}
|
|
29150
29229
|
}
|
|
29151
|
-
if (
|
|
29230
|
+
if (position === "right" || position === "all" || position === "external") {
|
|
29152
29231
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
29153
|
-
this.addBorder(sheetId, zone.right + 1, row, { left:
|
|
29232
|
+
this.addBorder(sheetId, zone.right + 1, row, { left: border });
|
|
29154
29233
|
}
|
|
29155
29234
|
}
|
|
29156
|
-
if (
|
|
29235
|
+
if (position === "top" || position === "all" || position === "external") {
|
|
29157
29236
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
29158
|
-
this.addBorder(sheetId, col, zone.top, { top:
|
|
29237
|
+
this.addBorder(sheetId, col, zone.top, { top: border });
|
|
29159
29238
|
}
|
|
29160
29239
|
}
|
|
29161
|
-
if (
|
|
29240
|
+
if (position === "bottom" || position === "all" || position === "external") {
|
|
29162
29241
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
29163
|
-
this.addBorder(sheetId, col, zone.bottom + 1, { top:
|
|
29242
|
+
this.addBorder(sheetId, col, zone.bottom + 1, { top: border });
|
|
29164
29243
|
}
|
|
29165
29244
|
}
|
|
29166
29245
|
}
|
|
@@ -29174,16 +29253,22 @@
|
|
|
29174
29253
|
const bordersBottomRight = this.getCellBorder({ sheetId, col: right, row: bottom });
|
|
29175
29254
|
this.clearBorders(sheetId, [zone]);
|
|
29176
29255
|
if (bordersTopLeft?.top) {
|
|
29177
|
-
this.setBorders(sheetId, [{ ...zone, bottom: top }], "top");
|
|
29256
|
+
this.setBorders(sheetId, [{ ...zone, bottom: top }], "top", bordersTopLeft.top);
|
|
29178
29257
|
}
|
|
29179
29258
|
if (bordersTopLeft?.left) {
|
|
29180
|
-
this.setBorders(sheetId, [{ ...zone, right: left }], "left");
|
|
29259
|
+
this.setBorders(sheetId, [{ ...zone, right: left }], "left", bordersTopLeft.left);
|
|
29260
|
+
}
|
|
29261
|
+
if (bordersBottomRight?.bottom) {
|
|
29262
|
+
this.setBorders(sheetId, [{ ...zone, top: bottom }], "bottom", bordersBottomRight.bottom);
|
|
29181
29263
|
}
|
|
29182
|
-
if (
|
|
29183
|
-
this.setBorders(sheetId, [{ ...zone, top: bottom }], "bottom");
|
|
29264
|
+
else if (bordersTopLeft?.bottom) {
|
|
29265
|
+
this.setBorders(sheetId, [{ ...zone, top: bottom }], "bottom", bordersTopLeft.bottom);
|
|
29184
29266
|
}
|
|
29185
|
-
if (bordersBottomRight?.right
|
|
29186
|
-
this.setBorders(sheetId, [{ ...zone, left: right }], "right");
|
|
29267
|
+
if (bordersBottomRight?.right) {
|
|
29268
|
+
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersBottomRight.right);
|
|
29269
|
+
}
|
|
29270
|
+
else if (bordersTopLeft?.right) {
|
|
29271
|
+
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
29187
29272
|
}
|
|
29188
29273
|
}
|
|
29189
29274
|
// ---------------------------------------------------------------------------
|
|
@@ -32119,6 +32204,8 @@
|
|
|
32119
32204
|
"getSheetSize",
|
|
32120
32205
|
"getSheetZone",
|
|
32121
32206
|
"getPaneDivisions",
|
|
32207
|
+
"checkZonesExistInSheet",
|
|
32208
|
+
"getCommandZones",
|
|
32122
32209
|
];
|
|
32123
32210
|
sheetIdsMapName = {};
|
|
32124
32211
|
orderedSheetIds = [];
|
|
@@ -32128,7 +32215,7 @@
|
|
|
32128
32215
|
// Command Handling
|
|
32129
32216
|
// ---------------------------------------------------------------------------
|
|
32130
32217
|
allowDispatch(cmd) {
|
|
32131
|
-
const genericChecks = this.chainValidations(this.checkSheetExists, this.
|
|
32218
|
+
const genericChecks = this.chainValidations(this.checkSheetExists, this.checkZonesAreInSheet)(cmd);
|
|
32132
32219
|
if (genericChecks !== 0 /* CommandResult.Success */) {
|
|
32133
32220
|
return genericChecks;
|
|
32134
32221
|
}
|
|
@@ -32468,6 +32555,37 @@
|
|
|
32468
32555
|
.map(({ col, row }) => this.getCell({ sheetId, col, row }))
|
|
32469
32556
|
.every((cell) => !cell || cell.content === "");
|
|
32470
32557
|
}
|
|
32558
|
+
getCommandZones(cmd) {
|
|
32559
|
+
const zones = [];
|
|
32560
|
+
if ("zone" in cmd) {
|
|
32561
|
+
zones.push(cmd.zone);
|
|
32562
|
+
}
|
|
32563
|
+
if ("target" in cmd) {
|
|
32564
|
+
zones.push(...cmd.target);
|
|
32565
|
+
}
|
|
32566
|
+
if ("ranges" in cmd) {
|
|
32567
|
+
zones.push(...cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone));
|
|
32568
|
+
}
|
|
32569
|
+
if ("col" in cmd && "row" in cmd) {
|
|
32570
|
+
zones.push({ top: cmd.row, left: cmd.col, bottom: cmd.row, right: cmd.col });
|
|
32571
|
+
}
|
|
32572
|
+
return zones;
|
|
32573
|
+
}
|
|
32574
|
+
/**
|
|
32575
|
+
* Check if zones in the command are well formed and
|
|
32576
|
+
* not outside the sheet.
|
|
32577
|
+
*/
|
|
32578
|
+
checkZonesExistInSheet(sheetId, zones) {
|
|
32579
|
+
if (!zones.every(isZoneValid))
|
|
32580
|
+
return 25 /* CommandResult.InvalidRange */;
|
|
32581
|
+
if (zones.length) {
|
|
32582
|
+
const sheetZone = this.getSheetZone(sheetId);
|
|
32583
|
+
return zones.every((zone) => isZoneInside(zone, sheetZone))
|
|
32584
|
+
? 0 /* CommandResult.Success */
|
|
32585
|
+
: 18 /* CommandResult.TargetOutOfSheet */;
|
|
32586
|
+
}
|
|
32587
|
+
return 0 /* CommandResult.Success */;
|
|
32588
|
+
}
|
|
32471
32589
|
updateCellPosition(cmd) {
|
|
32472
32590
|
const { sheetId, cellId, col, row } = cmd;
|
|
32473
32591
|
if (cellId) {
|
|
@@ -32916,9 +33034,6 @@
|
|
|
32916
33034
|
}
|
|
32917
33035
|
return { rowNumber, colNumber };
|
|
32918
33036
|
}
|
|
32919
|
-
// ----------------------------------------------------
|
|
32920
|
-
// HIDE / SHOW
|
|
32921
|
-
// ----------------------------------------------------
|
|
32922
33037
|
/**
|
|
32923
33038
|
* Check that any "sheetId" in the command matches an existing
|
|
32924
33039
|
* sheet.
|
|
@@ -32936,27 +33051,10 @@
|
|
|
32936
33051
|
* Check if zones in the command are well formed and
|
|
32937
33052
|
* not outside the sheet.
|
|
32938
33053
|
*/
|
|
32939
|
-
|
|
32940
|
-
|
|
32941
|
-
|
|
32942
|
-
|
|
32943
|
-
}
|
|
32944
|
-
if ("target" in cmd && Array.isArray(cmd.target)) {
|
|
32945
|
-
zones.push(...cmd.target);
|
|
32946
|
-
}
|
|
32947
|
-
if ("ranges" in cmd && Array.isArray(cmd.ranges)) {
|
|
32948
|
-
zones.push(...cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone));
|
|
32949
|
-
}
|
|
32950
|
-
if (!zones.every(isZoneValid)) {
|
|
32951
|
-
return 25 /* CommandResult.InvalidRange */;
|
|
32952
|
-
}
|
|
32953
|
-
else if (zones.length && "sheetId" in cmd) {
|
|
32954
|
-
const sheetZone = this.getSheetZone(cmd.sheetId);
|
|
32955
|
-
return zones.every((zone) => isZoneInside(zone, sheetZone))
|
|
32956
|
-
? 0 /* CommandResult.Success */
|
|
32957
|
-
: 18 /* CommandResult.TargetOutOfSheet */;
|
|
32958
|
-
}
|
|
32959
|
-
return 0 /* CommandResult.Success */;
|
|
33054
|
+
checkZonesAreInSheet(cmd) {
|
|
33055
|
+
if (!("sheetId" in cmd))
|
|
33056
|
+
return 0 /* CommandResult.Success */;
|
|
33057
|
+
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
32960
33058
|
}
|
|
32961
33059
|
}
|
|
32962
33060
|
|
|
@@ -33036,6 +33134,9 @@
|
|
|
33036
33134
|
case "UPDATE_CHART":
|
|
33037
33135
|
case "CREATE_CHART":
|
|
33038
33136
|
case "ADD_CONDITIONAL_FORMAT":
|
|
33137
|
+
case "SET_BORDER":
|
|
33138
|
+
case "SET_ZONE_BORDERS":
|
|
33139
|
+
case "SET_FORMATTING":
|
|
33039
33140
|
this.shouldUpdateColors = true;
|
|
33040
33141
|
}
|
|
33041
33142
|
}
|
|
@@ -33050,8 +33151,7 @@
|
|
|
33050
33151
|
getCustomColors() {
|
|
33051
33152
|
let usedColors = [];
|
|
33052
33153
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
33053
|
-
|
|
33054
|
-
usedColors = usedColors.concat(this.getColorsFromCells(cells), this.getFormattingColors(sheetId), this.getChartColors(sheetId));
|
|
33154
|
+
usedColors = usedColors.concat(this.getColorsFromCells(sheetId), this.getFormattingColors(sheetId), this.getChartColors(sheetId));
|
|
33055
33155
|
}
|
|
33056
33156
|
return sortWithClusters([
|
|
33057
33157
|
...new Set(
|
|
@@ -33061,7 +33161,8 @@
|
|
|
33061
33161
|
[...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
|
|
33062
33162
|
]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
|
|
33063
33163
|
}
|
|
33064
|
-
getColorsFromCells(
|
|
33164
|
+
getColorsFromCells(sheetId) {
|
|
33165
|
+
const cells = Object.values(this.getters.getCells(sheetId));
|
|
33065
33166
|
const colors = new Set();
|
|
33066
33167
|
for (const cell of cells) {
|
|
33067
33168
|
if (cell.style?.textColor) {
|
|
@@ -33071,6 +33172,9 @@
|
|
|
33071
33172
|
colors.add(cell.style.fillColor);
|
|
33072
33173
|
}
|
|
33073
33174
|
}
|
|
33175
|
+
for (const color of this.getters.getBordersColors(sheetId)) {
|
|
33176
|
+
colors.add(color);
|
|
33177
|
+
}
|
|
33074
33178
|
return [...colors];
|
|
33075
33179
|
}
|
|
33076
33180
|
getFormattingColors(sheetId) {
|
|
@@ -33344,7 +33448,7 @@
|
|
|
33344
33448
|
// magic "empty" value
|
|
33345
33449
|
// Returning {value: null} instead of undefined will ensure that we don't
|
|
33346
33450
|
// fall back on the default value of the argument provided to the formula's compute function
|
|
33347
|
-
return { value: null };
|
|
33451
|
+
return { value: null, format: cell?.format };
|
|
33348
33452
|
}
|
|
33349
33453
|
return getEvaluatedCell(cell);
|
|
33350
33454
|
}
|
|
@@ -33541,7 +33645,7 @@
|
|
|
33541
33645
|
}
|
|
33542
33646
|
break;
|
|
33543
33647
|
case "PASTE_CONDITIONAL_FORMAT":
|
|
33544
|
-
this.pasteCf(cmd.
|
|
33648
|
+
this.pasteCf(cmd.originPosition, cmd.targetPosition, cmd.operation);
|
|
33545
33649
|
break;
|
|
33546
33650
|
}
|
|
33547
33651
|
}
|
|
@@ -36173,6 +36277,7 @@
|
|
|
36173
36277
|
|
|
36174
36278
|
class Revision {
|
|
36175
36279
|
rootCommand;
|
|
36280
|
+
timestamp;
|
|
36176
36281
|
id;
|
|
36177
36282
|
clientId;
|
|
36178
36283
|
_commands = [];
|
|
@@ -36186,8 +36291,9 @@
|
|
|
36186
36291
|
* - clientId: Client who initiated the action
|
|
36187
36292
|
* - changes: List of changes applied on the state.
|
|
36188
36293
|
*/
|
|
36189
|
-
constructor(id, clientId, commands, rootCommand, changes) {
|
|
36294
|
+
constructor(id, clientId, commands, rootCommand, changes, timestamp) {
|
|
36190
36295
|
this.rootCommand = rootCommand;
|
|
36296
|
+
this.timestamp = timestamp;
|
|
36191
36297
|
this.id = id;
|
|
36192
36298
|
this.clientId = clientId;
|
|
36193
36299
|
this._commands = [...commands];
|
|
@@ -36259,7 +36365,7 @@
|
|
|
36259
36365
|
save(rootCommand, commands, changes) {
|
|
36260
36366
|
if (!commands.length || !changes.length || !this.canApplyOptimisticUpdate())
|
|
36261
36367
|
return;
|
|
36262
|
-
const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes);
|
|
36368
|
+
const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes, Date.now());
|
|
36263
36369
|
this.revisions.append(revision.id, revision);
|
|
36264
36370
|
this.trigger("new-local-state-update", { id: revision.id });
|
|
36265
36371
|
this.sendUpdateMessage({
|
|
@@ -36310,13 +36416,9 @@
|
|
|
36310
36416
|
}
|
|
36311
36417
|
loadInitialMessages(messages) {
|
|
36312
36418
|
this.isReplayingInitialRevisions = true;
|
|
36313
|
-
this.on("unexpected-revision-id", this, ({ revisionId }) => {
|
|
36314
|
-
throw new Error(`The spreadsheet could not be loaded. Revision ${revisionId} is corrupted.`);
|
|
36315
|
-
});
|
|
36316
36419
|
for (const message of messages) {
|
|
36317
36420
|
this.onMessageReceived(message);
|
|
36318
36421
|
}
|
|
36319
|
-
this.off("unexpected-revision-id", this);
|
|
36320
36422
|
this.isReplayingInitialRevisions = false;
|
|
36321
36423
|
}
|
|
36322
36424
|
/**
|
|
@@ -36402,6 +36504,10 @@
|
|
|
36402
36504
|
onMessageReceived(message) {
|
|
36403
36505
|
if (this.isAlreadyProcessed(message))
|
|
36404
36506
|
return;
|
|
36507
|
+
if (this.isWrongServerRevisionId(message)) {
|
|
36508
|
+
this.trigger("unexpected-revision-id");
|
|
36509
|
+
return;
|
|
36510
|
+
}
|
|
36405
36511
|
switch (message.type) {
|
|
36406
36512
|
case "CLIENT_MOVED":
|
|
36407
36513
|
this.onClientMoved(message);
|
|
@@ -36428,12 +36534,8 @@
|
|
|
36428
36534
|
});
|
|
36429
36535
|
break;
|
|
36430
36536
|
case "REMOTE_REVISION":
|
|
36431
|
-
|
|
36432
|
-
|
|
36433
|
-
return;
|
|
36434
|
-
}
|
|
36435
|
-
const { clientId, commands } = message;
|
|
36436
|
-
const revision = new Revision(message.nextRevisionId, clientId, commands, "REMOTE");
|
|
36537
|
+
const { clientId, commands, timestamp } = message;
|
|
36538
|
+
const revision = new Revision(message.nextRevisionId, clientId, commands, "REMOTE", undefined, timestamp);
|
|
36437
36539
|
if (revision.clientId !== this.clientId) {
|
|
36438
36540
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
36439
36541
|
const pendingCommands = this.pendingMessages
|
|
@@ -36446,7 +36548,7 @@
|
|
|
36446
36548
|
}
|
|
36447
36549
|
break;
|
|
36448
36550
|
case "SNAPSHOT_CREATED": {
|
|
36449
|
-
const revision = new Revision(message.nextRevisionId, "server", [], "SNAPSHOT");
|
|
36551
|
+
const revision = new Revision(message.nextRevisionId, "server", [], "SNAPSHOT", undefined, Date.now());
|
|
36450
36552
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
36451
36553
|
this.dropPendingHistoryMessages();
|
|
36452
36554
|
this.trigger("snapshot");
|
|
@@ -36563,6 +36665,17 @@
|
|
|
36563
36665
|
return false;
|
|
36564
36666
|
}
|
|
36565
36667
|
}
|
|
36668
|
+
isWrongServerRevisionId(message) {
|
|
36669
|
+
switch (message.type) {
|
|
36670
|
+
case "REMOTE_REVISION":
|
|
36671
|
+
case "REVISION_REDONE":
|
|
36672
|
+
case "REVISION_UNDONE":
|
|
36673
|
+
case "SNAPSHOT_CREATED":
|
|
36674
|
+
return message.serverRevisionId !== this.serverRevisionId;
|
|
36675
|
+
default:
|
|
36676
|
+
return false;
|
|
36677
|
+
}
|
|
36678
|
+
}
|
|
36566
36679
|
dropPendingHistoryMessages() {
|
|
36567
36680
|
this.waitingUndoRedoAck = false;
|
|
36568
36681
|
this.pendingMessages = this.pendingMessages.filter(({ type }) => type !== "REVISION_REDONE" && type !== "REVISION_UNDONE");
|
|
@@ -37278,7 +37391,7 @@
|
|
|
37278
37391
|
}
|
|
37279
37392
|
}
|
|
37280
37393
|
drawBorders(renderingContext) {
|
|
37281
|
-
const { ctx
|
|
37394
|
+
const { ctx } = renderingContext;
|
|
37282
37395
|
for (let box of this.boxes) {
|
|
37283
37396
|
const border = box.border;
|
|
37284
37397
|
if (border) {
|
|
@@ -37297,13 +37410,66 @@
|
|
|
37297
37410
|
}
|
|
37298
37411
|
}
|
|
37299
37412
|
}
|
|
37300
|
-
|
|
37413
|
+
/**
|
|
37414
|
+
* Following https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines,
|
|
37415
|
+
* we need to make sure that a "single" pixel line is drawn on a "half" pixel coordinate,
|
|
37416
|
+
* while a "double" pixel line is drawn on a "full" pixel coordinate. As, in the rendering
|
|
37417
|
+
* process, we always had 0.5 before rendering line (to make sure it is drawn on a "half"
|
|
37418
|
+
* pixel), we need to correct this behavior for the "medium" and the "dotted" styles, as
|
|
37419
|
+
* they are drawing a two pixels width line.
|
|
37420
|
+
* We also adapt here the coordinates of the line to make sure corner are correctly drawn,
|
|
37421
|
+
* avoiding a "round corners" effect. This is done by subtracting 1 pixel to the origin of
|
|
37422
|
+
* each line and adding 1 pixel to the end of each line (depending on the direction of the
|
|
37423
|
+
* line).
|
|
37424
|
+
*/
|
|
37425
|
+
function drawBorder({ style, color }, x1, y1, x2, y2) {
|
|
37301
37426
|
ctx.strokeStyle = color;
|
|
37302
|
-
|
|
37427
|
+
switch (style) {
|
|
37428
|
+
case "medium":
|
|
37429
|
+
ctx.lineWidth = 2;
|
|
37430
|
+
x1 += y1 === y2 ? -0.5 : 0.5;
|
|
37431
|
+
x2 += y1 === y2 ? 1.5 : 0.5;
|
|
37432
|
+
y1 += x1 === x2 ? -0.5 : 0.5;
|
|
37433
|
+
y2 += x1 === x2 ? 1.5 : 0.5;
|
|
37434
|
+
break;
|
|
37435
|
+
case "thick":
|
|
37436
|
+
ctx.lineWidth = 3;
|
|
37437
|
+
if (y1 === y2) {
|
|
37438
|
+
x1--;
|
|
37439
|
+
x2++;
|
|
37440
|
+
}
|
|
37441
|
+
if (x1 === x2) {
|
|
37442
|
+
y1--;
|
|
37443
|
+
y2++;
|
|
37444
|
+
}
|
|
37445
|
+
break;
|
|
37446
|
+
case "dashed":
|
|
37447
|
+
ctx.lineWidth = 1;
|
|
37448
|
+
ctx.setLineDash([1, 3]);
|
|
37449
|
+
break;
|
|
37450
|
+
case "dotted":
|
|
37451
|
+
ctx.lineWidth = 1;
|
|
37452
|
+
if (y1 === y2) {
|
|
37453
|
+
x1 += 0.5;
|
|
37454
|
+
x2 += 0.5;
|
|
37455
|
+
}
|
|
37456
|
+
if (x1 === x2) {
|
|
37457
|
+
y1 += 0.5;
|
|
37458
|
+
y2 += 0.5;
|
|
37459
|
+
}
|
|
37460
|
+
ctx.setLineDash([1, 1]);
|
|
37461
|
+
break;
|
|
37462
|
+
case "thin":
|
|
37463
|
+
default:
|
|
37464
|
+
ctx.lineWidth = 1;
|
|
37465
|
+
break;
|
|
37466
|
+
}
|
|
37303
37467
|
ctx.beginPath();
|
|
37304
37468
|
ctx.moveTo(x1, y1);
|
|
37305
37469
|
ctx.lineTo(x2, y2);
|
|
37306
37470
|
ctx.stroke();
|
|
37471
|
+
ctx.lineWidth = 1;
|
|
37472
|
+
ctx.setLineDash([]);
|
|
37307
37473
|
}
|
|
37308
37474
|
}
|
|
37309
37475
|
drawTexts(renderingContext) {
|
|
@@ -37781,6 +37947,9 @@
|
|
|
37781
37947
|
activeSheet;
|
|
37782
37948
|
willAddNewRange = false;
|
|
37783
37949
|
constructor(config, initialRanges, inputHasSingleRange) {
|
|
37950
|
+
if (inputHasSingleRange && initialRanges.length > 1) {
|
|
37951
|
+
throw new Error("Input with a single range cannot be instantiated with several range references.");
|
|
37952
|
+
}
|
|
37784
37953
|
super(config);
|
|
37785
37954
|
this.inputHasSingleRange = inputHasSingleRange;
|
|
37786
37955
|
this.insertNewRange(0, initialRanges);
|
|
@@ -37800,6 +37969,11 @@
|
|
|
37800
37969
|
return 30 /* CommandResult.MaximumRangesReached */;
|
|
37801
37970
|
}
|
|
37802
37971
|
break;
|
|
37972
|
+
case "CHANGE_RANGE":
|
|
37973
|
+
if (this.inputHasSingleRange && cmd.value.split(",").length > 1) {
|
|
37974
|
+
return 30 /* CommandResult.MaximumRangesReached */;
|
|
37975
|
+
}
|
|
37976
|
+
break;
|
|
37803
37977
|
}
|
|
37804
37978
|
return 0 /* CommandResult.Success */;
|
|
37805
37979
|
}
|
|
@@ -38456,18 +38630,7 @@
|
|
|
38456
38630
|
// Command Handling
|
|
38457
38631
|
// ---------------------------------------------------------------------------
|
|
38458
38632
|
allowDispatch(cmd) {
|
|
38459
|
-
|
|
38460
|
-
case "AUTORESIZE_ROWS":
|
|
38461
|
-
case "AUTORESIZE_COLUMNS":
|
|
38462
|
-
try {
|
|
38463
|
-
this.getters.getSheet(cmd.sheetId);
|
|
38464
|
-
break;
|
|
38465
|
-
}
|
|
38466
|
-
catch (error) {
|
|
38467
|
-
return 27 /* CommandResult.InvalidSheetId */;
|
|
38468
|
-
}
|
|
38469
|
-
}
|
|
38470
|
-
return 0 /* CommandResult.Success */;
|
|
38633
|
+
return this.chainValidations(this.checkSheetExists, this.checkZonesAreInSheet)(cmd);
|
|
38471
38634
|
}
|
|
38472
38635
|
handle(cmd) {
|
|
38473
38636
|
switch (cmd.type) {
|
|
@@ -38667,6 +38830,31 @@
|
|
|
38667
38830
|
splitWord.push(wordPart);
|
|
38668
38831
|
return splitWord;
|
|
38669
38832
|
}
|
|
38833
|
+
/**
|
|
38834
|
+
* Check that any "sheetId" in the command matches an existing
|
|
38835
|
+
* sheet.
|
|
38836
|
+
*/
|
|
38837
|
+
checkSheetExists(cmd) {
|
|
38838
|
+
if ("sheetId" in cmd && this.getters.tryGetSheet(cmd.sheetId) === undefined) {
|
|
38839
|
+
return 27 /* CommandResult.InvalidSheetId */;
|
|
38840
|
+
}
|
|
38841
|
+
return 0 /* CommandResult.Success */;
|
|
38842
|
+
}
|
|
38843
|
+
/**
|
|
38844
|
+
* Check if zones in the command are well formed and
|
|
38845
|
+
* not outside the sheet.
|
|
38846
|
+
*/
|
|
38847
|
+
checkZonesAreInSheet(cmd) {
|
|
38848
|
+
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
38849
|
+
const zones = this.getters.getCommandZones(cmd);
|
|
38850
|
+
if (!sheetId && zones.length > 0) {
|
|
38851
|
+
return 92 /* CommandResult.NoActiveSheet */;
|
|
38852
|
+
}
|
|
38853
|
+
if (sheetId && zones.length > 0) {
|
|
38854
|
+
return this.getters.checkZonesExistInSheet(sheetId, zones);
|
|
38855
|
+
}
|
|
38856
|
+
return 0 /* CommandResult.Success */;
|
|
38857
|
+
}
|
|
38670
38858
|
}
|
|
38671
38859
|
|
|
38672
38860
|
const genericRepeatsTransforms = [
|
|
@@ -39491,8 +39679,8 @@
|
|
|
39491
39679
|
this.pasteCell(origin, position, this.operation, clipboardOptions);
|
|
39492
39680
|
if (shouldPasteCF) {
|
|
39493
39681
|
this.dispatch("PASTE_CONDITIONAL_FORMAT", {
|
|
39494
|
-
|
|
39495
|
-
|
|
39682
|
+
originPosition: origin.position,
|
|
39683
|
+
targetPosition: position,
|
|
39496
39684
|
operation: this.operation,
|
|
39497
39685
|
});
|
|
39498
39686
|
}
|
|
@@ -39883,7 +40071,7 @@
|
|
|
39883
40071
|
allowDispatch(cmd) {
|
|
39884
40072
|
switch (cmd.type) {
|
|
39885
40073
|
case "CUT":
|
|
39886
|
-
const zones = cmd.
|
|
40074
|
+
const zones = cmd.cutTarget || this.getters.getSelectedZones();
|
|
39887
40075
|
const state = this.getClipboardState(zones, cmd.type);
|
|
39888
40076
|
return state.isCutAllowed(zones);
|
|
39889
40077
|
case "PASTE":
|
|
@@ -39913,7 +40101,7 @@
|
|
|
39913
40101
|
switch (cmd.type) {
|
|
39914
40102
|
case "COPY":
|
|
39915
40103
|
case "CUT":
|
|
39916
|
-
const zones = ("
|
|
40104
|
+
const zones = ("cutTarget" in cmd && cmd.cutTarget) || this.getters.getSelectedZones();
|
|
39917
40105
|
this.state = this.getClipboardState(zones, cmd.type);
|
|
39918
40106
|
this.status = "visible";
|
|
39919
40107
|
break;
|
|
@@ -40869,6 +41057,7 @@
|
|
|
40869
41057
|
"isSelected",
|
|
40870
41058
|
"isSingleColSelected",
|
|
40871
41059
|
"getElementsFromSelection",
|
|
41060
|
+
"tryGetActiveSheetId",
|
|
40872
41061
|
];
|
|
40873
41062
|
gridSelection = {
|
|
40874
41063
|
anchor: {
|
|
@@ -41084,6 +41273,9 @@
|
|
|
41084
41273
|
getActiveSheetId() {
|
|
41085
41274
|
return this.activeSheet.id;
|
|
41086
41275
|
}
|
|
41276
|
+
tryGetActiveSheetId() {
|
|
41277
|
+
return this.activeSheet?.id;
|
|
41278
|
+
}
|
|
41087
41279
|
getActiveCell() {
|
|
41088
41280
|
return this.getters.getEvaluatedCell(this.getActivePosition());
|
|
41089
41281
|
}
|
|
@@ -41286,7 +41478,8 @@
|
|
|
41286
41478
|
},
|
|
41287
41479
|
zone: selectedZone,
|
|
41288
41480
|
};
|
|
41289
|
-
this.
|
|
41481
|
+
const selections = this.gridSelection.zones.map((zone) => updateSelectionOnDeletion(zone, "left", [...cmd.elements]));
|
|
41482
|
+
this.setSelectionMixin(anchor, selections);
|
|
41290
41483
|
}
|
|
41291
41484
|
onRowsRemoved(cmd) {
|
|
41292
41485
|
const { cell, zone } = this.gridSelection.anchor;
|
|
@@ -41300,13 +41493,18 @@
|
|
|
41300
41493
|
},
|
|
41301
41494
|
zone: selectedZone,
|
|
41302
41495
|
};
|
|
41303
|
-
this.
|
|
41496
|
+
const selections = this.gridSelection.zones.map((zone) => updateSelectionOnDeletion(zone, "top", [...cmd.elements]));
|
|
41497
|
+
this.setSelectionMixin(anchor, selections);
|
|
41304
41498
|
}
|
|
41305
41499
|
onAddElements(cmd) {
|
|
41306
|
-
const
|
|
41307
|
-
const
|
|
41308
|
-
const
|
|
41309
|
-
|
|
41500
|
+
const start = cmd.dimension === "COL" ? "left" : "top";
|
|
41501
|
+
const anchorZone = updateSelectionOnInsertion(this.gridSelection.anchor.zone, start, cmd.base, cmd.position, cmd.quantity);
|
|
41502
|
+
const selection = this.gridSelection.zones.map((zone) => updateSelectionOnInsertion(zone, start, cmd.base, cmd.position, cmd.quantity));
|
|
41503
|
+
const anchor = {
|
|
41504
|
+
cell: { col: anchorZone.left, row: anchorZone.top },
|
|
41505
|
+
zone: anchorZone,
|
|
41506
|
+
};
|
|
41507
|
+
this.setSelectionMixin(anchor, selection);
|
|
41310
41508
|
}
|
|
41311
41509
|
onMoveElements(cmd) {
|
|
41312
41510
|
const thickness = cmd.elements.length;
|
|
@@ -41324,7 +41522,7 @@
|
|
|
41324
41522
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
41325
41523
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
41326
41524
|
this.dispatch("CUT", {
|
|
41327
|
-
|
|
41525
|
+
cutTarget: [
|
|
41328
41526
|
{
|
|
41329
41527
|
left: isCol ? start + deltaCol : 0,
|
|
41330
41528
|
right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
@@ -42552,7 +42750,6 @@
|
|
|
42552
42750
|
color: dimgrey;
|
|
42553
42751
|
}
|
|
42554
42752
|
.o-sidePanelClose {
|
|
42555
|
-
font-size: 1.5rem;
|
|
42556
42753
|
padding: 5px 10px;
|
|
42557
42754
|
cursor: pointer;
|
|
42558
42755
|
&:hover {
|
|
@@ -42737,7 +42934,6 @@
|
|
|
42737
42934
|
justify-content: center;
|
|
42738
42935
|
align-items: center;
|
|
42739
42936
|
margin: 2px;
|
|
42740
|
-
padding: 0px 3px;
|
|
42741
42937
|
border-radius: 2px;
|
|
42742
42938
|
min-width: 20px;
|
|
42743
42939
|
}
|
|
@@ -42794,7 +42990,228 @@
|
|
|
42794
42990
|
onClick: { type: Function, optional: true },
|
|
42795
42991
|
};
|
|
42796
42992
|
|
|
42993
|
+
/**
|
|
42994
|
+
* List the available borders positions and the corresponding icons.
|
|
42995
|
+
* The structure of this array is defined to match the order/lines we want
|
|
42996
|
+
* to display in the topbar's border tool.
|
|
42997
|
+
*/
|
|
42998
|
+
const BORDER_POSITIONS = [
|
|
42999
|
+
[
|
|
43000
|
+
["all", "o-spreadsheet-Icon.BORDERS"],
|
|
43001
|
+
["hv", "o-spreadsheet-Icon.BORDER_HV"],
|
|
43002
|
+
["h", "o-spreadsheet-Icon.BORDER_H"],
|
|
43003
|
+
["v", "o-spreadsheet-Icon.BORDER_V"],
|
|
43004
|
+
["external", "o-spreadsheet-Icon.BORDER_EXTERNAL"],
|
|
43005
|
+
],
|
|
43006
|
+
[
|
|
43007
|
+
["left", "o-spreadsheet-Icon.BORDER_LEFT"],
|
|
43008
|
+
["top", "o-spreadsheet-Icon.BORDER_TOP"],
|
|
43009
|
+
["right", "o-spreadsheet-Icon.BORDER_RIGHT"],
|
|
43010
|
+
["bottom", "o-spreadsheet-Icon.BORDER_BOTTOM"],
|
|
43011
|
+
["clear", "o-spreadsheet-Icon.BORDER_CLEAR"],
|
|
43012
|
+
],
|
|
43013
|
+
];
|
|
43014
|
+
// -----------------------------------------------------------------------------
|
|
43015
|
+
// Border Editor
|
|
43016
|
+
// -----------------------------------------------------------------------------
|
|
43017
|
+
css /* scss */ `
|
|
43018
|
+
.o-border-selector {
|
|
43019
|
+
padding: 4px;
|
|
43020
|
+
}
|
|
43021
|
+
.o-divider {
|
|
43022
|
+
border-right: 1px solid #e0e2e4;
|
|
43023
|
+
margin: 0 6px;
|
|
43024
|
+
}
|
|
43025
|
+
.o-border-selector-section {
|
|
43026
|
+
.o-dropdown-line {
|
|
43027
|
+
height: 30px;
|
|
43028
|
+
margin: 1px;
|
|
43029
|
+
.o-line-item {
|
|
43030
|
+
padding: 4px;
|
|
43031
|
+
width: 18px;
|
|
43032
|
+
height: 18px;
|
|
43033
|
+
}
|
|
43034
|
+
}
|
|
43035
|
+
.o-border-style-tool {
|
|
43036
|
+
padding: 0px 3px;
|
|
43037
|
+
margin: 2px;
|
|
43038
|
+
height: 25px;
|
|
43039
|
+
}
|
|
43040
|
+
}
|
|
43041
|
+
.o-style-preview {
|
|
43042
|
+
margin: 7px 5px 7px 5px;
|
|
43043
|
+
width: 60px;
|
|
43044
|
+
height: 5px;
|
|
43045
|
+
}
|
|
43046
|
+
.o-style-thin {
|
|
43047
|
+
border-bottom: 1px solid #000000;
|
|
43048
|
+
}
|
|
43049
|
+
.o-style-medium {
|
|
43050
|
+
border-bottom: 2px solid #000000;
|
|
43051
|
+
}
|
|
43052
|
+
.o-style-thick {
|
|
43053
|
+
border-bottom: 3px solid #000000;
|
|
43054
|
+
}
|
|
43055
|
+
.o-style-dashed {
|
|
43056
|
+
border-bottom: 1px dashed #000000;
|
|
43057
|
+
}
|
|
43058
|
+
.o-style-dotted {
|
|
43059
|
+
border-bottom: 1px dotted #000000;
|
|
43060
|
+
}
|
|
43061
|
+
.o-dropdown-border-type {
|
|
43062
|
+
&:not(.o-disabled):not(.active):hover {
|
|
43063
|
+
background-color: ${BG_HOVER_COLOR};
|
|
43064
|
+
}
|
|
43065
|
+
}
|
|
43066
|
+
.o-dropdown-border-check {
|
|
43067
|
+
width: 20px;
|
|
43068
|
+
font-size: 12px;
|
|
43069
|
+
}
|
|
43070
|
+
.o-border-style-dropdown {
|
|
43071
|
+
background: #ffffff;
|
|
43072
|
+
padding: 4px;
|
|
43073
|
+
.o-dropdown-line {
|
|
43074
|
+
.o-line-item.active {
|
|
43075
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
43076
|
+
}
|
|
43077
|
+
}
|
|
43078
|
+
}
|
|
43079
|
+
.o-border-picker-button {
|
|
43080
|
+
padding: 0px !important;
|
|
43081
|
+
margin: 5px 0px 0px 0px !important;
|
|
43082
|
+
height: 25px !important;
|
|
43083
|
+
}
|
|
43084
|
+
`;
|
|
43085
|
+
class BorderEditor extends owl.Component {
|
|
43086
|
+
static template = "o-spreadsheet-BorderEditor";
|
|
43087
|
+
static components = { ColorPickerWidget, Popover };
|
|
43088
|
+
BORDER_POSITIONS = BORDER_POSITIONS;
|
|
43089
|
+
lineStyleButtonRef = owl.useRef("lineStyleButton");
|
|
43090
|
+
borderStyles = borderStyles;
|
|
43091
|
+
state = owl.useState({
|
|
43092
|
+
activeTool: undefined,
|
|
43093
|
+
});
|
|
43094
|
+
toggleDropdownTool(tool) {
|
|
43095
|
+
const isOpen = this.state.activeTool === tool;
|
|
43096
|
+
this.state.activeTool = isOpen ? undefined : tool;
|
|
43097
|
+
}
|
|
43098
|
+
closeDropdown() {
|
|
43099
|
+
this.state.activeTool = undefined;
|
|
43100
|
+
}
|
|
43101
|
+
setBorderPosition(position) {
|
|
43102
|
+
this.props.onBorderPositionPicked(position);
|
|
43103
|
+
this.closeDropdown();
|
|
43104
|
+
}
|
|
43105
|
+
setBorderColor(color) {
|
|
43106
|
+
this.props.onBorderColorPicked(color);
|
|
43107
|
+
this.closeDropdown();
|
|
43108
|
+
}
|
|
43109
|
+
setBorderStyle(style) {
|
|
43110
|
+
this.props.onBorderStylePicked(style);
|
|
43111
|
+
this.closeDropdown();
|
|
43112
|
+
}
|
|
43113
|
+
get lineStylePickerPopoverProps() {
|
|
43114
|
+
return {
|
|
43115
|
+
anchorRect: this.lineStylePickerAnchorRect,
|
|
43116
|
+
positioning: "BottomLeft",
|
|
43117
|
+
verticalOffset: 0,
|
|
43118
|
+
};
|
|
43119
|
+
}
|
|
43120
|
+
get popoverProps() {
|
|
43121
|
+
return {
|
|
43122
|
+
anchorRect: this.props.anchorRect,
|
|
43123
|
+
maxHeight: this.props.maxHeight,
|
|
43124
|
+
positioning: "BottomLeft",
|
|
43125
|
+
verticalOffset: 0,
|
|
43126
|
+
};
|
|
43127
|
+
}
|
|
43128
|
+
get lineStylePickerAnchorRect() {
|
|
43129
|
+
const button = this.lineStyleButtonRef.el;
|
|
43130
|
+
if (button === null) {
|
|
43131
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
43132
|
+
}
|
|
43133
|
+
const buttonRect = button.getBoundingClientRect();
|
|
43134
|
+
return {
|
|
43135
|
+
x: buttonRect.x,
|
|
43136
|
+
y: buttonRect.y,
|
|
43137
|
+
width: buttonRect.width,
|
|
43138
|
+
height: buttonRect.height,
|
|
43139
|
+
};
|
|
43140
|
+
}
|
|
43141
|
+
}
|
|
43142
|
+
BorderEditor.props = {
|
|
43143
|
+
class: { type: String, optional: true },
|
|
43144
|
+
currentBorderColor: { type: String, optional: false },
|
|
43145
|
+
currentBorderStyle: { type: String, optional: false },
|
|
43146
|
+
currentBorderPosition: { type: String, optional: true },
|
|
43147
|
+
onBorderColorPicked: Function,
|
|
43148
|
+
onBorderStylePicked: Function,
|
|
43149
|
+
onBorderPositionPicked: Function,
|
|
43150
|
+
maxHeight: { type: Number, optional: true },
|
|
43151
|
+
anchorRect: Object,
|
|
43152
|
+
};
|
|
43153
|
+
|
|
43154
|
+
class BorderEditorWidget extends owl.Component {
|
|
43155
|
+
static template = "o-spreadsheet-BorderEditorWidget";
|
|
43156
|
+
static components = { BorderEditor };
|
|
43157
|
+
borderEditorButtonRef = owl.useRef("borderEditorButton");
|
|
43158
|
+
state = owl.useState({
|
|
43159
|
+
currentColor: DEFAULT_BORDER_DESC.color,
|
|
43160
|
+
currentStyle: DEFAULT_BORDER_DESC.style,
|
|
43161
|
+
currentPosition: undefined,
|
|
43162
|
+
});
|
|
43163
|
+
get borderEditorAnchorRect() {
|
|
43164
|
+
const button = this.borderEditorButtonRef.el;
|
|
43165
|
+
const buttonRect = button.getBoundingClientRect();
|
|
43166
|
+
return {
|
|
43167
|
+
x: buttonRect.x,
|
|
43168
|
+
y: buttonRect.y,
|
|
43169
|
+
width: buttonRect.width,
|
|
43170
|
+
height: buttonRect.height,
|
|
43171
|
+
};
|
|
43172
|
+
}
|
|
43173
|
+
onBorderPositionPicked(position) {
|
|
43174
|
+
this.state.currentPosition = position;
|
|
43175
|
+
this.updateBorder();
|
|
43176
|
+
}
|
|
43177
|
+
onBorderColorPicked(color) {
|
|
43178
|
+
this.state.currentColor = color;
|
|
43179
|
+
this.updateBorder();
|
|
43180
|
+
}
|
|
43181
|
+
onBorderStylePicked(style) {
|
|
43182
|
+
this.state.currentStyle = style;
|
|
43183
|
+
this.updateBorder();
|
|
43184
|
+
}
|
|
43185
|
+
updateBorder() {
|
|
43186
|
+
if (this.state.currentPosition === undefined) {
|
|
43187
|
+
return;
|
|
43188
|
+
}
|
|
43189
|
+
this.env.model.dispatch("SET_ZONE_BORDERS", {
|
|
43190
|
+
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
43191
|
+
target: this.env.model.getters.getSelectedZones(),
|
|
43192
|
+
border: {
|
|
43193
|
+
position: this.state.currentPosition,
|
|
43194
|
+
color: this.state.currentColor,
|
|
43195
|
+
style: this.state.currentStyle,
|
|
43196
|
+
},
|
|
43197
|
+
});
|
|
43198
|
+
}
|
|
43199
|
+
}
|
|
43200
|
+
BorderEditorWidget.props = {
|
|
43201
|
+
toggleBorderEditor: Function,
|
|
43202
|
+
showBorderEditor: Boolean,
|
|
43203
|
+
disabled: { type: Boolean, optional: true },
|
|
43204
|
+
dropdownMaxHeight: { type: Number, optional: true },
|
|
43205
|
+
class: { type: String, optional: true },
|
|
43206
|
+
};
|
|
43207
|
+
|
|
42797
43208
|
const COMPOSER_MAX_HEIGHT = 100;
|
|
43209
|
+
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
43210
|
+
const FX_SVG = /*xml*/ `
|
|
43211
|
+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
43212
|
+
<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'/>
|
|
43213
|
+
</svg>
|
|
43214
|
+
`;
|
|
42798
43215
|
css /* scss */ `
|
|
42799
43216
|
.o-topbar-composer {
|
|
42800
43217
|
height: fit-content;
|
|
@@ -42802,9 +43219,10 @@
|
|
|
42802
43219
|
border: 1px solid;
|
|
42803
43220
|
z-index: ${ComponentsImportance.TopBarComposer};
|
|
42804
43221
|
|
|
42805
|
-
.o-composer:empty:not(:focus)::before {
|
|
42806
|
-
|
|
42807
|
-
|
|
43222
|
+
.o-composer:empty:not(:focus):not(.active)::before {
|
|
43223
|
+
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
43224
|
+
position: relative;
|
|
43225
|
+
top: 20%;
|
|
42808
43226
|
}
|
|
42809
43227
|
}
|
|
42810
43228
|
`;
|
|
@@ -42927,11 +43345,6 @@
|
|
|
42927
43345
|
dropdownStyle: String,
|
|
42928
43346
|
};
|
|
42929
43347
|
|
|
42930
|
-
// If we ever change these colors, make sure the filter tool stays green to match the icon in the grid
|
|
42931
|
-
const ACTIVE_BG_COLOR = BACKGROUND_HEADER_FILTER_COLOR;
|
|
42932
|
-
const ACTIVE_FONT_COLOR = FILTERS_COLOR;
|
|
42933
|
-
const HOVERED_BG_COLOR = BG_HOVER_COLOR;
|
|
42934
|
-
const HOVERED_FONT_COLOR = "#000";
|
|
42935
43348
|
// -----------------------------------------------------------------------------
|
|
42936
43349
|
// TopBar
|
|
42937
43350
|
// -----------------------------------------------------------------------------
|
|
@@ -42941,27 +43354,6 @@
|
|
|
42941
43354
|
font-size: 13px;
|
|
42942
43355
|
font-weight: 500;
|
|
42943
43356
|
|
|
42944
|
-
.o-topbar-hoverable {
|
|
42945
|
-
cursor: pointer;
|
|
42946
|
-
.o-icon {
|
|
42947
|
-
color: ${ICONS_COLOR};
|
|
42948
|
-
}
|
|
42949
|
-
&:not(.o-disabled):not(.active):hover {
|
|
42950
|
-
background-color: ${HOVERED_BG_COLOR};
|
|
42951
|
-
color: ${HOVERED_FONT_COLOR};
|
|
42952
|
-
.o-icon {
|
|
42953
|
-
color: ${HOVERED_FONT_COLOR};
|
|
42954
|
-
}
|
|
42955
|
-
}
|
|
42956
|
-
&.active {
|
|
42957
|
-
background-color: ${ACTIVE_BG_COLOR};
|
|
42958
|
-
color: ${ACTIVE_FONT_COLOR};
|
|
42959
|
-
.o-icon {
|
|
42960
|
-
color: ${ACTIVE_FONT_COLOR};
|
|
42961
|
-
}
|
|
42962
|
-
}
|
|
42963
|
-
}
|
|
42964
|
-
|
|
42965
43357
|
.o-topbar-top {
|
|
42966
43358
|
border-bottom: 1px solid ${SEPARATOR_COLOR};
|
|
42967
43359
|
padding: 2px 10px;
|
|
@@ -42971,6 +43363,11 @@
|
|
|
42971
43363
|
.o-topbar-menu {
|
|
42972
43364
|
padding: 4px 6px;
|
|
42973
43365
|
margin: 0 2px;
|
|
43366
|
+
|
|
43367
|
+
&.active {
|
|
43368
|
+
background-color: ${BG_HOVER_COLOR};
|
|
43369
|
+
color: #000;
|
|
43370
|
+
}
|
|
42974
43371
|
}
|
|
42975
43372
|
}
|
|
42976
43373
|
}
|
|
@@ -43048,6 +43445,7 @@
|
|
|
43048
43445
|
TopBarComposer,
|
|
43049
43446
|
FontSizeEditor,
|
|
43050
43447
|
ActionButton,
|
|
43448
|
+
BorderEditorWidget,
|
|
43051
43449
|
};
|
|
43052
43450
|
state = owl.useState({
|
|
43053
43451
|
menuState: { isOpen: false, position: null, menuItems: [] },
|
|
@@ -43123,7 +43521,9 @@
|
|
|
43123
43521
|
this.state.activeTool = "";
|
|
43124
43522
|
this.state.menuState.isOpen = true;
|
|
43125
43523
|
this.state.menuState.position = { x: left, y: top + height };
|
|
43126
|
-
this.state.menuState.menuItems = menu
|
|
43524
|
+
this.state.menuState.menuItems = menu
|
|
43525
|
+
.children(this.env)
|
|
43526
|
+
.sort((a, b) => a.sequence - b.sequence);
|
|
43127
43527
|
this.state.menuState.parentMenu = menu;
|
|
43128
43528
|
this.isSelectingMenu = true;
|
|
43129
43529
|
this.openedEl = ev.target;
|
|
@@ -43209,6 +43609,11 @@
|
|
|
43209
43609
|
}
|
|
43210
43610
|
}
|
|
43211
43611
|
|
|
43612
|
+
// If we ever change these colors, make sure the filter tool stays green to match the icon in the grid
|
|
43613
|
+
const ACTIVE_BG_COLOR = BACKGROUND_HEADER_FILTER_COLOR;
|
|
43614
|
+
const ACTIVE_FONT_COLOR = FILTERS_COLOR;
|
|
43615
|
+
const HOVERED_BG_COLOR = BG_HOVER_COLOR;
|
|
43616
|
+
const HOVERED_FONT_COLOR = "#000";
|
|
43212
43617
|
css /* scss */ `
|
|
43213
43618
|
.o-spreadsheet {
|
|
43214
43619
|
position: relative;
|
|
@@ -43241,6 +43646,27 @@
|
|
|
43241
43646
|
margin-top: ${MENU_SEPARATOR_PADDING}px;
|
|
43242
43647
|
margin-bottom: ${MENU_SEPARATOR_PADDING}px;
|
|
43243
43648
|
}
|
|
43649
|
+
.o-hoverable-button {
|
|
43650
|
+
border-radius: 2px;
|
|
43651
|
+
cursor: pointer;
|
|
43652
|
+
.o-icon {
|
|
43653
|
+
color: ${ICONS_COLOR};
|
|
43654
|
+
}
|
|
43655
|
+
&:not(.o-disabled):not(.active):hover {
|
|
43656
|
+
background-color: ${HOVERED_BG_COLOR};
|
|
43657
|
+
color: ${HOVERED_FONT_COLOR};
|
|
43658
|
+
.o-icon {
|
|
43659
|
+
color: ${HOVERED_FONT_COLOR};
|
|
43660
|
+
}
|
|
43661
|
+
}
|
|
43662
|
+
&.active {
|
|
43663
|
+
background-color: ${ACTIVE_BG_COLOR};
|
|
43664
|
+
color: ${ACTIVE_FONT_COLOR};
|
|
43665
|
+
.o-icon {
|
|
43666
|
+
color: ${ACTIVE_FONT_COLOR};
|
|
43667
|
+
}
|
|
43668
|
+
}
|
|
43669
|
+
}
|
|
43244
43670
|
}
|
|
43245
43671
|
|
|
43246
43672
|
.o-two-columns {
|
|
@@ -43390,6 +43816,9 @@
|
|
|
43390
43816
|
}
|
|
43391
43817
|
}
|
|
43392
43818
|
openSidePanel(panel, panelProps) {
|
|
43819
|
+
if (this.sidePanel.isOpen && panel !== this.sidePanel.component) {
|
|
43820
|
+
this.sidePanel.panelProps?.onCloseSidePanel?.();
|
|
43821
|
+
}
|
|
43393
43822
|
this.sidePanel.component = panel;
|
|
43394
43823
|
this.sidePanel.panelProps = panelProps;
|
|
43395
43824
|
this.sidePanel.isOpen = true;
|
|
@@ -44099,13 +44528,13 @@
|
|
|
44099
44528
|
}
|
|
44100
44529
|
|
|
44101
44530
|
class SelectiveHistory {
|
|
44531
|
+
HEAD_BRANCH;
|
|
44532
|
+
HEAD_OPERATION;
|
|
44533
|
+
tree;
|
|
44102
44534
|
applyOperation;
|
|
44103
44535
|
revertOperation;
|
|
44104
44536
|
buildEmpty;
|
|
44105
44537
|
buildTransformation;
|
|
44106
|
-
HEAD_BRANCH;
|
|
44107
|
-
HEAD_OPERATION;
|
|
44108
|
-
tree;
|
|
44109
44538
|
/**
|
|
44110
44539
|
* The selective history is a data structure used to register changes/updates of a state.
|
|
44111
44540
|
* Each change/update is called an "operation".
|
|
@@ -44126,14 +44555,15 @@
|
|
|
44126
44555
|
* (used for internal implementation)
|
|
44127
44556
|
* @param buildTransformation Factory used to build transformations
|
|
44128
44557
|
*/
|
|
44129
|
-
constructor(
|
|
44130
|
-
this.applyOperation = applyOperation;
|
|
44131
|
-
this.revertOperation = revertOperation;
|
|
44132
|
-
this.buildEmpty = buildEmpty;
|
|
44133
|
-
this.buildTransformation = buildTransformation;
|
|
44558
|
+
constructor(args) {
|
|
44559
|
+
this.applyOperation = args.applyOperation;
|
|
44560
|
+
this.revertOperation = args.revertOperation;
|
|
44561
|
+
this.buildEmpty = args.buildEmpty;
|
|
44562
|
+
this.buildTransformation = args.buildTransformation;
|
|
44134
44563
|
this.HEAD_BRANCH = new Branch(this.buildTransformation);
|
|
44135
|
-
this.tree = new Tree(buildTransformation, this.HEAD_BRANCH);
|
|
44136
|
-
const
|
|
44564
|
+
this.tree = new Tree(this.buildTransformation, this.HEAD_BRANCH);
|
|
44565
|
+
const initialOperationId = args.initialOperationId;
|
|
44566
|
+
const initial = new Operation(initialOperationId, this.buildEmpty(initialOperationId));
|
|
44137
44567
|
this.tree.insertOperationLast(this.HEAD_BRANCH, initial);
|
|
44138
44568
|
this.HEAD_OPERATION = initial;
|
|
44139
44569
|
}
|
|
@@ -44247,21 +44677,27 @@
|
|
|
44247
44677
|
}
|
|
44248
44678
|
}
|
|
44249
44679
|
|
|
44250
|
-
function buildRevisionLog(
|
|
44251
|
-
return new SelectiveHistory(
|
|
44252
|
-
|
|
44253
|
-
|
|
44254
|
-
|
|
44255
|
-
|
|
44256
|
-
|
|
44257
|
-
|
|
44258
|
-
|
|
44259
|
-
|
|
44260
|
-
|
|
44261
|
-
return new Revision(toTransform.id, toTransform.clientId, transformAll(toTransform.commands, revision.commands), toTransform.rootCommand);
|
|
44680
|
+
function buildRevisionLog(args) {
|
|
44681
|
+
return new SelectiveHistory({
|
|
44682
|
+
initialOperationId: args.initialRevisionId,
|
|
44683
|
+
applyOperation: (revision) => {
|
|
44684
|
+
const commands = revision.commands.slice();
|
|
44685
|
+
const { changes } = args.recordChanges(() => {
|
|
44686
|
+
for (const command of commands) {
|
|
44687
|
+
args.dispatch(command);
|
|
44688
|
+
}
|
|
44689
|
+
});
|
|
44690
|
+
revision.setChanges(changes);
|
|
44262
44691
|
},
|
|
44263
|
-
|
|
44264
|
-
|
|
44692
|
+
revertOperation: (revision) => revertChanges([revision]),
|
|
44693
|
+
buildEmpty: (id) => new Revision(id, "empty", []),
|
|
44694
|
+
buildTransformation: {
|
|
44695
|
+
with: (revision) => (toTransform) => {
|
|
44696
|
+
return new Revision(toTransform.id, toTransform.clientId, transformAll(toTransform.commands, revision.commands), toTransform.rootCommand, undefined, toTransform.timestamp);
|
|
44697
|
+
},
|
|
44698
|
+
without: (revision) => (toTransform) => {
|
|
44699
|
+
return new Revision(toTransform.id, toTransform.clientId, transformAll(toTransform.commands, revision.commands.map(inverseCommand).flat()), toTransform.rootCommand, undefined, toTransform.timestamp);
|
|
44700
|
+
},
|
|
44265
44701
|
},
|
|
44266
44702
|
});
|
|
44267
44703
|
}
|
|
@@ -45934,11 +46370,21 @@
|
|
|
45934
46370
|
for (let border of Object.values(borders)) {
|
|
45935
46371
|
borderNodes.push(escapeXml /*xml*/ `
|
|
45936
46372
|
<border>
|
|
45937
|
-
<left ${formatBorderAttribute(border["left"])}
|
|
45938
|
-
|
|
45939
|
-
|
|
45940
|
-
<
|
|
45941
|
-
|
|
46373
|
+
<left ${formatBorderAttribute(border["left"])}>
|
|
46374
|
+
${addBorderColor(border["left"])}
|
|
46375
|
+
</left>
|
|
46376
|
+
<right ${formatBorderAttribute(border["right"])}>
|
|
46377
|
+
${addBorderColor(border["right"])}
|
|
46378
|
+
</right>
|
|
46379
|
+
<top ${formatBorderAttribute(border["top"])}>
|
|
46380
|
+
${addBorderColor(border["top"])}
|
|
46381
|
+
</top>
|
|
46382
|
+
<bottom ${formatBorderAttribute(border["bottom"])}>
|
|
46383
|
+
${addBorderColor(border["bottom"])}
|
|
46384
|
+
</bottom>
|
|
46385
|
+
<diagonal ${formatBorderAttribute(border["diagonal"])}>
|
|
46386
|
+
${addBorderColor(border["diagonal"])}
|
|
46387
|
+
</diagonal>
|
|
45942
46388
|
</border>
|
|
45943
46389
|
`);
|
|
45944
46390
|
}
|
|
@@ -45952,10 +46398,15 @@
|
|
|
45952
46398
|
if (!description) {
|
|
45953
46399
|
return escapeXml ``;
|
|
45954
46400
|
}
|
|
45955
|
-
return formatAttributes([
|
|
45956
|
-
|
|
45957
|
-
|
|
45958
|
-
|
|
46401
|
+
return formatAttributes([["style", description.style]]);
|
|
46402
|
+
}
|
|
46403
|
+
function addBorderColor(description) {
|
|
46404
|
+
if (!description) {
|
|
46405
|
+
return escapeXml ``;
|
|
46406
|
+
}
|
|
46407
|
+
return escapeXml /*xml*/ `
|
|
46408
|
+
<color ${formatAttributes([["rgb", toXlsxHexColor(description.color.rgb)]])}/>
|
|
46409
|
+
`;
|
|
45959
46410
|
}
|
|
45960
46411
|
function addStyles(styles) {
|
|
45961
46412
|
const styleNodes = [];
|
|
@@ -46565,6 +47016,7 @@
|
|
|
46565
47016
|
coreGetters;
|
|
46566
47017
|
uuidGenerator;
|
|
46567
47018
|
handlers = [];
|
|
47019
|
+
uiHandlers = [];
|
|
46568
47020
|
coreHandlers = [];
|
|
46569
47021
|
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
|
|
46570
47022
|
super();
|
|
@@ -46599,21 +47051,25 @@
|
|
|
46599
47051
|
this.setupCorePlugin(Plugin, workbookData);
|
|
46600
47052
|
}
|
|
46601
47053
|
Object.assign(this.getters, this.coreGetters);
|
|
47054
|
+
this.session.loadInitialMessages(stateUpdateMessages);
|
|
46602
47055
|
for (let Plugin of statefulUIPluginRegistry.getAll()) {
|
|
46603
47056
|
const plugin = this.setupUiPlugin(Plugin);
|
|
46604
47057
|
this.statefulUIPlugins.push(plugin);
|
|
46605
47058
|
this.handlers.push(plugin);
|
|
47059
|
+
this.uiHandlers.push(plugin);
|
|
46606
47060
|
}
|
|
46607
47061
|
for (let Plugin of coreViewsPluginRegistry.getAll()) {
|
|
46608
47062
|
const plugin = this.setupUiPlugin(Plugin);
|
|
46609
47063
|
this.coreViewsPlugins.push(plugin);
|
|
46610
47064
|
this.handlers.push(plugin);
|
|
47065
|
+
this.uiHandlers.push(plugin);
|
|
46611
47066
|
this.coreHandlers.push(plugin);
|
|
46612
47067
|
}
|
|
46613
47068
|
for (let Plugin of featurePluginRegistry.getAll()) {
|
|
46614
47069
|
const plugin = this.setupUiPlugin(Plugin);
|
|
46615
47070
|
this.featurePlugins.push(plugin);
|
|
46616
47071
|
this.handlers.push(plugin);
|
|
47072
|
+
this.uiHandlers.push(plugin);
|
|
46617
47073
|
}
|
|
46618
47074
|
this.uuidGenerator.setIsFastStrategy(false);
|
|
46619
47075
|
// starting plugins
|
|
@@ -46626,8 +47082,6 @@
|
|
|
46626
47082
|
// This should be done after construction of LocalHistory due to order of
|
|
46627
47083
|
// events
|
|
46628
47084
|
this.setupSessionEvents();
|
|
46629
|
-
// Load the initial revisions
|
|
46630
|
-
this.session.loadInitialMessages(stateUpdateMessages);
|
|
46631
47085
|
this.joinSession();
|
|
46632
47086
|
if (config.snapshotRequested) {
|
|
46633
47087
|
this.session.snapshot(this.exportData());
|
|
@@ -46691,14 +47145,18 @@
|
|
|
46691
47145
|
this.finalize();
|
|
46692
47146
|
}
|
|
46693
47147
|
setupSession(revisionId) {
|
|
46694
|
-
const session = new Session(buildRevisionLog(
|
|
46695
|
-
|
|
46696
|
-
|
|
46697
|
-
|
|
46698
|
-
|
|
46699
|
-
|
|
46700
|
-
|
|
46701
|
-
|
|
47148
|
+
const session = new Session(buildRevisionLog({
|
|
47149
|
+
initialRevisionId: revisionId,
|
|
47150
|
+
recordChanges: this.state.recordChanges.bind(this.state),
|
|
47151
|
+
dispatch: (command) => {
|
|
47152
|
+
const result = this.checkDispatchAllowed(command);
|
|
47153
|
+
if (!result.isSuccessful) {
|
|
47154
|
+
return;
|
|
47155
|
+
}
|
|
47156
|
+
this.isReplayingCommand = true;
|
|
47157
|
+
this.dispatchToHandlers(this.coreHandlers, command);
|
|
47158
|
+
this.isReplayingCommand = false;
|
|
47159
|
+
},
|
|
46702
47160
|
}), this.config.transportService, revisionId);
|
|
46703
47161
|
return session;
|
|
46704
47162
|
}
|
|
@@ -46780,7 +47238,7 @@
|
|
|
46780
47238
|
return new DispatchResult(results.flat());
|
|
46781
47239
|
}
|
|
46782
47240
|
checkDispatchAllowedLocalCommand(command) {
|
|
46783
|
-
const results = this.
|
|
47241
|
+
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
46784
47242
|
return new DispatchResult(results.flat());
|
|
46785
47243
|
}
|
|
46786
47244
|
finalize() {
|
|
@@ -47099,9 +47557,9 @@
|
|
|
47099
47557
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
47100
47558
|
|
|
47101
47559
|
|
|
47102
|
-
__info__.version = '16.3.0
|
|
47103
|
-
__info__.date = '2023-05-
|
|
47104
|
-
__info__.hash = '
|
|
47560
|
+
__info__.version = '16.3.0';
|
|
47561
|
+
__info__.date = '2023-05-17T14:44:57.860Z';
|
|
47562
|
+
__info__.hash = '33b37e4';
|
|
47105
47563
|
|
|
47106
47564
|
|
|
47107
47565
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|