[IMP] spreadsheet: update o_spreadsheet to latest version
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/4c5002db [IMP] function: hyperlink(url, label) https://github.com/odoo/o-spreadsheet/commit/9d84b33f [REF] popover: improve popover component https://github.com/odoo/o-spreadsheet/commit/5a33e7d7 [REM] figures: remove duplicated image component https://github.com/odoo/o-spreadsheet/commit/6df5f339 [IMP] chart: aggregate data for labels https://github.com/odoo/o-spreadsheet/commit/ee3d2ab7 [FIX] scrollbars: Fix size of the scrollbars https://github.com/odoo/o-spreadsheet/commit/11d6eeee [FIX] index.ts: export helper to create empty sheet https://github.com/odoo/o-spreadsheet/commit/53c18e51 [IMP] model: allow to run evaluation in non lazy mode closes odoo/odoo#108540 Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
This commit is contained in:
@@ -374,6 +374,7 @@
|
||||
const FILTER_ICON_EDGE_LENGTH = 17;
|
||||
// Menus
|
||||
const MENU_WIDTH = 250;
|
||||
const MENU_VERTICAL_PADDING = 8;
|
||||
const MENU_ITEM_HEIGHT = 28;
|
||||
const MENU_SEPARATOR_BORDER_WIDTH = 1;
|
||||
const MENU_SEPARATOR_PADDING = 5;
|
||||
@@ -4241,7 +4242,7 @@
|
||||
return "\n" + str + "\n";
|
||||
}
|
||||
|
||||
const ERROR_TOOLTIP_HEIGHT = 40;
|
||||
const ERROR_TOOLTIP_MAX_HEIGHT = 80;
|
||||
const ERROR_TOOLTIP_WIDTH = 180;
|
||||
css /* scss */ `
|
||||
.o-error-tooltip {
|
||||
@@ -4249,11 +4250,13 @@
|
||||
background-color: white;
|
||||
border-left: 3px solid red;
|
||||
padding: 10px;
|
||||
width: ${ERROR_TOOLTIP_WIDTH}px;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
`;
|
||||
class ErrorToolTip extends owl.Component {
|
||||
}
|
||||
ErrorToolTip.size = { width: ERROR_TOOLTIP_WIDTH, height: ERROR_TOOLTIP_HEIGHT };
|
||||
ErrorToolTip.maxSize = { maxHeight: ERROR_TOOLTIP_MAX_HEIGHT };
|
||||
ErrorToolTip.template = "o-spreadsheet-ErrorToolTip";
|
||||
ErrorToolTip.components = {};
|
||||
ErrorToolTip.props = {
|
||||
@@ -4627,8 +4630,8 @@
|
||||
* Return the o-spreadsheet element position relative
|
||||
* to the browser viewport.
|
||||
*/
|
||||
function useSpreadsheetPosition() {
|
||||
const position = owl.useState({ x: 0, y: 0 });
|
||||
function useSpreadsheetRect() {
|
||||
const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
|
||||
let spreadsheetElement = document.querySelector(".o-spreadsheet");
|
||||
updatePosition();
|
||||
function updatePosition() {
|
||||
@@ -4636,9 +4639,11 @@
|
||||
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
||||
}
|
||||
if (spreadsheetElement) {
|
||||
const { top, left } = spreadsheetElement.getBoundingClientRect();
|
||||
const { top, left, width, height } = spreadsheetElement.getBoundingClientRect();
|
||||
position.x = left;
|
||||
position.y = top;
|
||||
position.width = width;
|
||||
position.height = height;
|
||||
}
|
||||
}
|
||||
owl.onMounted(updatePosition);
|
||||
@@ -4669,76 +4674,266 @@
|
||||
owl.onPatched(updateElPosition);
|
||||
return position;
|
||||
}
|
||||
/**
|
||||
* Get the rectangle inside which a popover should stay when being displayed.
|
||||
* It's the value defined in `env.getPopoverContainerRect`, or the Rect of the "o-spreadsheet"
|
||||
* element by default.
|
||||
*
|
||||
* Coordinates are expressed expressed as absolute DOM position.
|
||||
*/
|
||||
function usePopoverContainer() {
|
||||
const container = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
|
||||
const component = owl.useComponent();
|
||||
const spreadsheetRect = useSpreadsheetRect();
|
||||
function updateRect() {
|
||||
const env = component.env;
|
||||
const newRect = "getPopoverContainerRect" in env ? env.getPopoverContainerRect() : spreadsheetRect;
|
||||
container.x = newRect.x;
|
||||
container.y = newRect.x;
|
||||
container.width = newRect.width;
|
||||
container.height = newRect.height;
|
||||
}
|
||||
updateRect();
|
||||
owl.onMounted(updateRect);
|
||||
owl.onPatched(updateRect);
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the intersection of two rectangles. Returns nothing if the two rectangles don't overlap
|
||||
*/
|
||||
function rectIntersection(rect1, rect2) {
|
||||
return zoneToRect(intersection(rectToZone(rect1), rectToZone(rect2)));
|
||||
}
|
||||
function rectToZone(rect) {
|
||||
return {
|
||||
left: rect.x,
|
||||
top: rect.y,
|
||||
right: rect.x + rect.width,
|
||||
bottom: rect.y + rect.height,
|
||||
};
|
||||
}
|
||||
function zoneToRect(zone) {
|
||||
if (!zone)
|
||||
return undefined;
|
||||
return {
|
||||
x: zone.left,
|
||||
y: zone.top,
|
||||
width: zone.right - zone.left,
|
||||
height: zone.bottom - zone.top,
|
||||
};
|
||||
}
|
||||
|
||||
css /* scss */ `
|
||||
.o-popover {
|
||||
position: absolute;
|
||||
z-index: ${ComponentsImportance.Popover};
|
||||
overflow: auto;
|
||||
box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
`;
|
||||
class Popover extends owl.Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.spreadsheetPosition = useSpreadsheetPosition();
|
||||
this.popoverRef = owl.useRef("popover");
|
||||
this.currentPosition = undefined;
|
||||
this.currentVisibility = undefined;
|
||||
this.spreadsheetRect = useSpreadsheetRect();
|
||||
}
|
||||
get style() {
|
||||
// the props's position is expressed relative to the "body" element
|
||||
// but we teleport the element in ".o-spreadsheet" to keep everything
|
||||
// within our control and to avoid leaking into external DOM
|
||||
const horizontalPosition = `left:${this.horizontalPosition() - this.spreadsheetPosition.x}`;
|
||||
const verticalPosition = `top:${this.verticalPosition() - this.spreadsheetPosition.y}`;
|
||||
const height = `max-height:${this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1}`;
|
||||
return `
|
||||
position: absolute;
|
||||
z-index: ${ComponentsImportance.Popover};
|
||||
${verticalPosition}px;
|
||||
${horizontalPosition}px;
|
||||
${height}px;
|
||||
width:${this.props.childWidth}px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);
|
||||
`;
|
||||
setup() {
|
||||
this.containerRect = usePopoverContainer();
|
||||
// useEffect occurs after the DOM is created and the element width/height are computed, but before
|
||||
// the element in rendered, so we can still set its position
|
||||
owl.useEffect(() => {
|
||||
var _a, _b, _c, _d;
|
||||
if (!this.containerRect)
|
||||
throw new Error("Popover container is not defined");
|
||||
this.resetPopoverElStyle();
|
||||
const el = this.popoverRef.el;
|
||||
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
||||
const elDims = {
|
||||
width: el.getBoundingClientRect().width,
|
||||
height: el.getBoundingClientRect().height,
|
||||
};
|
||||
const spreadsheetRect = this.spreadsheetRect;
|
||||
const anchor = rectIntersection(this.props.anchorRect, this.containerRect);
|
||||
const newVisibility = anchor ? "visible" : "hidden";
|
||||
if (this.currentVisibility !== "hidden" && newVisibility === "hidden") {
|
||||
(_b = (_a = this.props).onPopoverHidden) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||
}
|
||||
el.style.visibility = newVisibility;
|
||||
this.currentVisibility = newVisibility;
|
||||
if (!anchor)
|
||||
return;
|
||||
const popoverPositionHelper = this.props.positioning === "BottomLeft"
|
||||
? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
|
||||
: new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
|
||||
const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
|
||||
for (const property of Object.keys(style)) {
|
||||
el.style[property] = style[property];
|
||||
}
|
||||
const newPosition = popoverPositionHelper.getCurrentPosition(elDims);
|
||||
if (this.currentPosition && newPosition !== this.currentPosition) {
|
||||
(_d = (_c = this.props).onPopoverMoved) === null || _d === void 0 ? void 0 : _d.call(_c);
|
||||
}
|
||||
this.currentPosition = newPosition;
|
||||
});
|
||||
}
|
||||
get viewportDimension() {
|
||||
return this.env.model.getters.getSheetViewDimensionWithHeaders();
|
||||
}
|
||||
get shouldRenderRight() {
|
||||
const { x } = this.props.position;
|
||||
return x + this.props.childWidth < this.viewportDimension.width;
|
||||
}
|
||||
get shouldRenderBottom() {
|
||||
const { y } = this.props.position;
|
||||
return (y + this.props.childHeight <
|
||||
this.viewportDimension.height + (this.env.isDashboard() ? 0 : TOPBAR_HEIGHT));
|
||||
}
|
||||
horizontalPosition() {
|
||||
const { x } = this.props.position;
|
||||
if (this.shouldRenderRight) {
|
||||
return x;
|
||||
}
|
||||
return x - this.props.childWidth - this.props.flipHorizontalOffset;
|
||||
}
|
||||
verticalPosition() {
|
||||
const { y } = this.props.position;
|
||||
if (this.shouldRenderBottom) {
|
||||
return y;
|
||||
}
|
||||
return Math.max(y - this.props.childHeight + this.props.flipVerticalOffset, this.props.marginTop);
|
||||
resetPopoverElStyle() {
|
||||
const el = this.popoverRef.el;
|
||||
if (!el)
|
||||
return;
|
||||
el.style["visibility"] = "visible";
|
||||
el.style["max-height"] = el.style["max-width"] = "";
|
||||
el.style["bottom"] = el.style["top"] = el.style["right"] = el.style["left"] = "";
|
||||
}
|
||||
}
|
||||
Popover.template = "o-spreadsheet-Popover";
|
||||
Popover.defaultProps = {
|
||||
flipHorizontalOffset: 0,
|
||||
flipVerticalOffset: 0,
|
||||
positioning: "BottomLeft",
|
||||
verticalOffset: 0,
|
||||
marginTop: 0,
|
||||
onMouseWheel: () => { },
|
||||
onPopoverMoved: () => { },
|
||||
onPopoverHidden: () => { },
|
||||
};
|
||||
Popover.props = {
|
||||
position: Object,
|
||||
marginTop: { type: Number, optional: true },
|
||||
childWidth: Number,
|
||||
childHeight: Number,
|
||||
flipHorizontalOffset: { type: Number, optional: true },
|
||||
flipVerticalOffset: { type: Number, optional: true },
|
||||
anchorRect: Object,
|
||||
containerRect: { type: Object, optional: true },
|
||||
positioning: { type: String, optional: true },
|
||||
maxWidth: { type: Number, optional: true },
|
||||
maxHeight: { type: Number, optional: true },
|
||||
verticalOffset: { type: Number, optional: true },
|
||||
onMouseWheel: { type: Function, optional: true },
|
||||
onPopoverHidden: { type: Function, optional: true },
|
||||
onPopoverMoved: { type: Function, optional: true },
|
||||
slots: Object,
|
||||
};
|
||||
class PopoverPositionContext {
|
||||
constructor(anchorRect, containerRect, propsMaxSize, spreadsheetOffset) {
|
||||
this.anchorRect = anchorRect;
|
||||
this.containerRect = containerRect;
|
||||
this.propsMaxSize = propsMaxSize;
|
||||
this.spreadsheetOffset = spreadsheetOffset;
|
||||
}
|
||||
/** Check if there is enough space for the popover to be rendered at the bottom of the anchorRect */
|
||||
shouldRenderAtBottom(elementHeight) {
|
||||
return (elementHeight <= this.availableHeightDown ||
|
||||
this.availableHeightDown >= this.availableHeightUp);
|
||||
}
|
||||
/** Check if there is enough space for the popover to be rendered at the right of the anchorRect */
|
||||
shouldRenderAtRight(elementWidth) {
|
||||
return (elementWidth <= this.availableWidthRight ||
|
||||
this.availableWidthRight >= this.availableWidthLeft);
|
||||
}
|
||||
getMaxHeight(elementHeight) {
|
||||
const shouldRenderAtBottom = this.shouldRenderAtBottom(elementHeight);
|
||||
const availableHeight = shouldRenderAtBottom
|
||||
? this.availableHeightDown
|
||||
: this.availableHeightUp;
|
||||
return this.propsMaxSize.height
|
||||
? Math.min(availableHeight, this.propsMaxSize.height)
|
||||
: availableHeight;
|
||||
}
|
||||
getMaxWidth(elementWidth) {
|
||||
const shouldRenderAtRight = this.shouldRenderAtRight(elementWidth);
|
||||
const availableWidth = shouldRenderAtRight ? this.availableWidthRight : this.availableWidthLeft;
|
||||
return this.propsMaxSize.width
|
||||
? Math.min(availableWidth, this.propsMaxSize.width)
|
||||
: availableWidth;
|
||||
}
|
||||
getCss(elDims, verticalOffset) {
|
||||
const maxHeight = this.getMaxHeight(elDims.height);
|
||||
const maxWidth = this.getMaxWidth(elDims.width);
|
||||
const actualHeight = Math.min(maxHeight, elDims.height);
|
||||
const actualWidth = Math.min(maxWidth, elDims.width);
|
||||
const shouldRenderAtBottom = this.shouldRenderAtBottom(elDims.height);
|
||||
const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
|
||||
verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
|
||||
const cssProperties = {
|
||||
"max-height": maxHeight + "px",
|
||||
"max-width": maxWidth + "px",
|
||||
top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
|
||||
this.spreadsheetOffset.y -
|
||||
verticalOffset +
|
||||
"px",
|
||||
left: this.getLeftCoordinate(actualWidth, shouldRenderAtRight) - this.spreadsheetOffset.x + "px",
|
||||
};
|
||||
return cssProperties;
|
||||
}
|
||||
getCurrentPosition(elDims) {
|
||||
const shouldRenderAtBottom = this.shouldRenderAtBottom(elDims.height);
|
||||
const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
|
||||
if (shouldRenderAtBottom && shouldRenderAtRight)
|
||||
return "BottomRight";
|
||||
if (shouldRenderAtBottom && !shouldRenderAtRight)
|
||||
return "BottomLeft";
|
||||
if (!shouldRenderAtBottom && shouldRenderAtRight)
|
||||
return "TopRight";
|
||||
return "TopLeft";
|
||||
}
|
||||
}
|
||||
class BottomLeftPopoverContext extends PopoverPositionContext {
|
||||
get availableHeightUp() {
|
||||
return this.anchorRect.y - this.containerRect.y;
|
||||
}
|
||||
get availableHeightDown() {
|
||||
return this.containerRect.height - this.availableHeightUp - this.anchorRect.height;
|
||||
}
|
||||
get availableWidthRight() {
|
||||
return this.containerRect.x + this.containerRect.width - this.anchorRect.x;
|
||||
}
|
||||
get availableWidthLeft() {
|
||||
return this.anchorRect.x + this.anchorRect.width - this.containerRect.x;
|
||||
}
|
||||
getTopCoordinate(elementHeight, shouldRenderAtBottom) {
|
||||
if (shouldRenderAtBottom) {
|
||||
return this.anchorRect.y + this.anchorRect.height;
|
||||
}
|
||||
else {
|
||||
return this.anchorRect.y - elementHeight;
|
||||
}
|
||||
}
|
||||
getLeftCoordinate(elementWidth, shouldRenderAtRight) {
|
||||
if (shouldRenderAtRight) {
|
||||
return this.anchorRect.x;
|
||||
}
|
||||
else {
|
||||
return this.anchorRect.x + this.anchorRect.width - elementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
class TopRightPopoverContext extends PopoverPositionContext {
|
||||
get availableHeightUp() {
|
||||
return this.anchorRect.y + this.anchorRect.height - this.containerRect.y;
|
||||
}
|
||||
get availableHeightDown() {
|
||||
return this.containerRect.y + this.containerRect.height - this.anchorRect.y;
|
||||
}
|
||||
get availableWidthRight() {
|
||||
return this.containerRect.width - this.anchorRect.width - this.availableWidthLeft;
|
||||
}
|
||||
get availableWidthLeft() {
|
||||
return this.anchorRect.x - this.containerRect.x;
|
||||
}
|
||||
getTopCoordinate(elementHeight, shouldRenderAtBottom) {
|
||||
if (shouldRenderAtBottom) {
|
||||
return this.anchorRect.y;
|
||||
}
|
||||
else {
|
||||
return this.anchorRect.y + this.anchorRect.height - elementHeight;
|
||||
}
|
||||
}
|
||||
getLeftCoordinate(elementWidth, shouldRenderAtRight) {
|
||||
if (shouldRenderAtRight) {
|
||||
return this.anchorRect.x + this.anchorRect.width;
|
||||
}
|
||||
else {
|
||||
return this.anchorRect.x - elementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Context Menu Component
|
||||
@@ -4746,7 +4941,10 @@
|
||||
css /* scss */ `
|
||||
.o-menu {
|
||||
background-color: white;
|
||||
padding: 5px 0px;
|
||||
padding: ${MENU_VERTICAL_PADDING}px 0px;
|
||||
width: ${MENU_WIDTH}px;
|
||||
box-sizing: border-box !important;
|
||||
|
||||
.o-menu-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -4794,7 +4992,6 @@
|
||||
class Menu extends owl.Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.MENU_WIDTH = MENU_WIDTH;
|
||||
this.subMenu = owl.useState({
|
||||
isOpen: false,
|
||||
position: null,
|
||||
@@ -4819,20 +5016,25 @@
|
||||
return position;
|
||||
}
|
||||
get menuHeight() {
|
||||
return this.menuComponentHeight(this.props.menuItems);
|
||||
}
|
||||
get subMenuHeight() {
|
||||
return this.menuComponentHeight(this.subMenu.menuItems);
|
||||
const menuItems = this.props.menuItems;
|
||||
let menuItemsHeight = this.getMenuItemsHeight(menuItems);
|
||||
// We don't display separator at the end of a menu
|
||||
if (menuItems[menuItems.length - 1].separator) {
|
||||
menuItemsHeight -= MENU_SEPARATOR_HEIGHT;
|
||||
}
|
||||
return 2 * MENU_VERTICAL_PADDING + menuItemsHeight;
|
||||
}
|
||||
get popover() {
|
||||
const isRoot = this.props.depth === 1;
|
||||
// TODO: see if we could reformulate this margin
|
||||
const marginTop = 6 + TOPBAR_HEIGHT + HEADER_HEIGHT;
|
||||
return {
|
||||
// some margin between the header and the component
|
||||
marginTop,
|
||||
flipHorizontalOffset: MENU_WIDTH * (this.props.depth - 1),
|
||||
flipVerticalOffset: isRoot ? 0 : MENU_ITEM_HEIGHT,
|
||||
anchorRect: {
|
||||
x: this.props.position.x - MENU_WIDTH * (this.props.depth - 1),
|
||||
y: this.props.position.y,
|
||||
width: isRoot ? 0 : MENU_WIDTH,
|
||||
height: isRoot ? 0 : MENU_ITEM_HEIGHT,
|
||||
},
|
||||
positioning: "TopRight",
|
||||
verticalOffset: isRoot ? 0 : MENU_VERTICAL_PADDING,
|
||||
};
|
||||
}
|
||||
getColor(menu) {
|
||||
@@ -4852,9 +5054,9 @@
|
||||
* Return the number of pixels between the top of the menu
|
||||
* and the menu item at a given index.
|
||||
*/
|
||||
subMenuVerticalPosition(position) {
|
||||
const menusAbove = this.props.menuItems.slice(0, position);
|
||||
return this.menuComponentHeight(menusAbove) + this.position.y;
|
||||
subMenuVerticalPosition(menuIndex) {
|
||||
const menusAbove = this.props.menuItems.slice(0, menuIndex);
|
||||
return this.position.y + this.getMenuItemsHeight(menusAbove) + MENU_VERTICAL_PADDING;
|
||||
}
|
||||
onClick(ev) {
|
||||
// Don't close a root menu when clicked to open the submenus.
|
||||
@@ -4872,14 +5074,9 @@
|
||||
}
|
||||
this.closeSubMenu();
|
||||
}
|
||||
/**
|
||||
* Return the total height (in pixels) needed for some
|
||||
* menu items
|
||||
*/
|
||||
menuComponentHeight(menuItems) {
|
||||
const separators = menuItems.filter((m) => m.separator);
|
||||
const others = menuItems;
|
||||
return MENU_ITEM_HEIGHT * others.length + separators.length * MENU_SEPARATOR_HEIGHT;
|
||||
getMenuItemsHeight(menuItems) {
|
||||
const numberOfSeparators = menuItems.filter((m) => m.separator).length;
|
||||
return MENU_ITEM_HEIGHT * menuItems.length + MENU_SEPARATOR_HEIGHT * numberOfSeparators;
|
||||
}
|
||||
getName(menu) {
|
||||
return getMenuName(menu, this.env);
|
||||
@@ -4903,8 +5100,8 @@
|
||||
* If the given menu is not disabled, open it's submenu at the
|
||||
* correct position according to available surrounding space.
|
||||
*/
|
||||
openSubMenu(menu, position) {
|
||||
const y = this.subMenuVerticalPosition(position);
|
||||
openSubMenu(menu, menuIndex) {
|
||||
const y = this.subMenuVerticalPosition(menuIndex);
|
||||
this.subMenu.position = {
|
||||
x: this.position.x + MENU_WIDTH,
|
||||
y: y - (this.subMenu.scrollOffset || 0),
|
||||
@@ -4921,10 +5118,10 @@
|
||||
this.subMenu.isOpen = false;
|
||||
this.subMenu.parentMenu = undefined;
|
||||
}
|
||||
onClickMenu(menu, position) {
|
||||
onClickMenu(menu, menuIndex) {
|
||||
if (this.isEnabled(menu)) {
|
||||
if (this.isRoot(menu)) {
|
||||
this.openSubMenu(menu, position);
|
||||
this.openSubMenu(menu, menuIndex);
|
||||
}
|
||||
else {
|
||||
this.activateMenu(menu);
|
||||
@@ -4955,7 +5152,7 @@
|
||||
onMenuClicked: { type: Function, optional: true },
|
||||
};
|
||||
|
||||
const LINK_TOOLTIP_HEIGHT = 43;
|
||||
const LINK_TOOLTIP_HEIGHT = 32;
|
||||
const LINK_TOOLTIP_WIDTH = 220;
|
||||
css /* scss */ `
|
||||
.o-link-tool {
|
||||
@@ -4966,6 +5163,9 @@
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: ${LINK_TOOLTIP_HEIGHT}px;
|
||||
width: ${LINK_TOOLTIP_WIDTH}px;
|
||||
box-sizing: border-box !important;
|
||||
|
||||
img {
|
||||
margin-right: 3px;
|
||||
@@ -5045,7 +5245,6 @@
|
||||
}
|
||||
LinkDisplay.components = { Menu };
|
||||
LinkDisplay.template = "o-spreadsheet-LinkDisplay";
|
||||
LinkDisplay.size = { width: LINK_TOOLTIP_WIDTH, height: LINK_TOOLTIP_HEIGHT };
|
||||
const LinkCellPopoverBuilder = {
|
||||
onHover: (position, getters) => {
|
||||
const cell = getters.getEvaluatedCell(position);
|
||||
@@ -5152,7 +5351,7 @@
|
||||
const MENU_OFFSET_Y = 100;
|
||||
const PADDING = 12;
|
||||
const LINK_EDITOR_WIDTH = 340;
|
||||
const LINK_EDITOR_HEIGHT = 180;
|
||||
const LINK_EDITOR_HEIGHT = 165;
|
||||
css /* scss */ `
|
||||
.o-link-editor {
|
||||
font-size: 13px;
|
||||
@@ -5162,6 +5361,9 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 4px;
|
||||
height: ${LINK_EDITOR_HEIGHT}px;
|
||||
width: ${LINK_EDITOR_WIDTH}px;
|
||||
|
||||
.o-section {
|
||||
.o-section-title {
|
||||
font-weight: bold;
|
||||
@@ -5314,7 +5516,6 @@
|
||||
}
|
||||
}
|
||||
LinkEditor.template = "o-spreadsheet-LinkEditor";
|
||||
LinkEditor.size = { width: LINK_EDITOR_WIDTH, height: LINK_EDITOR_HEIGHT };
|
||||
LinkEditor.components = { Menu };
|
||||
const LinkEditorPopoverBuilder = {
|
||||
onOpen: (position, getters) => {
|
||||
@@ -5943,6 +6144,30 @@
|
||||
})),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Aggregates data based on labels
|
||||
*/
|
||||
function aggregateDataForLabels(labels, datasets) {
|
||||
const parseNumber = (value) => (typeof value === "number" ? value : 0);
|
||||
const labelSet = new Set(labels);
|
||||
const labelMap = {};
|
||||
labelSet.forEach((label) => {
|
||||
labelMap[label] = new Array(datasets.length).fill(0);
|
||||
});
|
||||
for (const indexOfLabel of range(0, labels.length)) {
|
||||
const label = labels[indexOfLabel];
|
||||
for (const indexOfDataset of range(0, datasets.length)) {
|
||||
labelMap[label][indexOfDataset] += parseNumber(datasets[indexOfDataset].data[indexOfLabel]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
labels: Object.keys(labelMap),
|
||||
dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
|
||||
...dataset,
|
||||
data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
|
||||
})),
|
||||
};
|
||||
}
|
||||
function truncateLabel(label) {
|
||||
if (!label) {
|
||||
return "";
|
||||
@@ -6090,6 +6315,7 @@
|
||||
this.verticalAxisPosition = definition.verticalAxisPosition;
|
||||
this.legendPosition = definition.legendPosition;
|
||||
this.stacked = definition.stacked;
|
||||
this.aggregated = definition.aggregated;
|
||||
}
|
||||
static transformDefinition(definition, executed) {
|
||||
return transformChartDefinitionWithDataSetsWithZone(definition, executed);
|
||||
@@ -6103,6 +6329,7 @@
|
||||
dataSets: context.range ? context.range : [],
|
||||
dataSetsHaveTitle: false,
|
||||
stacked: false,
|
||||
aggregated: false,
|
||||
legendPosition: "top",
|
||||
title: context.title || "",
|
||||
type: "bar",
|
||||
@@ -6146,9 +6373,13 @@
|
||||
: undefined,
|
||||
title: this.title,
|
||||
stacked: this.stacked,
|
||||
aggregated: this.aggregated,
|
||||
};
|
||||
}
|
||||
getDefinitionForExcel() {
|
||||
// Excel does not support aggregating labels
|
||||
if (this.aggregated)
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
@@ -6220,6 +6451,9 @@
|
||||
let labels = labelValues.formattedValues;
|
||||
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
||||
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
||||
if (chart.aggregated) {
|
||||
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
||||
}
|
||||
const config = getBarConfiguration(chart, labels);
|
||||
const colors = new ChartColors();
|
||||
for (let { label, data } of dataSetsValues) {
|
||||
@@ -6379,6 +6613,7 @@
|
||||
this.legendPosition = definition.legendPosition;
|
||||
this.labelsAsText = definition.labelsAsText;
|
||||
this.stacked = definition.stacked;
|
||||
this.aggregated = definition.aggregated;
|
||||
}
|
||||
static validateChartDefinition(validator, definition) {
|
||||
return validator.checkValidations(definition, checkDataset, checkLabelRange);
|
||||
@@ -6398,6 +6633,7 @@
|
||||
verticalAxisPosition: "left",
|
||||
labelRange: context.auxiliaryRange || undefined,
|
||||
stacked: false,
|
||||
aggregated: false,
|
||||
};
|
||||
}
|
||||
getDefinition() {
|
||||
@@ -6417,6 +6653,7 @@
|
||||
title: this.title,
|
||||
labelsAsText: this.labelsAsText,
|
||||
stacked: this.stacked,
|
||||
aggregated: this.aggregated,
|
||||
};
|
||||
}
|
||||
getContextCreation() {
|
||||
@@ -6438,6 +6675,9 @@
|
||||
return new LineChart(definition, this.sheetId, this.getters);
|
||||
}
|
||||
getDefinitionForExcel() {
|
||||
// Excel does not support aggregating labels
|
||||
if (this.aggregated)
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
@@ -6582,6 +6822,9 @@
|
||||
if (axisType === "time") {
|
||||
({ labels, dataSetsValues } = fixEmptyLabelsForDateCharts(labels, dataSetsValues));
|
||||
}
|
||||
if (chart.aggregated) {
|
||||
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
||||
}
|
||||
const config = getLineConfiguration(chart, labels);
|
||||
const labelFormat = getLabelFormat(getters, chart.labelRange);
|
||||
if (axisType === "time") {
|
||||
@@ -6746,6 +6989,7 @@
|
||||
dataSets,
|
||||
labelsAsText: false,
|
||||
stacked: false,
|
||||
aggregated: false,
|
||||
labelRange: labelRangeXc,
|
||||
type: "line",
|
||||
background: BACKGROUND_CHART_COLOR,
|
||||
@@ -6761,6 +7005,7 @@
|
||||
type: "bar",
|
||||
background: BACKGROUND_CHART_COLOR,
|
||||
stacked: false,
|
||||
aggregated: false,
|
||||
dataSetsHaveTitle,
|
||||
verticalAxisPosition: "left",
|
||||
legendPosition: newLegendPos,
|
||||
@@ -7059,6 +7304,7 @@
|
||||
this.labelRange = createRange(getters, sheetId, definition.labelRange);
|
||||
this.background = definition.background;
|
||||
this.legendPosition = definition.legendPosition;
|
||||
this.aggregated = definition.aggregated;
|
||||
}
|
||||
static transformDefinition(definition, executed) {
|
||||
return transformChartDefinitionWithDataSetsWithZone(definition, executed);
|
||||
@@ -7075,6 +7321,7 @@
|
||||
title: context.title || "",
|
||||
type: "pie",
|
||||
labelRange: context.auxiliaryRange || undefined,
|
||||
aggregated: false,
|
||||
};
|
||||
}
|
||||
getDefinition() {
|
||||
@@ -7101,6 +7348,7 @@
|
||||
? this.getters.getRangeString(labelRange, targetSheetId || this.sheetId)
|
||||
: undefined,
|
||||
title: this.title,
|
||||
aggregated: this.aggregated,
|
||||
};
|
||||
}
|
||||
copyForSheetId(sheetId) {
|
||||
@@ -7114,6 +7362,9 @@
|
||||
return new PieChart(definition, sheetId, this.getters);
|
||||
}
|
||||
getDefinitionForExcel() {
|
||||
// Excel does not support aggregating labels
|
||||
if (this.aggregated)
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
@@ -7173,6 +7424,9 @@
|
||||
let labels = labelValues.formattedValues;
|
||||
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
||||
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
||||
if (chart.aggregated) {
|
||||
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
||||
}
|
||||
const config = getPieConfiguration(chart, labels);
|
||||
const colors = new ChartColors();
|
||||
for (let { label, data } of dataSetsValues) {
|
||||
@@ -9303,6 +9557,11 @@
|
||||
labelRange: this.labelRange,
|
||||
});
|
||||
}
|
||||
onUpdateAggregated(ev) {
|
||||
this.props.updateChart({
|
||||
aggregated: ev.target.checked,
|
||||
});
|
||||
}
|
||||
}
|
||||
LineBarPieConfigPanel.template = "o-spreadsheet-LineBarPieConfigPanel";
|
||||
LineBarPieConfigPanel.components = { SelectionInput };
|
||||
@@ -9318,6 +9577,11 @@
|
||||
stacked: ev.target.checked,
|
||||
});
|
||||
}
|
||||
onUpdateAggregated(ev) {
|
||||
this.props.updateChart({
|
||||
aggregated: ev.target.checked,
|
||||
});
|
||||
}
|
||||
}
|
||||
BarConfigPanel.template = "o-spreadsheet-BarConfigPanel";
|
||||
|
||||
@@ -9787,6 +10051,11 @@
|
||||
stacked: ev.target.checked,
|
||||
});
|
||||
}
|
||||
onUpdateAggregated(ev) {
|
||||
this.props.updateChart({
|
||||
aggregated: ev.target.checked,
|
||||
});
|
||||
}
|
||||
}
|
||||
LineConfigPanel.template = "o-spreadsheet-LineConfigPanel";
|
||||
|
||||
@@ -18340,6 +18609,31 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
TEXT: TEXT
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// HYPERLINK
|
||||
// -----------------------------------------------------------------------------
|
||||
const HYPERLINK = {
|
||||
description: _lt("Creates a hyperlink in a cell."),
|
||||
args: args(`
|
||||
url (string) ${_lt("The full URL of the link enclosed in quotation marks.")}
|
||||
link_label (string, optional) ${_lt("The text to display in the cell, enclosed in quotation marks.")}
|
||||
`),
|
||||
returns: ["STRING"],
|
||||
compute: function (url, linkLabel) {
|
||||
const processedUrl = toString(url).trim();
|
||||
const processedLabel = toString(linkLabel) || processedUrl;
|
||||
if (processedUrl === "")
|
||||
return processedLabel;
|
||||
return markdownLink(processedLabel, processedUrl);
|
||||
},
|
||||
isExported: true,
|
||||
};
|
||||
|
||||
var web = /*#__PURE__*/Object.freeze({
|
||||
__proto__: null,
|
||||
HYPERLINK: HYPERLINK
|
||||
});
|
||||
|
||||
const functions$3 = {
|
||||
database,
|
||||
date,
|
||||
@@ -18353,6 +18647,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
statistical,
|
||||
text,
|
||||
engineering,
|
||||
web,
|
||||
};
|
||||
const functionNameRegex = /^[A-Z0-9\_\.]+$/;
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -21792,13 +22087,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
if (!popover.isOpen) {
|
||||
return { isOpen: false };
|
||||
}
|
||||
const coordinates = popover.coordinates;
|
||||
const anchorRect = popover.anchorRect;
|
||||
return {
|
||||
...popover,
|
||||
// transform from the "canvas coordinate system" to the "body coordinate system"
|
||||
coordinates: {
|
||||
x: coordinates.x + this.props.gridPosition.x,
|
||||
y: coordinates.y + this.props.gridPosition.y,
|
||||
anchorRect: {
|
||||
...anchorRect,
|
||||
x: anchorRect.x + this.props.gridRect.x,
|
||||
y: anchorRect.y + this.props.gridRect.y,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -21806,10 +22102,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
GridPopover.template = "o-spreadsheet-GridPopover";
|
||||
GridPopover.components = { Popover };
|
||||
GridPopover.props = {
|
||||
gridPosition: Object,
|
||||
hoveredCell: Object,
|
||||
onClosePopover: Function,
|
||||
onMouseWheel: Function,
|
||||
gridRect: Object,
|
||||
};
|
||||
|
||||
class AbstractResizer extends owl.Component {
|
||||
@@ -22744,7 +23040,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
left: `${this.props.leftOffset + x}px`,
|
||||
bottom: "0px",
|
||||
height: `${SCROLLBAR_WIDTH$1}px`,
|
||||
right: `${SCROLLBAR_WIDTH$1}px`,
|
||||
right: `0px`,
|
||||
};
|
||||
}
|
||||
onScroll(offset) {
|
||||
@@ -22789,7 +23085,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
top: `${this.props.topOffset + y}px`,
|
||||
right: "0px",
|
||||
width: `${SCROLLBAR_WIDTH$1}px`,
|
||||
bottom: `${SCROLLBAR_WIDTH$1}px`,
|
||||
bottom: `0px`,
|
||||
};
|
||||
}
|
||||
onScroll(offset) {
|
||||
@@ -22953,6 +23249,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
this.hiddenInput = owl.useRef("hiddenInput");
|
||||
this.canvasPosition = useAbsolutePosition(this.gridRef);
|
||||
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
||||
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
||||
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
||||
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
||||
owl.useExternalListener(document.body, "paste", this.paste);
|
||||
@@ -23034,6 +23331,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
isCellHovered(col, row) {
|
||||
return this.hoveredCell.col === col && this.hoveredCell.row === row;
|
||||
}
|
||||
getGridRect() {
|
||||
return { ...this.canvasPosition, ...this.env.model.getters.getSheetViewDimensionWithHeaders() };
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Zone selection with mouse
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -24627,6 +24927,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
verticalAxisPosition: chartData.verticalAxisPosition,
|
||||
legendPosition: chartData.legendPosition,
|
||||
stacked: chartData.stacked || false,
|
||||
aggregated: false,
|
||||
labelsAsText: false,
|
||||
};
|
||||
}
|
||||
@@ -29282,6 +29583,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
}
|
||||
ImageFigure.template = "o-spreadsheet-ImageFigure";
|
||||
ImageFigure.components = { Menu };
|
||||
ImageFigure.props = {
|
||||
figure: Object,
|
||||
onFigureDeleted: Function,
|
||||
};
|
||||
|
||||
class ImagePlugin extends CorePlugin {
|
||||
constructor() {
|
||||
@@ -31199,6 +31504,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
this.isUpToDate = false;
|
||||
this.evaluatedCells = {};
|
||||
this.evalContext = config.external;
|
||||
this.lazyEvaluation = config.lazyEvaluation;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Command Handling
|
||||
@@ -31299,6 +31605,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
this.evaluatedCells[sheetId][col] = {};
|
||||
}
|
||||
this.evaluatedCells[sheetId][col][row] = evaluatedCell;
|
||||
if (!this.lazyEvaluation) {
|
||||
this.evaluatedCells[sheetId][col][row]();
|
||||
}
|
||||
}
|
||||
*getAllCells() {
|
||||
// use a generator function to avoid re-building a new object
|
||||
@@ -33763,7 +34072,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
? { isOpen: false }
|
||||
: {
|
||||
...popover,
|
||||
...this.computePopoverProps(this.persistentPopover, popover.cellCorner),
|
||||
anchorRect: this.computePopoverAnchorRect(this.persistentPopover),
|
||||
};
|
||||
}
|
||||
if (col === undefined ||
|
||||
@@ -33780,7 +34089,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
? { isOpen: false }
|
||||
: {
|
||||
...popover,
|
||||
...this.computePopoverProps(position, popover.cellCorner),
|
||||
anchorRect: this.computePopoverAnchorRect(position),
|
||||
};
|
||||
}
|
||||
getPersistentPopoverTypeAtPosition({ col, row }) {
|
||||
@@ -33791,29 +34100,13 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
computePopoverProps({ col, row }, corner) {
|
||||
const { width, height } = this.getters.getVisibleRect(positionToZone({ col, row }));
|
||||
return {
|
||||
coordinates: this.computePopoverPosition({ col, row }, corner),
|
||||
cellWidth: -width,
|
||||
cellHeight: -height,
|
||||
};
|
||||
}
|
||||
computePopoverPosition({ col, row }, corner) {
|
||||
computePopoverAnchorRect({ col, row }) {
|
||||
const sheetId = this.getters.getActiveSheetId();
|
||||
const merge = this.getters.getMerge({ sheetId, col, row });
|
||||
if (merge) {
|
||||
col = corner === "TopRight" ? merge.right : merge.left;
|
||||
row = corner === "TopRight" ? merge.top : merge.bottom;
|
||||
}
|
||||
// x, y are relative to the canvas
|
||||
const { x, y, width, height } = this.getters.getVisibleRect(positionToZone({ col, row }));
|
||||
switch (corner) {
|
||||
case "BottomLeft":
|
||||
return { x, y: y + height };
|
||||
case "TopRight":
|
||||
return { x: x + width, y: y };
|
||||
return this.getters.getVisibleRect(merge);
|
||||
}
|
||||
return this.getters.getVisibleRect(positionToZone({ col, row }));
|
||||
}
|
||||
}
|
||||
CellPopoverPlugin.getters = ["getCellPopover", "getPersistentPopoverTypeAtPosition"];
|
||||
@@ -38085,6 +38378,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
const gridRef = owl.useRef("grid");
|
||||
this.canvasPosition = useAbsolutePosition(gridRef);
|
||||
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
||||
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
||||
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimension());
|
||||
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
||||
this.moveCanvas(deltaX, deltaY);
|
||||
@@ -38185,6 +38479,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
offsetY: offsetScrollbarY + deltaY,
|
||||
});
|
||||
}
|
||||
getGridRect() {
|
||||
return { ...this.canvasPosition, ...this.env.model.getters.getSheetViewDimensionWithHeaders() };
|
||||
}
|
||||
}
|
||||
SpreadsheetDashboard.template = "o-spreadsheet-SpreadsheetDashboard";
|
||||
SpreadsheetDashboard.components = {
|
||||
@@ -42784,6 +43081,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
moveClient: () => { },
|
||||
snapshotRequested: false,
|
||||
notifyUI: (payload) => this.trigger("notify-ui", payload),
|
||||
lazyEvaluation: "lazyEvaluation" in config ? config.lazyEvaluation : true,
|
||||
};
|
||||
}
|
||||
setupCorePluginConfig() {
|
||||
@@ -42805,6 +43103,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
moveClient: this.session.move.bind(this.session),
|
||||
external: this.config.external,
|
||||
uiActions: this.config,
|
||||
lazyEvaluation: this.config.lazyEvaluation,
|
||||
};
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -42966,6 +43265,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
computeTextWidth,
|
||||
createEmptyWorkbookData,
|
||||
createEmptySheet,
|
||||
createEmptyExcelSheet,
|
||||
getDefaultChartJsRuntime,
|
||||
chartFontColor,
|
||||
getMenuChildren,
|
||||
@@ -43038,8 +43338,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
exports.__info__.version = '2.0.0';
|
||||
exports.__info__.date = '2022-12-20T11:01:03.280Z';
|
||||
exports.__info__.hash = '7daa2dd';
|
||||
exports.__info__.date = '2022-12-22T13:54:58.664Z';
|
||||
exports.__info__.hash = '4c5002d';
|
||||
|
||||
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|
||||
//# sourceMappingURL=o_spreadsheet.js.map
|
||||
|
||||
@@ -291,8 +291,8 @@
|
||||
/>
|
||||
<canvas t-ref="canvas"/>
|
||||
<GridPopover
|
||||
gridPosition="canvasPosition"
|
||||
hoveredCell="hoveredCell"
|
||||
gridRect="getGridRect()"
|
||||
onMouseWheel.bind="onMouseWheel"
|
||||
onClosePopover.bind="onClosePopover"
|
||||
/>
|
||||
@@ -633,8 +633,8 @@
|
||||
</t>
|
||||
<GridPopover
|
||||
t-if="!menuState.isOpen"
|
||||
gridPosition="canvasPosition"
|
||||
hoveredCell="hoveredCell"
|
||||
gridRect="getGridRect()"
|
||||
onMouseWheel.bind="onMouseWheel"
|
||||
onClosePopover.bind="onClosePopover"
|
||||
/>
|
||||
@@ -676,11 +676,11 @@
|
||||
<t t-name="o-spreadsheet-GridPopover" owl="1">
|
||||
<Popover
|
||||
t-if="cellPopover.isOpen"
|
||||
position="cellPopover.coordinates"
|
||||
childWidth="cellPopover.Component.size.width"
|
||||
childHeight="cellPopover.Component.size.height"
|
||||
flipHorizontalOffset="cellPopover.cellWidth"
|
||||
flipVerticalOffset="cellPopover.cellHeight"
|
||||
positioning="cellPopover.cellCorner"
|
||||
maxHeight="cellPopover.Component.size and cellPopover.Component.size.maxHeight"
|
||||
maxWidth="cellPopover.Component.size and cellPopover.Component.size.maxHidth"
|
||||
anchorRect="cellPopover.anchorRect"
|
||||
containerRect="env.getPopoverContainerRect()"
|
||||
onMouseWheel="props.onMouseWheel">
|
||||
<t
|
||||
t-component="cellPopover.Component"
|
||||
@@ -1458,12 +1458,12 @@
|
||||
<t t-name="o-spreadsheet-Menu" owl="1">
|
||||
<Popover
|
||||
t-if="props.menuItems.length"
|
||||
position="props.position"
|
||||
childWidth="MENU_WIDTH"
|
||||
childHeight="menuHeight"
|
||||
flipHorizontalOffset="popover.flipHorizontalOffset"
|
||||
flipVerticalOffset="popover.flipVerticalOffset"
|
||||
marginTop="popover.marginTop">
|
||||
anchorRect="popover.anchorRect"
|
||||
positioning="popover.positioning"
|
||||
verticalOffset="popover.verticalOffset"
|
||||
onPopoverHidden="() => this.closeSubMenu()"
|
||||
onPopoverMoved="() => this.closeSubMenu()"
|
||||
maxHeight="menuHeight">
|
||||
<div
|
||||
t-ref="menu"
|
||||
class="o-menu"
|
||||
@@ -1511,7 +1511,7 @@
|
||||
|
||||
<t t-name="o-spreadsheet-Popover" owl="1">
|
||||
<t t-portal="'.o-spreadsheet'">
|
||||
<div t-att-style="style" class="o-popover" t-on-wheel="props.onMouseWheel">
|
||||
<div class="o-popover" t-ref="popover" t-on-wheel="props.onMouseWheel">
|
||||
<t t-slot="default"/>
|
||||
</div>
|
||||
</t>
|
||||
@@ -1610,6 +1610,16 @@
|
||||
onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
|
||||
onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
|
||||
/>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="aggregated"
|
||||
t-att-checked="props.definition.aggregated"
|
||||
t-on-change="onUpdateAggregated"
|
||||
class="align-middle"
|
||||
/>
|
||||
Aggregate
|
||||
</label>
|
||||
</div>
|
||||
<div class="o-section o-sidepanel-error" t-if="errorMessages">
|
||||
<div t-foreach="errorMessages" t-as="error" t-key="error">
|
||||
@@ -1892,6 +1902,16 @@
|
||||
onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
|
||||
onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
|
||||
/>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="aggregated"
|
||||
t-att-checked="props.definition.aggregated"
|
||||
t-on-change="onUpdateAggregated"
|
||||
class="align-middle"
|
||||
/>
|
||||
Aggregate
|
||||
</label>
|
||||
</div>
|
||||
<div class="o-section o-sidepanel-error" t-if="errorMessages">
|
||||
<div t-foreach="errorMessages" t-as="error" t-key="error">
|
||||
@@ -1990,6 +2010,16 @@
|
||||
onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
|
||||
onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
|
||||
/>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="aggregated"
|
||||
t-att-checked="props.definition.aggregated"
|
||||
t-on-change="onUpdateAggregated"
|
||||
class="align-middle"
|
||||
/>
|
||||
Aggregate
|
||||
</label>
|
||||
<div t-if="canTreatLabelsAsText">
|
||||
<label>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user