@odoo/o-spreadsheet 18.3.1 → 18.3.3
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 +695 -137
- package/dist/o-spreadsheet.d.ts +278 -164
- package/dist/o-spreadsheet.esm.js +695 -137
- package/dist/o-spreadsheet.iife.js +695 -137
- package/dist/o-spreadsheet.iife.min.js +419 -383
- package/dist/o_spreadsheet.xml +64 -16
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.3.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.3.3
|
|
6
|
+
* @date 2025-05-13T17:54:43.312Z
|
|
7
|
+
* @hash b79924a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -3320,7 +3320,7 @@
|
|
|
3320
3320
|
*/
|
|
3321
3321
|
const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
|
|
3322
3322
|
decimalSeparator = escapeRegExp(decimalSeparator);
|
|
3323
|
-
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e
|
|
3323
|
+
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
|
|
3324
3324
|
});
|
|
3325
3325
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
3326
3326
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
@@ -6001,6 +6001,67 @@
|
|
|
6001
6001
|
return MIN_DELAY + (MAX_DELAY - MIN_DELAY) * Math.exp(-ACCELERATION * (value - 1));
|
|
6002
6002
|
}
|
|
6003
6003
|
|
|
6004
|
+
function createDefaultRows(rowNumber) {
|
|
6005
|
+
const rows = [];
|
|
6006
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
6007
|
+
const row = {
|
|
6008
|
+
cells: {},
|
|
6009
|
+
};
|
|
6010
|
+
rows.push(row);
|
|
6011
|
+
}
|
|
6012
|
+
return rows;
|
|
6013
|
+
}
|
|
6014
|
+
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
6015
|
+
return headers.map((header) => {
|
|
6016
|
+
if (header >= indexHeaderAdded) {
|
|
6017
|
+
return header + numberAdded;
|
|
6018
|
+
}
|
|
6019
|
+
return header;
|
|
6020
|
+
});
|
|
6021
|
+
}
|
|
6022
|
+
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
6023
|
+
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
6024
|
+
return headers
|
|
6025
|
+
.map((header) => {
|
|
6026
|
+
for (const deletedHeader of deletedHeaders) {
|
|
6027
|
+
if (header > deletedHeader) {
|
|
6028
|
+
header--;
|
|
6029
|
+
}
|
|
6030
|
+
else if (header === deletedHeader) {
|
|
6031
|
+
return undefined;
|
|
6032
|
+
}
|
|
6033
|
+
}
|
|
6034
|
+
return header;
|
|
6035
|
+
})
|
|
6036
|
+
.filter(isDefined);
|
|
6037
|
+
}
|
|
6038
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6039
|
+
let i = 1;
|
|
6040
|
+
let name = `${baseName}${i}`;
|
|
6041
|
+
while (existingNames.includes(name)) {
|
|
6042
|
+
name = `${baseName}${i}`;
|
|
6043
|
+
i++;
|
|
6044
|
+
}
|
|
6045
|
+
return name;
|
|
6046
|
+
}
|
|
6047
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6048
|
+
let i = 1;
|
|
6049
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6050
|
+
let name = baseName.toString();
|
|
6051
|
+
while (existingNames.includes(name)) {
|
|
6052
|
+
name = `${baseName} (${i})`;
|
|
6053
|
+
i++;
|
|
6054
|
+
}
|
|
6055
|
+
return name;
|
|
6056
|
+
}
|
|
6057
|
+
function isSheetNameEqual(name1, name2) {
|
|
6058
|
+
if (name1 === undefined || name2 === undefined) {
|
|
6059
|
+
return false;
|
|
6060
|
+
}
|
|
6061
|
+
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6062
|
+
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6063
|
+
}
|
|
6064
|
+
|
|
6004
6065
|
function createRange(args, getSheetSize) {
|
|
6005
6066
|
const unboundedZone = args.zone;
|
|
6006
6067
|
const zone = boundUnboundedZone(unboundedZone, getSheetSize(args.sheetId));
|
|
@@ -6291,7 +6352,7 @@
|
|
|
6291
6352
|
elements.sort((a, b) => b - a);
|
|
6292
6353
|
const groups = groupConsecutive(elements);
|
|
6293
6354
|
return (range) => {
|
|
6294
|
-
if (range.sheetId
|
|
6355
|
+
if (!isSheetNameEqual(range.sheetId, cmd.sheetId)) {
|
|
6295
6356
|
return { changeType: "NONE" };
|
|
6296
6357
|
}
|
|
6297
6358
|
let newRange = range;
|
|
@@ -6498,41 +6559,6 @@
|
|
|
6498
6559
|
return results.map((r) => r.elem);
|
|
6499
6560
|
}
|
|
6500
6561
|
|
|
6501
|
-
function createDefaultRows(rowNumber) {
|
|
6502
|
-
const rows = [];
|
|
6503
|
-
for (let i = 0; i < rowNumber; i++) {
|
|
6504
|
-
const row = {
|
|
6505
|
-
cells: {},
|
|
6506
|
-
};
|
|
6507
|
-
rows.push(row);
|
|
6508
|
-
}
|
|
6509
|
-
return rows;
|
|
6510
|
-
}
|
|
6511
|
-
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
6512
|
-
return headers.map((header) => {
|
|
6513
|
-
if (header >= indexHeaderAdded) {
|
|
6514
|
-
return header + numberAdded;
|
|
6515
|
-
}
|
|
6516
|
-
return header;
|
|
6517
|
-
});
|
|
6518
|
-
}
|
|
6519
|
-
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
6520
|
-
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
6521
|
-
return headers
|
|
6522
|
-
.map((header) => {
|
|
6523
|
-
for (const deletedHeader of deletedHeaders) {
|
|
6524
|
-
if (header > deletedHeader) {
|
|
6525
|
-
header--;
|
|
6526
|
-
}
|
|
6527
|
-
else if (header === deletedHeader) {
|
|
6528
|
-
return undefined;
|
|
6529
|
-
}
|
|
6530
|
-
}
|
|
6531
|
-
return header;
|
|
6532
|
-
})
|
|
6533
|
-
.filter(isDefined);
|
|
6534
|
-
}
|
|
6535
|
-
|
|
6536
6562
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
6537
6563
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
6538
6564
|
}
|
|
@@ -8274,6 +8300,25 @@
|
|
|
8274
8300
|
return `${normalizedValue}`;
|
|
8275
8301
|
},
|
|
8276
8302
|
};
|
|
8303
|
+
/**
|
|
8304
|
+
* normalizes month number + year
|
|
8305
|
+
*/
|
|
8306
|
+
const monthAdapter = {
|
|
8307
|
+
normalizeFunctionValue(value) {
|
|
8308
|
+
const date = toNumber(value, DEFAULT_LOCALE);
|
|
8309
|
+
return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
|
|
8310
|
+
},
|
|
8311
|
+
toValueAndFormat(normalizedValue) {
|
|
8312
|
+
return {
|
|
8313
|
+
value: toNumber(normalizedValue, DEFAULT_LOCALE),
|
|
8314
|
+
format: "mmmm yyyy",
|
|
8315
|
+
};
|
|
8316
|
+
},
|
|
8317
|
+
toFunctionValue(normalizedValue) {
|
|
8318
|
+
const jsDate = toJsDate(normalizedValue, DEFAULT_LOCALE);
|
|
8319
|
+
return `DATE(${jsDate.getFullYear()},${jsDate.getMonth() + 1},1)`;
|
|
8320
|
+
},
|
|
8321
|
+
};
|
|
8277
8322
|
/**
|
|
8278
8323
|
* normalizes quarter number
|
|
8279
8324
|
*/
|
|
@@ -8409,6 +8454,7 @@
|
|
|
8409
8454
|
.add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
|
|
8410
8455
|
.add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
|
|
8411
8456
|
.add("month_number", nullHandlerDecorator(monthNumberAdapter))
|
|
8457
|
+
.add("month", nullHandlerDecorator(monthAdapter))
|
|
8412
8458
|
.add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
|
|
8413
8459
|
.add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
|
|
8414
8460
|
.add("hour_number", nullHandlerDecorator(hourNumberAdapter))
|
|
@@ -8425,10 +8471,9 @@
|
|
|
8425
8471
|
avg: _t("Average"),
|
|
8426
8472
|
sum: _t("Sum"),
|
|
8427
8473
|
};
|
|
8428
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8429
8474
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8430
|
-
integer:
|
|
8431
|
-
char:
|
|
8475
|
+
integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
|
|
8476
|
+
char: ["count_distinct", "count"],
|
|
8432
8477
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8433
8478
|
datetime: ["max", "min", "count_distinct", "count"],
|
|
8434
8479
|
};
|
|
@@ -8589,10 +8634,7 @@
|
|
|
8589
8634
|
return normalizer(groupValueString, dimension.granularity);
|
|
8590
8635
|
}
|
|
8591
8636
|
function normalizeDateTime(value, granularity) {
|
|
8592
|
-
|
|
8593
|
-
throw new Error("Missing granularity");
|
|
8594
|
-
}
|
|
8595
|
-
return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
|
|
8637
|
+
return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
|
|
8596
8638
|
}
|
|
8597
8639
|
function toFunctionPivotValue(value, dimension) {
|
|
8598
8640
|
if (value === null) {
|
|
@@ -8604,10 +8646,7 @@
|
|
|
8604
8646
|
return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
|
|
8605
8647
|
}
|
|
8606
8648
|
function toFunctionValueDateTime(value, granularity) {
|
|
8607
|
-
|
|
8608
|
-
throw new Error("Missing granularity");
|
|
8609
|
-
}
|
|
8610
|
-
return pivotTimeAdapter(granularity).toFunctionValue(value);
|
|
8649
|
+
return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
|
|
8611
8650
|
}
|
|
8612
8651
|
const pivotNormalizationValueRegistry = new Registry();
|
|
8613
8652
|
pivotNormalizationValueRegistry
|
|
@@ -9802,7 +9841,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9802
9841
|
const functionProxy = new Proxy(value, {
|
|
9803
9842
|
// trap the function call
|
|
9804
9843
|
apply(target, thisArg, argArray) {
|
|
9805
|
-
Reflect.apply(target, thisStore, argArray);
|
|
9844
|
+
const res = Reflect.apply(target, thisStore, argArray);
|
|
9845
|
+
if (res === "noStateChange") {
|
|
9846
|
+
return;
|
|
9847
|
+
}
|
|
9806
9848
|
callback();
|
|
9807
9849
|
},
|
|
9808
9850
|
});
|
|
@@ -9824,7 +9866,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9824
9866
|
const ModelStore = createAbstractStore("Model");
|
|
9825
9867
|
|
|
9826
9868
|
class RendererStore {
|
|
9827
|
-
mutators = ["register", "unRegister"];
|
|
9869
|
+
mutators = ["register", "unRegister", "drawLayer"];
|
|
9828
9870
|
renderers = {};
|
|
9829
9871
|
register(renderer) {
|
|
9830
9872
|
if (!renderer.renderingLayers.length) {
|
|
@@ -9844,14 +9886,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9844
9886
|
}
|
|
9845
9887
|
drawLayer(context, layer) {
|
|
9846
9888
|
const renderers = this.renderers[layer];
|
|
9847
|
-
if (
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
context.ctx.restore();
|
|
9889
|
+
if (renderers) {
|
|
9890
|
+
for (const renderer of renderers) {
|
|
9891
|
+
context.ctx.save();
|
|
9892
|
+
renderer.drawLayer(context, layer);
|
|
9893
|
+
context.ctx.restore();
|
|
9894
|
+
}
|
|
9854
9895
|
}
|
|
9896
|
+
return "noStateChange";
|
|
9855
9897
|
}
|
|
9856
9898
|
}
|
|
9857
9899
|
|
|
@@ -9904,16 +9946,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9904
9946
|
focusComposer(listener, args) {
|
|
9905
9947
|
this.activeComposer = listener;
|
|
9906
9948
|
if (this.getters.isReadonly()) {
|
|
9907
|
-
return;
|
|
9949
|
+
return "noStateChange";
|
|
9908
9950
|
}
|
|
9909
9951
|
this._focusMode = args.focusMode || "contentFocus";
|
|
9910
9952
|
if (this._focusMode !== "inactive") {
|
|
9911
9953
|
this.setComposerContent(args);
|
|
9912
9954
|
}
|
|
9955
|
+
return;
|
|
9913
9956
|
}
|
|
9914
9957
|
focusActiveComposer(args) {
|
|
9915
9958
|
if (this.getters.isReadonly()) {
|
|
9916
|
-
return;
|
|
9959
|
+
return "noStateChange";
|
|
9917
9960
|
}
|
|
9918
9961
|
if (!this.activeComposer) {
|
|
9919
9962
|
throw new Error("No composer is registered");
|
|
@@ -9922,6 +9965,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9922
9965
|
if (this._focusMode !== "inactive") {
|
|
9923
9966
|
this.setComposerContent(args);
|
|
9924
9967
|
}
|
|
9968
|
+
return;
|
|
9925
9969
|
}
|
|
9926
9970
|
/**
|
|
9927
9971
|
* Start the edition or update the content if it's already started.
|
|
@@ -10081,20 +10125,24 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10081
10125
|
}
|
|
10082
10126
|
|
|
10083
10127
|
const chartJsExtensionRegistry = new Registry();
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10128
|
+
function areChartJSExtensionsLoaded() {
|
|
10129
|
+
return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
|
|
10130
|
+
}
|
|
10131
|
+
function registerChartJSExtensions() {
|
|
10132
|
+
if (!window.Chart || areChartJSExtensionsLoaded()) {
|
|
10133
|
+
return;
|
|
10134
|
+
}
|
|
10135
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
10136
|
+
registryItem.register(window.Chart);
|
|
10137
|
+
}
|
|
10138
|
+
}
|
|
10139
|
+
function unregisterChartJsExtensions() {
|
|
10140
|
+
if (!window.Chart) {
|
|
10141
|
+
return;
|
|
10142
|
+
}
|
|
10143
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
10144
|
+
registryItem.unregister(window.Chart);
|
|
10096
10145
|
}
|
|
10097
|
-
return window.Chart;
|
|
10098
10146
|
}
|
|
10099
10147
|
|
|
10100
10148
|
function getFunnelChartController() {
|
|
@@ -10521,7 +10569,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10521
10569
|
}
|
|
10522
10570
|
function formatChartDatasetValue(axisFormats, locale) {
|
|
10523
10571
|
return (value, axisId) => {
|
|
10524
|
-
const format =
|
|
10572
|
+
const format = axisFormats?.[axisId];
|
|
10525
10573
|
return formatTickValue({ format, locale })(value);
|
|
10526
10574
|
};
|
|
10527
10575
|
}
|
|
@@ -10698,7 +10746,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10698
10746
|
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10699
10747
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10700
10748
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10701
|
-
const displayValue = options.callback(value);
|
|
10749
|
+
const displayValue = options.callback(value, "y");
|
|
10702
10750
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10703
10751
|
}
|
|
10704
10752
|
}
|
|
@@ -11460,13 +11508,35 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
11460
11508
|
}
|
|
11461
11509
|
}
|
|
11462
11510
|
`;
|
|
11463
|
-
chartJsExtensionRegistry.add("chartShowValuesPlugin",
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
chartJsExtensionRegistry.add("
|
|
11468
|
-
|
|
11469
|
-
|
|
11511
|
+
chartJsExtensionRegistry.add("chartShowValuesPlugin", {
|
|
11512
|
+
register: (Chart) => Chart.register(chartShowValuesPlugin),
|
|
11513
|
+
unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
|
|
11514
|
+
});
|
|
11515
|
+
chartJsExtensionRegistry.add("waterfallLinesPlugin", {
|
|
11516
|
+
register: (Chart) => Chart.register(waterfallLinesPlugin),
|
|
11517
|
+
unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
|
|
11518
|
+
});
|
|
11519
|
+
chartJsExtensionRegistry.add("funnelController", {
|
|
11520
|
+
register: (Chart) => Chart.register(getFunnelChartController()),
|
|
11521
|
+
unregister: (Chart) => Chart.unregister(getFunnelChartController()),
|
|
11522
|
+
});
|
|
11523
|
+
chartJsExtensionRegistry.add("funnelElement", {
|
|
11524
|
+
register: (Chart) => Chart.register(getFunnelChartElement()),
|
|
11525
|
+
unregister: (Chart) => Chart.unregister(getFunnelChartElement()),
|
|
11526
|
+
});
|
|
11527
|
+
chartJsExtensionRegistry.add("funnelTooltipPositioner", {
|
|
11528
|
+
register: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = funnelTooltipPositioner),
|
|
11529
|
+
// @ts-expect-error
|
|
11530
|
+
unregister: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = undefined),
|
|
11531
|
+
});
|
|
11532
|
+
chartJsExtensionRegistry.add("sunburstLabelsPlugin", {
|
|
11533
|
+
register: (Chart) => Chart.register(sunburstLabelsPlugin),
|
|
11534
|
+
unregister: (Chart) => Chart.unregister(sunburstLabelsPlugin),
|
|
11535
|
+
});
|
|
11536
|
+
chartJsExtensionRegistry.add("sunburstHoverPlugin", {
|
|
11537
|
+
register: (Chart) => Chart.register(sunburstHoverPlugin),
|
|
11538
|
+
unregister: (Chart) => Chart.unregister(sunburstHoverPlugin),
|
|
11539
|
+
});
|
|
11470
11540
|
class ChartJsComponent extends owl.Component {
|
|
11471
11541
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
11472
11542
|
static props = {
|
|
@@ -11518,8 +11588,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
11518
11588
|
createChart(chartData) {
|
|
11519
11589
|
const canvas = this.canvas.el;
|
|
11520
11590
|
const ctx = canvas.getContext("2d");
|
|
11521
|
-
|
|
11522
|
-
this.chart = new Chart(ctx, chartData);
|
|
11591
|
+
this.chart = new window.Chart(ctx, chartData);
|
|
11523
11592
|
}
|
|
11524
11593
|
updateChartJs(chartData) {
|
|
11525
11594
|
if (chartData.data && chartData.data.datasets) {
|
|
@@ -19824,7 +19893,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19824
19893
|
return { value: "" };
|
|
19825
19894
|
}
|
|
19826
19895
|
if (result.value === null) {
|
|
19827
|
-
result
|
|
19896
|
+
return { ...result, value: "" };
|
|
19828
19897
|
}
|
|
19829
19898
|
return result;
|
|
19830
19899
|
},
|
|
@@ -19845,7 +19914,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19845
19914
|
return { value: "" };
|
|
19846
19915
|
}
|
|
19847
19916
|
if (result.value === null) {
|
|
19848
|
-
result
|
|
19917
|
+
return { ...result, value: "" };
|
|
19849
19918
|
}
|
|
19850
19919
|
return result;
|
|
19851
19920
|
},
|
|
@@ -19866,7 +19935,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19866
19935
|
return { value: "" };
|
|
19867
19936
|
}
|
|
19868
19937
|
if (result.value === null) {
|
|
19869
|
-
result
|
|
19938
|
+
return { ...result, value: "" };
|
|
19870
19939
|
}
|
|
19871
19940
|
return result;
|
|
19872
19941
|
},
|
|
@@ -19892,7 +19961,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19892
19961
|
return { value: "" };
|
|
19893
19962
|
}
|
|
19894
19963
|
if (result.value === null) {
|
|
19895
|
-
result
|
|
19964
|
+
return { ...result, value: "" };
|
|
19896
19965
|
}
|
|
19897
19966
|
return result;
|
|
19898
19967
|
}
|
|
@@ -20039,6 +20108,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20039
20108
|
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
20040
20109
|
throw new InvalidReferenceError();
|
|
20041
20110
|
}
|
|
20111
|
+
if (evalContext.__originCellPosition &&
|
|
20112
|
+
range.sheetId === evalContext.__originSheetId &&
|
|
20113
|
+
isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
|
|
20114
|
+
throw new CircularDependencyError();
|
|
20115
|
+
}
|
|
20042
20116
|
dependencies.push(range);
|
|
20043
20117
|
}
|
|
20044
20118
|
for (const measure of forMeasures) {
|
|
@@ -20481,6 +20555,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20481
20555
|
};
|
|
20482
20556
|
}
|
|
20483
20557
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
20558
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
20559
|
+
this.getters.getPivotPresenceTracker(pivotId)?.trackValue(_measure, domain);
|
|
20560
|
+
}
|
|
20484
20561
|
return pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
20485
20562
|
},
|
|
20486
20563
|
};
|
|
@@ -20512,6 +20589,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20512
20589
|
};
|
|
20513
20590
|
}
|
|
20514
20591
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
20592
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
20593
|
+
this.getters.getPivotPresenceTracker(_pivotId)?.trackHeader(domain);
|
|
20594
|
+
}
|
|
20515
20595
|
const lastNode = domain.at(-1);
|
|
20516
20596
|
if (lastNode?.field === "measure") {
|
|
20517
20597
|
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
@@ -20734,6 +20814,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20734
20814
|
return data === undefined || data.value === null;
|
|
20735
20815
|
}
|
|
20736
20816
|
const getNeutral = { number: 0, string: "", boolean: false };
|
|
20817
|
+
function areAlmostEqual(value1, value2, epsilon = 2e-16) {
|
|
20818
|
+
return Math.abs(value1 - value2) < epsilon;
|
|
20819
|
+
}
|
|
20737
20820
|
const EQ = {
|
|
20738
20821
|
description: _t("Equal."),
|
|
20739
20822
|
args: [
|
|
@@ -20755,6 +20838,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20755
20838
|
if (typeof _value2 === "string") {
|
|
20756
20839
|
_value2 = _value2.toUpperCase();
|
|
20757
20840
|
}
|
|
20841
|
+
if (typeof _value1 === "number" && typeof _value2 === "number") {
|
|
20842
|
+
return { value: areAlmostEqual(_value1, _value2) };
|
|
20843
|
+
}
|
|
20758
20844
|
return { value: _value1 === _value2 };
|
|
20759
20845
|
},
|
|
20760
20846
|
};
|
|
@@ -20794,6 +20880,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20794
20880
|
],
|
|
20795
20881
|
compute: function (value1, value2) {
|
|
20796
20882
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
20883
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
20884
|
+
return !areAlmostEqual(v1, v2) && v1 > v2;
|
|
20885
|
+
}
|
|
20797
20886
|
return v1 > v2;
|
|
20798
20887
|
});
|
|
20799
20888
|
},
|
|
@@ -20809,6 +20898,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20809
20898
|
],
|
|
20810
20899
|
compute: function (value1, value2) {
|
|
20811
20900
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
20901
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
20902
|
+
return areAlmostEqual(v1, v2) || v1 > v2;
|
|
20903
|
+
}
|
|
20812
20904
|
return v1 >= v2;
|
|
20813
20905
|
});
|
|
20814
20906
|
},
|
|
@@ -22501,7 +22593,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22501
22593
|
.find((token) => {
|
|
22502
22594
|
const { xc, sheetName: sheet } = splitReference(token.value);
|
|
22503
22595
|
const sheetName = sheet || this.getters.getSheetName(this.sheetId);
|
|
22504
|
-
if (this.getters.getSheetName(activeSheetId)
|
|
22596
|
+
if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
|
|
22505
22597
|
return false;
|
|
22506
22598
|
}
|
|
22507
22599
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
@@ -24398,6 +24490,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24398
24490
|
},
|
|
24399
24491
|
},
|
|
24400
24492
|
animation: false,
|
|
24493
|
+
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
|
|
24401
24494
|
};
|
|
24402
24495
|
function chartToImageUrl(runtime, figure, type) {
|
|
24403
24496
|
// wrap the canvas in a div with a fixed size because chart.js would
|
|
@@ -24437,6 +24530,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24437
24530
|
const div = document.createElement("div");
|
|
24438
24531
|
div.style.width = `${figure.width}px`;
|
|
24439
24532
|
div.style.height = `${figure.height}px`;
|
|
24533
|
+
div.style.position = "fixed";
|
|
24534
|
+
div.style.opacity = "0";
|
|
24440
24535
|
const canvas = document.createElement("canvas");
|
|
24441
24536
|
div.append(canvas);
|
|
24442
24537
|
canvas.setAttribute("width", figure.width.toString());
|
|
@@ -24447,8 +24542,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24447
24542
|
if ("chartJsConfig" in runtime) {
|
|
24448
24543
|
const config = deepCopy(runtime.chartJsConfig);
|
|
24449
24544
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
24450
|
-
const
|
|
24451
|
-
const chart = new Chart(canvas, config);
|
|
24545
|
+
const chart = new window.Chart(canvas, config);
|
|
24452
24546
|
chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
24453
24547
|
chart.destroy();
|
|
24454
24548
|
}
|
|
@@ -25200,11 +25294,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25200
25294
|
}
|
|
25201
25295
|
let missingTimeAdapterAlreadyWarned = false;
|
|
25202
25296
|
function isLuxonTimeAdapterInstalled() {
|
|
25203
|
-
|
|
25204
|
-
if (!Chart) {
|
|
25297
|
+
if (!window.Chart) {
|
|
25205
25298
|
return false;
|
|
25206
25299
|
}
|
|
25207
|
-
const adapter = new Chart._adapters._date({});
|
|
25300
|
+
const adapter = new window.Chart._adapters._date({});
|
|
25208
25301
|
// @ts-ignore
|
|
25209
25302
|
const isInstalled = adapter._id === "luxon";
|
|
25210
25303
|
if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
|
|
@@ -25702,6 +25795,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25702
25795
|
target.style.cursor = "default";
|
|
25703
25796
|
},
|
|
25704
25797
|
onClick: (event, legendItem, legend) => {
|
|
25798
|
+
if (event.type !== "click") {
|
|
25799
|
+
return;
|
|
25800
|
+
}
|
|
25705
25801
|
const index = legendItem.datasetIndex;
|
|
25706
25802
|
if (!legend.legendItems || index === undefined) {
|
|
25707
25803
|
return;
|
|
@@ -29638,10 +29734,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29638
29734
|
const imageUrl = chartToImageUrl(runtime, figure, chartType);
|
|
29639
29735
|
const innerHTML = `<img src="${xmlEscape(imageUrl)}" />`;
|
|
29640
29736
|
const blob = await chartToImageFile(runtime, figure, chartType);
|
|
29641
|
-
env.clipboard.write({
|
|
29737
|
+
await env.clipboard.write({
|
|
29642
29738
|
"text/html": innerHTML,
|
|
29643
29739
|
"image/png": blob,
|
|
29644
29740
|
});
|
|
29741
|
+
env.notifyUser({
|
|
29742
|
+
text: _t("The chart was copied to your clipboard"),
|
|
29743
|
+
sticky: false,
|
|
29744
|
+
type: "info",
|
|
29745
|
+
});
|
|
29645
29746
|
},
|
|
29646
29747
|
},
|
|
29647
29748
|
{
|
|
@@ -31491,7 +31592,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31491
31592
|
({ xc, sheetName } = splitReference(reference));
|
|
31492
31593
|
let rangeSheetIndex;
|
|
31493
31594
|
if (sheetName) {
|
|
31494
|
-
const index = data.sheets.findIndex((sheet) => sheet.name
|
|
31595
|
+
const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
|
|
31495
31596
|
if (index < 0) {
|
|
31496
31597
|
throw new Error("Unable to find a sheet with the name " + sheetName);
|
|
31497
31598
|
}
|
|
@@ -31848,7 +31949,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31848
31949
|
formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
|
|
31849
31950
|
externalRefId = Number(externalRefId) - 1;
|
|
31850
31951
|
cellRef = cellRef.replace(/\$/g, "");
|
|
31851
|
-
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name
|
|
31952
|
+
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
|
|
31852
31953
|
if (sheetIndex === -1) {
|
|
31853
31954
|
return match;
|
|
31854
31955
|
}
|
|
@@ -32499,7 +32600,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32499
32600
|
*/
|
|
32500
32601
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
32501
32602
|
for (let tableSheet of convertedSheets) {
|
|
32502
|
-
const tables = xlsxSheets.find((s) => s.sheetName
|
|
32603
|
+
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
32503
32604
|
for (let table of tables) {
|
|
32504
32605
|
const tabRef = table.name + "[";
|
|
32505
32606
|
for (let sheet of convertedSheets) {
|
|
@@ -34848,6 +34949,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34848
34949
|
initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
|
|
34849
34950
|
initialMessages = fixChartDefinitions(data, initialMessages);
|
|
34850
34951
|
initialMessages = fixFigureOffset(data, initialMessages);
|
|
34952
|
+
initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
|
|
34851
34953
|
return initialMessages;
|
|
34852
34954
|
}
|
|
34853
34955
|
/**
|
|
@@ -34980,6 +35082,42 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34980
35082
|
}
|
|
34981
35083
|
return messages;
|
|
34982
35084
|
}
|
|
35085
|
+
function fixTranslatedDuplicateSheetName(data, initialMessages) {
|
|
35086
|
+
const sheetNames = {};
|
|
35087
|
+
for (const sheet of data.sheets || []) {
|
|
35088
|
+
sheetNames[sheet.id] = sheet.name;
|
|
35089
|
+
}
|
|
35090
|
+
const messages = [];
|
|
35091
|
+
for (const message of initialMessages) {
|
|
35092
|
+
if (message.type === "REMOTE_REVISION") {
|
|
35093
|
+
const commands = [];
|
|
35094
|
+
for (const cmd of message.commands) {
|
|
35095
|
+
switch (cmd.type) {
|
|
35096
|
+
case "DUPLICATE_SHEET":
|
|
35097
|
+
cmd.sheetNameTo =
|
|
35098
|
+
cmd.sheetNameTo ??
|
|
35099
|
+
getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
|
|
35100
|
+
break;
|
|
35101
|
+
case "CREATE_SHEET":
|
|
35102
|
+
sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
|
|
35103
|
+
break;
|
|
35104
|
+
case "RENAME_SHEET":
|
|
35105
|
+
sheetNames[cmd.sheetId] = cmd.newName || getNextSheetName(Object.values(sheetNames));
|
|
35106
|
+
break;
|
|
35107
|
+
}
|
|
35108
|
+
commands.push(cmd);
|
|
35109
|
+
}
|
|
35110
|
+
messages.push({
|
|
35111
|
+
...message,
|
|
35112
|
+
commands,
|
|
35113
|
+
});
|
|
35114
|
+
}
|
|
35115
|
+
else {
|
|
35116
|
+
messages.push(message);
|
|
35117
|
+
}
|
|
35118
|
+
}
|
|
35119
|
+
return initialMessages;
|
|
35120
|
+
}
|
|
34983
35121
|
// -----------------------------------------------------------------------------
|
|
34984
35122
|
// Helpers
|
|
34985
35123
|
// -----------------------------------------------------------------------------
|
|
@@ -35117,12 +35255,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35117
35255
|
}
|
|
35118
35256
|
}
|
|
35119
35257
|
hover(position) {
|
|
35258
|
+
if (position.col === this.col && position.row === this.row) {
|
|
35259
|
+
return "noStateChange";
|
|
35260
|
+
}
|
|
35120
35261
|
this.col = position.col;
|
|
35121
35262
|
this.row = position.row;
|
|
35263
|
+
return;
|
|
35122
35264
|
}
|
|
35123
35265
|
clear() {
|
|
35266
|
+
if (this.col === undefined && this.row === undefined) {
|
|
35267
|
+
return "noStateChange";
|
|
35268
|
+
}
|
|
35124
35269
|
this.col = undefined;
|
|
35125
35270
|
this.row = undefined;
|
|
35271
|
+
return;
|
|
35126
35272
|
}
|
|
35127
35273
|
}
|
|
35128
35274
|
|
|
@@ -35144,7 +35290,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35144
35290
|
this.persistentPopover = { col, row, sheetId, type };
|
|
35145
35291
|
}
|
|
35146
35292
|
close() {
|
|
35293
|
+
if (!this.persistentPopover) {
|
|
35294
|
+
return "noStateChange";
|
|
35295
|
+
}
|
|
35147
35296
|
this.persistentPopover = undefined;
|
|
35297
|
+
return;
|
|
35148
35298
|
}
|
|
35149
35299
|
get persistentCellPopover() {
|
|
35150
35300
|
return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
|
|
@@ -36038,10 +36188,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36038
36188
|
name: _t("Duplicate"),
|
|
36039
36189
|
execute: (env) => {
|
|
36040
36190
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
36191
|
+
const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
|
|
36041
36192
|
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
36193
|
+
const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
|
|
36042
36194
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
36043
36195
|
sheetId: sheetIdFrom,
|
|
36044
36196
|
sheetIdTo,
|
|
36197
|
+
sheetNameTo,
|
|
36045
36198
|
});
|
|
36046
36199
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
|
|
36047
36200
|
},
|
|
@@ -40682,7 +40835,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40682
40835
|
const cancelledReasons = [
|
|
40683
40836
|
...(this.state.datasetDispatchResult?.reasons || []),
|
|
40684
40837
|
...(this.state.labelsDispatchResult?.reasons || []),
|
|
40685
|
-
];
|
|
40838
|
+
].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
|
|
40686
40839
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
40687
40840
|
}
|
|
40688
40841
|
get isDatasetInvalid() {
|
|
@@ -42259,10 +42412,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42259
42412
|
}
|
|
42260
42413
|
|
|
42261
42414
|
class DOMFocusableElementStore {
|
|
42262
|
-
mutators = ["setFocusableElement"];
|
|
42415
|
+
mutators = ["setFocusableElement", "focus"];
|
|
42263
42416
|
focusableElement = undefined;
|
|
42264
42417
|
setFocusableElement(element) {
|
|
42265
42418
|
this.focusableElement = element;
|
|
42419
|
+
return "noStateChange";
|
|
42420
|
+
}
|
|
42421
|
+
focus() {
|
|
42422
|
+
if (this.focusableElement === document.activeElement) {
|
|
42423
|
+
return "noStateChange";
|
|
42424
|
+
}
|
|
42425
|
+
this.focusableElement?.focus();
|
|
42426
|
+
return;
|
|
42266
42427
|
}
|
|
42267
42428
|
}
|
|
42268
42429
|
|
|
@@ -42934,7 +43095,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42934
43095
|
if (document.activeElement === this.contentHelper.el &&
|
|
42935
43096
|
this.props.composerStore.editionMode === "inactive" &&
|
|
42936
43097
|
!this.props.isDefaultFocus) {
|
|
42937
|
-
this.DOMFocusableElementStore.
|
|
43098
|
+
this.DOMFocusableElementStore.focus();
|
|
42938
43099
|
}
|
|
42939
43100
|
});
|
|
42940
43101
|
owl.useEffect(() => {
|
|
@@ -43214,6 +43375,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
43214
43375
|
openAssistant() {
|
|
43215
43376
|
this.assistant.forcedClosed = false;
|
|
43216
43377
|
}
|
|
43378
|
+
onWheel(event) {
|
|
43379
|
+
// detect if scrollbar is available
|
|
43380
|
+
if (this.composerRef.el &&
|
|
43381
|
+
this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
|
|
43382
|
+
event.stopPropagation();
|
|
43383
|
+
}
|
|
43384
|
+
}
|
|
43217
43385
|
// ---------------------------------------------------------------------------
|
|
43218
43386
|
// Private
|
|
43219
43387
|
// ---------------------------------------------------------------------------
|
|
@@ -48938,8 +49106,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
48938
49106
|
|
|
48939
49107
|
const NULL_SYMBOL = Symbol("NULL");
|
|
48940
49108
|
function createDate(dimension, value, locale) {
|
|
48941
|
-
const granularity = dimension.granularity;
|
|
48942
|
-
if (!
|
|
49109
|
+
const granularity = dimension.granularity || "month";
|
|
49110
|
+
if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
|
|
48943
49111
|
throw new Error(`Unknown date granularity: ${granularity}`);
|
|
48944
49112
|
}
|
|
48945
49113
|
const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
|
|
@@ -48958,6 +49126,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
48958
49126
|
case "month_number":
|
|
48959
49127
|
number = date.getMonth() + 1;
|
|
48960
49128
|
break;
|
|
49129
|
+
case "month":
|
|
49130
|
+
number = Math.floor(toNumber(value, locale));
|
|
49131
|
+
break;
|
|
48961
49132
|
case "iso_week_number":
|
|
48962
49133
|
number = date.getIsoWeek();
|
|
48963
49134
|
break;
|
|
@@ -49051,6 +49222,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49051
49222
|
set: new Set(),
|
|
49052
49223
|
values: {},
|
|
49053
49224
|
},
|
|
49225
|
+
month: {
|
|
49226
|
+
set: new Set(),
|
|
49227
|
+
values: {},
|
|
49228
|
+
},
|
|
49054
49229
|
iso_week_number: {
|
|
49055
49230
|
set: new Set(),
|
|
49056
49231
|
values: {},
|
|
@@ -49261,7 +49436,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49261
49436
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
49262
49437
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
49263
49438
|
if (dimension.type === "datetime") {
|
|
49264
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
49439
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
49265
49440
|
return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
|
|
49266
49441
|
}
|
|
49267
49442
|
if (!finalCell) {
|
|
@@ -49379,7 +49554,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49379
49554
|
if (nonEmptyCells.length === 0) {
|
|
49380
49555
|
return "integer";
|
|
49381
49556
|
}
|
|
49382
|
-
if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
|
|
49557
|
+
if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
|
|
49383
49558
|
return "datetime";
|
|
49384
49559
|
}
|
|
49385
49560
|
if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
|
|
@@ -49458,7 +49633,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49458
49633
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
49459
49634
|
}
|
|
49460
49635
|
else {
|
|
49461
|
-
|
|
49636
|
+
if (field.type === "char") {
|
|
49637
|
+
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
49638
|
+
}
|
|
49639
|
+
else {
|
|
49640
|
+
entry[field.name] = cell;
|
|
49641
|
+
}
|
|
49462
49642
|
}
|
|
49463
49643
|
}
|
|
49464
49644
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -49472,7 +49652,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49472
49652
|
for (const entry of dataEntries) {
|
|
49473
49653
|
for (const dimension of dateDimensions) {
|
|
49474
49654
|
const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
|
|
49475
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
49655
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
49476
49656
|
const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
|
|
49477
49657
|
entry[dimension.nameWithGranularity] = {
|
|
49478
49658
|
value,
|
|
@@ -49492,6 +49672,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49492
49672
|
"year",
|
|
49493
49673
|
"quarter_number",
|
|
49494
49674
|
"month_number",
|
|
49675
|
+
"month",
|
|
49495
49676
|
"iso_week_number",
|
|
49496
49677
|
"day_of_month",
|
|
49497
49678
|
"day",
|
|
@@ -49742,7 +49923,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49742
49923
|
: this.datetimeGranularities);
|
|
49743
49924
|
}
|
|
49744
49925
|
for (const field of dateFields) {
|
|
49745
|
-
granularitiesPerFields[field.fieldName].delete(field.granularity);
|
|
49926
|
+
granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
|
|
49746
49927
|
}
|
|
49747
49928
|
return granularitiesPerFields;
|
|
49748
49929
|
}
|
|
@@ -52082,6 +52263,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52082
52263
|
}
|
|
52083
52264
|
get composerProps() {
|
|
52084
52265
|
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
52266
|
+
// Remove the wrapper border width
|
|
52267
|
+
const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
|
|
52085
52268
|
return {
|
|
52086
52269
|
rect: { ...this.rect },
|
|
52087
52270
|
delimitation: {
|
|
@@ -52099,6 +52282,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52099
52282
|
}),
|
|
52100
52283
|
onInputContextMenu: this.props.onInputContextMenu,
|
|
52101
52284
|
composerStore: this.composerStore,
|
|
52285
|
+
inputStyle: `max-height: ${maxHeight}px;`,
|
|
52102
52286
|
};
|
|
52103
52287
|
}
|
|
52104
52288
|
get containerStyle() {
|
|
@@ -53179,9 +53363,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53179
53363
|
}
|
|
53180
53364
|
}
|
|
53181
53365
|
hover(position) {
|
|
53366
|
+
if (position.col === this.col && position.row === this.row) {
|
|
53367
|
+
return "noStateChange";
|
|
53368
|
+
}
|
|
53182
53369
|
this.col = position.col;
|
|
53183
53370
|
this.row = position.row;
|
|
53184
53371
|
this.computeOverlay();
|
|
53372
|
+
return;
|
|
53185
53373
|
}
|
|
53186
53374
|
clear() {
|
|
53187
53375
|
this.col = undefined;
|
|
@@ -54813,10 +55001,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54813
55001
|
ctx.scale(dpr, dpr);
|
|
54814
55002
|
for (const layer of OrderedLayers()) {
|
|
54815
55003
|
model.drawLayer(renderingContext, layer);
|
|
54816
|
-
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
54817
|
-
// it does not mutate anything. Most importantly it's used
|
|
54818
|
-
// during rendering. Invoking a mutator during rendering would
|
|
54819
|
-
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
54820
55004
|
rendererStore.drawLayer(renderingContext, layer);
|
|
54821
55005
|
}
|
|
54822
55006
|
}
|
|
@@ -55510,7 +55694,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55510
55694
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
55511
55695
|
owl.useEffect(() => {
|
|
55512
55696
|
if (!this.sidePanel.isOpen) {
|
|
55513
|
-
this.DOMFocusableElementStore.
|
|
55697
|
+
this.DOMFocusableElementStore.focus();
|
|
55514
55698
|
}
|
|
55515
55699
|
}, () => [this.sidePanel.isOpen]);
|
|
55516
55700
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
@@ -55719,7 +55903,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55719
55903
|
focusDefaultElement() {
|
|
55720
55904
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
55721
55905
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
55722
|
-
this.DOMFocusableElementStore.
|
|
55906
|
+
this.DOMFocusableElementStore.focus();
|
|
55723
55907
|
}
|
|
55724
55908
|
}
|
|
55725
55909
|
get gridEl() {
|
|
@@ -56068,6 +56252,322 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56068
56252
|
}
|
|
56069
56253
|
}
|
|
56070
56254
|
|
|
56255
|
+
css /* scss */ `
|
|
56256
|
+
.o_pivot_html_renderer {
|
|
56257
|
+
width: 100%;
|
|
56258
|
+
border-collapse: collapse;
|
|
56259
|
+
|
|
56260
|
+
&:hover {
|
|
56261
|
+
cursor: pointer;
|
|
56262
|
+
}
|
|
56263
|
+
|
|
56264
|
+
td,
|
|
56265
|
+
th {
|
|
56266
|
+
border: 1px solid #dee2e6;
|
|
56267
|
+
background-color: #fff;
|
|
56268
|
+
padding: 0.3rem;
|
|
56269
|
+
white-space: nowrap;
|
|
56270
|
+
|
|
56271
|
+
&:hover {
|
|
56272
|
+
filter: brightness(0.9);
|
|
56273
|
+
}
|
|
56274
|
+
}
|
|
56275
|
+
|
|
56276
|
+
td {
|
|
56277
|
+
text-align: right;
|
|
56278
|
+
}
|
|
56279
|
+
|
|
56280
|
+
th {
|
|
56281
|
+
background-color: #f5f5f5;
|
|
56282
|
+
font-weight: bold;
|
|
56283
|
+
color: black;
|
|
56284
|
+
}
|
|
56285
|
+
|
|
56286
|
+
.o_missing_value {
|
|
56287
|
+
color: #46646d;
|
|
56288
|
+
background: #e7f2f6;
|
|
56289
|
+
}
|
|
56290
|
+
}
|
|
56291
|
+
`;
|
|
56292
|
+
class PivotHTMLRenderer extends owl.Component {
|
|
56293
|
+
static template = "o_spreadsheet.PivotHTMLRenderer";
|
|
56294
|
+
static components = { Checkbox };
|
|
56295
|
+
static props = {
|
|
56296
|
+
pivotId: String,
|
|
56297
|
+
onCellClicked: Function,
|
|
56298
|
+
};
|
|
56299
|
+
pivot = this.env.model.getters.getPivot(this.props.pivotId);
|
|
56300
|
+
data = {
|
|
56301
|
+
columns: [],
|
|
56302
|
+
rows: [],
|
|
56303
|
+
values: [],
|
|
56304
|
+
};
|
|
56305
|
+
state = owl.useState({
|
|
56306
|
+
showMissingValuesOnly: false,
|
|
56307
|
+
});
|
|
56308
|
+
setup() {
|
|
56309
|
+
const table = this.pivot.getTableStructure();
|
|
56310
|
+
const formulaId = this.env.model.getters.getPivotFormulaId(this.props.pivotId);
|
|
56311
|
+
this.data = {
|
|
56312
|
+
columns: this._buildColHeaders(formulaId, table),
|
|
56313
|
+
rows: this._buildRowHeaders(formulaId, table),
|
|
56314
|
+
values: this._buildValues(formulaId, table),
|
|
56315
|
+
};
|
|
56316
|
+
}
|
|
56317
|
+
get tracker() {
|
|
56318
|
+
return this.env.model.getters.getPivotPresenceTracker(this.props.pivotId);
|
|
56319
|
+
}
|
|
56320
|
+
// ---------------------------------------------------------------------
|
|
56321
|
+
// Missing values building
|
|
56322
|
+
// ---------------------------------------------------------------------
|
|
56323
|
+
/**
|
|
56324
|
+
* Retrieve the data to display in the Pivot Table
|
|
56325
|
+
* In the case when showMissingValuesOnly is false, the returned value
|
|
56326
|
+
* is the complete data
|
|
56327
|
+
* In the case when showMissingValuesOnly is true, the returned value is
|
|
56328
|
+
* the data which contains only missing values in the rows and cols. In
|
|
56329
|
+
* the rows, we also return the parent rows of rows which contains missing
|
|
56330
|
+
* values, to give context to the user.
|
|
56331
|
+
*
|
|
56332
|
+
*/
|
|
56333
|
+
getTableData() {
|
|
56334
|
+
if (!this.state.showMissingValuesOnly) {
|
|
56335
|
+
return this.data;
|
|
56336
|
+
}
|
|
56337
|
+
const colIndexes = this.getColumnsIndexes();
|
|
56338
|
+
const rowIndexes = this.getRowsIndexes();
|
|
56339
|
+
const columns = this.buildColumnsMissing(colIndexes);
|
|
56340
|
+
const rows = this.buildRowsMissing(rowIndexes);
|
|
56341
|
+
const values = this.buildValuesMissing(colIndexes, rowIndexes);
|
|
56342
|
+
return { columns, rows, values };
|
|
56343
|
+
}
|
|
56344
|
+
/**
|
|
56345
|
+
* Retrieve the parents of the given row
|
|
56346
|
+
* ex:
|
|
56347
|
+
* Australia
|
|
56348
|
+
* January
|
|
56349
|
+
* February
|
|
56350
|
+
* The parent of "January" is "Australia"
|
|
56351
|
+
*/
|
|
56352
|
+
addRecursiveRow(index) {
|
|
56353
|
+
const rows = this.pivot.getTableStructure().rows;
|
|
56354
|
+
const row = [...rows[index].values];
|
|
56355
|
+
if (row.length <= 1) {
|
|
56356
|
+
return [index];
|
|
56357
|
+
}
|
|
56358
|
+
row.pop();
|
|
56359
|
+
const parentRowIndex = rows.findIndex((r) => JSON.stringify(r.values) === JSON.stringify(row));
|
|
56360
|
+
return [index].concat(this.addRecursiveRow(parentRowIndex));
|
|
56361
|
+
}
|
|
56362
|
+
/**
|
|
56363
|
+
* Create the columns to be used, based on the indexes of the columns in
|
|
56364
|
+
* which a missing value is present
|
|
56365
|
+
*
|
|
56366
|
+
*/
|
|
56367
|
+
buildColumnsMissing(indexes) {
|
|
56368
|
+
// columnsMap explode the columns in an array of array of the same
|
|
56369
|
+
// size with the index of each column, repeated 'span' times.
|
|
56370
|
+
// ex:
|
|
56371
|
+
// | A | B |
|
|
56372
|
+
// | 1 | 2 | 3 |
|
|
56373
|
+
// => [
|
|
56374
|
+
// [0, 0, 1]
|
|
56375
|
+
// [0, 1, 2]
|
|
56376
|
+
// ]
|
|
56377
|
+
const columnsMap = [];
|
|
56378
|
+
for (const column of this.data.columns) {
|
|
56379
|
+
const columnMap = [];
|
|
56380
|
+
for (const index in column) {
|
|
56381
|
+
for (let i = 0; i < column[index].span; i++) {
|
|
56382
|
+
columnMap.push(parseInt(index, 10));
|
|
56383
|
+
}
|
|
56384
|
+
}
|
|
56385
|
+
columnsMap.push(columnMap);
|
|
56386
|
+
}
|
|
56387
|
+
// Remove the columns that are not present in indexes
|
|
56388
|
+
for (let i = columnsMap[columnsMap.length - 1].length; i >= 0; i--) {
|
|
56389
|
+
if (!indexes.includes(i)) {
|
|
56390
|
+
for (const columnMap of columnsMap) {
|
|
56391
|
+
columnMap.splice(i, 1);
|
|
56392
|
+
}
|
|
56393
|
+
}
|
|
56394
|
+
}
|
|
56395
|
+
// Build the columns
|
|
56396
|
+
const columns = [];
|
|
56397
|
+
for (const mapIndex in columnsMap) {
|
|
56398
|
+
const column = [];
|
|
56399
|
+
let index = undefined;
|
|
56400
|
+
let span = 1;
|
|
56401
|
+
for (let i = 0; i < columnsMap[mapIndex].length; i++) {
|
|
56402
|
+
if (index !== columnsMap[mapIndex][i]) {
|
|
56403
|
+
if (index !== undefined) {
|
|
56404
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
56405
|
+
}
|
|
56406
|
+
index = columnsMap[mapIndex][i];
|
|
56407
|
+
span = 1;
|
|
56408
|
+
}
|
|
56409
|
+
else {
|
|
56410
|
+
span++;
|
|
56411
|
+
}
|
|
56412
|
+
}
|
|
56413
|
+
if (index !== undefined) {
|
|
56414
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
56415
|
+
}
|
|
56416
|
+
columns.push(column);
|
|
56417
|
+
}
|
|
56418
|
+
return columns;
|
|
56419
|
+
}
|
|
56420
|
+
/**
|
|
56421
|
+
* Create the rows to be used, based on the indexes of the rows in
|
|
56422
|
+
* which a missing value is present.
|
|
56423
|
+
*/
|
|
56424
|
+
buildRowsMissing(indexes) {
|
|
56425
|
+
return indexes.map((index) => this.data.rows[index]);
|
|
56426
|
+
}
|
|
56427
|
+
/**
|
|
56428
|
+
* Create the value to be used, based on the indexes of the columns and
|
|
56429
|
+
* rows in which a missing value is present.
|
|
56430
|
+
*/
|
|
56431
|
+
buildValuesMissing(colIndexes, rowIndexes) {
|
|
56432
|
+
const values = colIndexes.map(() => []);
|
|
56433
|
+
for (const row of rowIndexes) {
|
|
56434
|
+
for (const col in colIndexes) {
|
|
56435
|
+
values[col].push(this.data.values[colIndexes[col]][row]);
|
|
56436
|
+
}
|
|
56437
|
+
}
|
|
56438
|
+
return values;
|
|
56439
|
+
}
|
|
56440
|
+
getColumnsIndexes() {
|
|
56441
|
+
const indexes = new Set();
|
|
56442
|
+
for (let i = 0; i < this.data.columns.length; i++) {
|
|
56443
|
+
const exploded = [];
|
|
56444
|
+
for (let y = 0; y < this.data.columns[i].length; y++) {
|
|
56445
|
+
for (let x = 0; x < this.data.columns[i][y].span; x++) {
|
|
56446
|
+
exploded.push(this.data.columns[i][y]);
|
|
56447
|
+
}
|
|
56448
|
+
}
|
|
56449
|
+
for (let y = 0; y < exploded.length; y++) {
|
|
56450
|
+
if (exploded[y].isMissing) {
|
|
56451
|
+
indexes.add(y);
|
|
56452
|
+
}
|
|
56453
|
+
}
|
|
56454
|
+
}
|
|
56455
|
+
for (let i = 0; i < this.data.columns[this.data.columns.length - 1].length; i++) {
|
|
56456
|
+
const values = this.data.values[i];
|
|
56457
|
+
if (values.find((x) => x.isMissing)) {
|
|
56458
|
+
indexes.add(i);
|
|
56459
|
+
}
|
|
56460
|
+
}
|
|
56461
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
56462
|
+
}
|
|
56463
|
+
getRowsIndexes() {
|
|
56464
|
+
const rowIndexes = new Set();
|
|
56465
|
+
for (let i = 0; i < this.data.rows.length; i++) {
|
|
56466
|
+
if (this.data.rows[i].isMissing) {
|
|
56467
|
+
rowIndexes.add(i);
|
|
56468
|
+
}
|
|
56469
|
+
for (const col of this.data.values) {
|
|
56470
|
+
if (col[i].isMissing) {
|
|
56471
|
+
this.addRecursiveRow(i).forEach((x) => rowIndexes.add(x));
|
|
56472
|
+
}
|
|
56473
|
+
}
|
|
56474
|
+
}
|
|
56475
|
+
return Array.from(rowIndexes).sort((a, b) => a - b);
|
|
56476
|
+
}
|
|
56477
|
+
// ---------------------------------------------------------------------
|
|
56478
|
+
// Data table creation
|
|
56479
|
+
// ---------------------------------------------------------------------
|
|
56480
|
+
_buildColHeaders(id, table) {
|
|
56481
|
+
const headers = [];
|
|
56482
|
+
for (const row of table.columns) {
|
|
56483
|
+
const current = [];
|
|
56484
|
+
for (const cell of row) {
|
|
56485
|
+
const args = [];
|
|
56486
|
+
for (let i = 0; i < cell.fields.length; i++) {
|
|
56487
|
+
args.push({ value: cell.fields[i] }, { value: cell.values[i] });
|
|
56488
|
+
}
|
|
56489
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56490
|
+
const locale = this.env.model.getters.getLocale();
|
|
56491
|
+
if (domain.at(-1)?.field === "measure") {
|
|
56492
|
+
const { value, format } = this.pivot.getPivotMeasureValue(toString(domain.at(-1).value), domain);
|
|
56493
|
+
current.push({
|
|
56494
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56495
|
+
value: formatValue(value, { format, locale }),
|
|
56496
|
+
span: cell.width,
|
|
56497
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56498
|
+
});
|
|
56499
|
+
}
|
|
56500
|
+
else {
|
|
56501
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
56502
|
+
current.push({
|
|
56503
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56504
|
+
value: formatValue(value, { format, locale }),
|
|
56505
|
+
span: cell.width,
|
|
56506
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56507
|
+
});
|
|
56508
|
+
}
|
|
56509
|
+
}
|
|
56510
|
+
headers.push(current);
|
|
56511
|
+
}
|
|
56512
|
+
const last = headers[headers.length - 1];
|
|
56513
|
+
headers[headers.length - 1] = last.map((cell) => {
|
|
56514
|
+
if (!cell.isMissing) {
|
|
56515
|
+
cell.style = "color: #756f6f;";
|
|
56516
|
+
}
|
|
56517
|
+
return cell;
|
|
56518
|
+
});
|
|
56519
|
+
return headers;
|
|
56520
|
+
}
|
|
56521
|
+
_buildRowHeaders(id, table) {
|
|
56522
|
+
const headers = [];
|
|
56523
|
+
for (const row of table.rows) {
|
|
56524
|
+
const args = [];
|
|
56525
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
56526
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
56527
|
+
}
|
|
56528
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56529
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
56530
|
+
const locale = this.env.model.getters.getLocale();
|
|
56531
|
+
const cell = {
|
|
56532
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56533
|
+
value: formatValue(value, { format, locale }),
|
|
56534
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56535
|
+
};
|
|
56536
|
+
if (row.indent > 1) {
|
|
56537
|
+
cell.style = `padding-left: ${row.indent - 1 * 10}px`;
|
|
56538
|
+
}
|
|
56539
|
+
headers.push(cell);
|
|
56540
|
+
}
|
|
56541
|
+
return headers;
|
|
56542
|
+
}
|
|
56543
|
+
_buildValues(id, table) {
|
|
56544
|
+
const values = [];
|
|
56545
|
+
for (const col of table.columns.at(-1) || []) {
|
|
56546
|
+
const current = [];
|
|
56547
|
+
const measure = toString(col.values[col.values.length - 1]);
|
|
56548
|
+
for (const row of table.rows) {
|
|
56549
|
+
const args = [];
|
|
56550
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
56551
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
56552
|
+
}
|
|
56553
|
+
for (let i = 0; i < col.fields.length - 1; i++) {
|
|
56554
|
+
args.push({ value: col.fields[i] }, { value: col.values[i] });
|
|
56555
|
+
}
|
|
56556
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56557
|
+
const { value, format } = this.pivot.getPivotCellValueAndFormat(measure, domain);
|
|
56558
|
+
const locale = this.env.model.getters.getLocale();
|
|
56559
|
+
current.push({
|
|
56560
|
+
formula: `=PIVOT.VALUE(${generatePivotArgs(id, domain, measure).join(",")})`,
|
|
56561
|
+
value: formatValue(value, { format, locale }),
|
|
56562
|
+
isMissing: !this.tracker?.isValuePresent(measure, domain),
|
|
56563
|
+
});
|
|
56564
|
+
}
|
|
56565
|
+
values.push(current);
|
|
56566
|
+
}
|
|
56567
|
+
return values;
|
|
56568
|
+
}
|
|
56569
|
+
}
|
|
56570
|
+
|
|
56071
56571
|
/**
|
|
56072
56572
|
* BasePlugin
|
|
56073
56573
|
*
|
|
@@ -57420,7 +57920,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57420
57920
|
case "CREATE_CHART":
|
|
57421
57921
|
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartDuplicate));
|
|
57422
57922
|
case "UPDATE_CHART":
|
|
57423
|
-
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists));
|
|
57923
|
+
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists, this.checkChartChanged));
|
|
57424
57924
|
default:
|
|
57425
57925
|
return "Success" /* CommandResult.Success */;
|
|
57426
57926
|
}
|
|
@@ -57574,10 +58074,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57574
58074
|
: "Success" /* CommandResult.Success */;
|
|
57575
58075
|
}
|
|
57576
58076
|
checkChartExists(cmd) {
|
|
57577
|
-
return this.
|
|
58077
|
+
return this.isChartDefined(cmd.figureId)
|
|
57578
58078
|
? "Success" /* CommandResult.Success */
|
|
57579
58079
|
: "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
|
|
57580
58080
|
}
|
|
58081
|
+
checkChartChanged(cmd) {
|
|
58082
|
+
return deepEquals(this.getChartDefinition(cmd.figureId), cmd.definition)
|
|
58083
|
+
? "NoChanges" /* CommandResult.NoChanges */
|
|
58084
|
+
: "Success" /* CommandResult.Success */;
|
|
58085
|
+
}
|
|
57581
58086
|
}
|
|
57582
58087
|
|
|
57583
58088
|
// -----------------------------------------------------------------------------
|
|
@@ -59835,6 +60340,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59835
60340
|
"getCommandZones",
|
|
59836
60341
|
"getUnboundedZone",
|
|
59837
60342
|
"checkElementsIncludeAllNonFrozenHeaders",
|
|
60343
|
+
"getDuplicateSheetName",
|
|
59838
60344
|
];
|
|
59839
60345
|
sheetIdsMapName = {};
|
|
59840
60346
|
orderedSheetIds = [];
|
|
@@ -59859,7 +60365,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59859
60365
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
59860
60366
|
}
|
|
59861
60367
|
case "DUPLICATE_SHEET": {
|
|
59862
|
-
|
|
60368
|
+
if (this.sheets[cmd.sheetIdTo])
|
|
60369
|
+
return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
|
|
60370
|
+
if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
|
|
60371
|
+
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
60372
|
+
return "Success" /* CommandResult.Success */;
|
|
59863
60373
|
}
|
|
59864
60374
|
case "MOVE_SHEET":
|
|
59865
60375
|
try {
|
|
@@ -59936,7 +60446,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59936
60446
|
this.showSheet(cmd.sheetId);
|
|
59937
60447
|
break;
|
|
59938
60448
|
case "DUPLICATE_SHEET":
|
|
59939
|
-
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
|
|
60449
|
+
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
|
|
59940
60450
|
break;
|
|
59941
60451
|
case "DELETE_SHEET":
|
|
59942
60452
|
this.deleteSheet(this.sheets[cmd.sheetId]);
|
|
@@ -60077,7 +60587,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60077
60587
|
if (name) {
|
|
60078
60588
|
const unquotedName = getUnquotedSheetName(name);
|
|
60079
60589
|
for (const key in this.sheetIdsMapName) {
|
|
60080
|
-
if (key
|
|
60590
|
+
if (isSheetNameEqual(key, unquotedName)) {
|
|
60081
60591
|
return this.sheetIdsMapName[key];
|
|
60082
60592
|
}
|
|
60083
60593
|
}
|
|
@@ -60143,10 +60653,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60143
60653
|
}
|
|
60144
60654
|
getNextSheetName(baseName = "Sheet") {
|
|
60145
60655
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
60146
|
-
return
|
|
60147
|
-
compute: (name, i) => `${name}${i}`,
|
|
60148
|
-
computeFirstOne: true,
|
|
60149
|
-
});
|
|
60656
|
+
return getNextSheetName(names, baseName);
|
|
60150
60657
|
}
|
|
60151
60658
|
getSheetSize(sheetId) {
|
|
60152
60659
|
return {
|
|
@@ -60329,7 +60836,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60329
60836
|
}
|
|
60330
60837
|
const { orderedSheetIds, sheets } = this;
|
|
60331
60838
|
const name = sheetName && sheetName.trim().toLowerCase();
|
|
60332
|
-
if (orderedSheetIds.find((id) => sheets[id]?.name
|
|
60839
|
+
if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
|
|
60333
60840
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
60334
60841
|
}
|
|
60335
60842
|
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
@@ -60393,9 +60900,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60393
60900
|
showSheet(sheetId) {
|
|
60394
60901
|
this.history.update("sheets", sheetId, "isVisible", true);
|
|
60395
60902
|
}
|
|
60396
|
-
duplicateSheet(fromId, toId) {
|
|
60903
|
+
duplicateSheet(fromId, toId, toName) {
|
|
60397
60904
|
const sheet = this.getSheet(fromId);
|
|
60398
|
-
const toName = this.getDuplicateSheetName(sheet.name);
|
|
60399
60905
|
const newSheet = deepCopy(sheet);
|
|
60400
60906
|
newSheet.id = toId;
|
|
60401
60907
|
newSheet.name = toName;
|
|
@@ -60428,8 +60934,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60428
60934
|
}
|
|
60429
60935
|
getDuplicateSheetName(sheetName) {
|
|
60430
60936
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
60431
|
-
|
|
60432
|
-
return getUniqueText(baseName.toString(), names);
|
|
60937
|
+
return getDuplicateSheetName(sheetName, names);
|
|
60433
60938
|
}
|
|
60434
60939
|
deleteSheet(sheet) {
|
|
60435
60940
|
const name = sheet.name;
|
|
@@ -63233,8 +63738,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63233
63738
|
const EMPTY_ARRAY = [];
|
|
63234
63739
|
|
|
63235
63740
|
const MAX_ITERATION = 30;
|
|
63236
|
-
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
63237
|
-
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
63741
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
63742
|
+
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
63238
63743
|
class Evaluator {
|
|
63239
63744
|
context;
|
|
63240
63745
|
getters;
|
|
@@ -69415,6 +69920,55 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69415
69920
|
}
|
|
69416
69921
|
}
|
|
69417
69922
|
|
|
69923
|
+
class PivotPresenceTracker {
|
|
69924
|
+
trackedValues = new Set();
|
|
69925
|
+
domainToArray(domain) {
|
|
69926
|
+
return domain.flatMap((node) => [node.field, toString(node.value)]);
|
|
69927
|
+
}
|
|
69928
|
+
isValuePresent(measure, domain) {
|
|
69929
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
69930
|
+
return this.trackedValues.has(key);
|
|
69931
|
+
}
|
|
69932
|
+
isHeaderPresent(domain) {
|
|
69933
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
69934
|
+
return this.trackedValues.has(key);
|
|
69935
|
+
}
|
|
69936
|
+
trackValue(measure, domain) {
|
|
69937
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
69938
|
+
this.trackedValues.add(key);
|
|
69939
|
+
}
|
|
69940
|
+
trackHeader(domain) {
|
|
69941
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
69942
|
+
this.trackedValues.add(key);
|
|
69943
|
+
}
|
|
69944
|
+
}
|
|
69945
|
+
|
|
69946
|
+
class PivotPresencePlugin extends UIPlugin {
|
|
69947
|
+
static getters = ["getPivotPresenceTracker"];
|
|
69948
|
+
trackPresencePivotId;
|
|
69949
|
+
tracker;
|
|
69950
|
+
handle(cmd) {
|
|
69951
|
+
switch (cmd.type) {
|
|
69952
|
+
case "PIVOT_START_PRESENCE_TRACKING":
|
|
69953
|
+
this.tracker = new PivotPresenceTracker();
|
|
69954
|
+
this.trackPresencePivotId = cmd.pivotId;
|
|
69955
|
+
break;
|
|
69956
|
+
case "PIVOT_STOP_PRESENCE_TRACKING":
|
|
69957
|
+
this.trackPresencePivotId = undefined;
|
|
69958
|
+
break;
|
|
69959
|
+
}
|
|
69960
|
+
}
|
|
69961
|
+
getPivotPresenceTracker(pivotId) {
|
|
69962
|
+
if (this.trackPresencePivotId !== pivotId) {
|
|
69963
|
+
return undefined;
|
|
69964
|
+
}
|
|
69965
|
+
if (!this.tracker) {
|
|
69966
|
+
throw new Error("Tracker not initialized");
|
|
69967
|
+
}
|
|
69968
|
+
return this.tracker;
|
|
69969
|
+
}
|
|
69970
|
+
}
|
|
69971
|
+
|
|
69418
69972
|
class SplitToColumnsPlugin extends UIPlugin {
|
|
69419
69973
|
static getters = ["getAutomaticSeparator"];
|
|
69420
69974
|
allowDispatch(cmd) {
|
|
@@ -72383,6 +72937,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72383
72937
|
.add("automatic_sum", AutomaticSumPlugin)
|
|
72384
72938
|
.add("format", FormatPlugin)
|
|
72385
72939
|
.add("insert_pivot", InsertPivotPlugin)
|
|
72940
|
+
.add("pivot_presence", PivotPresencePlugin)
|
|
72386
72941
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
72387
72942
|
.add("collaborative", CollaborativePlugin)
|
|
72388
72943
|
.add("history", HistoryPlugin)
|
|
@@ -72772,11 +73327,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72772
73327
|
if (ev.key === "Enter") {
|
|
72773
73328
|
ev.preventDefault();
|
|
72774
73329
|
this.stopEdition();
|
|
72775
|
-
this.DOMFocusableElementStore.
|
|
73330
|
+
this.DOMFocusableElementStore.focus();
|
|
72776
73331
|
}
|
|
72777
73332
|
if (ev.key === "Escape") {
|
|
72778
73333
|
this.cancelEdition();
|
|
72779
|
-
this.DOMFocusableElementStore.
|
|
73334
|
+
this.DOMFocusableElementStore.focus();
|
|
72780
73335
|
}
|
|
72781
73336
|
}
|
|
72782
73337
|
onMouseEventSheetName(ev) {
|
|
@@ -75337,11 +75892,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
75337
75892
|
this.checkViewportSize();
|
|
75338
75893
|
stores.on("store-updated", this, render);
|
|
75339
75894
|
resizeObserver.observe(this.spreadsheetRef.el);
|
|
75895
|
+
registerChartJSExtensions();
|
|
75340
75896
|
});
|
|
75341
75897
|
owl.onWillUnmount(() => {
|
|
75342
75898
|
this.unbindModelEvents();
|
|
75343
75899
|
stores.off("store-updated", this);
|
|
75344
75900
|
resizeObserver.disconnect();
|
|
75901
|
+
unregisterChartJsExtensions();
|
|
75345
75902
|
});
|
|
75346
75903
|
owl.onPatched(() => {
|
|
75347
75904
|
this.checkViewportSize();
|
|
@@ -79783,6 +80340,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79783
80340
|
PivotDimensionOrder,
|
|
79784
80341
|
PivotDimension,
|
|
79785
80342
|
PivotLayoutConfigurator,
|
|
80343
|
+
PivotHTMLRenderer,
|
|
79786
80344
|
PivotDeferUpdate,
|
|
79787
80345
|
PivotTitleSection,
|
|
79788
80346
|
CogWheelMenu,
|
|
@@ -79880,9 +80438,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79880
80438
|
exports.tokenize = tokenize;
|
|
79881
80439
|
|
|
79882
80440
|
|
|
79883
|
-
__info__.version = "18.3.
|
|
79884
|
-
__info__.date = "2025-05-
|
|
79885
|
-
__info__.hash = "
|
|
80441
|
+
__info__.version = "18.3.3";
|
|
80442
|
+
__info__.date = "2025-05-13T17:54:43.312Z";
|
|
80443
|
+
__info__.hash = "b79924a";
|
|
79886
80444
|
|
|
79887
80445
|
|
|
79888
80446
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|