@odoo/o-spreadsheet 19.4.0-alpha.6 → 19.4.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o_spreadsheet.cjs +609 -325
- package/dist/o_spreadsheet.css +3 -3
- package/dist/o_spreadsheet.esm.js +609 -325
- package/dist/o_spreadsheet.iife.js +609 -325
- package/dist/o_spreadsheet.min.iife.js +273 -274
- package/dist/o_spreadsheet.xml +3 -3
- package/dist/types/formulas/code_builder.d.ts +19 -5
- package/dist/types/helpers/figures/charts/runtime/chart_highlight.d.ts +9 -0
- package/dist/types/helpers/figures/charts/runtime/chartjs_legend.d.ts +12 -10
- package/dist/types/helpers/figures/charts/runtime/chartjs_scales.d.ts +11 -12
- package/dist/types/helpers/pivot/pivot_composer_helpers.d.ts +4 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/plugins/ui_core_views/pivot_ui.d.ts +17 -8
- 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 19.4.0-alpha.
|
|
6
|
-
* @date 2026-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.4.0-alpha.7
|
|
6
|
+
* @date 2026-05-20T14:40:27.236Z
|
|
7
|
+
* @hash 7ee566f
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, whenReady, xml } from "@odoo/owl";
|
|
@@ -139,17 +139,234 @@ if (typeof globalThis.document === "undefined") {
|
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/components/helpers/dom_helpers.ts
|
|
144
|
+
const macRegex = /Mac/i;
|
|
145
|
+
let zoomCssDoesNotAffectBoundingRect = false;
|
|
146
|
+
function defineZoomCssImpactOnBoundingRect() {
|
|
147
|
+
const div = document.createElement("div");
|
|
148
|
+
div.setAttribute("style", `width:10px;height:1px;zoom:2;position:absolute;z-index:-10000`);
|
|
149
|
+
document.body.appendChild(div);
|
|
150
|
+
zoomCssDoesNotAffectBoundingRect = div.getBoundingClientRect().width !== 20;
|
|
151
|
+
document.body.removeChild(div);
|
|
152
|
+
}
|
|
153
|
+
whenReady(defineZoomCssImpactOnBoundingRect);
|
|
154
|
+
const MODIFIER_KEYS = [
|
|
155
|
+
"Shift",
|
|
156
|
+
"Control",
|
|
157
|
+
"Alt",
|
|
158
|
+
"Meta"
|
|
159
|
+
];
|
|
160
|
+
/**
|
|
161
|
+
* Return true if the event was triggered from
|
|
162
|
+
* a child element.
|
|
163
|
+
*/
|
|
164
|
+
function isChildEvent(parent, ev) {
|
|
165
|
+
if (!parent) return false;
|
|
166
|
+
return !!ev.target && parent.contains(ev.target);
|
|
167
|
+
}
|
|
168
|
+
function gridOverlayPosition(zoom = 1) {
|
|
169
|
+
const spreadsheetElement = document.querySelector(".o-grid-overlay");
|
|
170
|
+
const result = spreadsheetElement && zoomCorrectedElementRect(spreadsheetElement, zoom);
|
|
171
|
+
if (!result) throw new Error("Can't find spreadsheet position");
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
function zoomCorrectedElementRect(el, zoomLevel) {
|
|
175
|
+
const zoomedElement = el.closest(".o-zoomable");
|
|
176
|
+
let targetEl;
|
|
177
|
+
let zoom = 1;
|
|
178
|
+
if (zoomedElement) {
|
|
179
|
+
targetEl = zoomedElement;
|
|
180
|
+
zoom = zoomCssDoesNotAffectBoundingRect ? zoomLevel : 1;
|
|
181
|
+
} else targetEl = el;
|
|
182
|
+
const rect = targetEl.getBoundingClientRect();
|
|
183
|
+
return {
|
|
184
|
+
x: rect.x * zoom,
|
|
185
|
+
y: rect.y * zoom,
|
|
186
|
+
width: rect.width * zoom,
|
|
187
|
+
height: rect.height * zoom
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function getRefBoundingRect(ref) {
|
|
191
|
+
if (!ref.el) return {
|
|
192
|
+
x: 0,
|
|
193
|
+
y: 0,
|
|
194
|
+
width: 0,
|
|
195
|
+
height: 0
|
|
196
|
+
};
|
|
197
|
+
return getBoundingRectAsPOJO(ref.el);
|
|
198
|
+
}
|
|
199
|
+
function getBoundingRectAsPOJO(el) {
|
|
200
|
+
const rect = el.getBoundingClientRect();
|
|
201
|
+
return {
|
|
202
|
+
x: rect.x,
|
|
203
|
+
y: rect.y,
|
|
204
|
+
width: rect.width,
|
|
205
|
+
height: rect.height
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Iterate over all the children of `el` in the dom tree starting at `el`, depth first.
|
|
210
|
+
*/
|
|
211
|
+
function* iterateChildren(el) {
|
|
212
|
+
yield el;
|
|
213
|
+
if (el.hasChildNodes()) for (const child of el.childNodes) yield* iterateChildren(child);
|
|
214
|
+
}
|
|
215
|
+
function getOpenedMenus() {
|
|
216
|
+
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
217
|
+
}
|
|
218
|
+
function getCurrentSelection(el) {
|
|
219
|
+
const { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
220
|
+
return {
|
|
221
|
+
start: findSelectionIndex(el, startElement, startSelectionOffset),
|
|
222
|
+
end: findSelectionIndex(el, endElement, endSelectionOffset)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function getStartAndEndSelection(el) {
|
|
226
|
+
const selection = document.getSelection();
|
|
227
|
+
return {
|
|
228
|
+
startElement: selection.anchorNode || el,
|
|
229
|
+
startSelectionOffset: selection.anchorOffset,
|
|
230
|
+
endElement: selection.focusNode || el,
|
|
231
|
+
endSelectionOffset: selection.focusOffset
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
236
|
+
* The selected node is either a Text node or an Element node.
|
|
237
|
+
*
|
|
238
|
+
* case 1 -Text node:
|
|
239
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
240
|
+
* content length of all previous nodes.
|
|
241
|
+
*
|
|
242
|
+
* case 2 - Element node:
|
|
243
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
244
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
245
|
+
*
|
|
246
|
+
* See the MDN documentation for more details.
|
|
247
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
248
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
249
|
+
*
|
|
250
|
+
*/
|
|
251
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
252
|
+
let usedCharacters = 0;
|
|
253
|
+
const it = iterateChildren(el);
|
|
254
|
+
let current = it.next();
|
|
255
|
+
let isFirstParagraph = true;
|
|
256
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
257
|
+
if (!current.value.hasChildNodes()) {
|
|
258
|
+
if (current.value.textContent) usedCharacters += current.value.textContent.length;
|
|
259
|
+
}
|
|
260
|
+
if (current.value.nodeName === "P" || current.value.nodeName === "DIV" && current.value !== el) if (isFirstParagraph) isFirstParagraph = false;
|
|
261
|
+
else usedCharacters++;
|
|
262
|
+
current = it.next();
|
|
263
|
+
}
|
|
264
|
+
if (current.value !== nodeToFind)
|
|
265
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
266
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
267
|
+
*
|
|
268
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
269
|
+
*/
|
|
270
|
+
return 0;
|
|
271
|
+
else if (!current.value.hasChildNodes()) usedCharacters += nodeOffset;
|
|
272
|
+
else {
|
|
273
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
274
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
275
|
+
if (child.textContent !== null) {
|
|
276
|
+
let chars = child.textContent.length;
|
|
277
|
+
if (child.nodeName === "P" && index !== children.length - 1) chars++;
|
|
278
|
+
return acc + chars;
|
|
279
|
+
} else return acc;
|
|
280
|
+
}, 0);
|
|
281
|
+
}
|
|
282
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") usedCharacters++;
|
|
283
|
+
return usedCharacters;
|
|
284
|
+
}
|
|
285
|
+
const letterRegex = /^[a-zA-Z]$/;
|
|
286
|
+
/**
|
|
287
|
+
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
288
|
+
*
|
|
289
|
+
* @argument ev - The keyboard event to transform
|
|
290
|
+
* @argument mode - Use either ev.key of ev.code to get the string shortcut
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* event : { ctrlKey: true, key: "a" } => "Ctrl+A"
|
|
294
|
+
* event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
|
|
295
|
+
*/
|
|
296
|
+
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
297
|
+
let keyDownString = "";
|
|
298
|
+
if (!MODIFIER_KEYS.includes(ev.key)) {
|
|
299
|
+
if (isCtrlKey(ev)) keyDownString += "Ctrl+";
|
|
300
|
+
if (ev.altKey) keyDownString += "Alt+";
|
|
301
|
+
if (ev.shiftKey) keyDownString += "Shift+";
|
|
302
|
+
}
|
|
303
|
+
const key = mode === "key" ? ev.key : ev.code;
|
|
304
|
+
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
305
|
+
return keyDownString;
|
|
306
|
+
}
|
|
307
|
+
function isMacOS() {
|
|
308
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
312
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
313
|
+
* On Mac, this is the "meta" or "command" key.
|
|
314
|
+
*/
|
|
315
|
+
function isCtrlKey(ev) {
|
|
316
|
+
return isMacOS() || isIOS() ? ev.metaKey : ev.ctrlKey;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* @param {MouseEvent} ev - The mouse event.
|
|
320
|
+
* @returns {boolean} Returns true if the event was triggered by a middle-click
|
|
321
|
+
* or a Ctrl + Click (Cmd + Click on Mac).
|
|
322
|
+
*/
|
|
323
|
+
function isMiddleClickOrCtrlClick(ev) {
|
|
324
|
+
return ev.button === 1 || isCtrlKey(ev) && ev.button === 0;
|
|
325
|
+
}
|
|
326
|
+
function downloadFile(dataUrl, fileName) {
|
|
327
|
+
const a = document.createElement("a");
|
|
328
|
+
a.href = dataUrl;
|
|
329
|
+
a.download = fileName;
|
|
330
|
+
document.body.appendChild(a);
|
|
331
|
+
a.click();
|
|
332
|
+
document.body.removeChild(a);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Detects if the current browser is Firefox
|
|
336
|
+
*/
|
|
337
|
+
function isBrowserFirefox() {
|
|
338
|
+
return /Firefox/i.test(navigator.userAgent);
|
|
339
|
+
}
|
|
340
|
+
function maxTouchPoints() {
|
|
341
|
+
return navigator.maxTouchPoints || 1;
|
|
342
|
+
}
|
|
343
|
+
function isAndroid() {
|
|
344
|
+
return /Android/i.test(navigator.userAgent);
|
|
345
|
+
}
|
|
346
|
+
function isIOS() {
|
|
347
|
+
return /(iPad|iPhone|iPod)/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && maxTouchPoints() > 1;
|
|
348
|
+
}
|
|
349
|
+
function isOtherMobileOS() {
|
|
350
|
+
return /(webOS|BlackBerry|Windows Phone)/i.test(navigator.userAgent);
|
|
351
|
+
}
|
|
352
|
+
function isMobileOS() {
|
|
353
|
+
return isAndroid() || isIOS() || isOtherMobileOS();
|
|
354
|
+
}
|
|
355
|
+
|
|
142
356
|
//#endregion
|
|
143
357
|
//#region src/actions/action.ts
|
|
144
358
|
function createActions(menuItems) {
|
|
145
359
|
return menuItems.map(createAction).sort((a, b) => a.sequence - b.sequence);
|
|
146
360
|
}
|
|
361
|
+
function adaptShortcutMacOs(shortcut) {
|
|
362
|
+
return shortcut.replace("Ctrl", "⌘").replace("Alt", "⌃");
|
|
363
|
+
}
|
|
147
364
|
let nextItemId = 1;
|
|
148
365
|
function createAction(item) {
|
|
149
366
|
const name = item.name;
|
|
150
367
|
const children = item.children;
|
|
151
368
|
const description = item.description;
|
|
152
|
-
const shortcut = item.shortcut;
|
|
369
|
+
const shortcut = item.shortcut && isMacOS() ? adaptShortcutMacOs(item.shortcut) : item.shortcut;
|
|
153
370
|
const icon = item.icon;
|
|
154
371
|
const secondaryIcon = item.secondaryIcon;
|
|
155
372
|
const itemId = item.id || nextItemId++;
|
|
@@ -5031,36 +5248,77 @@ function applyVectorization(context, descr, args, acceptToVectorize = void 0) {
|
|
|
5031
5248
|
} else args[i] = arg[0][0];
|
|
5032
5249
|
}
|
|
5033
5250
|
}
|
|
5034
|
-
|
|
5035
|
-
const
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5251
|
+
const argsToFocus = argTargeting(descr, args.length);
|
|
5252
|
+
const argDefinitions = new Array(args.length);
|
|
5253
|
+
for (let k = 0; k < args.length; k++) argDefinitions[k] = descr.args[argsToFocus[k].index];
|
|
5254
|
+
if (countVectorizedCol === 1 && countVectorizedRow === 1) return errorHandlingCompute(descr, context, args, argDefinitions);
|
|
5255
|
+
const argsBuffer = new Array(args.length);
|
|
5256
|
+
const argGetters = [];
|
|
5257
|
+
const vectorizedIndices = [];
|
|
5258
|
+
for (let k = 0; k < args.length; k++) {
|
|
5259
|
+
const arg = args[k];
|
|
5260
|
+
switch (vectorArgsType?.[k]) {
|
|
5261
|
+
case "matrix":
|
|
5262
|
+
argGetters.push((i, j) => arg[i][j]);
|
|
5263
|
+
vectorizedIndices.push(k);
|
|
5264
|
+
break;
|
|
5265
|
+
case "horizontal":
|
|
5266
|
+
argGetters.push((i) => arg[i][0]);
|
|
5267
|
+
vectorizedIndices.push(k);
|
|
5268
|
+
break;
|
|
5269
|
+
case "vertical":
|
|
5270
|
+
argGetters.push((_i, j) => arg[0][j]);
|
|
5271
|
+
vectorizedIndices.push(k);
|
|
5272
|
+
break;
|
|
5273
|
+
case void 0:
|
|
5274
|
+
argsBuffer[k] = arg;
|
|
5275
|
+
break;
|
|
5041
5276
|
}
|
|
5042
|
-
}
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5277
|
+
}
|
|
5278
|
+
const nbVectorized = vectorizedIndices.length;
|
|
5279
|
+
const result = new Array(countVectorizedCol);
|
|
5280
|
+
for (let col = 0; col < countVectorizedCol; col++) {
|
|
5281
|
+
const column = new Array(countVectorizedRow);
|
|
5282
|
+
result[col] = column;
|
|
5283
|
+
for (let row = 0; row < countVectorizedRow; row++) {
|
|
5284
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
5285
|
+
column[row] = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
5286
|
+
continue;
|
|
5287
|
+
}
|
|
5288
|
+
for (let k = 0; k < nbVectorized; k++) argsBuffer[vectorizedIndices[k]] = argGetters[k](col, row);
|
|
5289
|
+
const singleCellComputeResult = errorHandlingCompute(descr, context, argsBuffer, argDefinitions);
|
|
5290
|
+
column[row] = isMatrix(singleCellComputeResult) ? singleCellComputeResult[0][0] : singleCellComputeResult;
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
return result;
|
|
5048
5294
|
}
|
|
5049
5295
|
function computeFunctionToObject(descr, context, args) {
|
|
5050
5296
|
if (context.debug) {
|
|
5051
5297
|
debugger;
|
|
5052
5298
|
context.debug = false;
|
|
5053
5299
|
}
|
|
5054
|
-
const
|
|
5300
|
+
const compute = descr.compute;
|
|
5301
|
+
let result;
|
|
5302
|
+
switch (args.length) {
|
|
5303
|
+
case 1:
|
|
5304
|
+
result = compute.call(context, args[0]);
|
|
5305
|
+
break;
|
|
5306
|
+
case 2:
|
|
5307
|
+
result = compute.call(context, args[0], args[1]);
|
|
5308
|
+
break;
|
|
5309
|
+
case 3:
|
|
5310
|
+
result = compute.call(context, args[0], args[1], args[2]);
|
|
5311
|
+
break;
|
|
5312
|
+
default: result = compute.apply(context, args);
|
|
5313
|
+
}
|
|
5055
5314
|
if (!isMatrix(result)) return isFunctionResultObject(result) ? result : { value: result };
|
|
5056
5315
|
if (isFunctionResultObject(result[0][0])) return result;
|
|
5057
5316
|
return matrixMap(result, (row) => ({ value: row }));
|
|
5058
5317
|
}
|
|
5059
|
-
function errorHandlingCompute(descr, context, args) {
|
|
5060
|
-
const argsToFocus = argTargeting(descr, args.length);
|
|
5318
|
+
function errorHandlingCompute(descr, context, args, argDefinitions) {
|
|
5061
5319
|
for (let i = 0; i < args.length; i++) {
|
|
5062
5320
|
const arg = args[i];
|
|
5063
|
-
if (!
|
|
5321
|
+
if (!argDefinitions[i].acceptErrors && !isMatrix(arg) && isEvaluationError(arg?.value)) return arg;
|
|
5064
5322
|
}
|
|
5065
5323
|
try {
|
|
5066
5324
|
return computeFunctionToObject(descr, context, args);
|
|
@@ -6259,8 +6517,13 @@ function getApplyRangeChangeAddColRow(cmd) {
|
|
|
6259
6517
|
changeType: "NONE",
|
|
6260
6518
|
range
|
|
6261
6519
|
};
|
|
6520
|
+
const isUnboundedAtEnd = range.unboundedZone[end] === void 0;
|
|
6521
|
+
if (isUnboundedAtEnd && !range.unboundedZone.hasHeader) return {
|
|
6522
|
+
changeType: "RESIZE",
|
|
6523
|
+
range: createAdaptedRange(range, dimension, "RESIZE", cmd.quantity)
|
|
6524
|
+
};
|
|
6262
6525
|
if (cmd.position === "after") {
|
|
6263
|
-
if (range.zone[start] <= cmd.base && cmd.base < range.zone[end]) return {
|
|
6526
|
+
if (range.zone[start] <= cmd.base && (cmd.base < range.zone[end] || isUnboundedAtEnd)) return {
|
|
6264
6527
|
changeType: "RESIZE",
|
|
6265
6528
|
range: createAdaptedRange(range, dimension, "RESIZE", cmd.quantity)
|
|
6266
6529
|
};
|
|
@@ -6506,40 +6769,65 @@ function getRange(sheetXC, sheetId) {
|
|
|
6506
6769
|
|
|
6507
6770
|
//#endregion
|
|
6508
6771
|
//#region src/formulas/code_builder.ts
|
|
6772
|
+
var JsString = class extends String {};
|
|
6773
|
+
/**
|
|
6774
|
+
* Creates a JsString from a raw string, bypassing the template string interpolation checks.
|
|
6775
|
+
* This can lead to security vulnerabilities if the string is not trusted!
|
|
6776
|
+
*/
|
|
6777
|
+
function dangerouslyCreateJsStr(trustedStr) {
|
|
6778
|
+
return new JsString(trustedStr);
|
|
6779
|
+
}
|
|
6780
|
+
/**
|
|
6781
|
+
* Creates a JsString from a template string, ensuring that all interpolated values are safe.
|
|
6782
|
+
*/
|
|
6783
|
+
function jsStr(strings, ...values) {
|
|
6784
|
+
let str = "";
|
|
6785
|
+
for (let i = 0; i < strings.length; i++) {
|
|
6786
|
+
const value = values[i];
|
|
6787
|
+
if (i >= values.length) str += strings[i];
|
|
6788
|
+
else if (isSafeJsValue(value)) str += strings[i] + value;
|
|
6789
|
+
else if (Array.isArray(value) && value.every(isSafeJsValue)) str += strings[i] + value.map((v) => v.toString()).join(",");
|
|
6790
|
+
else throw new Error(`Invalid interpolated value at index ${i}: ${value}`);
|
|
6791
|
+
}
|
|
6792
|
+
return dangerouslyCreateJsStr(str);
|
|
6793
|
+
}
|
|
6794
|
+
function isSafeJsValue(value) {
|
|
6795
|
+
return value instanceof JsString || typeof value === "number" || typeof value === "boolean";
|
|
6796
|
+
}
|
|
6509
6797
|
var FunctionCodeBuilder = class {
|
|
6510
6798
|
scope;
|
|
6511
|
-
code =
|
|
6799
|
+
code = [];
|
|
6512
6800
|
constructor(scope = new Scope()) {
|
|
6513
6801
|
this.scope = scope;
|
|
6514
6802
|
}
|
|
6515
6803
|
append(...lines) {
|
|
6516
|
-
|
|
6804
|
+
for (const line of lines) if (line instanceof FunctionCodeImpl) this.code.push(...line.code);
|
|
6805
|
+
else if (line instanceof JsString) this.code.push(line);
|
|
6806
|
+
else throw new Error(`Invalid line: ${line}`);
|
|
6517
6807
|
}
|
|
6518
6808
|
return(expression) {
|
|
6809
|
+
if (!isSafeJsValue(expression)) throw new Error(`Expected JsString, got ${expression}`);
|
|
6519
6810
|
return new FunctionCodeImpl(this.scope, this.code, expression);
|
|
6520
6811
|
}
|
|
6521
6812
|
toString() {
|
|
6522
|
-
return indentCode(this.code);
|
|
6813
|
+
return indentCode(this.code.join("\n"));
|
|
6523
6814
|
}
|
|
6524
6815
|
};
|
|
6525
6816
|
var FunctionCodeImpl = class {
|
|
6526
6817
|
scope;
|
|
6527
|
-
returnExpression;
|
|
6528
6818
|
code;
|
|
6819
|
+
returnExpression;
|
|
6529
6820
|
constructor(scope, code, returnExpression) {
|
|
6530
6821
|
this.scope = scope;
|
|
6822
|
+
this.code = code;
|
|
6531
6823
|
this.returnExpression = returnExpression;
|
|
6532
|
-
this.code = indentCode(code);
|
|
6533
|
-
}
|
|
6534
|
-
toString() {
|
|
6535
|
-
return this.code;
|
|
6536
6824
|
}
|
|
6537
6825
|
assignResultToVariable() {
|
|
6538
6826
|
if (this.scope.isAlreadyDeclared(this.returnExpression)) return this;
|
|
6539
6827
|
const variableName = this.scope.nextVariableName();
|
|
6540
6828
|
const code = new FunctionCodeBuilder(this.scope);
|
|
6541
|
-
code.append(this.code);
|
|
6542
|
-
code.append(`const ${variableName} = ${this.returnExpression};`);
|
|
6829
|
+
code.append(...this.code);
|
|
6830
|
+
code.append(jsStr`const ${variableName} = ${this.returnExpression};`);
|
|
6543
6831
|
return code.return(variableName);
|
|
6544
6832
|
}
|
|
6545
6833
|
};
|
|
@@ -6547,12 +6835,12 @@ var Scope = class {
|
|
|
6547
6835
|
nextId = 1;
|
|
6548
6836
|
declaredVariables = /* @__PURE__ */ new Set();
|
|
6549
6837
|
nextVariableName() {
|
|
6550
|
-
const name = `_${this.nextId++}`;
|
|
6551
|
-
this.declaredVariables.add(name);
|
|
6838
|
+
const name = jsStr`_${this.nextId++}`;
|
|
6839
|
+
this.declaredVariables.add(name.toString());
|
|
6552
6840
|
return name;
|
|
6553
6841
|
}
|
|
6554
6842
|
isAlreadyDeclared(name) {
|
|
6555
|
-
return this.declaredVariables.has(name);
|
|
6843
|
+
return this.declaredVariables.has(name.toString());
|
|
6556
6844
|
}
|
|
6557
6845
|
};
|
|
6558
6846
|
/**
|
|
@@ -6769,6 +7057,7 @@ function compileTokens(tokens) {
|
|
|
6769
7057
|
try {
|
|
6770
7058
|
return compileTokensOrThrow(tokens);
|
|
6771
7059
|
} catch (error) {
|
|
7060
|
+
if (!(error instanceof EvaluationError)) throw error;
|
|
6772
7061
|
return {
|
|
6773
7062
|
tokens,
|
|
6774
7063
|
literalValues: {
|
|
@@ -6799,7 +7088,7 @@ function compileTokensOrThrow(tokens) {
|
|
|
6799
7088
|
const compiledAST = compileAST(ast);
|
|
6800
7089
|
const code = new FunctionCodeBuilder();
|
|
6801
7090
|
code.append(compiledAST);
|
|
6802
|
-
code.append(`return ${compiledAST.returnExpression};`);
|
|
7091
|
+
code.append(jsStr`return ${compiledAST.returnExpression};`);
|
|
6803
7092
|
functionCache[cacheKey] = new Function("deps", "ref", "range", "getSymbolValue", "ctx", code.toString());
|
|
6804
7093
|
/**
|
|
6805
7094
|
* This function compile the function arguments. It is mostly straightforward,
|
|
@@ -6832,19 +7121,21 @@ function compileTokensOrThrow(tokens) {
|
|
|
6832
7121
|
function compileAST(ast, hasRange = false) {
|
|
6833
7122
|
const code = new FunctionCodeBuilder(scope);
|
|
6834
7123
|
if (ast.debug) {
|
|
6835
|
-
code.append(
|
|
6836
|
-
code.append(`ctx["debug"] = true;`);
|
|
7124
|
+
code.append(jsStr`debugger;`);
|
|
7125
|
+
code.append(jsStr`ctx["debug"] = true;`);
|
|
6837
7126
|
}
|
|
6838
7127
|
switch (ast.type) {
|
|
6839
|
-
case "BOOLEAN": return code.return(`{ value: ${ast.value} }`);
|
|
6840
|
-
case "NUMBER": return code.return(`this.literalValues.numbers[${numberCount++}]`);
|
|
6841
|
-
case "STRING": return code.return(`this.literalValues.strings[${stringCount++}]`);
|
|
6842
|
-
case "REFERENCE": return code.return(`${ast.value.includes(":") || hasRange ? `range` : `ref`}(deps[${dependencyCount++}])`);
|
|
7128
|
+
case "BOOLEAN": return code.return(jsStr`{ value: ${ast.value} }`);
|
|
7129
|
+
case "NUMBER": return code.return(jsStr`this.literalValues.numbers[${numberCount++}]`);
|
|
7130
|
+
case "STRING": return code.return(jsStr`this.literalValues.strings[${stringCount++}]`);
|
|
7131
|
+
case "REFERENCE": return code.return(jsStr`${ast.value.includes(":") || hasRange ? jsStr`range` : jsStr`ref`}(deps[${dependencyCount++}])`);
|
|
6843
7132
|
case "FUNCALL":
|
|
6844
7133
|
const args = compileFunctionArgs(ast).map((arg) => arg.assignResultToVariable());
|
|
6845
7134
|
code.append(...args);
|
|
6846
7135
|
const fnName = ast.value.toUpperCase();
|
|
6847
|
-
|
|
7136
|
+
if (!Object.hasOwn(functions$1, fnName)) throw new Error(`Unknown function: "${fnName}"`);
|
|
7137
|
+
const jsFnName = dangerouslyCreateJsStr(fnName);
|
|
7138
|
+
return code.return(jsStr`ctx['${jsFnName}'](${args.map((arg) => arg.returnExpression)})`);
|
|
6848
7139
|
case "ARRAY": return compileAST({
|
|
6849
7140
|
type: "FUNCALL",
|
|
6850
7141
|
value: "ARRAY.LITERAL",
|
|
@@ -6859,23 +7150,25 @@ function compileTokensOrThrow(tokens) {
|
|
|
6859
7150
|
tokenEndIndex: 0
|
|
6860
7151
|
});
|
|
6861
7152
|
case "UNARY_OPERATION": {
|
|
6862
|
-
|
|
7153
|
+
if (!Object.hasOwn(UNARY_OPERATOR_MAP, ast.value)) throw new Error(`Unknown operator: "${ast.value}"`);
|
|
7154
|
+
const fnName = dangerouslyCreateJsStr(UNARY_OPERATOR_MAP[ast.value]);
|
|
6863
7155
|
const operand = compileAST(ast.operand, ast.value === "#").assignResultToVariable();
|
|
6864
7156
|
code.append(operand);
|
|
6865
|
-
return code.return(`ctx['${fnName}'](${operand.returnExpression})`);
|
|
7157
|
+
return code.return(jsStr`ctx['${fnName}'](${operand.returnExpression})`);
|
|
6866
7158
|
}
|
|
6867
7159
|
case "BIN_OPERATION": {
|
|
6868
|
-
|
|
7160
|
+
if (!Object.hasOwn(OPERATOR_MAP, ast.value)) throw new Error(`Unknown operator: "${ast.value}"`);
|
|
7161
|
+
const fnName = dangerouslyCreateJsStr(OPERATOR_MAP[ast.value]);
|
|
6869
7162
|
const left = compileAST(ast.left, false).assignResultToVariable();
|
|
6870
7163
|
const right = compileAST(ast.right, false).assignResultToVariable();
|
|
6871
7164
|
code.append(left);
|
|
6872
7165
|
code.append(right);
|
|
6873
|
-
return code.return(`ctx['${fnName}'](${left.returnExpression}, ${right.returnExpression})`);
|
|
7166
|
+
return code.return(jsStr`ctx['${fnName}'](${left.returnExpression}, ${right.returnExpression})`);
|
|
6874
7167
|
}
|
|
6875
7168
|
case "SYMBOL":
|
|
6876
7169
|
const symbolIndex = symbols.indexOf(ast.value);
|
|
6877
|
-
return code.return(`getSymbolValue(this.symbols[${symbolIndex}], ${hasRange})`);
|
|
6878
|
-
case "EMPTY": return code.return(
|
|
7170
|
+
return code.return(jsStr`getSymbolValue(this.symbols[${symbolIndex}], ${hasRange})`);
|
|
7171
|
+
case "EMPTY": return code.return(jsStr`undefined`);
|
|
6879
7172
|
}
|
|
6880
7173
|
}
|
|
6881
7174
|
}
|
|
@@ -11552,220 +11845,6 @@ var ScorecardChartConfigBuilder = class {
|
|
|
11552
11845
|
}
|
|
11553
11846
|
};
|
|
11554
11847
|
|
|
11555
|
-
//#endregion
|
|
11556
|
-
//#region src/components/helpers/dom_helpers.ts
|
|
11557
|
-
const macRegex = /Mac/i;
|
|
11558
|
-
let zoomCssDoesNotAffectBoundingRect = false;
|
|
11559
|
-
function defineZoomCssImpactOnBoundingRect() {
|
|
11560
|
-
const div = document.createElement("div");
|
|
11561
|
-
div.setAttribute("style", `width:10px;height:1px;zoom:2;position:absolute;z-index:-10000`);
|
|
11562
|
-
document.body.appendChild(div);
|
|
11563
|
-
zoomCssDoesNotAffectBoundingRect = div.getBoundingClientRect().width !== 20;
|
|
11564
|
-
document.body.removeChild(div);
|
|
11565
|
-
}
|
|
11566
|
-
whenReady(defineZoomCssImpactOnBoundingRect);
|
|
11567
|
-
const MODIFIER_KEYS = [
|
|
11568
|
-
"Shift",
|
|
11569
|
-
"Control",
|
|
11570
|
-
"Alt",
|
|
11571
|
-
"Meta"
|
|
11572
|
-
];
|
|
11573
|
-
/**
|
|
11574
|
-
* Return true if the event was triggered from
|
|
11575
|
-
* a child element.
|
|
11576
|
-
*/
|
|
11577
|
-
function isChildEvent(parent, ev) {
|
|
11578
|
-
if (!parent) return false;
|
|
11579
|
-
return !!ev.target && parent.contains(ev.target);
|
|
11580
|
-
}
|
|
11581
|
-
function gridOverlayPosition(zoom = 1) {
|
|
11582
|
-
const spreadsheetElement = document.querySelector(".o-grid-overlay");
|
|
11583
|
-
const result = spreadsheetElement && zoomCorrectedElementRect(spreadsheetElement, zoom);
|
|
11584
|
-
if (!result) throw new Error("Can't find spreadsheet position");
|
|
11585
|
-
return result;
|
|
11586
|
-
}
|
|
11587
|
-
function zoomCorrectedElementRect(el, zoomLevel) {
|
|
11588
|
-
const zoomedElement = el.closest(".o-zoomable");
|
|
11589
|
-
let targetEl;
|
|
11590
|
-
let zoom = 1;
|
|
11591
|
-
if (zoomedElement) {
|
|
11592
|
-
targetEl = zoomedElement;
|
|
11593
|
-
zoom = zoomCssDoesNotAffectBoundingRect ? zoomLevel : 1;
|
|
11594
|
-
} else targetEl = el;
|
|
11595
|
-
const rect = targetEl.getBoundingClientRect();
|
|
11596
|
-
return {
|
|
11597
|
-
x: rect.x * zoom,
|
|
11598
|
-
y: rect.y * zoom,
|
|
11599
|
-
width: rect.width * zoom,
|
|
11600
|
-
height: rect.height * zoom
|
|
11601
|
-
};
|
|
11602
|
-
}
|
|
11603
|
-
function getRefBoundingRect(ref) {
|
|
11604
|
-
if (!ref.el) return {
|
|
11605
|
-
x: 0,
|
|
11606
|
-
y: 0,
|
|
11607
|
-
width: 0,
|
|
11608
|
-
height: 0
|
|
11609
|
-
};
|
|
11610
|
-
return getBoundingRectAsPOJO(ref.el);
|
|
11611
|
-
}
|
|
11612
|
-
function getBoundingRectAsPOJO(el) {
|
|
11613
|
-
const rect = el.getBoundingClientRect();
|
|
11614
|
-
return {
|
|
11615
|
-
x: rect.x,
|
|
11616
|
-
y: rect.y,
|
|
11617
|
-
width: rect.width,
|
|
11618
|
-
height: rect.height
|
|
11619
|
-
};
|
|
11620
|
-
}
|
|
11621
|
-
/**
|
|
11622
|
-
* Iterate over all the children of `el` in the dom tree starting at `el`, depth first.
|
|
11623
|
-
*/
|
|
11624
|
-
function* iterateChildren(el) {
|
|
11625
|
-
yield el;
|
|
11626
|
-
if (el.hasChildNodes()) for (const child of el.childNodes) yield* iterateChildren(child);
|
|
11627
|
-
}
|
|
11628
|
-
function getOpenedMenus() {
|
|
11629
|
-
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
11630
|
-
}
|
|
11631
|
-
function getCurrentSelection(el) {
|
|
11632
|
-
const { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
11633
|
-
return {
|
|
11634
|
-
start: findSelectionIndex(el, startElement, startSelectionOffset),
|
|
11635
|
-
end: findSelectionIndex(el, endElement, endSelectionOffset)
|
|
11636
|
-
};
|
|
11637
|
-
}
|
|
11638
|
-
function getStartAndEndSelection(el) {
|
|
11639
|
-
const selection = document.getSelection();
|
|
11640
|
-
return {
|
|
11641
|
-
startElement: selection.anchorNode || el,
|
|
11642
|
-
startSelectionOffset: selection.anchorOffset,
|
|
11643
|
-
endElement: selection.focusNode || el,
|
|
11644
|
-
endSelectionOffset: selection.focusOffset
|
|
11645
|
-
};
|
|
11646
|
-
}
|
|
11647
|
-
/**
|
|
11648
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
11649
|
-
* The selected node is either a Text node or an Element node.
|
|
11650
|
-
*
|
|
11651
|
-
* case 1 -Text node:
|
|
11652
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
11653
|
-
* content length of all previous nodes.
|
|
11654
|
-
*
|
|
11655
|
-
* case 2 - Element node:
|
|
11656
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
11657
|
-
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
11658
|
-
*
|
|
11659
|
-
* See the MDN documentation for more details.
|
|
11660
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
11661
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
11662
|
-
*
|
|
11663
|
-
*/
|
|
11664
|
-
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
11665
|
-
let usedCharacters = 0;
|
|
11666
|
-
const it = iterateChildren(el);
|
|
11667
|
-
let current = it.next();
|
|
11668
|
-
let isFirstParagraph = true;
|
|
11669
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
11670
|
-
if (!current.value.hasChildNodes()) {
|
|
11671
|
-
if (current.value.textContent) usedCharacters += current.value.textContent.length;
|
|
11672
|
-
}
|
|
11673
|
-
if (current.value.nodeName === "P" || current.value.nodeName === "DIV" && current.value !== el) if (isFirstParagraph) isFirstParagraph = false;
|
|
11674
|
-
else usedCharacters++;
|
|
11675
|
-
current = it.next();
|
|
11676
|
-
}
|
|
11677
|
-
if (current.value !== nodeToFind)
|
|
11678
|
-
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
11679
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
11680
|
-
*
|
|
11681
|
-
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
11682
|
-
*/
|
|
11683
|
-
return 0;
|
|
11684
|
-
else if (!current.value.hasChildNodes()) usedCharacters += nodeOffset;
|
|
11685
|
-
else {
|
|
11686
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
11687
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
11688
|
-
if (child.textContent !== null) {
|
|
11689
|
-
let chars = child.textContent.length;
|
|
11690
|
-
if (child.nodeName === "P" && index !== children.length - 1) chars++;
|
|
11691
|
-
return acc + chars;
|
|
11692
|
-
} else return acc;
|
|
11693
|
-
}, 0);
|
|
11694
|
-
}
|
|
11695
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") usedCharacters++;
|
|
11696
|
-
return usedCharacters;
|
|
11697
|
-
}
|
|
11698
|
-
const letterRegex = /^[a-zA-Z]$/;
|
|
11699
|
-
/**
|
|
11700
|
-
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
11701
|
-
*
|
|
11702
|
-
* @argument ev - The keyboard event to transform
|
|
11703
|
-
* @argument mode - Use either ev.key of ev.code to get the string shortcut
|
|
11704
|
-
*
|
|
11705
|
-
* @example
|
|
11706
|
-
* event : { ctrlKey: true, key: "a" } => "Ctrl+A"
|
|
11707
|
-
* event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
|
|
11708
|
-
*/
|
|
11709
|
-
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
11710
|
-
let keyDownString = "";
|
|
11711
|
-
if (!MODIFIER_KEYS.includes(ev.key)) {
|
|
11712
|
-
if (isCtrlKey(ev)) keyDownString += "Ctrl+";
|
|
11713
|
-
if (ev.altKey) keyDownString += "Alt+";
|
|
11714
|
-
if (ev.shiftKey) keyDownString += "Shift+";
|
|
11715
|
-
}
|
|
11716
|
-
const key = mode === "key" ? ev.key : ev.code;
|
|
11717
|
-
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
11718
|
-
return keyDownString;
|
|
11719
|
-
}
|
|
11720
|
-
function isMacOS() {
|
|
11721
|
-
return Boolean(macRegex.test(navigator.userAgent));
|
|
11722
|
-
}
|
|
11723
|
-
/**
|
|
11724
|
-
* @param {KeyboardEvent | MouseEvent} ev
|
|
11725
|
-
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
11726
|
-
* On Mac, this is the "meta" or "command" key.
|
|
11727
|
-
*/
|
|
11728
|
-
function isCtrlKey(ev) {
|
|
11729
|
-
return isMacOS() || isIOS() ? ev.metaKey : ev.ctrlKey;
|
|
11730
|
-
}
|
|
11731
|
-
/**
|
|
11732
|
-
* @param {MouseEvent} ev - The mouse event.
|
|
11733
|
-
* @returns {boolean} Returns true if the event was triggered by a middle-click
|
|
11734
|
-
* or a Ctrl + Click (Cmd + Click on Mac).
|
|
11735
|
-
*/
|
|
11736
|
-
function isMiddleClickOrCtrlClick(ev) {
|
|
11737
|
-
return ev.button === 1 || isCtrlKey(ev) && ev.button === 0;
|
|
11738
|
-
}
|
|
11739
|
-
function downloadFile(dataUrl, fileName) {
|
|
11740
|
-
const a = document.createElement("a");
|
|
11741
|
-
a.href = dataUrl;
|
|
11742
|
-
a.download = fileName;
|
|
11743
|
-
document.body.appendChild(a);
|
|
11744
|
-
a.click();
|
|
11745
|
-
document.body.removeChild(a);
|
|
11746
|
-
}
|
|
11747
|
-
/**
|
|
11748
|
-
* Detects if the current browser is Firefox
|
|
11749
|
-
*/
|
|
11750
|
-
function isBrowserFirefox() {
|
|
11751
|
-
return /Firefox/i.test(navigator.userAgent);
|
|
11752
|
-
}
|
|
11753
|
-
function maxTouchPoints() {
|
|
11754
|
-
return navigator.maxTouchPoints || 1;
|
|
11755
|
-
}
|
|
11756
|
-
function isAndroid() {
|
|
11757
|
-
return /Android/i.test(navigator.userAgent);
|
|
11758
|
-
}
|
|
11759
|
-
function isIOS() {
|
|
11760
|
-
return /(iPad|iPhone|iPod)/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && maxTouchPoints() > 1;
|
|
11761
|
-
}
|
|
11762
|
-
function isOtherMobileOS() {
|
|
11763
|
-
return /(webOS|BlackBerry|Windows Phone)/i.test(navigator.userAgent);
|
|
11764
|
-
}
|
|
11765
|
-
function isMobileOS() {
|
|
11766
|
-
return isAndroid() || isIOS() || isOtherMobileOS();
|
|
11767
|
-
}
|
|
11768
|
-
|
|
11769
11848
|
//#endregion
|
|
11770
11849
|
//#region src/components/helpers/zoom.ts
|
|
11771
11850
|
/**
|
|
@@ -11850,6 +11929,9 @@ var ScorecardChart = class extends Component {
|
|
|
11850
11929
|
window.devicePixelRatio
|
|
11851
11930
|
];
|
|
11852
11931
|
});
|
|
11932
|
+
const resizeObserver = new ResizeObserver(() => this.createChart());
|
|
11933
|
+
onMounted(() => resizeObserver.observe(this.canvas.el));
|
|
11934
|
+
onWillUnmount(() => resizeObserver.disconnect());
|
|
11853
11935
|
}
|
|
11854
11936
|
createChart() {
|
|
11855
11937
|
const canvas = this.canvas.el;
|
|
@@ -13541,6 +13623,15 @@ var GaugeChartComponent = class extends Component {
|
|
|
13541
13623
|
window.devicePixelRatio
|
|
13542
13624
|
];
|
|
13543
13625
|
});
|
|
13626
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
13627
|
+
if (animation) {
|
|
13628
|
+
animation.stop();
|
|
13629
|
+
animation = null;
|
|
13630
|
+
}
|
|
13631
|
+
drawGaugeChart(this.canvasEl, this.runtime, this.env.model.getters.getViewportZoomLevel());
|
|
13632
|
+
});
|
|
13633
|
+
onMounted(() => resizeObserver.observe(this.canvas.el));
|
|
13634
|
+
onWillUnmount(() => resizeObserver.disconnect());
|
|
13544
13635
|
}
|
|
13545
13636
|
drawGaugeWithAnimation() {
|
|
13546
13637
|
drawGaugeChart(this.canvasEl, {
|
|
@@ -23475,7 +23566,7 @@ const insertImage = {
|
|
|
23475
23566
|
};
|
|
23476
23567
|
const insertTable = {
|
|
23477
23568
|
name: () => _t("Table"),
|
|
23478
|
-
|
|
23569
|
+
shortcut: "Alt+T",
|
|
23479
23570
|
execute: INSERT_TABLE,
|
|
23480
23571
|
isVisible: (env) => IS_SELECTION_CONTINUOUS(env) && !env.model.getters.getFirstTableInSelection(),
|
|
23481
23572
|
isEnabled: (env) => !env.isSmall,
|
|
@@ -23524,7 +23615,7 @@ const categoriesFunctionListMenuBuilder = () => {
|
|
|
23524
23615
|
};
|
|
23525
23616
|
const insertLink = {
|
|
23526
23617
|
name: _t("Link"),
|
|
23527
|
-
|
|
23618
|
+
shortcut: "Ctrl+Shift+K",
|
|
23528
23619
|
execute: INSERT_LINK,
|
|
23529
23620
|
icon: "o-spreadsheet-Icon.INSERT_LINK"
|
|
23530
23621
|
};
|
|
@@ -23583,7 +23674,7 @@ const insertDropdown = {
|
|
|
23583
23674
|
};
|
|
23584
23675
|
const insertSheet = {
|
|
23585
23676
|
name: _t("Insert sheet"),
|
|
23586
|
-
|
|
23677
|
+
shortcut: "Shift+F11",
|
|
23587
23678
|
execute: (env) => {
|
|
23588
23679
|
const activeSheetId = env.model.getters.getActiveSheetId();
|
|
23589
23680
|
const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
|
|
@@ -27732,6 +27823,74 @@ function getCalendarChartLayout(definition, args) {
|
|
|
27732
27823
|
} };
|
|
27733
27824
|
}
|
|
27734
27825
|
|
|
27826
|
+
//#endregion
|
|
27827
|
+
//#region src/helpers/figures/charts/runtime/chart_highlight.ts
|
|
27828
|
+
const HIGHLIGHT_TRANSPARENCY = .2;
|
|
27829
|
+
function highlightComboChartItem(item, dataSets) {
|
|
27830
|
+
const index = item.datasetIndex;
|
|
27831
|
+
for (let i = 0; i < dataSets.length; i++) {
|
|
27832
|
+
if (i === index) continue;
|
|
27833
|
+
const dataset = dataSets[i];
|
|
27834
|
+
for (const key of ["borderColor", "backgroundColor"]) {
|
|
27835
|
+
if (!(key in dataset)) continue;
|
|
27836
|
+
dataset[key] = setColorAlpha(dataset[key], i === index ? 1 : HIGHLIGHT_TRANSPARENCY);
|
|
27837
|
+
}
|
|
27838
|
+
}
|
|
27839
|
+
}
|
|
27840
|
+
function resetComboChartHighlights(dataSets) {
|
|
27841
|
+
for (const dataset of dataSets) for (const key of ["borderColor", "backgroundColor"]) {
|
|
27842
|
+
if (!(key in dataset)) continue;
|
|
27843
|
+
dataset[key] = setColorAlpha(dataset[key], 1);
|
|
27844
|
+
}
|
|
27845
|
+
}
|
|
27846
|
+
function highlightLineChartItem(item, dataSets) {
|
|
27847
|
+
const index = item.datasetIndex;
|
|
27848
|
+
for (let i = 0; i < dataSets.length; i++) {
|
|
27849
|
+
const dataset = dataSets[i];
|
|
27850
|
+
const color = setColorAlpha(dataset.borderColor, i === index ? 1 : HIGHLIGHT_TRANSPARENCY);
|
|
27851
|
+
dataset.borderColor = color;
|
|
27852
|
+
dataset.pointBackgroundColor = color;
|
|
27853
|
+
dataset.backgroundColor = setColorAlpha(dataset.backgroundColor, LINE_FILL_TRANSPARENCY * (i === index ? 1 : HIGHLIGHT_TRANSPARENCY));
|
|
27854
|
+
}
|
|
27855
|
+
}
|
|
27856
|
+
function resetLineChartHighlights(dataSets) {
|
|
27857
|
+
for (const dataset of dataSets) {
|
|
27858
|
+
const color = setColorAlpha(dataset.borderColor, 1);
|
|
27859
|
+
dataset.borderColor = color;
|
|
27860
|
+
dataset.pointBackgroundColor = color;
|
|
27861
|
+
dataset.backgroundColor = setColorAlpha(dataset.backgroundColor, LINE_FILL_TRANSPARENCY);
|
|
27862
|
+
}
|
|
27863
|
+
}
|
|
27864
|
+
function toggleLineBarDataVisibility(chart, item) {
|
|
27865
|
+
const index = item.datasetIndex;
|
|
27866
|
+
if (index === void 0) return;
|
|
27867
|
+
if (chart.isDatasetVisible(index)) chart.hide(index);
|
|
27868
|
+
else chart.show(index);
|
|
27869
|
+
}
|
|
27870
|
+
function highlightPieChartItem(item, dataSets) {
|
|
27871
|
+
for (const dataset of dataSets) {
|
|
27872
|
+
const backgroundColors = dataset.backgroundColor;
|
|
27873
|
+
if (!backgroundColors) return;
|
|
27874
|
+
backgroundColors.forEach((color, i, colors) => {
|
|
27875
|
+
colors[i] = setColorAlpha(color, i === item.index ? 1 : HIGHLIGHT_TRANSPARENCY);
|
|
27876
|
+
});
|
|
27877
|
+
}
|
|
27878
|
+
}
|
|
27879
|
+
function resetPieChartHighlights(dataSets) {
|
|
27880
|
+
for (const dataset of dataSets) {
|
|
27881
|
+
const backgroundColors = dataset.backgroundColor;
|
|
27882
|
+
if (!backgroundColors) return;
|
|
27883
|
+
backgroundColors.forEach((color, i, colors) => {
|
|
27884
|
+
colors[i] = setColorAlpha(color, 1);
|
|
27885
|
+
});
|
|
27886
|
+
}
|
|
27887
|
+
}
|
|
27888
|
+
function togglePieDataVisibility(chart, item) {
|
|
27889
|
+
const index = item.index;
|
|
27890
|
+
if (index === void 0) return;
|
|
27891
|
+
chart.toggleDataVisibility(index);
|
|
27892
|
+
}
|
|
27893
|
+
|
|
27735
27894
|
//#endregion
|
|
27736
27895
|
//#region src/helpers/figures/charts/runtime/chartjs_legend.ts
|
|
27737
27896
|
function getLegendDisplayOptions({ legendPosition }) {
|
|
@@ -27742,7 +27901,20 @@ function getLegendDisplayOptions({ legendPosition }) {
|
|
|
27742
27901
|
}
|
|
27743
27902
|
function getBarChartLegend(definition, args) {
|
|
27744
27903
|
return {
|
|
27745
|
-
...
|
|
27904
|
+
...getInteractiveLegendConfig({
|
|
27905
|
+
highlightItem: highlightComboChartItem,
|
|
27906
|
+
unHighlightItems: resetComboChartHighlights,
|
|
27907
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
27908
|
+
}),
|
|
27909
|
+
...getLegendDisplayOptions(definition),
|
|
27910
|
+
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
27911
|
+
pointStyle: "rect",
|
|
27912
|
+
lineWidth: 3
|
|
27913
|
+
})
|
|
27914
|
+
};
|
|
27915
|
+
}
|
|
27916
|
+
function getPyramidChartLegend(definition, args) {
|
|
27917
|
+
return {
|
|
27746
27918
|
...getLegendDisplayOptions(definition),
|
|
27747
27919
|
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
27748
27920
|
pointStyle: "rect",
|
|
@@ -27755,7 +27927,11 @@ function getLineChartLegend(definition, args) {
|
|
|
27755
27927
|
const pointStyle = filled ? "rect" : "line";
|
|
27756
27928
|
const lineWidth = filled ? 2 : 3;
|
|
27757
27929
|
return {
|
|
27758
|
-
...
|
|
27930
|
+
...getInteractiveLegendConfig({
|
|
27931
|
+
highlightItem: highlightLineChartItem,
|
|
27932
|
+
unHighlightItems: resetLineChartHighlights,
|
|
27933
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
27934
|
+
}),
|
|
27759
27935
|
...getLegendDisplayOptions(definition),
|
|
27760
27936
|
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
27761
27937
|
pointStyle,
|
|
@@ -27768,6 +27944,11 @@ function getPieChartLegend(definition, args) {
|
|
|
27768
27944
|
const colors = getPieColors(new ColorGenerator(Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0)), definition.slicesColors), dataSetsValues);
|
|
27769
27945
|
const fontColor = chartFontColor(definition.background);
|
|
27770
27946
|
return {
|
|
27947
|
+
...getInteractiveLegendConfig({
|
|
27948
|
+
highlightItem: highlightPieChartItem,
|
|
27949
|
+
unHighlightItems: resetPieChartHighlights,
|
|
27950
|
+
toggleDataVisibility: togglePieDataVisibility
|
|
27951
|
+
}),
|
|
27771
27952
|
...getLegendDisplayOptions(definition),
|
|
27772
27953
|
labels: {
|
|
27773
27954
|
usePointStyle: true,
|
|
@@ -27777,7 +27958,9 @@ function getPieChartLegend(definition, args) {
|
|
|
27777
27958
|
fillStyle: colors[index],
|
|
27778
27959
|
pointStyle: "rect",
|
|
27779
27960
|
lineWidth: 2,
|
|
27780
|
-
fontColor
|
|
27961
|
+
fontColor,
|
|
27962
|
+
index,
|
|
27963
|
+
hidden: !c.getDataVisibility?.(index)
|
|
27781
27964
|
})) || []).filter((label) => label.text),
|
|
27782
27965
|
filter: (legendItem, data) => {
|
|
27783
27966
|
return "datasetIndex" in legendItem ? !data.datasets[legendItem.datasetIndex].hidden : true;
|
|
@@ -27787,9 +27970,13 @@ function getPieChartLegend(definition, args) {
|
|
|
27787
27970
|
}
|
|
27788
27971
|
function getScatterChartLegend(definition, args) {
|
|
27789
27972
|
return {
|
|
27790
|
-
...
|
|
27973
|
+
...getInteractiveLegendConfig({
|
|
27974
|
+
highlightItem: highlightLineChartItem,
|
|
27975
|
+
unHighlightItems: resetLineChartHighlights,
|
|
27976
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
27977
|
+
}),
|
|
27791
27978
|
...getLegendDisplayOptions(definition),
|
|
27792
|
-
...
|
|
27979
|
+
...getScatterPlotLegendLabels(chartFontColor(definition.background), {
|
|
27793
27980
|
pointStyle: "circle",
|
|
27794
27981
|
strokeStyle: definition.background || "#ffffff",
|
|
27795
27982
|
lineWidth: 8
|
|
@@ -27810,7 +27997,11 @@ function getBubbleChartLegend(definition, args) {
|
|
|
27810
27997
|
}
|
|
27811
27998
|
function getComboChartLegend(definition, args) {
|
|
27812
27999
|
return {
|
|
27813
|
-
...
|
|
28000
|
+
...getInteractiveLegendConfig({
|
|
28001
|
+
highlightItem: highlightComboChartItem,
|
|
28002
|
+
unHighlightItems: resetComboChartHighlights,
|
|
28003
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
28004
|
+
}),
|
|
27814
28005
|
...getLegendDisplayOptions(definition),
|
|
27815
28006
|
...getCustomLegendLabels(chartFontColor(definition.background), { lineWidth: 3 })
|
|
27816
28007
|
};
|
|
@@ -27859,7 +28050,11 @@ function getRadarChartLegend(definition, args) {
|
|
|
27859
28050
|
const pointStyle = fill ? "rect" : "line";
|
|
27860
28051
|
const lineWidth = fill ? 2 : 3;
|
|
27861
28052
|
return {
|
|
27862
|
-
...
|
|
28053
|
+
...getInteractiveLegendConfig({
|
|
28054
|
+
highlightItem: highlightLineChartItem,
|
|
28055
|
+
unHighlightItems: resetLineChartHighlights,
|
|
28056
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
28057
|
+
}),
|
|
27863
28058
|
...getLegendDisplayOptions(definition),
|
|
27864
28059
|
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
27865
28060
|
pointStyle,
|
|
@@ -27889,29 +28084,44 @@ function getSunburstChartLegend(definition, args) {
|
|
|
27889
28084
|
}
|
|
27890
28085
|
};
|
|
27891
28086
|
}
|
|
27892
|
-
|
|
27893
|
-
|
|
27894
|
-
|
|
27895
|
-
|
|
27896
|
-
|
|
27897
|
-
|
|
27898
|
-
|
|
27899
|
-
|
|
27900
|
-
|
|
27901
|
-
|
|
27902
|
-
|
|
27903
|
-
|
|
27904
|
-
|
|
27905
|
-
|
|
27906
|
-
|
|
27907
|
-
|
|
27908
|
-
|
|
27909
|
-
|
|
27910
|
-
|
|
27911
|
-
|
|
27912
|
-
|
|
28087
|
+
function getInteractiveLegendConfig({ highlightItem, unHighlightItems, toggleDataVisibility }) {
|
|
28088
|
+
return {
|
|
28089
|
+
onHover: (event, item, legend) => {
|
|
28090
|
+
if (!item.hidden) {
|
|
28091
|
+
const datasets = legend.chart.data.datasets;
|
|
28092
|
+
highlightItem(item, datasets);
|
|
28093
|
+
legend.chart.update();
|
|
28094
|
+
}
|
|
28095
|
+
const target = event.native?.target;
|
|
28096
|
+
if (target && target instanceof HTMLElement) target.style.cursor = "pointer";
|
|
28097
|
+
},
|
|
28098
|
+
onLeave: (event, item, legend) => {
|
|
28099
|
+
if (!item.hidden) {
|
|
28100
|
+
const datasets = legend.chart.data.datasets;
|
|
28101
|
+
unHighlightItems(datasets);
|
|
28102
|
+
legend.chart.update();
|
|
28103
|
+
}
|
|
28104
|
+
const target = event.native?.target;
|
|
28105
|
+
if (target && target instanceof HTMLElement) target.style.cursor = "default";
|
|
28106
|
+
},
|
|
28107
|
+
onClick: (event, item, legend) => {
|
|
28108
|
+
if (event.type !== "click" || !legend.legendItems) return;
|
|
28109
|
+
if (legend.chart.options.animation) legend.chart.options.animation = false;
|
|
28110
|
+
toggleDataVisibility(legend.chart, item);
|
|
28111
|
+
if (!item.hidden) unHighlightItems(legend.chart.data.datasets);
|
|
28112
|
+
else highlightItem(item, legend.chart.data.datasets);
|
|
28113
|
+
legend.chart.update();
|
|
28114
|
+
event.native.preventDefault();
|
|
28115
|
+
event.native.stopPropagation();
|
|
28116
|
+
}
|
|
28117
|
+
};
|
|
28118
|
+
}
|
|
27913
28119
|
const INTERACTIVE_LEGEND_CONFIG_FOR_BUBBLE_CHART = {
|
|
27914
|
-
...
|
|
28120
|
+
...getInteractiveLegendConfig({
|
|
28121
|
+
highlightItem: highlightLineChartItem,
|
|
28122
|
+
unHighlightItems: resetLineChartHighlights,
|
|
28123
|
+
toggleDataVisibility: toggleLineBarDataVisibility
|
|
28124
|
+
}),
|
|
27915
28125
|
onClick: (event, legendItem, legend) => {
|
|
27916
28126
|
if (event.type !== "click") return;
|
|
27917
28127
|
const index = legendItem.datasetIndex;
|
|
@@ -27978,6 +28188,37 @@ function getBubbleChartLegendLabels(fontColor, legendLabelConfig, labels) {
|
|
|
27978
28188
|
filter: (legendItem, data) => true
|
|
27979
28189
|
} };
|
|
27980
28190
|
}
|
|
28191
|
+
function getScatterPlotLegendLabels(fontColor, legendLabelConfig) {
|
|
28192
|
+
return { labels: {
|
|
28193
|
+
color: fontColor,
|
|
28194
|
+
usePointStyle: true,
|
|
28195
|
+
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
28196
|
+
if (isTrendLineAxis(dataset["xAxisID"])) return {
|
|
28197
|
+
text: truncateLabel(dataset.label),
|
|
28198
|
+
fontColor,
|
|
28199
|
+
strokeStyle: dataset.borderColor,
|
|
28200
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28201
|
+
pointStyle: "line",
|
|
28202
|
+
datasetIndex: index,
|
|
28203
|
+
lineWidth: 3
|
|
28204
|
+
};
|
|
28205
|
+
return {
|
|
28206
|
+
text: truncateLabel(dataset.label),
|
|
28207
|
+
fontColor,
|
|
28208
|
+
strokeStyle: dataset.borderColor,
|
|
28209
|
+
fillStyle: dataset["pointBackgroundColor"],
|
|
28210
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28211
|
+
pointStyle: "circle",
|
|
28212
|
+
datasetIndex: index,
|
|
28213
|
+
lineWidth: 8,
|
|
28214
|
+
...legendLabelConfig
|
|
28215
|
+
};
|
|
28216
|
+
}).filter((label) => label.text),
|
|
28217
|
+
filter: (legendItem, data) => {
|
|
28218
|
+
return "datasetIndex" in legendItem ? !data.datasets[legendItem.datasetIndex].hidden : true;
|
|
28219
|
+
}
|
|
28220
|
+
} };
|
|
28221
|
+
}
|
|
27981
28222
|
|
|
27982
28223
|
//#endregion
|
|
27983
28224
|
//#region src/types/chart/sunburst_chart.ts
|
|
@@ -29617,11 +29858,12 @@ const ChartRangeDataSourceHandler = {
|
|
|
29617
29858
|
type: "range",
|
|
29618
29859
|
dataSets: [],
|
|
29619
29860
|
dataSetsHaveTitle: false,
|
|
29861
|
+
labelRange: context.auxiliaryRange,
|
|
29620
29862
|
...context.dataSource
|
|
29621
29863
|
};
|
|
29622
29864
|
},
|
|
29623
29865
|
fromHierarchicalContextCreation(context) {
|
|
29624
|
-
if (context.dataSource?.type !== "range" || context.hierarchicalDataSource
|
|
29866
|
+
if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
|
|
29625
29867
|
type: "range",
|
|
29626
29868
|
dataSets: [],
|
|
29627
29869
|
dataSetsHaveTitle: false
|
|
@@ -37613,7 +37855,7 @@ function getVisiblePivotCellPositions(getters, pivotId) {
|
|
|
37613
37855
|
col,
|
|
37614
37856
|
row
|
|
37615
37857
|
};
|
|
37616
|
-
if (
|
|
37858
|
+
if (getters.getPivotIdsFromPosition(position).includes(pivotId)) positions.push(position);
|
|
37617
37859
|
}
|
|
37618
37860
|
return positions;
|
|
37619
37861
|
}
|
|
@@ -39687,6 +39929,9 @@ const PIVOT_FUNCTIONS = [
|
|
|
39687
39929
|
function getFirstPivotFunction(compiledFormula, getters) {
|
|
39688
39930
|
return compiledFormula.getFunctionsFromTokens(PIVOT_FUNCTIONS, getters)[0];
|
|
39689
39931
|
}
|
|
39932
|
+
function getPivotFunctions(compiledFormula, getters) {
|
|
39933
|
+
return compiledFormula.getFunctionsFromTokens(PIVOT_FUNCTIONS, getters);
|
|
39934
|
+
}
|
|
39690
39935
|
/**
|
|
39691
39936
|
* Parse a spreadsheet formula and detect the number of PIVOT functions that are
|
|
39692
39937
|
* present in the given formula.
|
|
@@ -49290,6 +49535,7 @@ var helpers_index_exports = /* @__PURE__ */ __exportAll({
|
|
|
49290
49535
|
getPieChartLegend: () => getPieChartLegend,
|
|
49291
49536
|
getPieChartTooltip: () => getPieChartTooltip,
|
|
49292
49537
|
getPyramidChartData: () => getPyramidChartData,
|
|
49538
|
+
getPyramidChartLegend: () => getPyramidChartLegend,
|
|
49293
49539
|
getPyramidChartScales: () => getPyramidChartScales,
|
|
49294
49540
|
getPyramidChartShowValues: () => getPyramidChartShowValues,
|
|
49295
49541
|
getPyramidChartTooltip: () => getPyramidChartTooltip,
|
|
@@ -57969,6 +58215,7 @@ var PivotUIPlugin = class extends CoreViewPlugin {
|
|
|
57969
58215
|
"getFirstPivotFunction",
|
|
57970
58216
|
"getPivotCellSortDirection",
|
|
57971
58217
|
"getPivotIdFromPosition",
|
|
58218
|
+
"getPivotIdsFromPosition",
|
|
57972
58219
|
"getPivotCellFromPosition",
|
|
57973
58220
|
"generateNewCalculatedMeasureName",
|
|
57974
58221
|
"isPivotUnused",
|
|
@@ -58028,37 +58275,52 @@ var PivotUIPlugin = class extends CoreViewPlugin {
|
|
|
58028
58275
|
}
|
|
58029
58276
|
}
|
|
58030
58277
|
/**
|
|
58031
|
-
* Get the id of the pivot at the given position. Returns undefined if there
|
|
58278
|
+
* Get the id of the first pivot in the formula at the given position. Returns undefined if there
|
|
58032
58279
|
* is no pivot at this position
|
|
58033
58280
|
*/
|
|
58034
58281
|
getPivotIdFromPosition(position) {
|
|
58282
|
+
return this.getPivotIdsFromPosition(position)[0];
|
|
58283
|
+
}
|
|
58284
|
+
/**
|
|
58285
|
+
* Get all of the ids of the pivot present in the formula at the given position.
|
|
58286
|
+
*/
|
|
58287
|
+
getPivotIdsFromPosition(position) {
|
|
58035
58288
|
const cell = this.getters.getCorrespondingFormulaCell(position);
|
|
58036
|
-
if (cell && cell.isFormula)
|
|
58037
|
-
|
|
58038
|
-
|
|
58039
|
-
|
|
58040
|
-
|
|
58041
|
-
|
|
58042
|
-
|
|
58289
|
+
if (cell && cell.isFormula) return this.getPivotIdsFromFormula(position.sheetId, cell.compiledFormula);
|
|
58290
|
+
return [];
|
|
58291
|
+
}
|
|
58292
|
+
getPivotIdsFromFormula(sheetId, formula) {
|
|
58293
|
+
return this.getPivotFunctions(sheetId, formula).map((pivotFunction) => {
|
|
58294
|
+
const pivotId = pivotFunction.args[0]?.toString();
|
|
58295
|
+
return pivotId && this.getters.getPivotId(pivotId);
|
|
58296
|
+
}).filter(isDefined);
|
|
58043
58297
|
}
|
|
58044
58298
|
isSpillPivotFormula(position) {
|
|
58045
58299
|
const cell = this.getters.getCorrespondingFormulaCell(position);
|
|
58046
58300
|
if (cell && cell.isFormula) return this.getFirstPivotFunction(position.sheetId, cell.compiledFormula)?.functionName === "PIVOT";
|
|
58047
58301
|
return false;
|
|
58048
58302
|
}
|
|
58049
|
-
|
|
58050
|
-
const
|
|
58051
|
-
if (!
|
|
58052
|
-
const
|
|
58053
|
-
|
|
58054
|
-
functionName,
|
|
58055
|
-
|
|
58303
|
+
getPivotFunctions(sheetId, formula) {
|
|
58304
|
+
const pivotFunctions = getPivotFunctions(formula, this.getters);
|
|
58305
|
+
if (!pivotFunctions.length) return [];
|
|
58306
|
+
const evaluatedPivotFunctions = [];
|
|
58307
|
+
for (const pivotFunction of pivotFunctions) {
|
|
58308
|
+
const { functionName, args } = pivotFunction;
|
|
58309
|
+
const evaluatedArgs = args.map((argAst) => {
|
|
58056
58310
|
if (argAst.type === "EMPTY") return;
|
|
58057
58311
|
else if (argAst.type === "STRING" || argAst.type === "BOOLEAN" || argAst.type === "NUMBER") return argAst.value;
|
|
58058
58312
|
const argsString = astToFormula(argAst);
|
|
58059
58313
|
return this.getters.evaluateFormula(sheetId, argsString);
|
|
58060
|
-
})
|
|
58061
|
-
|
|
58314
|
+
});
|
|
58315
|
+
evaluatedPivotFunctions.push({
|
|
58316
|
+
functionName,
|
|
58317
|
+
args: evaluatedArgs
|
|
58318
|
+
});
|
|
58319
|
+
}
|
|
58320
|
+
return evaluatedPivotFunctions;
|
|
58321
|
+
}
|
|
58322
|
+
getFirstPivotFunction(sheetId, formula) {
|
|
58323
|
+
return this.getPivotFunctions(sheetId, formula)[0];
|
|
58062
58324
|
}
|
|
58063
58325
|
/**
|
|
58064
58326
|
* Returns the domain args of a pivot formula from a position.
|
|
@@ -58164,8 +58426,8 @@ var PivotUIPlugin = class extends CoreViewPlugin {
|
|
|
58164
58426
|
const unusedPivots = new Set(this.getters.getPivotIds());
|
|
58165
58427
|
for (const sheetId of this.getters.getSheetIds()) for (const cell of this.getters.getCells(sheetId)) {
|
|
58166
58428
|
const position = this.getters.getCellPosition(cell.id);
|
|
58167
|
-
const
|
|
58168
|
-
|
|
58429
|
+
const pivotIds = this.getPivotIdsFromPosition(position);
|
|
58430
|
+
for (const pivotId of pivotIds) {
|
|
58169
58431
|
unusedPivots.delete(pivotId);
|
|
58170
58432
|
if (!unusedPivots.size) {
|
|
58171
58433
|
this.unusedPivotsInFormulas = [];
|
|
@@ -58173,6 +58435,21 @@ var PivotUIPlugin = class extends CoreViewPlugin {
|
|
|
58173
58435
|
}
|
|
58174
58436
|
}
|
|
58175
58437
|
}
|
|
58438
|
+
for (const pivotId of this.getters.getPivotIds()) {
|
|
58439
|
+
const pivot = this.getters.getPivot(pivotId);
|
|
58440
|
+
for (const measure of pivot.definition.measures) if (measure.computedBy) {
|
|
58441
|
+
const { sheetId } = measure.computedBy;
|
|
58442
|
+
const formula = this.getters.getMeasureCompiledFormula(pivotId, measure);
|
|
58443
|
+
const relatedPivotIds = this.getPivotIdsFromFormula(sheetId, formula);
|
|
58444
|
+
for (const relatedPivotId of relatedPivotIds) {
|
|
58445
|
+
unusedPivots.delete(relatedPivotId);
|
|
58446
|
+
if (!unusedPivots.size) {
|
|
58447
|
+
this.unusedPivotsInFormulas = [];
|
|
58448
|
+
return [];
|
|
58449
|
+
}
|
|
58450
|
+
}
|
|
58451
|
+
}
|
|
58452
|
+
}
|
|
58176
58453
|
this.unusedPivotsInFormulas = [...unusedPivots];
|
|
58177
58454
|
return this.unusedPivotsInFormulas;
|
|
58178
58455
|
}
|
|
@@ -62849,12 +63126,13 @@ var CarouselUIPlugin = class extends UIPlugin {
|
|
|
62849
63126
|
const chartId = this.getChartIdFromFigureId(chartFigureId);
|
|
62850
63127
|
if (!chartId) return;
|
|
62851
63128
|
const carousel = this.getters.getCarousel(figureId);
|
|
63129
|
+
const newItem = {
|
|
63130
|
+
type: "chart",
|
|
63131
|
+
chartId
|
|
63132
|
+
};
|
|
62852
63133
|
const definition = {
|
|
62853
63134
|
...carousel,
|
|
62854
|
-
items: [...carousel.items,
|
|
62855
|
-
type: "chart",
|
|
62856
|
-
chartId
|
|
62857
|
-
}]
|
|
63135
|
+
items: [...carousel.items, newItem]
|
|
62858
63136
|
};
|
|
62859
63137
|
this.dispatch("UPDATE_CAROUSEL", {
|
|
62860
63138
|
sheetId,
|
|
@@ -62871,6 +63149,11 @@ var CarouselUIPlugin = class extends UIPlugin {
|
|
|
62871
63149
|
sheetId,
|
|
62872
63150
|
figureId: chartFigureId
|
|
62873
63151
|
});
|
|
63152
|
+
this.dispatch("UPDATE_CAROUSEL_ACTIVE_ITEM", {
|
|
63153
|
+
figureId,
|
|
63154
|
+
sheetId,
|
|
63155
|
+
item: newItem
|
|
63156
|
+
});
|
|
62874
63157
|
}
|
|
62875
63158
|
duplicateCarouselChart({ carouselId, chartId, sheetId, duplicatedChartId }) {
|
|
62876
63159
|
const chart = this.getters.getChart(chartId);
|
|
@@ -77212,7 +77495,7 @@ const PyramidChart = {
|
|
|
77212
77495
|
scales: getPyramidChartScales(definition, chartData),
|
|
77213
77496
|
plugins: {
|
|
77214
77497
|
title: getChartTitle(definition, getters),
|
|
77215
|
-
legend:
|
|
77498
|
+
legend: getPyramidChartLegend(definition, chartData),
|
|
77216
77499
|
tooltip: getPyramidChartTooltip(definition, chartData),
|
|
77217
77500
|
chartShowValuesPlugin: getPyramidChartShowValues(definition, chartData),
|
|
77218
77501
|
background: { color: chartData.background }
|
|
@@ -85689,7 +85972,8 @@ const constants = {
|
|
|
85689
85972
|
FIGURE_ID_SPLITTER: "??",
|
|
85690
85973
|
GRID_ICON_EDGE_LENGTH: 17,
|
|
85691
85974
|
GRID_ICON_MARGIN: 2,
|
|
85692
|
-
CHART_TYPES
|
|
85975
|
+
CHART_TYPES,
|
|
85976
|
+
DARK_MODE_FILTER_STRING
|
|
85693
85977
|
};
|
|
85694
85978
|
const chartHelpers = {
|
|
85695
85979
|
...helpers_index_exports$1,
|
|
@@ -85699,6 +85983,6 @@ const chartHelpers = {
|
|
|
85699
85983
|
//#endregion
|
|
85700
85984
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, BadExpressionError, CHART_TYPES, CellErrorType, CellValueType, CircularDependencyError, ClientDisconnectedError, ClipboardMIMEType, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DEFAULT_LOCALE_DIGIT_GROUPING, DIRECTION, DispatchResult, DivisionByZeroError, EvaluationError, InvalidReferenceError, LocalTransportService, Model, NEXT_VALUE, NotAvailableError, NumberTooLargeError, OrderedLayers, PREVIOUS_VALUE, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, SplillBlockedError, Spreadsheet, SpreadsheetPivotTable, UIPlugin, UnknownFunctionError, __info__, addFunction, addRenderingLayer, astToFormula, availableConditionalFormatOperators, availableDataValidationOperators, availableFiltersOperators, borderStyles, canExecuteInReadonly, categories, chartHelpers, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, errorTypes, filterDateCriterionOperators, filterNumberCriterionOperators, filterTextCriterionOperators, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidSubtotalFormulasCommands, invalidateBordersCommands, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isHeadersDependant, isMatrix, isPositionDependent, isRangeDependant, isSheetDependent, isTargetDependent, isZoneDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, schemeToColorScale, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
85701
85985
|
|
|
85702
|
-
__info__.version = "19.4.0-alpha.
|
|
85703
|
-
__info__.date = "2026-05-
|
|
85704
|
-
__info__.hash = "
|
|
85986
|
+
__info__.version = "19.4.0-alpha.7";
|
|
85987
|
+
__info__.date = "2026-05-20T14:40:27.236Z";
|
|
85988
|
+
__info__.hash = "7ee566f";
|