@odoo/o-spreadsheet 19.1.0-alpha.3 → 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 +164 -116
- package/dist/o-spreadsheet.d.ts +215 -152
- package/dist/o-spreadsheet.esm.js +164 -116
- package/dist/o-spreadsheet.iife.js +164 -116
- package/dist/o-spreadsheet.iife.min.js +311 -311
- package/dist/o_spreadsheet.xml +61 -17
- package/package.json +5 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.1.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.1.0-alpha.4
|
|
6
|
+
* @date 2025-10-07T10:03:20.917Z
|
|
7
|
+
* @hash b7cfed8
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -593,7 +593,6 @@ const BACKGROUND_HEADER_COLOR = "#F8F9FA";
|
|
|
593
593
|
const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
|
|
594
594
|
const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
|
|
595
595
|
const TEXT_HEADER_COLOR = "#666666";
|
|
596
|
-
const FIGURE_BORDER_COLOR = "#c9ccd2";
|
|
597
596
|
const SELECTION_BORDER_COLOR = "#3266ca";
|
|
598
597
|
const HEADER_BORDER_COLOR = "#C0C0C0";
|
|
599
598
|
const CELL_BORDER_COLOR = "#E2E3E3";
|
|
@@ -601,7 +600,6 @@ const BACKGROUND_CHART_COLOR = "#FFFFFF";
|
|
|
601
600
|
const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
|
|
602
601
|
const LINK_COLOR = HIGHLIGHT_COLOR;
|
|
603
602
|
const FILTERS_COLOR = "#188038";
|
|
604
|
-
const HEADER_GROUPING_BORDER_COLOR = "#999";
|
|
605
603
|
const FROZEN_PANE_HEADER_BORDER_COLOR = "#BCBCBC";
|
|
606
604
|
const FROZEN_PANE_BORDER_COLOR = "#DADFE8";
|
|
607
605
|
const COMPOSER_ASSISTANT_COLOR = "#9B359B";
|
|
@@ -844,22 +842,6 @@ const DRAG_THRESHOLD = 5; // in pixels, to avoid unwanted drag when clicking
|
|
|
844
842
|
// Miscellaneous
|
|
845
843
|
//------------------------------------------------------------------------------
|
|
846
844
|
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
847
|
-
/**
|
|
848
|
-
* Remove quotes from a quoted string
|
|
849
|
-
* ```js
|
|
850
|
-
* removeStringQuotes('"Hello"')
|
|
851
|
-
* > 'Hello'
|
|
852
|
-
* ```
|
|
853
|
-
*/
|
|
854
|
-
function removeStringQuotes(str) {
|
|
855
|
-
if (str[0] === '"') {
|
|
856
|
-
str = str.slice(1);
|
|
857
|
-
}
|
|
858
|
-
if (str[str.length - 1] === '"' && str[str.length - 2] !== "\\") {
|
|
859
|
-
return str.slice(0, str.length - 1);
|
|
860
|
-
}
|
|
861
|
-
return str;
|
|
862
|
-
}
|
|
863
845
|
function isCloneable(obj) {
|
|
864
846
|
return "clone" in obj && obj.clone instanceof Function;
|
|
865
847
|
}
|
|
@@ -928,6 +910,13 @@ function isPlainObject(obj) {
|
|
|
928
910
|
function getUnquotedSheetName(sheetName) {
|
|
929
911
|
return unquote(sheetName, "'");
|
|
930
912
|
}
|
|
913
|
+
/**
|
|
914
|
+
* Remove quotes from a quoted string
|
|
915
|
+
* ```js
|
|
916
|
+
* unquote('"Hello"')
|
|
917
|
+
* > 'Hello'
|
|
918
|
+
* ```
|
|
919
|
+
*/
|
|
931
920
|
function unquote(string, quoteChar = '"') {
|
|
932
921
|
if (string.startsWith(quoteChar)) {
|
|
933
922
|
string = string.slice(1);
|
|
@@ -1332,9 +1321,7 @@ function removeIndexesFromArray(array, indexes) {
|
|
|
1332
1321
|
return newArray;
|
|
1333
1322
|
}
|
|
1334
1323
|
function insertItemsAtIndex(array, items, index) {
|
|
1335
|
-
|
|
1336
|
-
newArray.splice(index, 0, ...items);
|
|
1337
|
-
return newArray;
|
|
1324
|
+
return array.slice(0, index).concat(items).concat(array.slice(index));
|
|
1338
1325
|
}
|
|
1339
1326
|
function replaceItemAtIndex(array, newItem, index) {
|
|
1340
1327
|
const newArray = [...array];
|
|
@@ -5584,7 +5571,7 @@ function tokensToTextInternalFormat(tokens) {
|
|
|
5584
5571
|
* Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
|
|
5585
5572
|
*
|
|
5586
5573
|
* As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
|
|
5587
|
-
* preceded by a data token "h", then it's not a month but
|
|
5574
|
+
* preceded by a data token "h", then it's not a month but a minute.
|
|
5588
5575
|
*/
|
|
5589
5576
|
function convertTokensToMinutesInDateFormat(tokens) {
|
|
5590
5577
|
const dateParts = tokens.filter((token) => token.type === "DATE_PART");
|
|
@@ -5627,6 +5614,9 @@ function internalFormatPartToFormat(internalFormat) {
|
|
|
5627
5614
|
case "REPEATED_CHAR":
|
|
5628
5615
|
format += "*" + token.value;
|
|
5629
5616
|
break;
|
|
5617
|
+
case "DATE_PART":
|
|
5618
|
+
format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
|
|
5619
|
+
break;
|
|
5630
5620
|
default:
|
|
5631
5621
|
format += token.value;
|
|
5632
5622
|
}
|
|
@@ -5700,7 +5690,7 @@ function formatValue(value, { format, locale, formatWidth }) {
|
|
|
5700
5690
|
return value;
|
|
5701
5691
|
}
|
|
5702
5692
|
const internalFormat = parseFormat(format);
|
|
5703
|
-
const formatToApply =
|
|
5693
|
+
const formatToApply = getFormatToApply(value, internalFormat).format;
|
|
5704
5694
|
if (!formatToApply || formatToApply.type !== "text") {
|
|
5705
5695
|
return value;
|
|
5706
5696
|
}
|
|
@@ -5711,16 +5701,15 @@ function formatValue(value, { format, locale, formatWidth }) {
|
|
|
5711
5701
|
format = createDefaultFormat(value);
|
|
5712
5702
|
}
|
|
5713
5703
|
const internalFormat = parseFormat(format);
|
|
5714
|
-
|
|
5715
|
-
|
|
5704
|
+
const { format: formatToApply, isNegativeFormat } = getFormatToApply(value, internalFormat);
|
|
5705
|
+
if (!formatToApply) {
|
|
5706
|
+
return value.toString();
|
|
5716
5707
|
}
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
formatToApply = internalFormat.negative;
|
|
5720
|
-
value = -value;
|
|
5708
|
+
if (formatToApply.type === "text") {
|
|
5709
|
+
return applyTextInternalFormat(value.toString(), formatToApply, formatWidth);
|
|
5721
5710
|
}
|
|
5722
|
-
|
|
5723
|
-
|
|
5711
|
+
if (isNegativeFormat) {
|
|
5712
|
+
value = Math.abs(value);
|
|
5724
5713
|
}
|
|
5725
5714
|
if (formatToApply.type === "date") {
|
|
5726
5715
|
return repeatCharToFitWidth(applyDateTimeFormat(value, formatToApply), formatWidth);
|
|
@@ -5732,6 +5721,31 @@ function formatValue(value, { format, locale, formatWidth }) {
|
|
|
5732
5721
|
return "";
|
|
5733
5722
|
}
|
|
5734
5723
|
}
|
|
5724
|
+
function getFormatToApply(value, internalFormat) {
|
|
5725
|
+
let formatToApply = undefined;
|
|
5726
|
+
let isNegativeFormat = false;
|
|
5727
|
+
switch (typeof value) {
|
|
5728
|
+
case "number":
|
|
5729
|
+
if (value < 0 && internalFormat.negative) {
|
|
5730
|
+
formatToApply = internalFormat.negative;
|
|
5731
|
+
isNegativeFormat = true;
|
|
5732
|
+
}
|
|
5733
|
+
else if (value === 0 && internalFormat.zero) {
|
|
5734
|
+
formatToApply = internalFormat.zero;
|
|
5735
|
+
}
|
|
5736
|
+
else {
|
|
5737
|
+
formatToApply = internalFormat.positive;
|
|
5738
|
+
}
|
|
5739
|
+
break;
|
|
5740
|
+
case "string":
|
|
5741
|
+
const format = internalFormat.text || internalFormat.positive;
|
|
5742
|
+
if (format.type === "text") {
|
|
5743
|
+
formatToApply = format;
|
|
5744
|
+
}
|
|
5745
|
+
break;
|
|
5746
|
+
}
|
|
5747
|
+
return { format: formatToApply, isNegativeFormat };
|
|
5748
|
+
}
|
|
5735
5749
|
function applyTextInternalFormat(value, internalFormat, formatWidth) {
|
|
5736
5750
|
let formattedValue = "";
|
|
5737
5751
|
for (const token of internalFormat.tokens) {
|
|
@@ -6343,6 +6357,27 @@ function isTextFormat(format) {
|
|
|
6343
6357
|
return false;
|
|
6344
6358
|
}
|
|
6345
6359
|
}
|
|
6360
|
+
function formatHasRepeatedChar(value, format) {
|
|
6361
|
+
if (!format) {
|
|
6362
|
+
return false;
|
|
6363
|
+
}
|
|
6364
|
+
try {
|
|
6365
|
+
const internalFormat = parseFormat(format);
|
|
6366
|
+
const { format: formatToApply } = getFormatToApply(value, internalFormat);
|
|
6367
|
+
if (formatToApply?.type === "text" || formatToApply?.type === "date") {
|
|
6368
|
+
const tokens = formatToApply.tokens;
|
|
6369
|
+
return tokens.some((token) => token.type === "REPEATED_CHAR");
|
|
6370
|
+
}
|
|
6371
|
+
else if (formatToApply?.type === "number") {
|
|
6372
|
+
return (formatToApply.integerPart.some((token) => token.type === "REPEATED_CHAR") ||
|
|
6373
|
+
(formatToApply.decimalPart
|
|
6374
|
+
? formatToApply.decimalPart.some((token) => token.type === "REPEATED_CHAR")
|
|
6375
|
+
: false));
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
catch { }
|
|
6379
|
+
return false;
|
|
6380
|
+
}
|
|
6346
6381
|
|
|
6347
6382
|
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
6348
6383
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
@@ -18637,7 +18672,7 @@ function parseOperand(tokens) {
|
|
|
18637
18672
|
case "STRING":
|
|
18638
18673
|
return {
|
|
18639
18674
|
type: "STRING",
|
|
18640
|
-
value:
|
|
18675
|
+
value: unquote(current.value),
|
|
18641
18676
|
tokenStartIndex: current.tokenIndex,
|
|
18642
18677
|
tokenEndIndex: current.tokenIndex,
|
|
18643
18678
|
};
|
|
@@ -22394,7 +22429,7 @@ function formulaArguments(tokens) {
|
|
|
22394
22429
|
dependencies.push(token.value);
|
|
22395
22430
|
break;
|
|
22396
22431
|
case "STRING":
|
|
22397
|
-
const value =
|
|
22432
|
+
const value = unquote(token.value);
|
|
22398
22433
|
literalValues.strings.push({ value });
|
|
22399
22434
|
break;
|
|
22400
22435
|
case "NUMBER": {
|
|
@@ -24646,6 +24681,7 @@ class ScorecardChart extends owl.Component {
|
|
|
24646
24681
|
static template = "o-spreadsheet-ScorecardChart";
|
|
24647
24682
|
static props = {
|
|
24648
24683
|
chartId: String,
|
|
24684
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
24649
24685
|
};
|
|
24650
24686
|
canvas = owl.useRef("chartContainer");
|
|
24651
24687
|
get runtime() {
|
|
@@ -27409,26 +27445,6 @@ function createBarChartRuntime(chart, getters) {
|
|
|
27409
27445
|
return { chartJsConfig: config, background: chart.background || BACKGROUND_CHART_COLOR };
|
|
27410
27446
|
}
|
|
27411
27447
|
|
|
27412
|
-
class FullScreenChartStore extends SpreadsheetStore {
|
|
27413
|
-
mutators = ["toggleFullScreenChart"];
|
|
27414
|
-
fullScreenFigure = undefined;
|
|
27415
|
-
toggleFullScreenChart(figureId) {
|
|
27416
|
-
if (this.fullScreenFigure?.id === figureId) {
|
|
27417
|
-
this.fullScreenFigure = undefined;
|
|
27418
|
-
}
|
|
27419
|
-
else {
|
|
27420
|
-
this.makeFullScreen(figureId);
|
|
27421
|
-
}
|
|
27422
|
-
}
|
|
27423
|
-
makeFullScreen(figureId) {
|
|
27424
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
27425
|
-
const figure = this.getters.getFigure(sheetId, figureId);
|
|
27426
|
-
if (figure) {
|
|
27427
|
-
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
27428
|
-
}
|
|
27429
|
-
}
|
|
27430
|
-
}
|
|
27431
|
-
|
|
27432
27448
|
const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
|
|
27433
27449
|
const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
|
|
27434
27450
|
class ZoomableChartStore extends SpreadsheetStore {
|
|
@@ -27593,7 +27609,6 @@ chartJsExtensionRegistry.add("zoomWindowPlugin", {
|
|
|
27593
27609
|
class ZoomableChartJsComponent extends ChartJsComponent {
|
|
27594
27610
|
static template = "o-spreadsheet-ZoomableChartJsComponent";
|
|
27595
27611
|
store;
|
|
27596
|
-
fullScreenChartStore;
|
|
27597
27612
|
masterChartCanvas = owl.useRef("masterChartCanvas");
|
|
27598
27613
|
masterChart;
|
|
27599
27614
|
mode;
|
|
@@ -27604,7 +27619,6 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27604
27619
|
removeEventListeners = () => { };
|
|
27605
27620
|
setup() {
|
|
27606
27621
|
this.store = useStore(ZoomableChartStore);
|
|
27607
|
-
this.fullScreenChartStore = useStore(FullScreenChartStore);
|
|
27608
27622
|
super.setup();
|
|
27609
27623
|
}
|
|
27610
27624
|
unmount() {
|
|
@@ -27619,12 +27633,8 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27619
27633
|
`;
|
|
27620
27634
|
}
|
|
27621
27635
|
get sliceable() {
|
|
27622
|
-
if (this.
|
|
27623
|
-
|
|
27624
|
-
const chartFigureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
27625
|
-
if (fullScreenFigureId === chartFigureId) {
|
|
27626
|
-
return true;
|
|
27627
|
-
}
|
|
27636
|
+
if (this.props.isFullScreen) {
|
|
27637
|
+
return true;
|
|
27628
27638
|
}
|
|
27629
27639
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27630
27640
|
return ("zoomable" in definition && definition?.zoomable) ?? false;
|
|
@@ -27687,9 +27697,6 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27687
27697
|
const xMax = Math.max(...xValues);
|
|
27688
27698
|
return { xMin, xMax };
|
|
27689
27699
|
}
|
|
27690
|
-
get shouldAnimate() {
|
|
27691
|
-
return this.env.model.getters.isDashboard() && !this.sliceable;
|
|
27692
|
-
}
|
|
27693
27700
|
createChart(chartRuntime) {
|
|
27694
27701
|
const chartData = chartRuntime.chartJsConfig;
|
|
27695
27702
|
this.isBarChart = chartData.type === "bar";
|
|
@@ -27708,6 +27715,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27708
27715
|
const masterChartCtx = this.masterChartCanvas.el.getContext("2d");
|
|
27709
27716
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27710
27717
|
this.resetAxesLimits();
|
|
27718
|
+
if (this.chart?.options) {
|
|
27719
|
+
this.chart.options.animation = false;
|
|
27720
|
+
}
|
|
27711
27721
|
}
|
|
27712
27722
|
updateChartJs(chartRuntime) {
|
|
27713
27723
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27741,6 +27751,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27741
27751
|
}
|
|
27742
27752
|
}
|
|
27743
27753
|
this.resetAxesLimits();
|
|
27754
|
+
if (this.chart?.options) {
|
|
27755
|
+
this.chart.options.animation = false;
|
|
27756
|
+
}
|
|
27744
27757
|
}
|
|
27745
27758
|
resetAxesLimits() {
|
|
27746
27759
|
if (!this.chart) {
|
|
@@ -27838,7 +27851,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27838
27851
|
onPointerDownInMasterChart(ev) {
|
|
27839
27852
|
this.removeEventListeners();
|
|
27840
27853
|
const position = ev.offsetX;
|
|
27841
|
-
if (!this.masterChart?.chartArea || !this.chart?.scales
|
|
27854
|
+
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
27842
27855
|
return;
|
|
27843
27856
|
}
|
|
27844
27857
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
@@ -31396,6 +31409,26 @@ function getCarouselItemTitle(getters, item) {
|
|
|
31396
31409
|
return matchedChart.displayName;
|
|
31397
31410
|
}
|
|
31398
31411
|
|
|
31412
|
+
class FullScreenFigureStore extends SpreadsheetStore {
|
|
31413
|
+
mutators = ["toggleFullScreenFigure"];
|
|
31414
|
+
fullScreenFigure = undefined;
|
|
31415
|
+
toggleFullScreenFigure(figureId) {
|
|
31416
|
+
if (this.fullScreenFigure?.id === figureId) {
|
|
31417
|
+
this.fullScreenFigure = undefined;
|
|
31418
|
+
}
|
|
31419
|
+
else {
|
|
31420
|
+
this.makeFullScreen(figureId);
|
|
31421
|
+
}
|
|
31422
|
+
}
|
|
31423
|
+
makeFullScreen(figureId) {
|
|
31424
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
31425
|
+
const figure = this.getters.getFigure(sheetId, figureId);
|
|
31426
|
+
if (figure) {
|
|
31427
|
+
this.fullScreenFigure = { ...figure, x: 0, y: 0, width: 0, height: 0 };
|
|
31428
|
+
}
|
|
31429
|
+
}
|
|
31430
|
+
}
|
|
31431
|
+
|
|
31399
31432
|
/**
|
|
31400
31433
|
* This file is largely inspired by owl 1.
|
|
31401
31434
|
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
@@ -32133,12 +32166,13 @@ class MenuPopover extends owl.Component {
|
|
|
32133
32166
|
class ChartDashboardMenu extends owl.Component {
|
|
32134
32167
|
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
32135
32168
|
static components = { MenuPopover };
|
|
32136
|
-
static props = { chartId: String };
|
|
32169
|
+
static props = { chartId: String, hasFullScreenButton: { type: Boolean, optional: true } };
|
|
32170
|
+
static defaultProps = { hasFullScreenButton: true };
|
|
32137
32171
|
fullScreenFigureStore;
|
|
32138
32172
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32139
32173
|
setup() {
|
|
32140
32174
|
super.setup();
|
|
32141
|
-
this.fullScreenFigureStore = useStore(
|
|
32175
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32142
32176
|
}
|
|
32143
32177
|
getMenuItems() {
|
|
32144
32178
|
return [this.fullScreenMenuItem].filter(isDefined);
|
|
@@ -32154,6 +32188,9 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
32154
32188
|
this.menuState.menuItems = getChartMenuActions(figureId, () => { }, this.env);
|
|
32155
32189
|
}
|
|
32156
32190
|
get fullScreenMenuItem() {
|
|
32191
|
+
if (!this.props.hasFullScreenButton) {
|
|
32192
|
+
return undefined;
|
|
32193
|
+
}
|
|
32157
32194
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
32158
32195
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32159
32196
|
if (definition.type === "scorecard") {
|
|
@@ -32165,7 +32202,7 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
32165
32202
|
label: isFullScreen ? _t("Exit Full Screen") : _t("Full Screen"),
|
|
32166
32203
|
class: `text-muted fa ${isFullScreen ? "fa-compress" : "fa-expand"}`,
|
|
32167
32204
|
onClick: () => {
|
|
32168
|
-
this.fullScreenFigureStore.
|
|
32205
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(figureId);
|
|
32169
32206
|
},
|
|
32170
32207
|
};
|
|
32171
32208
|
}
|
|
@@ -32177,6 +32214,7 @@ class CarouselFigure extends owl.Component {
|
|
|
32177
32214
|
figureUI: Object,
|
|
32178
32215
|
onFigureDeleted: Function,
|
|
32179
32216
|
editFigureStyle: { type: Function, optional: true },
|
|
32217
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32180
32218
|
};
|
|
32181
32219
|
static components = { ChartDashboardMenu, MenuPopover };
|
|
32182
32220
|
carouselTabsRef = owl.useRef("carouselTabs");
|
|
@@ -32184,8 +32222,10 @@ class CarouselFigure extends owl.Component {
|
|
|
32184
32222
|
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
32185
32223
|
hiddenItems = [];
|
|
32186
32224
|
animationStore;
|
|
32225
|
+
fullScreenFigureStore;
|
|
32187
32226
|
setup() {
|
|
32188
32227
|
this.animationStore = useStore(ChartAnimationStore);
|
|
32228
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
32189
32229
|
owl.useEffect(() => {
|
|
32190
32230
|
if (this.selectedCarouselItem?.type === "carouselDataView") {
|
|
32191
32231
|
this.props.editFigureStyle?.({ "pointer-events": "none" });
|
|
@@ -32232,7 +32272,8 @@ class CarouselFigure extends owl.Component {
|
|
|
32232
32272
|
item,
|
|
32233
32273
|
});
|
|
32234
32274
|
if (item.type === "chart") {
|
|
32235
|
-
|
|
32275
|
+
const animationChartId = item.chartId + (this.props.isFullScreen ? "-fullscreen" : "");
|
|
32276
|
+
this.animationStore?.enableAnimationForChart(animationChartId);
|
|
32236
32277
|
}
|
|
32237
32278
|
}
|
|
32238
32279
|
get headerStyle() {
|
|
@@ -32296,6 +32337,17 @@ class CarouselFigure extends owl.Component {
|
|
|
32296
32337
|
this.menuState.anchorRect = rect;
|
|
32297
32338
|
this.menuState.menuItems = createActions(menuItems);
|
|
32298
32339
|
}
|
|
32340
|
+
toggleFullScreen() {
|
|
32341
|
+
if (this.selectedCarouselItem?.type === "chart") {
|
|
32342
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.props.figureUI.id);
|
|
32343
|
+
}
|
|
32344
|
+
}
|
|
32345
|
+
get fullScreenButtonTitle() {
|
|
32346
|
+
return this.props.isFullScreen ? _t("Exit Full Screen") : _t("Full Screen");
|
|
32347
|
+
}
|
|
32348
|
+
get visibleCarouselItems() {
|
|
32349
|
+
return this.carousel.items.filter((item) => item.type === "carouselDataView" && this.props.isFullScreen ? false : true);
|
|
32350
|
+
}
|
|
32299
32351
|
}
|
|
32300
32352
|
|
|
32301
32353
|
class ChartFigure extends owl.Component {
|
|
@@ -32304,6 +32356,7 @@ class ChartFigure extends owl.Component {
|
|
|
32304
32356
|
figureUI: Object,
|
|
32305
32357
|
onFigureDeleted: Function,
|
|
32306
32358
|
editFigureStyle: { type: Function, optional: true },
|
|
32359
|
+
isFullScreen: { type: Boolean, optional: true },
|
|
32307
32360
|
};
|
|
32308
32361
|
static components = { ChartDashboardMenu };
|
|
32309
32362
|
onDoubleClick() {
|
|
@@ -32406,9 +32459,7 @@ class FigureComponent extends owl.Component {
|
|
|
32406
32459
|
return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
|
|
32407
32460
|
}
|
|
32408
32461
|
getBorderStyle(position) {
|
|
32409
|
-
|
|
32410
|
-
const borderColor = this.isSelected ? SELECTION_BORDER_COLOR : FIGURE_BORDER_COLOR;
|
|
32411
|
-
return `border-${position}: ${borderWidth}px solid ${borderColor};`;
|
|
32462
|
+
return `border-${position}-width: ${this.getBorderWidth()}px;`;
|
|
32412
32463
|
}
|
|
32413
32464
|
get wrapperStyle() {
|
|
32414
32465
|
const { x, y, width, height } = this.props.figureUI;
|
|
@@ -51344,6 +51395,9 @@ class GridRenderer extends SpreadsheetStore {
|
|
|
51344
51395
|
}
|
|
51345
51396
|
const { align } = this.getters.getCellStyle(position);
|
|
51346
51397
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
51398
|
+
if (formatHasRepeatedChar(evaluatedCell.value, evaluatedCell.format)) {
|
|
51399
|
+
return "left";
|
|
51400
|
+
}
|
|
51347
51401
|
if (isOverflowing && evaluatedCell.type === CellValueType.number) {
|
|
51348
51402
|
return align !== "center" ? "left" : align;
|
|
51349
51403
|
}
|
|
@@ -56815,7 +56869,7 @@ class PivotMeasureEditor extends owl.Component {
|
|
|
56815
56869
|
return undefined;
|
|
56816
56870
|
}
|
|
56817
56871
|
get isCalculatedMeasureInvalid() {
|
|
56818
|
-
return
|
|
56872
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
56819
56873
|
}
|
|
56820
56874
|
}
|
|
56821
56875
|
|
|
@@ -59530,16 +59584,16 @@ class ClickableCellSortIcon extends owl.Component {
|
|
|
59530
59584
|
}
|
|
59531
59585
|
}
|
|
59532
59586
|
|
|
59533
|
-
class
|
|
59534
|
-
static template = "o-spreadsheet-
|
|
59587
|
+
class FullScreenFigure extends owl.Component {
|
|
59588
|
+
static template = "o-spreadsheet-FullScreenFigure";
|
|
59535
59589
|
static props = {};
|
|
59536
|
-
static components = {
|
|
59537
|
-
|
|
59538
|
-
ref = owl.useRef("
|
|
59590
|
+
static components = { ChartFigure };
|
|
59591
|
+
fullScreenFigureStore;
|
|
59592
|
+
ref = owl.useRef("fullScreenFigure");
|
|
59539
59593
|
spreadsheetRect = useSpreadsheetRect();
|
|
59540
59594
|
figureRegistry = figureRegistry;
|
|
59541
59595
|
setup() {
|
|
59542
|
-
this.
|
|
59596
|
+
this.fullScreenFigureStore = useStore(FullScreenFigureStore);
|
|
59543
59597
|
const animationStore = useStore(ChartAnimationStore);
|
|
59544
59598
|
let lastFigureId = undefined;
|
|
59545
59599
|
owl.onWillUpdateProps(() => {
|
|
@@ -59551,7 +59605,7 @@ class FullScreenChart extends owl.Component {
|
|
|
59551
59605
|
owl.useEffect((el) => el?.focus(), () => [this.ref.el]);
|
|
59552
59606
|
}
|
|
59553
59607
|
get figureUI() {
|
|
59554
|
-
return this.
|
|
59608
|
+
return this.fullScreenFigureStore.fullScreenFigure;
|
|
59555
59609
|
}
|
|
59556
59610
|
get chartId() {
|
|
59557
59611
|
if (!this.figureUI)
|
|
@@ -59560,7 +59614,7 @@ class FullScreenChart extends owl.Component {
|
|
|
59560
59614
|
}
|
|
59561
59615
|
exitFullScreen() {
|
|
59562
59616
|
if (this.figureUI) {
|
|
59563
|
-
this.
|
|
59617
|
+
this.fullScreenFigureStore.toggleFullScreenFigure(this.figureUI.id);
|
|
59564
59618
|
}
|
|
59565
59619
|
}
|
|
59566
59620
|
onKeyDown(ev) {
|
|
@@ -59568,15 +59622,10 @@ class FullScreenChart extends owl.Component {
|
|
|
59568
59622
|
this.exitFullScreen();
|
|
59569
59623
|
}
|
|
59570
59624
|
}
|
|
59571
|
-
get
|
|
59572
|
-
if (!this.
|
|
59625
|
+
get figureComponent() {
|
|
59626
|
+
if (!this.figureUI)
|
|
59573
59627
|
return undefined;
|
|
59574
|
-
|
|
59575
|
-
const component = chartComponentRegistry.get(type);
|
|
59576
|
-
if (!component) {
|
|
59577
|
-
throw new Error(`Component is not defined for type ${type}`);
|
|
59578
|
-
}
|
|
59579
|
-
return component;
|
|
59628
|
+
return figureRegistry.get(this.figureUI.tag).Component;
|
|
59580
59629
|
}
|
|
59581
59630
|
}
|
|
59582
59631
|
|
|
@@ -62279,11 +62328,11 @@ class HeaderSizePlugin extends CorePlugin {
|
|
|
62279
62328
|
break;
|
|
62280
62329
|
}
|
|
62281
62330
|
case "ADD_COLUMNS_ROWS": {
|
|
62282
|
-
const sizes =
|
|
62331
|
+
const sizes = this.sizes[cmd.sheetId][cmd.dimension];
|
|
62283
62332
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62284
62333
|
const baseSize = sizes[cmd.base];
|
|
62285
|
-
sizes
|
|
62286
|
-
this.history.update("sizes", cmd.sheetId, cmd.dimension,
|
|
62334
|
+
const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
|
|
62335
|
+
this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
|
|
62287
62336
|
break;
|
|
62288
62337
|
}
|
|
62289
62338
|
case "RESIZE_COLUMNS_ROWS":
|
|
@@ -62434,9 +62483,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
62434
62483
|
break;
|
|
62435
62484
|
}
|
|
62436
62485
|
case "ADD_COLUMNS_ROWS": {
|
|
62437
|
-
const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
|
|
62438
62486
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
62439
|
-
hiddenHeaders.
|
|
62487
|
+
const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
|
|
62440
62488
|
this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
|
|
62441
62489
|
break;
|
|
62442
62490
|
}
|
|
@@ -66620,12 +66668,12 @@ class SpreadsheetRTree {
|
|
|
66620
66668
|
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
66621
66669
|
}
|
|
66622
66670
|
rtreeItemComparer(left, right) {
|
|
66623
|
-
return (left.
|
|
66624
|
-
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66671
|
+
return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
66625
66672
|
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
66626
66673
|
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
66627
66674
|
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
66628
|
-
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom
|
|
66675
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
|
|
66676
|
+
deepEquals(left.data, right.data));
|
|
66629
66677
|
}
|
|
66630
66678
|
}
|
|
66631
66679
|
/**
|
|
@@ -79473,8 +79521,8 @@ class RowGroup extends AbstractHeaderGroup {
|
|
|
79473
79521
|
left: `calc(50% - 1px)`, // -1px: we want the border to be on the center
|
|
79474
79522
|
width: `30%`,
|
|
79475
79523
|
height: `calc(100% - ${groupBox.headerRect.height / 2}px)`,
|
|
79476
|
-
"border-left": `1px solid
|
|
79477
|
-
"border-bottom": groupBox.isEndHidden ? "" : `1px solid
|
|
79524
|
+
"border-left": `1px solid`,
|
|
79525
|
+
"border-bottom": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79478
79526
|
});
|
|
79479
79527
|
}
|
|
79480
79528
|
get groupHeaderStyle() {
|
|
@@ -79526,8 +79574,8 @@ class ColGroup extends AbstractHeaderGroup {
|
|
|
79526
79574
|
left: `${groupBox.headerRect.width / 2}px`,
|
|
79527
79575
|
width: `calc(100% - ${groupBox.headerRect.width / 2}px)`,
|
|
79528
79576
|
height: `30%`,
|
|
79529
|
-
"border-top": `1px solid
|
|
79530
|
-
"border-right": groupBox.isEndHidden ? "" : `1px solid
|
|
79577
|
+
"border-top": `1px solid`,
|
|
79578
|
+
"border-right": groupBox.isEndHidden ? "" : `1px solid`,
|
|
79531
79579
|
});
|
|
79532
79580
|
}
|
|
79533
79581
|
get groupHeaderStyle() {
|
|
@@ -79864,6 +79912,9 @@ class SmallBottomBar extends owl.Component {
|
|
|
79864
79912
|
? this.composerFocusStore.focusMode
|
|
79865
79913
|
: "inactive";
|
|
79866
79914
|
}
|
|
79915
|
+
get showFxIcon() {
|
|
79916
|
+
return this.focus === "inactive" && !this.composerStore.currentContent;
|
|
79917
|
+
}
|
|
79867
79918
|
get rect() {
|
|
79868
79919
|
return this.composerRef.el
|
|
79869
79920
|
? getBoundingRectAsPOJO(this.composerRef.el)
|
|
@@ -79906,13 +79957,6 @@ class SmallBottomBar extends owl.Component {
|
|
|
79906
79957
|
}
|
|
79907
79958
|
|
|
79908
79959
|
const COMPOSER_MAX_HEIGHT = 300;
|
|
79909
|
-
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
79910
|
-
// FIXME This svg is hardcoded in the css file. We should find a better way to handle it.
|
|
79911
|
-
// const FX_SVG = /*xml*/ `
|
|
79912
|
-
// <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
79913
|
-
// <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'/>
|
|
79914
|
-
// </svg>
|
|
79915
|
-
// `;
|
|
79916
79960
|
class TopBarComposer extends owl.Component {
|
|
79917
79961
|
static template = "o-spreadsheet-TopBarComposer";
|
|
79918
79962
|
static props = {};
|
|
@@ -79939,6 +79983,9 @@ class TopBarComposer extends owl.Component {
|
|
|
79939
79983
|
? this.composerFocusStore.focusMode
|
|
79940
79984
|
: "inactive";
|
|
79941
79985
|
}
|
|
79986
|
+
get showFxIcon() {
|
|
79987
|
+
return this.focus === "inactive" && !this.composerStore.currentContent;
|
|
79988
|
+
}
|
|
79942
79989
|
get composerStyle() {
|
|
79943
79990
|
const style = {
|
|
79944
79991
|
padding: "5px 0px 5px 8px",
|
|
@@ -80876,7 +80923,7 @@ class Spreadsheet extends owl.Component {
|
|
|
80876
80923
|
SidePanels,
|
|
80877
80924
|
SpreadsheetDashboard,
|
|
80878
80925
|
HeaderGroupContainer,
|
|
80879
|
-
|
|
80926
|
+
FullScreenFigure,
|
|
80880
80927
|
};
|
|
80881
80928
|
sidePanel;
|
|
80882
80929
|
spreadsheetRef = owl.useRef("spreadsheet");
|
|
@@ -85600,6 +85647,7 @@ const components = {
|
|
|
85600
85647
|
Grid,
|
|
85601
85648
|
GridOverlay,
|
|
85602
85649
|
ScorecardChart,
|
|
85650
|
+
GaugeChartComponent,
|
|
85603
85651
|
LineConfigPanel,
|
|
85604
85652
|
BarConfigPanel,
|
|
85605
85653
|
PieChartDesignPanel,
|
|
@@ -85638,7 +85686,7 @@ const components = {
|
|
|
85638
85686
|
RadioSelection,
|
|
85639
85687
|
GeoChartRegionSelectSection,
|
|
85640
85688
|
ChartDashboardMenu,
|
|
85641
|
-
|
|
85689
|
+
FullScreenFigure,
|
|
85642
85690
|
};
|
|
85643
85691
|
const hooks = {
|
|
85644
85692
|
useDragAndDropListItems,
|
|
@@ -85738,6 +85786,6 @@ exports.tokenColors = tokenColors;
|
|
|
85738
85786
|
exports.tokenize = tokenize;
|
|
85739
85787
|
|
|
85740
85788
|
|
|
85741
|
-
__info__.version = "19.1.0-alpha.
|
|
85742
|
-
__info__.date = "2025-
|
|
85743
|
-
__info__.hash = "
|
|
85789
|
+
__info__.version = "19.1.0-alpha.4";
|
|
85790
|
+
__info__.date = "2025-10-07T10:03:20.917Z";
|
|
85791
|
+
__info__.hash = "b7cfed8";
|