@odoo/o-spreadsheet 19.1.0-alpha.2 → 19.1.0-alpha.4
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 +173 -122
- package/dist/o-spreadsheet.d.ts +215 -152
- package/dist/o-spreadsheet.esm.js +173 -122
- package/dist/o-spreadsheet.iife.js +173 -122
- package/dist/o-spreadsheet.iife.min.js +311 -311
- package/dist/o_spreadsheet.xml +62 -18
- package/package.json +9 -7
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.1.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.1.0-alpha.4
|
|
6
|
+
* @date 2025-10-07T10:03:20.917Z
|
|
7
|
+
* @hash b7cfed8
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -592,7 +592,6 @@
|
|
|
592
592
|
const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
|
|
593
593
|
const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
|
|
594
594
|
const TEXT_HEADER_COLOR = "#666666";
|
|
595
|
-
const FIGURE_BORDER_COLOR = "#c9ccd2";
|
|
596
595
|
const SELECTION_BORDER_COLOR = "#3266ca";
|
|
597
596
|
const HEADER_BORDER_COLOR = "#C0C0C0";
|
|
598
597
|
const CELL_BORDER_COLOR = "#E2E3E3";
|
|
@@ -600,7 +599,6 @@
|
|
|
600
599
|
const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
|
|
601
600
|
const LINK_COLOR = HIGHLIGHT_COLOR;
|
|
602
601
|
const FILTERS_COLOR = "#188038";
|
|
603
|
-
const HEADER_GROUPING_BORDER_COLOR = "#999";
|
|
604
602
|
const FROZEN_PANE_HEADER_BORDER_COLOR = "#BCBCBC";
|
|
605
603
|
const FROZEN_PANE_BORDER_COLOR = "#DADFE8";
|
|
606
604
|
const COMPOSER_ASSISTANT_COLOR = "#9B359B";
|
|
@@ -843,22 +841,6 @@
|
|
|
843
841
|
// Miscellaneous
|
|
844
842
|
//------------------------------------------------------------------------------
|
|
845
843
|
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
846
|
-
/**
|
|
847
|
-
* Remove quotes from a quoted string
|
|
848
|
-
* ```js
|
|
849
|
-
* removeStringQuotes('"Hello"')
|
|
850
|
-
* > 'Hello'
|
|
851
|
-
* ```
|
|
852
|
-
*/
|
|
853
|
-
function removeStringQuotes(str) {
|
|
854
|
-
if (str[0] === '"') {
|
|
855
|
-
str = str.slice(1);
|
|
856
|
-
}
|
|
857
|
-
if (str[str.length - 1] === '"' && str[str.length - 2] !== "\\") {
|
|
858
|
-
return str.slice(0, str.length - 1);
|
|
859
|
-
}
|
|
860
|
-
return str;
|
|
861
|
-
}
|
|
862
844
|
function isCloneable(obj) {
|
|
863
845
|
return "clone" in obj && obj.clone instanceof Function;
|
|
864
846
|
}
|
|
@@ -927,6 +909,13 @@
|
|
|
927
909
|
function getUnquotedSheetName(sheetName) {
|
|
928
910
|
return unquote(sheetName, "'");
|
|
929
911
|
}
|
|
912
|
+
/**
|
|
913
|
+
* Remove quotes from a quoted string
|
|
914
|
+
* ```js
|
|
915
|
+
* unquote('"Hello"')
|
|
916
|
+
* > 'Hello'
|
|
917
|
+
* ```
|
|
918
|
+
*/
|
|
930
919
|
function unquote(string, quoteChar = '"') {
|
|
931
920
|
if (string.startsWith(quoteChar)) {
|
|
932
921
|
string = string.slice(1);
|
|
@@ -1331,9 +1320,7 @@
|
|
|
1331
1320
|
return newArray;
|
|
1332
1321
|
}
|
|
1333
1322
|
function insertItemsAtIndex(array, items, index) {
|
|
1334
|
-
|
|
1335
|
-
newArray.splice(index, 0, ...items);
|
|
1336
|
-
return newArray;
|
|
1323
|
+
return array.slice(0, index).concat(items).concat(array.slice(index));
|
|
1337
1324
|
}
|
|
1338
1325
|
function replaceItemAtIndex(array, newItem, index) {
|
|
1339
1326
|
const newArray = [...array];
|
|
@@ -5583,7 +5570,7 @@
|
|
|
5583
5570
|
* Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
|
|
5584
5571
|
*
|
|
5585
5572
|
* As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
|
|
5586
|
-
* preceded by a data token "h", then it's not a month but
|
|
5573
|
+
* preceded by a data token "h", then it's not a month but a minute.
|
|
5587
5574
|
*/
|
|
5588
5575
|
function convertTokensToMinutesInDateFormat(tokens) {
|
|
5589
5576
|
const dateParts = tokens.filter((token) => token.type === "DATE_PART");
|
|
@@ -5626,6 +5613,9 @@
|
|
|
5626
5613
|
case "REPEATED_CHAR":
|
|
5627
5614
|
format += "*" + token.value;
|
|
5628
5615
|
break;
|
|
5616
|
+
case "DATE_PART":
|
|
5617
|
+
format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
|
|
5618
|
+
break;
|
|
5629
5619
|
default:
|
|
5630
5620
|
format += token.value;
|
|
5631
5621
|
}
|
|
@@ -5699,7 +5689,7 @@
|
|
|
5699
5689
|
return value;
|
|
5700
5690
|
}
|
|
5701
5691
|
const internalFormat = parseFormat(format);
|
|
5702
|
-
const formatToApply =
|
|
5692
|
+
const formatToApply = getFormatToApply(value, internalFormat).format;
|
|
5703
5693
|
if (!formatToApply || formatToApply.type !== "text") {
|
|
5704
5694
|
return value;
|
|
5705
5695
|
}
|
|
@@ -5710,16 +5700,15 @@
|
|
|
5710
5700
|
format = createDefaultFormat(value);
|
|
5711
5701
|
}
|
|
5712
5702
|
const internalFormat = parseFormat(format);
|
|
5713
|
-
|
|
5714
|
-
|
|
5703
|
+
const { format: formatToApply, isNegativeFormat } = getFormatToApply(value, internalFormat);
|
|
5704
|
+
if (!formatToApply) {
|
|
5705
|
+
return value.toString();
|
|
5715
5706
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
formatToApply = internalFormat.negative;
|
|
5719
|
-
value = -value;
|
|
5707
|
+
if (formatToApply.type === "text") {
|
|
5708
|
+
return applyTextInternalFormat(value.toString(), formatToApply, formatWidth);
|
|
5720
5709
|
}
|
|
5721
|
-
|
|
5722
|
-
|
|
5710
|
+
if (isNegativeFormat) {
|
|
5711
|
+
value = Math.abs(value);
|
|
5723
5712
|
}
|
|
5724
5713
|
if (formatToApply.type === "date") {
|
|
5725
5714
|
return repeatCharToFitWidth(applyDateTimeFormat(value, formatToApply), formatWidth);
|
|
@@ -5731,6 +5720,31 @@
|
|
|
5731
5720
|
return "";
|
|
5732
5721
|
}
|
|
5733
5722
|
}
|
|
5723
|
+
function getFormatToApply(value, internalFormat) {
|
|
5724
|
+
let formatToApply = undefined;
|
|
5725
|
+
let isNegativeFormat = false;
|
|
5726
|
+
switch (typeof value) {
|
|
5727
|
+
case "number":
|
|
5728
|
+
if (value < 0 && internalFormat.negative) {
|
|
5729
|
+
formatToApply = internalFormat.negative;
|
|
5730
|
+
isNegativeFormat = true;
|
|
5731
|
+
}
|
|
5732
|
+
else if (value === 0 && internalFormat.zero) {
|
|
5733
|
+
formatToApply = internalFormat.zero;
|
|
5734
|
+
}
|
|
5735
|
+
else {
|
|
5736
|
+
formatToApply = internalFormat.positive;
|
|
5737
|
+
}
|
|
5738
|
+
break;
|
|
5739
|
+
case "string":
|
|
5740
|
+
const format = internalFormat.text || internalFormat.positive;
|
|
5741
|
+
if (format.type === "text") {
|
|
5742
|
+
formatToApply = format;
|
|
5743
|
+
}
|
|
5744
|
+
break;
|
|
5745
|
+
}
|
|
5746
|
+
return { format: formatToApply, isNegativeFormat };
|
|
5747
|
+
}
|
|
5734
5748
|
function applyTextInternalFormat(value, internalFormat, formatWidth) {
|
|
5735
5749
|
let formattedValue = "";
|
|
5736
5750
|
for (const token of internalFormat.tokens) {
|
|
@@ -6342,6 +6356,27 @@
|
|
|
6342
6356
|
return false;
|
|
6343
6357
|
}
|
|
6344
6358
|
}
|
|
6359
|
+
function formatHasRepeatedChar(value, format) {
|
|
6360
|
+
if (!format) {
|
|
6361
|
+
return false;
|
|
6362
|
+
}
|
|
6363
|
+
try {
|
|
6364
|
+
const internalFormat = parseFormat(format);
|
|
6365
|
+
const { format: formatToApply } = getFormatToApply(value, internalFormat);
|
|
6366
|
+
if (formatToApply?.type === "text" || formatToApply?.type === "date") {
|
|
6367
|
+
const tokens = formatToApply.tokens;
|
|
6368
|
+
return tokens.some((token) => token.type === "REPEATED_CHAR");
|
|
6369
|
+
}
|
|
6370
|
+
else if (formatToApply?.type === "number") {
|
|
6371
|
+
return (formatToApply.integerPart.some((token) => token.type === "REPEATED_CHAR") ||
|
|
6372
|
+
(formatToApply.decimalPart
|
|
6373
|
+
? formatToApply.decimalPart.some((token) => token.type === "REPEATED_CHAR")
|
|
6374
|
+
: false));
|
|
6375
|
+
}
|
|
6376
|
+
}
|
|
6377
|
+
catch { }
|
|
6378
|
+
return false;
|
|
6379
|
+
}
|
|
6345
6380
|
|
|
6346
6381
|
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
6347
6382
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
@@ -18636,7 +18671,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18636
18671
|
case "STRING":
|
|
18637
18672
|
return {
|
|
18638
18673
|
type: "STRING",
|
|
18639
|
-
value:
|
|
18674
|
+
value: unquote(current.value),
|
|
18640
18675
|
tokenStartIndex: current.tokenIndex,
|
|
18641
18676
|
tokenEndIndex: current.tokenIndex,
|
|
18642
18677
|
};
|
|
@@ -22393,7 +22428,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22393
22428
|
dependencies.push(token.value);
|
|
22394
22429
|
break;
|
|
22395
22430
|
case "STRING":
|
|
22396
|
-
const value =
|
|
22431
|
+
const value = unquote(token.value);
|
|
22397
22432
|
literalValues.strings.push({ value });
|
|
22398
22433
|
break;
|
|
22399
22434
|
case "NUMBER": {
|
|
@@ -24645,6 +24680,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24645
24680
|
static template = "o-spreadsheet-ScorecardChart";
|
|
24646
24681
|
static props = {
|
|
24647
24682
|
chartId: String,
|
|
24683
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
24648
24684
|
};
|
|
24649
24685
|
canvas = owl.useRef("chartContainer");
|
|
24650
24686
|
get runtime() {
|
|
@@ -26564,7 +26600,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26564
26600
|
},
|
|
26565
26601
|
pointLabels: {
|
|
26566
26602
|
color: chartFontColor(definition.background),
|
|
26567
|
-
callback: truncateLabel,
|
|
26603
|
+
callback: (label) => truncateLabel(label),
|
|
26568
26604
|
},
|
|
26569
26605
|
suggestedMin: minValue < 0 ? minValue - 1 : 0,
|
|
26570
26606
|
},
|
|
@@ -27408,26 +27444,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27408
27444
|
return { chartJsConfig: config, background: chart.background || BACKGROUND_CHART_COLOR };
|
|
27409
27445
|
}
|
|
27410
27446
|
|
|
27411
|
-
class FullScreenChartStore extends SpreadsheetStore {
|
|
27412
|
-
mutators = ["toggleFullScreenChart"];
|
|
27413
|
-
fullScreenFigure = undefined;
|
|
27414
|
-
toggleFullScreenChart(figureId) {
|
|
27415
|
-
if (this.fullScreenFigure?.id === figureId) {
|
|
27416
|
-
this.fullScreenFigure = undefined;
|
|
27417
|
-
}
|
|
27418
|
-
else {
|
|
27419
|
-
this.makeFullScreen(figureId);
|
|
27420
|
-
}
|
|
27421
|
-
}
|
|
27422
|
-
makeFullScreen(figureId) {
|
|
27423
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
27424
|
-
const figure = this.getters.getFigure(sheetId, figureId);
|
|
27425
|
-
if (figure) {
|
|
27426
|
-
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
27427
|
-
}
|
|
27428
|
-
}
|
|
27429
|
-
}
|
|
27430
|
-
|
|
27431
27447
|
const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
|
|
27432
27448
|
const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
|
|
27433
27449
|
class ZoomableChartStore extends SpreadsheetStore {
|
|
@@ -27592,7 +27608,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27592
27608
|
class ZoomableChartJsComponent extends ChartJsComponent {
|
|
27593
27609
|
static template = "o-spreadsheet-ZoomableChartJsComponent";
|
|
27594
27610
|
store;
|
|
27595
|
-
fullScreenChartStore;
|
|
27596
27611
|
masterChartCanvas = owl.useRef("masterChartCanvas");
|
|
27597
27612
|
masterChart;
|
|
27598
27613
|
mode;
|
|
@@ -27603,7 +27618,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27603
27618
|
removeEventListeners = () => { };
|
|
27604
27619
|
setup() {
|
|
27605
27620
|
this.store = useStore(ZoomableChartStore);
|
|
27606
|
-
this.fullScreenChartStore = useStore(FullScreenChartStore);
|
|
27607
27621
|
super.setup();
|
|
27608
27622
|
}
|
|
27609
27623
|
unmount() {
|
|
@@ -27618,12 +27632,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27618
27632
|
`;
|
|
27619
27633
|
}
|
|
27620
27634
|
get sliceable() {
|
|
27621
|
-
if (this.
|
|
27622
|
-
|
|
27623
|
-
const chartFigureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
27624
|
-
if (fullScreenFigureId === chartFigureId) {
|
|
27625
|
-
return true;
|
|
27626
|
-
}
|
|
27635
|
+
if (this.props.isFullScreen) {
|
|
27636
|
+
return true;
|
|
27627
27637
|
}
|
|
27628
27638
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27629
27639
|
return ("zoomable" in definition && definition?.zoomable) ?? false;
|
|
@@ -27686,9 +27696,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27686
27696
|
const xMax = Math.max(...xValues);
|
|
27687
27697
|
return { xMin, xMax };
|
|
27688
27698
|
}
|
|
27689
|
-
get shouldAnimate() {
|
|
27690
|
-
return this.env.model.getters.isDashboard() && !this.sliceable;
|
|
27691
|
-
}
|
|
27692
27699
|
createChart(chartRuntime) {
|
|
27693
27700
|
const chartData = chartRuntime.chartJsConfig;
|
|
27694
27701
|
this.isBarChart = chartData.type === "bar";
|
|
@@ -27707,6 +27714,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27707
27714
|
const masterChartCtx = this.masterChartCanvas.el.getContext("2d");
|
|
27708
27715
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27709
27716
|
this.resetAxesLimits();
|
|
27717
|
+
if (this.chart?.options) {
|
|
27718
|
+
this.chart.options.animation = false;
|
|
27719
|
+
}
|
|
27710
27720
|
}
|
|
27711
27721
|
updateChartJs(chartRuntime) {
|
|
27712
27722
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27740,6 +27750,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27740
27750
|
}
|
|
27741
27751
|
}
|
|
27742
27752
|
this.resetAxesLimits();
|
|
27753
|
+
if (this.chart?.options) {
|
|
27754
|
+
this.chart.options.animation = false;
|
|
27755
|
+
}
|
|
27743
27756
|
}
|
|
27744
27757
|
resetAxesLimits() {
|
|
27745
27758
|
if (!this.chart) {
|
|
@@ -27837,7 +27850,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27837
27850
|
onPointerDownInMasterChart(ev) {
|
|
27838
27851
|
this.removeEventListeners();
|
|
27839
27852
|
const position = ev.offsetX;
|
|
27840
|
-
if (!this.masterChart?.chartArea || !this.chart?.scales
|
|
27853
|
+
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
27841
27854
|
return;
|
|
27842
27855
|
}
|
|
27843
27856
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
@@ -31395,6 +31408,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31395
31408
|
return matchedChart.displayName;
|
|
31396
31409
|
}
|
|
31397
31410
|
|
|
31411
|
+
class FullScreenFigureStore extends SpreadsheetStore {
|
|
31412
|
+
mutators = ["toggleFullScreenFigure"];
|
|
31413
|
+
fullScreenFigure = undefined;
|
|
31414
|
+
toggleFullScreenFigure(figureId) {
|
|
31415
|
+
if (this.fullScreenFigure?.id === figureId) {
|
|
31416
|
+
this.fullScreenFigure = undefined;
|
|
31417
|
+
}
|
|
31418
|
+
else {
|
|
31419
|
+
this.makeFullScreen(figureId);
|
|
31420
|
+
}
|
|
31421
|
+
}
|
|
31422
|
+
makeFullScreen(figureId) {
|
|
31423
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
31424
|
+
const figure = this.getters.getFigure(sheetId, figureId);
|
|
31425
|
+
if (figure) {
|
|
31426
|
+
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
31427
|
+
}
|
|
31428
|
+
}
|
|
31429
|
+
}
|
|
31430
|
+
|
|
31398
31431
|
/**
|
|
31399
31432
|
* This file is largely inspired by owl 1.
|
|
31400
31433
|
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
@@ -32132,12 +32165,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32132
32165
|
class ChartDashboardMenu extends owl.Component {
|
|
32133
32166
|
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
32134
32167
|
static components = { MenuPopover };
|
|
32135
|
-
static props = { chartId: String };
|
|
32168
|
+
static props = { chartId: String, hasFullScreenButton: { type: Boolean, optional: true } };
|
|
32169
|
+
static defaultProps = { hasFullScreenButton: true };
|
|
32136
32170
|
fullScreenFigureStore;
|
|
32137
32171
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32138
32172
|
setup() {
|
|
32139
32173
|
super.setup();
|
|
32140
|
-
this.fullScreenFigureStore = useStore(
|
|
32174
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32141
32175
|
}
|
|
32142
32176
|
getMenuItems() {
|
|
32143
32177
|
return [this.fullScreenMenuItem].filter(isDefined);
|
|
@@ -32153,6 +32187,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32153
32187
|
this.menuState.menuItems = getChartMenuActions(figureId, () => { }, this.env);
|
|
32154
32188
|
}
|
|
32155
32189
|
get fullScreenMenuItem() {
|
|
32190
|
+
if (!this.props.hasFullScreenButton) {
|
|
32191
|
+
return undefined;
|
|
32192
|
+
}
|
|
32156
32193
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
32157
32194
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32158
32195
|
if (definition.type === "scorecard") {
|
|
@@ -32164,7 +32201,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32164
32201
|
label: isFullScreen ? _t("Exit Full Screen") : _t("Full Screen"),
|
|
32165
32202
|
class: `text-muted fa ${isFullScreen ? "fa-compress" : "fa-expand"}`,
|
|
32166
32203
|
onClick: () => {
|
|
32167
|
-
this.fullScreenFigureStore.
|
|
32204
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(figureId);
|
|
32168
32205
|
},
|
|
32169
32206
|
};
|
|
32170
32207
|
}
|
|
@@ -32176,6 +32213,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32176
32213
|
figureUI: Object,
|
|
32177
32214
|
onFigureDeleted: Function,
|
|
32178
32215
|
editFigureStyle: { type: Function, optional: true },
|
|
32216
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32179
32217
|
};
|
|
32180
32218
|
static components = { ChartDashboardMenu, MenuPopover };
|
|
32181
32219
|
carouselTabsRef = owl.useRef("carouselTabs");
|
|
@@ -32183,8 +32221,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32183
32221
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32184
32222
|
hiddenItems = [];
|
|
32185
32223
|
animationStore;
|
|
32224
|
+
fullScreenFigureStore;
|
|
32186
32225
|
setup() {
|
|
32187
32226
|
this.animationStore = useStore(ChartAnimationStore);
|
|
32227
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32188
32228
|
owl.useEffect(() => {
|
|
32189
32229
|
if (this.selectedCarouselItem?.type === "carouselDataView") {
|
|
32190
32230
|
this.props.editFigureStyle?.({ "pointer-events": "none" });
|
|
@@ -32231,18 +32271,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32231
32271
|
item,
|
|
32232
32272
|
});
|
|
32233
32273
|
if (item.type === "chart") {
|
|
32234
|
-
|
|
32274
|
+
const animationChartId = item.chartId + (this.props.isFullScreen ? "-fullscreen" : "");
|
|
32275
|
+
this.animationStore?.enableAnimationForChart(animationChartId);
|
|
32235
32276
|
}
|
|
32236
32277
|
}
|
|
32237
32278
|
get headerStyle() {
|
|
32238
32279
|
const cssProperties = {};
|
|
32239
|
-
if (this.selectedCarouselItem?.type === "
|
|
32240
|
-
cssProperties["background-color"] = "#ffffff";
|
|
32241
|
-
}
|
|
32242
|
-
else if (this.selectedCarouselItem?.type === "chart") {
|
|
32280
|
+
if (this.selectedCarouselItem?.type === "chart") {
|
|
32243
32281
|
const chart = this.env.model.getters.getChartRuntime(this.selectedCarouselItem.chartId);
|
|
32244
32282
|
cssProperties["background-color"] = chart.background;
|
|
32245
32283
|
}
|
|
32284
|
+
else {
|
|
32285
|
+
cssProperties["background-color"] = "#ffffff";
|
|
32286
|
+
}
|
|
32246
32287
|
return cssPropertiesToCss(cssProperties);
|
|
32247
32288
|
}
|
|
32248
32289
|
get title() {
|
|
@@ -32295,6 +32336,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32295
32336
|
this.menuState.anchorRect = rect;
|
|
32296
32337
|
this.menuState.menuItems = createActions(menuItems);
|
|
32297
32338
|
}
|
|
32339
|
+
toggleFullScreen() {
|
|
32340
|
+
if (this.selectedCarouselItem?.type === "chart") {
|
|
32341
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.props.figureUI.id);
|
|
32342
|
+
}
|
|
32343
|
+
}
|
|
32344
|
+
get fullScreenButtonTitle() {
|
|
32345
|
+
return this.props.isFullScreen ? _t("Exit Full Screen") : _t("Full Screen");
|
|
32346
|
+
}
|
|
32347
|
+
get visibleCarouselItems() {
|
|
32348
|
+
return this.carousel.items.filter((item) => item.type === "carouselDataView" && this.props.isFullScreen ? false : true);
|
|
32349
|
+
}
|
|
32298
32350
|
}
|
|
32299
32351
|
|
|
32300
32352
|
class ChartFigure extends owl.Component {
|
|
@@ -32303,6 +32355,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32303
32355
|
figureUI: Object,
|
|
32304
32356
|
onFigureDeleted: Function,
|
|
32305
32357
|
editFigureStyle: { type: Function, optional: true },
|
|
32358
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32306
32359
|
};
|
|
32307
32360
|
static components = { ChartDashboardMenu };
|
|
32308
32361
|
onDoubleClick() {
|
|
@@ -32405,9 +32458,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32405
32458
|
return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
|
|
32406
32459
|
}
|
|
32407
32460
|
getBorderStyle(position) {
|
|
32408
|
-
|
|
32409
|
-
const borderColor = this.isSelected ? SELECTION_BORDER_COLOR : FIGURE_BORDER_COLOR;
|
|
32410
|
-
return `border-${position}: ${borderWidth}px solid ${borderColor};`;
|
|
32461
|
+
return `border-${position}-width: ${this.getBorderWidth()}px;`;
|
|
32411
32462
|
}
|
|
32412
32463
|
get wrapperStyle() {
|
|
32413
32464
|
const { x, y, width, height } = this.props.figureUI;
|
|
@@ -51343,6 +51394,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51343
51394
|
}
|
|
51344
51395
|
const { align } = this.getters.getCellStyle(position);
|
|
51345
51396
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
51397
|
+
if (formatHasRepeatedChar(evaluatedCell.value, evaluatedCell.format)) {
|
|
51398
|
+
return "left";
|
|
51399
|
+
}
|
|
51346
51400
|
if (isOverflowing && evaluatedCell.type === CellValueType.number) {
|
|
51347
51401
|
return align !== "center" ? "left" : align;
|
|
51348
51402
|
}
|
|
@@ -56814,7 +56868,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56814
56868
|
return undefined;
|
|
56815
56869
|
}
|
|
56816
56870
|
get isCalculatedMeasureInvalid() {
|
|
56817
|
-
return
|
|
56871
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
56818
56872
|
}
|
|
56819
56873
|
}
|
|
56820
56874
|
|
|
@@ -59529,16 +59583,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59529
59583
|
}
|
|
59530
59584
|
}
|
|
59531
59585
|
|
|
59532
|
-
class
|
|
59533
|
-
static template = "o-spreadsheet-
|
|
59586
|
+
class FullScreenFigure extends owl.Component {
|
|
59587
|
+
static template = "o-spreadsheet-FullScreenFigure";
|
|
59534
59588
|
static props = {};
|
|
59535
|
-
static components = {
|
|
59536
|
-
|
|
59537
|
-
ref = owl.useRef("
|
|
59589
|
+
static components = { ChartFigure };
|
|
59590
|
+
fullScreenFigureStore;
|
|
59591
|
+
ref = owl.useRef("fullScreenFigure");
|
|
59538
59592
|
spreadsheetRect = useSpreadsheetRect();
|
|
59539
59593
|
figureRegistry = figureRegistry;
|
|
59540
59594
|
setup() {
|
|
59541
|
-
this.
|
|
59595
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
59542
59596
|
const animationStore = useStore(ChartAnimationStore);
|
|
59543
59597
|
let lastFigureId = undefined;
|
|
59544
59598
|
owl.onWillUpdateProps(() => {
|
|
@@ -59550,7 +59604,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59550
59604
|
owl.useEffect((el) => el?.focus(), () => [this.ref.el]);
|
|
59551
59605
|
}
|
|
59552
59606
|
get figureUI() {
|
|
59553
|
-
return this.
|
|
59607
|
+
return this.fullScreenFigureStore.fullScreenFigure;
|
|
59554
59608
|
}
|
|
59555
59609
|
get chartId() {
|
|
59556
59610
|
if (!this.figureUI)
|
|
@@ -59559,7 +59613,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59559
59613
|
}
|
|
59560
59614
|
exitFullScreen() {
|
|
59561
59615
|
if (this.figureUI) {
|
|
59562
|
-
this.
|
|
59616
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.figureUI.id);
|
|
59563
59617
|
}
|
|
59564
59618
|
}
|
|
59565
59619
|
onKeyDown(ev) {
|
|
@@ -59567,15 +59621,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59567
59621
|
this.exitFullScreen();
|
|
59568
59622
|
}
|
|
59569
59623
|
}
|
|
59570
|
-
get
|
|
59571
|
-
if (!this.
|
|
59624
|
+
get figureComponent() {
|
|
59625
|
+
if (!this.figureUI)
|
|
59572
59626
|
return undefined;
|
|
59573
|
-
|
|
59574
|
-
const component = chartComponentRegistry.get(type);
|
|
59575
|
-
if (!component) {
|
|
59576
|
-
throw new Error(`Component is not defined for type ${type}`);
|
|
59577
|
-
}
|
|
59578
|
-
return component;
|
|
59627
|
+
return figureRegistry.get(this.figureUI.tag).Component;
|
|
59579
59628
|
}
|
|
59580
59629
|
}
|
|
59581
59630
|
|
|
@@ -62278,11 +62327,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62278
62327
|
break;
|
|
62279
62328
|
}
|
|
62280
62329
|
case "ADD_COLUMNS_ROWS": {
|
|
62281
|
-
const sizes =
|
|
62330
|
+
const sizes = this.sizes[cmd.sheetId][cmd.dimension];
|
|
62282
62331
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62283
62332
|
const baseSize = sizes[cmd.base];
|
|
62284
|
-
sizes
|
|
62285
|
-
this.history.update("sizes", cmd.sheetId, cmd.dimension,
|
|
62333
|
+
const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
|
|
62334
|
+
this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
|
|
62286
62335
|
break;
|
|
62287
62336
|
}
|
|
62288
62337
|
case "RESIZE_COLUMNS_ROWS":
|
|
@@ -62433,9 +62482,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62433
62482
|
break;
|
|
62434
62483
|
}
|
|
62435
62484
|
case "ADD_COLUMNS_ROWS": {
|
|
62436
|
-
const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
|
|
62437
62485
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62438
|
-
hiddenHeaders.
|
|
62486
|
+
const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
|
|
62439
62487
|
this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
|
|
62440
62488
|
break;
|
|
62441
62489
|
}
|
|
@@ -66619,12 +66667,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66619
66667
|
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
66620
66668
|
}
|
|
66621
66669
|
rtreeItemComparer(left, right) {
|
|
66622
|
-
return (left.
|
|
66623
|
-
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66670
|
+
return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66624
66671
|
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
66625
66672
|
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
66626
66673
|
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
66627
|
-
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom
|
|
66674
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
|
|
66675
|
+
deepEquals(left.data, right.data));
|
|
66628
66676
|
}
|
|
66629
66677
|
}
|
|
66630
66678
|
/**
|
|
@@ -72879,7 +72927,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72879
72927
|
return "Success" /* CommandResult.Success */;
|
|
72880
72928
|
}
|
|
72881
72929
|
checkArrayFormulaInSortZone({ sheetId, zone }) {
|
|
72882
|
-
const arrayFormulaInZone = positions(zone).some(({ col, row }) =>
|
|
72930
|
+
const arrayFormulaInZone = positions(zone).some(({ col, row }) => {
|
|
72931
|
+
const originPosition = this.getters.getArrayFormulaSpreadingOn({ sheetId, col, row });
|
|
72932
|
+
return originPosition && !deepEquals(originPosition, { sheetId, col, row });
|
|
72933
|
+
});
|
|
72883
72934
|
return arrayFormulaInZone ? "SortZoneWithArrayFormulas" /* CommandResult.SortZoneWithArrayFormulas */ : "Success" /* CommandResult.Success */;
|
|
72884
72935
|
}
|
|
72885
72936
|
/**
|
|
@@ -79469,8 +79520,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79469
79520
|
left: `calc(50% - 1px)`, // -1px: we want the border to be on the center
|
|
79470
79521
|
width: `30%`,
|
|
79471
79522
|
height: `calc(100% - ${groupBox.headerRect.height / 2}px)`,
|
|
79472
|
-
"border-left": `1px solid
|
|
79473
|
-
"border-bottom": groupBox.isEndHidden ? "" : `1px solid
|
|
79523
|
+
"border-left": `1px solid`,
|
|
79524
|
+
"border-bottom": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79474
79525
|
});
|
|
79475
79526
|
}
|
|
79476
79527
|
get groupHeaderStyle() {
|
|
@@ -79522,8 +79573,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79522
79573
|
left: `${groupBox.headerRect.width / 2}px`,
|
|
79523
79574
|
width: `calc(100% - ${groupBox.headerRect.width / 2}px)`,
|
|
79524
79575
|
height: `30%`,
|
|
79525
|
-
"border-top": `1px solid
|
|
79526
|
-
"border-right": groupBox.isEndHidden ? "" : `1px solid
|
|
79576
|
+
"border-top": `1px solid`,
|
|
79577
|
+
"border-right": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79527
79578
|
});
|
|
79528
79579
|
}
|
|
79529
79580
|
get groupHeaderStyle() {
|
|
@@ -79860,6 +79911,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79860
79911
|
? this.composerFocusStore.focusMode
|
|
79861
79912
|
: "inactive";
|
|
79862
79913
|
}
|
|
79914
|
+
get showFxIcon() {
|
|
79915
|
+
return this.focus === "inactive" && !this.composerStore.currentContent;
|
|
79916
|
+
}
|
|
79863
79917
|
get rect() {
|
|
79864
79918
|
return this.composerRef.el
|
|
79865
79919
|
? getBoundingRectAsPOJO(this.composerRef.el)
|
|
@@ -79902,13 +79956,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79902
79956
|
}
|
|
79903
79957
|
|
|
79904
79958
|
const COMPOSER_MAX_HEIGHT = 300;
|
|
79905
|
-
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
79906
|
-
// FIXME This svg is hardcoded in the css file. We should find a better way to handle it.
|
|
79907
|
-
// const FX_SVG = /*xml*/ `
|
|
79908
|
-
// <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
79909
|
-
// <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'/>
|
|
79910
|
-
// </svg>
|
|
79911
|
-
// `;
|
|
79912
79959
|
class TopBarComposer extends owl.Component {
|
|
79913
79960
|
static template = "o-spreadsheet-TopBarComposer";
|
|
79914
79961
|
static props = {};
|
|
@@ -79935,6 +79982,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79935
79982
|
? this.composerFocusStore.focusMode
|
|
79936
79983
|
: "inactive";
|
|
79937
79984
|
}
|
|
79985
|
+
get showFxIcon() {
|
|
79986
|
+
return this.focus === "inactive" && !this.composerStore.currentContent;
|
|
79987
|
+
}
|
|
79938
79988
|
get composerStyle() {
|
|
79939
79989
|
const style = {
|
|
79940
79990
|
padding: "5px 0px 5px 8px",
|
|
@@ -80872,7 +80922,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
80872
80922
|
SidePanels,
|
|
80873
80923
|
SpreadsheetDashboard,
|
|
80874
80924
|
HeaderGroupContainer,
|
|
80875
|
-
|
|
80925
|
+
FullScreenFigure,
|
|
80876
80926
|
};
|
|
80877
80927
|
sidePanel;
|
|
80878
80928
|
spreadsheetRef = owl.useRef("spreadsheet");
|
|
@@ -85596,6 +85646,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85596
85646
|
Grid,
|
|
85597
85647
|
GridOverlay,
|
|
85598
85648
|
ScorecardChart,
|
|
85649
|
+
GaugeChartComponent,
|
|
85599
85650
|
LineConfigPanel,
|
|
85600
85651
|
BarConfigPanel,
|
|
85601
85652
|
PieChartDesignPanel,
|
|
@@ -85634,7 +85685,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85634
85685
|
RadioSelection,
|
|
85635
85686
|
GeoChartRegionSelectSection,
|
|
85636
85687
|
ChartDashboardMenu,
|
|
85637
|
-
|
|
85688
|
+
FullScreenFigure,
|
|
85638
85689
|
};
|
|
85639
85690
|
const hooks = {
|
|
85640
85691
|
useDragAndDropListItems,
|
|
@@ -85734,9 +85785,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85734
85785
|
exports.tokenize = tokenize;
|
|
85735
85786
|
|
|
85736
85787
|
|
|
85737
|
-
__info__.version = "19.1.0-alpha.
|
|
85738
|
-
__info__.date = "2025-
|
|
85739
|
-
__info__.hash = "
|
|
85788
|
+
__info__.version = "19.1.0-alpha.4";
|
|
85789
|
+
__info__.date = "2025-10-07T10:03:20.917Z";
|
|
85790
|
+
__info__.hash = "b7cfed8";
|
|
85740
85791
|
|
|
85741
85792
|
|
|
85742
85793
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|